Skip to content

Commit

Permalink
Run rust tests from wasi-testsuite
Browse files Browse the repository at this point in the history
  • Loading branch information
zoraaver committed Sep 20, 2023
1 parent d436e84 commit bcbfad9
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 83 deletions.
193 changes: 113 additions & 80 deletions core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ fd_prestats_init(struct fd_prestats *pt)

// Grows the preopened resource table to a required lower bound and a
// minimum number of free preopened resource table entries.
static bool
static __wasi_errno_t
fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr)
REQUIRES_EXCLUSIVE(pt->lock)
{
Expand All @@ -352,7 +352,7 @@ fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr)
struct fd_prestat *prestats =
wasm_runtime_malloc((uint32)(sizeof(*prestats) * size));
if (prestats == NULL)
return false;
return __WASI_ENOMEM;

if (pt->prestats && pt->size > 0) {
bh_memcpy_s(prestats, (uint32)(sizeof(*prestats) * size),
Expand All @@ -368,27 +368,39 @@ fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr)
pt->prestats = prestats;
pt->size = size;
}
return true;
return __WASI_ESUCCESS;
}

// Inserts a preopened resource record into the preopened resource table.
bool
fd_prestats_insert(struct fd_prestats *pt, const char *dir, __wasi_fd_t fd)
static __wasi_errno_t
fd_prestats_insert_locked(struct fd_prestats *pt, const char *dir,
__wasi_fd_t fd)
{
// Grow the preopened resource table if needed.
rwlock_wrlock(&pt->lock);
if (!fd_prestats_grow(pt, fd, 1)) {
rwlock_unlock(&pt->lock);
return false;
__wasi_errno_t error = fd_prestats_grow(pt, fd, 1);

if (error != __WASI_ESUCCESS) {
return error;
}

pt->prestats[fd].dir = bh_strdup(dir);
rwlock_unlock(&pt->lock);

if (pt->prestats[fd].dir == NULL)
return false;
return __WASI_ENOMEM;

return true;
return __WASI_ESUCCESS;
}

// Inserts a preopened resource record into the preopened resource table.
bool
fd_prestats_insert(struct fd_prestats *pt, const char *dir, __wasi_fd_t fd)
{
rwlock_wrlock(&pt->lock);

__wasi_errno_t error = fd_prestats_insert_locked(pt, dir, fd);

rwlock_unlock(&pt->lock);

return error == __WASI_ESUCCESS;
}

// Looks up a preopened resource table entry by number.
Expand All @@ -407,6 +419,24 @@ fd_prestats_get_entry(struct fd_prestats *pt, __wasi_fd_t fd,
return 0;
}

// Remove a preopened resource record from the preopened resource table by
// number
static __wasi_errno_t
fd_prestats_remove_entry(struct fd_prestats *pt, __wasi_fd_t fd)
{
// Test for file descriptor existence.
if (fd >= pt->size)
return __WASI_EBADF;
struct fd_prestat *prestat = &pt->prestats[fd];

if (prestat->dir != NULL) {
wasm_runtime_free((void *)prestat->dir);
prestat->dir = NULL;
}

return __WASI_ESUCCESS;
}

struct fd_object {
struct refcount refcount;
__wasi_filetype_t type;
Expand Down Expand Up @@ -808,12 +838,14 @@ wasmtime_ssp_fd_prestat_dir_name(struct fd_prestats *prestats, __wasi_fd_t fd,
rwlock_unlock(&prestats->lock);
return error;
}
if (path_len != strlen(prestat->dir)) {

const size_t prestat_dir_len = (size_t)strlen(prestat->dir);
if (path_len < prestat_dir_len) {
rwlock_unlock(&prestats->lock);
return EINVAL;
return __WASI_ENAMETOOLONG;
}

bh_memcpy_s(path, (uint32)path_len, prestat->dir, (uint32)path_len);
bh_memcpy_s(path, (uint32)path_len, prestat->dir, (uint32)prestat_dir_len);

rwlock_unlock(&prestats->lock);

Expand All @@ -824,34 +856,35 @@ __wasi_errno_t
wasmtime_ssp_fd_close(struct fd_table *curfds, struct fd_prestats *prestats,
__wasi_fd_t fd)
{
// Don't allow closing a pre-opened resource.
// TODO: Eventually, we do want to permit this, once libpreopen in
// userspace is capable of removing entries from its tables as well.
{
rwlock_rdlock(&prestats->lock);
struct fd_prestat *prestat;
__wasi_errno_t error = fd_prestats_get_entry(prestats, fd, &prestat);
rwlock_unlock(&prestats->lock);
if (error == 0) {
return __WASI_ENOTSUP;
}
}

// Validate the file descriptor.
struct fd_table *ft = curfds;
rwlock_wrlock(&ft->lock);
rwlock_wrlock(&prestats->lock);

struct fd_entry *fe;
__wasi_errno_t error = fd_table_get_entry(ft, fd, 0, 0, &fe);
if (error != 0) {
rwlock_unlock(&prestats->lock);
rwlock_unlock(&ft->lock);
return error;
}

// Remove it from the file descriptor table.
struct fd_object *fo;
fd_table_detach(ft, fd, &fo);

// Remove it from the preopened resource table if it exists
error = fd_prestats_remove_entry(prestats, fd);

rwlock_unlock(&prestats->lock);
rwlock_unlock(&ft->lock);

fd_object_release(fo);

if (error != __WASI_EBADF && error != 0) {
return error;
}

return 0;
}

Expand Down Expand Up @@ -1057,33 +1090,21 @@ __wasi_errno_t
wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats,
__wasi_fd_t from, __wasi_fd_t to)
{
// Don't allow renumbering over a pre-opened resource.
// TODO: Eventually, we do want to permit this, once libpreopen in
// userspace is capable of removing entries from its tables as well.
{
rwlock_rdlock(&prestats->lock);
struct fd_prestat *prestat;
__wasi_errno_t error = fd_prestats_get_entry(prestats, to, &prestat);
if (error != 0) {
error = fd_prestats_get_entry(prestats, from, &prestat);
}
rwlock_unlock(&prestats->lock);
if (error == 0) {
return __WASI_ENOTSUP;
}
}

struct fd_table *ft = curfds;
rwlock_wrlock(&ft->lock);
rwlock_wrlock(&prestats->lock);

struct fd_entry *fe_from;
__wasi_errno_t error = fd_table_get_entry(ft, from, 0, 0, &fe_from);
if (error != 0) {
rwlock_unlock(&prestats->lock);
rwlock_unlock(&ft->lock);
return error;
}
struct fd_entry *fe_to;
error = fd_table_get_entry(ft, to, 0, 0, &fe_to);
if (error != 0) {
rwlock_unlock(&prestats->lock);
rwlock_unlock(&ft->lock);
return error;
}
Expand All @@ -1100,8 +1121,45 @@ wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats,
fd_object_release(fo);
--ft->used;

// Handle renumbering of any preopened resources
struct fd_prestat *prestat_from;
__wasi_errno_t prestat_from_error =
fd_prestats_get_entry(prestats, from, &prestat_from);

struct fd_prestat *prestat_to;
__wasi_errno_t prestat_to_error =
fd_prestats_get_entry(prestats, to, &prestat_to);

// Renumbering over two preopened resources.
if (prestat_from_error == 0 && prestat_to_error == 0) {
error = fd_prestats_remove_entry(prestats, to);

if (error == 0) {
error = fd_prestats_insert_locked(prestats, prestat_from->dir, to);

if (error == 0) {
error = fd_prestats_remove_entry(prestats, from);
}
}
}
// Renumbering from a non-preopened fd to a preopened fd. In this case, we
// can't a keep the destination fd entry in the preopened table so remove
// it entirely.
else if (prestat_from_error != 0 && prestat_to_error == 0) {
error = fd_prestats_remove_entry(prestats, to);
}
// Renumbering from a preopened fd to a non-preopened fd
else if (prestat_from_error == 0 && prestat_to_error != 0) {
error = fd_prestats_insert_locked(prestats, prestat_from->dir, to);
if (error == 0) {
error = fd_prestats_remove_entry(prestats, from);
}
}

rwlock_unlock(&prestats->lock);
rwlock_unlock(&ft->lock);
return 0;

return error;
}

__wasi_errno_t
Expand Down Expand Up @@ -1871,31 +1929,20 @@ wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd,
needed_base |= __WASI_RIGHT_PATH_FILESTAT_SET_SIZE;
}

// It's not clear whether we want to support these flags in the standard
// yet: https://github.com/WebAssembly/wasi-filesystem/issues/98 so disable
// them in the meanwhile.
if (((fs_flags & __WASI_FDFLAG_DSYNC) != 0)
|| ((fs_flags & __WASI_FDFLAG_RSYNC) != 0)
|| ((fs_flags & __WASI_FDFLAG_SYNC) != 0)) {
return __WASI_ENOTSUP;
}

// Convert file descriptor flags.
if ((fs_flags & __WASI_FDFLAG_APPEND) != 0)
noflags |= O_APPEND;
if ((fs_flags & __WASI_FDFLAG_DSYNC) != 0) {
#ifdef O_DSYNC
noflags |= O_DSYNC;
#else
noflags |= O_SYNC;
#endif
needed_inheriting |= __WASI_RIGHT_FD_DATASYNC;
}
if ((fs_flags & __WASI_FDFLAG_NONBLOCK) != 0)
noflags |= O_NONBLOCK;
if ((fs_flags & __WASI_FDFLAG_RSYNC) != 0) {
#ifdef O_RSYNC
noflags |= O_RSYNC;
#else
noflags |= O_SYNC;
#endif
needed_inheriting |= __WASI_RIGHT_FD_SYNC;
}
if ((fs_flags & __WASI_FDFLAG_SYNC) != 0) {
noflags |= O_SYNC;
needed_inheriting |= __WASI_RIGHT_FD_SYNC;
}
if (write && (noflags & (O_APPEND | O_TRUNC)) == 0)
needed_inheriting |= __WASI_RIGHT_FD_SEEK;

Expand Down Expand Up @@ -1951,20 +1998,6 @@ wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd,
return error;
}

