From bcbfad968e9bf0e584c7db38dd6fc2d77a841e0f Mon Sep 17 00:00:00 2001 From: Zoraaver Singh Date: Mon, 21 Aug 2023 09:55:40 +0100 Subject: [PATCH] Run rust tests from wasi-testsuite --- .../sandboxed-system-primitives/src/posix.c | 193 ++++++++++-------- tests/wamr-test-suites/test_wamr.sh | 2 +- .../wasi-test-script/excluded_tests.json | 7 + .../wasi-test-script/run_wasi_tests.sh | 26 ++- 4 files changed, 145 insertions(+), 83 deletions(-) create mode 100644 tests/wamr-test-suites/wasi-test-script/excluded_tests.json diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index a9831d770b..779956f0dd 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -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) { @@ -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), @@ -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. @@ -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; @@ -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); @@ -824,25 +856,15 @@ __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; } @@ -850,8 +872,19 @@ wasmtime_ssp_fd_close(struct fd_table *curfds, struct fd_prestats *prestats, // 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; } @@ -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; } @@ -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 @@ -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; @@ -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); } diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index f336552074..1427c3262f 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -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 diff --git a/tests/wamr-test-suites/wasi-test-script/excluded_tests.json b/tests/wamr-test-suites/wasi-test-script/excluded_tests.json new file mode 100644 index 0000000000..8dae090ae9 --- /dev/null +++ b/tests/wamr-test-suites/wasi-test-script/excluded_tests.json @@ -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" + } +} \ No newline at end of file diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 37607859ba..a6698063f9 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -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}" @@ -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]} @@ -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