diff --git a/Cargo.lock b/Cargo.lock index df08919502a..f16024dd151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -891,6 +891,26 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "gumdrop" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46571f5d540478cf70d2a42dd0d6d8e9f4b9cc7531544b93311e657b86568a0b" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "half" version = "1.7.1" @@ -2364,6 +2384,18 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasi-test-generator" +version = "2.0.0" +dependencies = [ + "glob", + "gumdrop", + "serde", + "serde_json", + "tempfile", + "wast 24.0.0", +] + [[package]] name = "wasm-bindgen" version = "0.2.75" @@ -2926,7 +2958,7 @@ dependencies = [ "wasmer", "wasmer-vfs", "wasmer-wasi", - "wast", + "wast 37.0.0", ] [[package]] @@ -2948,6 +2980,7 @@ dependencies = [ "test-generator", "tracing", "tracing-subscriber", + "wasi-test-generator", "wasmer", "wasmer-cache", "wasmer-compiler", @@ -3003,6 +3036,15 @@ dependencies = [ "wasmparser 0.80.0", ] +[[package]] +name = "wast" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff1e3bd3ad0b2ee7784add89c30dc96b89a54b43e5d6d95d774eda1863b3500" +dependencies = [ + "leb128", +] + [[package]] name = "wast" version = "37.0.0" @@ -3018,7 +3060,7 @@ version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab2cc8d9a69d1ab28a41d9149bb06bb927aba8fc9d56625f8b597a564c83f50" dependencies = [ - "wast", + "wast 37.0.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a19e0789477..44449c8945e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ wasmer-engine-dylib = { version = "2.0.0", path = "lib/engine-dylib", optional = wasmer-engine-staticlib = { version = "2.0.0", path = "lib/engine-staticlib", optional = true } wasmer-wasi = { version = "2.0.0", path = "lib/wasi", optional = true } wasmer-wast = { version = "2.0.0", path = "tests/lib/wast", optional = true } +wasi-test-generator = { version = "2.0.0", path = "tests/wasi-wast", optional = true } wasmer-cache = { version = "2.0.0", path = "lib/cache", optional = true } wasmer-types = { version = "2.0.0", path = "lib/types" } wasmer-middlewares = { version = "2.0.0", path = "lib/middlewares", optional = true } @@ -50,6 +51,7 @@ members = [ "lib/wasi-types", "lib/wasi-experimental-io-devices", "lib/types", + "tests/wasi-wast", "tests/lib/wast", "tests/lib/compiler-test-derive", "tests/integration/cli", diff --git a/Makefile b/Makefile index 9c0d92e5c28..b73dc17d508 100644 --- a/Makefile +++ b/Makefile @@ -564,6 +564,9 @@ test-capi-integration-%: test-wasi-unit: cargo test --manifest-path lib/wasi/Cargo.toml --release +test-wasi: + cargo test --release --tests $(compiler_features) -- wasi::wasitests + test-examples: cargo test --release $(compiler_features) --features wasi --examples @@ -573,6 +576,10 @@ test-integration: test-integration-ios: cargo test -p wasmer-integration-tests-ios +generate-wasi-tests: +# Uncomment the following for installing the toolchain +# cargo run -p wasi-test-generator -- -s + cargo run -p wasi-test-generator -- -g ##### # # Packaging. diff --git a/lib/vfs/src/lib.rs b/lib/vfs/src/lib.rs index d69f52e8c13..b3fa148167f 100644 --- a/lib/vfs/src/lib.rs +++ b/lib/vfs/src/lib.rs @@ -35,6 +35,7 @@ pub trait FileSystem: fmt::Debug + Send + Sync + 'static { self.metadata(path) } fn remove_file(&self, path: &Path) -> Result<()>; + fn new_open_options(&self) -> OpenOptions; } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index ac6a546c0d7..b428447fe70 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1990,7 +1990,7 @@ pub fn path_remove_directory( ), } - if state.fs_remove_dir(path_str).is_err() { + if state.fs_remove_dir(host_path_to_remove).is_err() { // reinsert to prevent FS from being in bad state if let Kind::Dir { ref mut entries, .. @@ -2070,8 +2070,11 @@ pub fn path_rename( unreachable!("Fatal internal logic error: parent of inode is not a directory") } }; + let source_entry = match &mut state.fs.inodes[source_parent_inode].kind { - Kind::Dir { entries, .. } => wasi_try!(entries.remove(&source_entry_name), __WASI_EINVAL), + Kind::Dir { entries, .. } => { + wasi_try!(entries.remove(&source_entry_name), __WASI_EINVAL) + } Kind::Root { .. } => return __WASI_ENOTCAPABLE, Kind::Symlink { .. } | Kind::File { .. } | Kind::Buffer { .. } => { unreachable!("Fatal internal logic error: parent of inode is not a directory") @@ -2107,7 +2110,15 @@ pub fn path_rename( } } } - Kind::Dir { path, .. } => unimplemented!("wasi::path_rename on Directories"), + Kind::Dir { ref path, .. } => { + let cloned_path = path.clone(); + if let Err(e) = state.fs_rename(cloned_path, &host_adjusted_target_path) { + return e; + } + if let Kind::Dir { path, .. } = &mut state.fs.inodes[source_entry].kind { + *path = host_adjusted_target_path; + } + } Kind::Buffer { .. } => {} Kind::Symlink { .. } => {} Kind::Root { .. } => unreachable!("The root can not be moved"), diff --git a/tests/compilers/config.rs b/tests/compilers/config.rs index 406eea2eac8..8274ed20044 100644 --- a/tests/compilers/config.rs +++ b/tests/compilers/config.rs @@ -125,7 +125,7 @@ impl Config { self.add_middlewares(&mut compiler); Box::new(compiler) } - #[allow(dead_code)] + #[allow(unreachable_patterns)] compiler => { panic!( "The {:?} Compiler is not enabled. Enable it via the features", diff --git a/tests/wasi-wast/Cargo.toml b/tests/wasi-wast/Cargo.toml index 76ae5b76f53..bc8022faa02 100644 --- a/tests/wasi-wast/Cargo.toml +++ b/tests/wasi-wast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasi-test-generator" -version = "0.17.0" +version = "2.0.0" description = "Tests for our WASI implementation" license = "MIT" authors = ["Wasmer Engineering Team "] diff --git a/tests/wasi-wast/README.md b/tests/wasi-wast/README.md index 36968c6318f..a17321f8b4a 100644 --- a/tests/wasi-wast/README.md +++ b/tests/wasi-wast/README.md @@ -12,6 +12,9 @@ In order to run the test generator properly you will need: ## Usage ``` +Positional arguments: + free if you want to specify specific tests to generate + Optional arguments: -a, --all-versions Whether or not to do operations for all versions of WASI or just the latest. -g, --generate-wasm Whether or not the Wasm will be generated. @@ -26,6 +29,12 @@ cargo run -- -as # set up the toolchains for all targets cargo run -- -ag # generate the WASI tests for all targets ``` +If you want to generate specific tests (it's faster when you're developing) you can use this command: + +```bash +cargo run -- -g fd_rename_path # If you want to run the test in fd_rename_path.rs +``` + ## Updating in Wasmer Run diff --git a/tests/wasi-wast/src/main.rs b/tests/wasi-wast/src/main.rs index ce2a43e3f7a..fabdf052478 100644 --- a/tests/wasi-wast/src/main.rs +++ b/tests/wasi-wast/src/main.rs @@ -14,6 +14,9 @@ use gumdrop::Options; #[derive(Debug, Options)] pub struct TestGenOptions { + /// if you want to specify specific tests to generate + #[options(free)] + free: Vec, /// Whether or not to do operations for all versions of WASI or just the latest. all_versions: bool, /// Whether or not the Wasm will be generated. @@ -48,6 +51,7 @@ fn main() { // Generate the WASI Wasm files if generate_wasm { - build(wasi_versions); + let specific_tests: Vec<&str> = opts.free.iter().map(|st| st.as_str()).collect(); + build(wasi_versions, &specific_tests); } } diff --git a/tests/wasi-wast/src/wasi_version.rs b/tests/wasi-wast/src/wasi_version.rs index 10abf6785e8..88dd4c61b20 100644 --- a/tests/wasi-wast/src/wasi_version.rs +++ b/tests/wasi-wast/src/wasi_version.rs @@ -16,7 +16,7 @@ impl WasiVersion { pub fn get_compiler_toolchain(&self) -> &'static str { match self { WasiVersion::Unstable => "nightly-2019-09-13", - WasiVersion::Snapshot1 => "nightly-2019-12-18", + WasiVersion::Snapshot1 => "1.53.0", } } diff --git a/tests/wasi-wast/src/wasitests.rs b/tests/wasi-wast/src/wasitests.rs index 72fa7ab0b81..9ac9a861a2b 100644 --- a/tests/wasi-wast/src/wasitests.rs +++ b/tests/wasi-wast/src/wasitests.rs @@ -147,7 +147,6 @@ fn compile_wasm_for_version( .create(true) .open(&temp_wasi_rs_file_name) .unwrap(); - actual_file.write_all(b"#![feature(wasi_ext)]\n").unwrap(); actual_file.write_all(file_contents.as_bytes()).unwrap(); } @@ -246,13 +245,21 @@ fn compile(temp_dir: &Path, file: &str, wasi_versions: &[WasiVersion]) { } const WASI_TEST_SRC_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/wasi/tests/*.rs"); -pub fn build(wasi_versions: &[WasiVersion]) { +pub fn build(wasi_versions: &[WasiVersion], specific_tests: &[&str]) { let temp_dir = tempfile::TempDir::new().unwrap(); for entry in glob(WASI_TEST_SRC_DIR).unwrap() { match entry { Ok(path) => { let test = path.to_str().unwrap(); - compile(temp_dir.path(), test, wasi_versions); + if !specific_tests.is_empty() { + if let Some(filename) = path.file_stem().map(|f| f.to_str()).flatten() { + if specific_tests.contains(&filename) { + compile(temp_dir.path(), test, wasi_versions); + } + } + } else { + compile(temp_dir.path(), test, wasi_versions); + } } Err(e) => println!("{:?}", e), } diff --git a/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wasm b/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wasm new file mode 100755 index 00000000000..b16a95b6227 Binary files /dev/null and b/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wasm differ diff --git a/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wast b/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wast new file mode 100644 index 00000000000..fd3e59714b3 --- /dev/null +++ b/tests/wasi-wast/wasi/snapshot1/fd_rename_path.wast @@ -0,0 +1,6 @@ +;; This file was generated by https://github.com/wasmerio/wasi-tests + +(wasi_test "fd_rename_path.wasm" + (preopens "test_fs") + (assert_return (i64.const 0)) +) diff --git a/tests/wasi-wast/wasi/tests/fd_rename_path.rs b/tests/wasi-wast/wasi/tests/fd_rename_path.rs new file mode 100644 index 00000000000..d9b5d96021d --- /dev/null +++ b/tests/wasi-wast/wasi/tests/fd_rename_path.rs @@ -0,0 +1,18 @@ +// WASI: +// dir: test_fs + +use std::fs; +use std::path::PathBuf; + +fn main() { + let old_path = PathBuf::from("test_fs/wasitests/dirtorename"); + let new_path = PathBuf::from("test_fs/wasitests/dirrenamed"); + // Clean the test environment + let _ = fs::remove_dir(&old_path); + let _ = fs::remove_dir(&new_path); + + fs::create_dir_all(&old_path).expect("cannot create the directory"); + + fs::rename(old_path, &new_path).expect("cannot rename the directory"); + fs::remove_dir(&new_path).expect("cannot remove the directory"); +}