{
struct stat sb;

if (fstat(nfd, &sb) < 0) {
close(nfd);
return convert_errno(errno);
}

if (S_ISDIR(sb.st_mode))
rights_base |= (__wasi_rights_t)RIGHTS_DIRECTORY_BASE;
else if (S_ISREG(sb.st_mode))
rights_base |= (__wasi_rights_t)RIGHTS_REGULAR_FILE_BASE;
}

return fd_table_insert_fd(curfds, nfd, type, rights_base & max_base,
rights_inheriting & max_inheriting, fd);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/wamr-test-suites/test_wamr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ PLATFORM=$(uname -s | tr A-Z a-z)
PARALLELISM=0
ENABLE_QEMU=0
QEMU_FIRMWARE=""
WASI_TESTSUITE_COMMIT="aca78d919355ae00af141e6741a439039615b257"
WASI_TESTSUITE_COMMIT="cf64229727f71043d5849e73934e249e12cb9e06"

while getopts ":s:cabgvt:m:MCpSXxwPGQF:" opt
do
Expand Down
7 changes: 7 additions & 0 deletions tests/wamr-test-suites/wasi-test-script/excluded_tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"WASI threads proposal": {
"wasi_threads_exit_nonmain_wasi_read": "Pending implementation: termination of a thread blocking in a WASI call",
"wasi_threads_exit_main_wasi_read": "Pending implementation: termination of a thread blocking in a WASI call",
"wasi_threads_return_main_wasi_read": "Pending implementation: termination of a thread blocking in a WASI call"
}
}
26 changes: 24 additions & 2 deletions tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,29 @@ readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/b
readonly IWASM_CMD_STRESS="${IWASM_CMD} --max-threads=12"
readonly WAMRC_CMD="${WORK_DIR}/../../../../wamr-compiler/build/wamrc"
readonly C_TESTS="tests/c/testsuite/"
readonly RUST_TESTS="tests/rust/testsuite/"
readonly ASSEMBLYSCRIPT_TESTS="tests/assemblyscript/testsuite/"
readonly THREAD_PROPOSAL_TESTS="tests/proposals/wasi-threads/"
readonly THREAD_INTERNAL_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/test/"
readonly THREAD_STRESS_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/stress-test/"
readonly LIB_SOCKET_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/"

