diff --git a/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs b/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs index be3a35ac36..0d89518df1 100644 --- a/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs +++ b/crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs @@ -5,6 +5,17 @@ use wasmtime::{Linker, Module, Store}; use wasmtime_wasi::sync::{Wasi, WasiCtxBuilder}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { + run(data, bin_name, workspace, false) +} +pub fn instantiate_inherit_stdio( + data: &[u8], + bin_name: &str, + workspace: Option<&Path>, +) -> anyhow::Result<()> { + run(data, bin_name, workspace, true) +} + +fn run(data: &[u8], bin_name: &str, workspace: Option<&Path>, stdio: bool) -> anyhow::Result<()> { let stdout = WritePipe::new_in_memory(); let stderr = WritePipe::new_in_memory(); @@ -15,6 +26,10 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any // Additionally register any preopened directories if we have them. let mut builder = WasiCtxBuilder::new(); + if stdio { + builder = builder.inherit_stdio(); + } + builder = builder .arg(bin_name)? .arg(".")? @@ -26,24 +41,8 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(workspace) }?; builder = builder.preopened_dir(preopen_dir, ".")?; } - - #[cfg(windows)] - { - builder = builder - .env("ERRNO_MODE_WINDOWS", "1")? - .env("NO_DANGLING_FILESYSTEM", "1")? - .env("NO_FD_ALLOCATE", "1")? - .env("NO_RENAME_DIR_TO_EMPTY_DIR", "1")? - } - #[cfg(all(unix, not(target_os = "macos")))] - { - builder = builder.env("ERRNO_MODE_UNIX", "1")?; - } - #[cfg(target_os = "macos")] - { - builder = builder - .env("ERRNO_MODE_MACOS", "1")? - .env("NO_FD_ALLOCATE", "1")?; + for (var, val) in super::test_suite_environment() { + builder = builder.env(var, val)?; } // cap-std-sync does not yet support the sync family of fdflags @@ -82,41 +81,3 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any } } } - -pub fn instantiate_inherit_stdio( - data: &[u8], - bin_name: &str, - workspace: Option<&Path>, -) -> anyhow::Result<()> { - let r = { - let store = Store::default(); - - // Create our wasi context. - // Additionally register any preopened directories if we have them. - let mut builder = WasiCtxBuilder::new(); - - builder = builder.arg(bin_name)?.arg(".")?.inherit_stdio(); - - if let Some(workspace) = workspace { - println!("preopen: {:?}", workspace); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(workspace) }?; - builder = builder.preopened_dir(preopen_dir, ".")?; - } - - let snapshot1 = Wasi::new(&store, builder.build()?); - - let mut linker = Linker::new(&store); - - snapshot1.add_to_linker(&mut linker)?; - - let module = Module::new(store.engine(), &data).context("failed to create wasm module")?; - let instance = linker.instantiate(&module)?; - let start = instance.get_typed_func::<(), ()>("_start")?; - start.call(()).map_err(anyhow::Error::from) - }; - - match r { - Ok(()) => Ok(()), - Err(trap) => Err(trap.context(format!("error while testing Wasm module '{}'", bin_name,))), - } -} diff --git a/crates/test-programs/tests/wasm_tests/runtime/mod.rs b/crates/test-programs/tests/wasm_tests/runtime/mod.rs index caabcf7b30..0ef4f5d725 100644 --- a/crates/test-programs/tests/wasm_tests/runtime/mod.rs +++ b/crates/test-programs/tests/wasm_tests/runtime/mod.rs @@ -1,2 +1,34 @@ pub mod cap_std_sync; pub mod tokio; + +// Configure the test suite environment. +// Test programs use these environment variables to determine what behavior +// is expected: different errnos are expected on windows, mac, and other unixes, +// and other filesystem operations are supported or not. +pub fn test_suite_environment() -> &'static [(&str, &str)] { + #[cfg(windows)] + { + &[ + ("ERRNO_MODE_WINDOWS", "1"), + // Windows does not support dangling links or symlinks in the filesystem. + ("NO_DANGLING_FILESYSTEM", "1"), + // Windows does not support fd_allocate. + ("NO_FD_ALLOCATE", "1"), + // Windows does not support renaming a directory to an empty directory - + // empty directory must be deleted. + ("NO_RENAME_DIR_TO_EMPTY_DIR", "1"), + ] + } + #[cfg(all(unix, not(target_os = "macos")))] + { + &[("ERRNO_MODE_UNIX", "1")] + } + #[cfg(target_os = "macos")] + { + &[ + ("ERRNO_MODE_MACOS", "1"), + // MacOS does not support fd_allocate + ("NO_FD_ALLOCATE", "1"), + ] + } +} diff --git a/crates/test-programs/tests/wasm_tests/runtime/tokio.rs b/crates/test-programs/tests/wasm_tests/runtime/tokio.rs index 88bdb380a4..ba5fcf16db 100644 --- a/crates/test-programs/tests/wasm_tests/runtime/tokio.rs +++ b/crates/test-programs/tests/wasm_tests/runtime/tokio.rs @@ -5,6 +5,17 @@ use wasmtime::{Config, Engine, Linker, Module, Store}; use wasmtime_wasi::tokio::{Wasi, WasiCtxBuilder}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { + run(data, bin_name, workspace, false) +} +pub fn instantiate_inherit_stdio( + data: &[u8], + bin_name: &str, + workspace: Option<&Path>, +) -> anyhow::Result<()> { + run(data, bin_name, workspace, true) +} + +fn run(data: &[u8], bin_name: &str, workspace: Option<&Path>, stdio: bool) -> anyhow::Result<()> { let stdout = WritePipe::new_in_memory(); let stdout_ = stdout.clone(); let stderr = WritePipe::new_in_memory(); @@ -20,9 +31,12 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any let store = Store::new(&engine); // Create our wasi context. - // Additionally register any preopened directories if we have them. let mut builder = WasiCtxBuilder::new(); + if stdio { + builder = builder.inherit_stdio(); + } + builder = builder .arg(bin_name)? .arg(".")? @@ -35,26 +49,12 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any builder = builder.preopened_dir(preopen_dir, ".")?; } - #[cfg(windows)] - { - builder = builder - .env("ERRNO_MODE_WINDOWS", "1")? - .env("NO_DANGLING_FILESYSTEM", "1")? - .env("NO_FD_ALLOCATE", "1")? - .env("NO_RENAME_DIR_TO_EMPTY_DIR", "1")? - } - #[cfg(all(unix, not(target_os = "macos")))] - { - builder = builder.env("ERRNO_MODE_UNIX", "1")?; - } - #[cfg(target_os = "macos")] - { - builder = builder - .env("ERRNO_MODE_MACOS", "1")? - .env("NO_FD_ALLOCATE", "1")?; + for (var, val) in super::test_suite_environment() { + builder = builder.env(var, val)?; } - // cap-std-sync does not yet support the sync family of fdflags + // tokio does not yet support the sync family of fdflags, because cap-std-sync + // does not. builder = builder.env("NO_FDFLAGS_SYNC_SUPPORT", "1")?; Wasi::set_context(&store, builder.build()?) @@ -89,48 +89,3 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any } } } - -pub fn instantiate_inherit_stdio( - data: &[u8], - bin_name: &str, - workspace: Option<&Path>, -) -> anyhow::Result<()> { - let r = tokio::runtime::Runtime::new() - .expect("create runtime") - .block_on(async { - let mut config = Config::new(); - config.async_support(true); - config.consume_fuel(true); - Wasi::add_to_config(&mut config); - let engine = Engine::new(&config)?; - let store = Store::new(&engine); - - // Create our wasi context. - // Additionally register any preopened directories if we have them. - let mut builder = WasiCtxBuilder::new(); - - builder = builder.arg(bin_name)?.arg(".")?.inherit_stdio(); - - if let Some(workspace) = workspace { - println!("preopen: {:?}", workspace); - let preopen_dir = unsafe { cap_std::fs::Dir::open_ambient_dir(workspace) }?; - builder = builder.preopened_dir(preopen_dir, ".")?; - } - - store.out_of_fuel_async_yield(u32::MAX, 10000); - Wasi::set_context(&store, builder.build()?) - .map_err(|_| anyhow::anyhow!("wasi set_context failed"))?; - - let module = - Module::new(store.engine(), &data).context("failed to create wasm module")?; - let linker = Linker::new(&store); - let instance = linker.instantiate_async(&module).await?; - let start = instance.get_typed_func::<(), ()>("_start")?; - start.call_async(()).await.map_err(anyhow::Error::from) - }); - - match r { - Ok(()) => Ok(()), - Err(trap) => Err(trap.context(format!("error while testing Wasm module '{}'", bin_name,))), - } -}