readonly TEST_FILTER="${WAMR_DIR}/tests/wamr-test-suites/wasi-test-script/excluded_tests.json"

run_aot_tests () {
local tests=("$@")
local -n tests=$1
local -n excluded_tests=$2

for test_wasm in ${tests[@]}; do
local test_name=$(basename -s .wasm $test_wasm)

for excluded_test in "${excluded_tests[@]}"; do
if [[ $excluded_test == "\"$test_name\"" ]]; then
echo "Skipping test $test_name"
continue 2
fi
done

local iwasm="${IWASM_CMD}"
if [[ $test_wasm =~ "stress" ]]; then
iwasm="${IWASM_CMD_STRESS}"
Expand Down Expand Up @@ -67,10 +81,12 @@ if [[ $MODE != "aot" ]];then
-r adapters/wasm-micro-runtime.py \
-t \
${C_TESTS} \
${RUST_TESTS} \
${ASSEMBLYSCRIPT_TESTS} \
${THREAD_PROPOSAL_TESTS} \
${THREAD_INTERNAL_TESTS} \
${LIB_SOCKET_TESTS} \
--exclude-filter ${TEST_FILTER}

ret=${PIPESTATUS[0]}

Expand All @@ -96,7 +112,13 @@ else
for testsuite in ${THREAD_STRESS_TESTS} ${THREAD_PROPOSAL_TESTS} ${THREAD_INTERNAL_TESTS}; do
tests=$(ls ${testsuite}*.wasm)
tests_array=($tests)
run_aot_tests "${tests_array[@]}"

readarray -t excluded_tests_array < <(jq -c \
--slurpfile testsuite_manifest $testsuite/manifest.json \
'.[$testsuite_manifest[0].name] // {} | keys[]' \
$TEST_FILTER)

run_aot_tests tests_array excluded_tests_array
done
fi

Expand Down

0 comments on commit bcbfad9

Please sign in to comment.