Path: blob/main/crates/wasi-common/tests/all/async_.rs
3124 views
use super::*;1use test_programs_artifacts::*;2use wasi_common::WasiCtx;3use wasi_common::tokio::{WasiCtxBuilder, add_to_linker};45foreach_p1!(assert_test_exists);67pub fn prepare_workspace(exe_name: &str) -> Result<TempDir> {8let prefix = format!("wasi_tokio_{exe_name}_");9let tempdir = tempfile::Builder::new().prefix(&prefix).tempdir()?;10Ok(tempdir)11}1213async fn run(path: &str, inherit_stdio: bool) -> Result<()> {14let path = Path::new(path);15let name = path.file_stem().unwrap().to_str().unwrap();16let workspace = prepare_workspace(name)?;17let stdout = WritePipe::new_in_memory();18let stderr = WritePipe::new_in_memory();19let r = {20let engine = test_programs_artifacts::engine(|_config| {});21let mut linker = Linker::<WasiCtx>::new(&engine);22add_to_linker(&mut linker, |cx| cx)?;2324// Create our wasi context.25// Additionally register any preopened directories if we have them.26let mut builder = WasiCtxBuilder::new();2728if inherit_stdio {29builder.inherit_stdio();30} else {31builder32.stdout(Box::new(stdout.clone()))33.stderr(Box::new(stderr.clone()));34}35builder.arg(name)?.arg(".")?;36println!("preopen: {workspace:?}");37let preopen_dir =38cap_std::fs::Dir::open_ambient_dir(workspace.path(), cap_std::ambient_authority())?;39builder.preopened_dir(preopen_dir, ".")?;40for (var, val) in test_programs_artifacts::wasi_tests_environment() {41builder.env(var, val)?;42}4344let mut store = Store::new(&engine, builder.build());45let module = Module::from_file(&engine, path)?;46let instance = linker.instantiate_async(&mut store, &module).await?;47let start = instance.get_typed_func::<(), ()>(&mut store, "_start")?;48start.call_async(&mut store, ()).await?;49Ok(())50};5152r.map_err(move |trap: EnvError| {53let stdout = stdout54.try_into_inner()55.expect("sole ref to stdout")56.into_inner();57if !stdout.is_empty() {58println!("guest stdout:\n{}\n===", String::from_utf8_lossy(&stdout));59}60let stderr = stderr61.try_into_inner()62.expect("sole ref to stderr")63.into_inner();64if !stderr.is_empty() {65println!("guest stderr:\n{}\n===", String::from_utf8_lossy(&stderr));66}67trap.context(format!(68"error while testing wasi-tests {name} with cap-std-sync"69))70})?;71Ok(())72}7374// Below here is mechanical: there should be one test for every binary in75// wasi-tests.76#[test_log::test(tokio::test(flavor = "multi_thread"))]77async fn p1_big_random_buf() {78run(P1_BIG_RANDOM_BUF, true).await.unwrap()79}80#[test_log::test(tokio::test(flavor = "multi_thread"))]81async fn p1_clock_time_get() {82run(P1_CLOCK_TIME_GET, true).await.unwrap()83}84#[test_log::test(tokio::test(flavor = "multi_thread"))]85async fn p1_close_preopen() {86run(P1_CLOSE_PREOPEN, true).await.unwrap()87}88#[test_log::test(tokio::test(flavor = "multi_thread"))]89async fn p1_dangling_fd() {90run(P1_DANGLING_FD, true).await.unwrap()91}92#[test_log::test(tokio::test(flavor = "multi_thread"))]93async fn p1_dangling_symlink() {94run(P1_DANGLING_SYMLINK, true).await.unwrap()95}96#[test_log::test(tokio::test(flavor = "multi_thread"))]97async fn p1_directory_seek() {98run(P1_DIRECTORY_SEEK, true).await.unwrap()99}100#[test_log::test(tokio::test(flavor = "multi_thread"))]101async fn p1_dir_fd_op_failures() {102run(P1_DIR_FD_OP_FAILURES, true).await.unwrap()103}104#[test_log::test(tokio::test(flavor = "multi_thread"))]105async fn p1_fd_advise() {106run(P1_FD_ADVISE, true).await.unwrap()107}108#[test_log::test(tokio::test(flavor = "multi_thread"))]109async fn p1_fd_filestat_get() {110run(P1_FD_FILESTAT_GET, true).await.unwrap()111}112#[test_log::test(tokio::test(flavor = "multi_thread"))]113async fn p1_fd_filestat_set() {114run(P1_FD_FILESTAT_SET, true).await.unwrap()115}116#[test_log::test(tokio::test(flavor = "multi_thread"))]117async fn p1_fd_flags_set() {118run(P1_FD_FLAGS_SET, true).await.unwrap()119}120#[test_log::test(tokio::test(flavor = "multi_thread"))]121async fn p1_fd_readdir() {122run(P1_FD_READDIR, true).await.unwrap()123}124#[test_log::test(tokio::test(flavor = "multi_thread"))]125async fn p1_file_allocate() {126run(P1_FILE_ALLOCATE, true).await.unwrap()127}128// see sync.rs for notes about ignores here129#[test_log::test(tokio::test(flavor = "multi_thread"))]130#[cfg_attr(not(target_os = "linux"), ignore)]131async fn p1_file_pread_pwrite() {132run(P1_FILE_PREAD_PWRITE, true).await.unwrap()133}134#[test_log::test(tokio::test(flavor = "multi_thread"))]135async fn p1_file_read_write() {136run(P1_FILE_READ_WRITE, true).await.unwrap()137}138#[test_log::test(tokio::test(flavor = "multi_thread"))]139async fn p1_file_seek_tell() {140run(P1_FILE_SEEK_TELL, true).await.unwrap()141}142#[test_log::test(tokio::test(flavor = "multi_thread"))]143async fn p1_file_truncation() {144run(P1_FILE_TRUNCATION, true).await.unwrap()145}146#[test_log::test(tokio::test(flavor = "multi_thread"))]147async fn p1_file_unbuffered_write() {148run(P1_FILE_UNBUFFERED_WRITE, true).await.unwrap()149}150#[test_log::test(tokio::test(flavor = "multi_thread"))]151async fn p1_interesting_paths() {152run(P1_INTERESTING_PATHS, true).await.unwrap()153}154#[test_log::test(tokio::test(flavor = "multi_thread"))]155async fn p1_regular_file_isatty() {156run(P1_REGULAR_FILE_ISATTY, false).await.unwrap()157}158#[test_log::test(tokio::test(flavor = "multi_thread"))]159async fn p1_nofollow_errors() {160run(P1_NOFOLLOW_ERRORS, true).await.unwrap()161}162#[test_log::test(tokio::test(flavor = "multi_thread"))]163async fn p1_overwrite_preopen() {164run(P1_OVERWRITE_PREOPEN, true).await.unwrap()165}166#[test_log::test(tokio::test(flavor = "multi_thread"))]167async fn p1_path_exists() {168run(P1_PATH_EXISTS, true).await.unwrap()169}170#[test_log::test(tokio::test(flavor = "multi_thread"))]171async fn p1_path_filestat() {172run(P1_PATH_FILESTAT, true).await.unwrap()173}174#[test_log::test(tokio::test(flavor = "multi_thread"))]175async fn p1_path_link() {176run(P1_PATH_LINK, true).await.unwrap()177}178#[test_log::test(tokio::test(flavor = "multi_thread"))]179async fn p1_path_open_create_existing() {180run(P1_PATH_OPEN_CREATE_EXISTING, true).await.unwrap()181}182#[test_log::test(tokio::test(flavor = "multi_thread"))]183async fn p1_path_open_read_write() {184run(P1_PATH_OPEN_READ_WRITE, true).await.unwrap()185}186#[test_log::test(tokio::test(flavor = "multi_thread"))]187async fn p1_path_open_dirfd_not_dir() {188run(P1_PATH_OPEN_DIRFD_NOT_DIR, true).await.unwrap()189}190#[test_log::test(tokio::test(flavor = "multi_thread"))]191async fn p1_path_open_missing() {192run(P1_PATH_OPEN_MISSING, true).await.unwrap()193}194#[test_log::test(tokio::test(flavor = "multi_thread"))]195async fn p1_path_open_nonblock() {196run(P1_PATH_OPEN_NONBLOCK, true).await.unwrap()197}198#[test_log::test(tokio::test(flavor = "multi_thread"))]199async fn p1_path_rename_dir_trailing_slashes() {200run(P1_PATH_RENAME_DIR_TRAILING_SLASHES, true)201.await202.unwrap()203}204#[test_log::test(tokio::test(flavor = "multi_thread"))]205async fn p1_path_rename() {206run(P1_PATH_RENAME, true).await.unwrap()207}208#[test_log::test(tokio::test(flavor = "multi_thread"))]209async fn p1_path_symlink_trailing_slashes() {210run(P1_PATH_SYMLINK_TRAILING_SLASHES, true).await.unwrap()211}212#[test_log::test(tokio::test(flavor = "multi_thread"))]213async fn p1_poll_oneoff_files() {214run(P1_POLL_ONEOFF_FILES, false).await.unwrap()215}216#[test_log::test(tokio::test(flavor = "multi_thread"))]217async fn p1_poll_oneoff_stdio() {218run(P1_POLL_ONEOFF_STDIO, true).await.unwrap()219}220#[test_log::test(tokio::test(flavor = "multi_thread"))]221async fn p1_readlink() {222run(P1_READLINK, true).await.unwrap()223}224#[test_log::test(tokio::test(flavor = "multi_thread"))]225async fn p1_remove_directory() {226run(P1_REMOVE_DIRECTORY, true).await.unwrap()227}228#[test_log::test(tokio::test(flavor = "multi_thread"))]229async fn p1_remove_nonempty_directory() {230run(P1_REMOVE_NONEMPTY_DIRECTORY, true).await.unwrap()231}232#[test_log::test(tokio::test(flavor = "multi_thread"))]233async fn p1_renumber() {234run(P1_RENUMBER, true).await.unwrap()235}236#[test_log::test(tokio::test(flavor = "multi_thread"))]237async fn p1_sched_yield() {238run(P1_SCHED_YIELD, true).await.unwrap()239}240#[test_log::test(tokio::test(flavor = "multi_thread"))]241async fn p1_stdio() {242run(P1_STDIO, true).await.unwrap()243}244#[test_log::test(tokio::test(flavor = "multi_thread"))]245async fn p1_stdio_isatty() {246// Only a valid test if the host executable's stdio is a terminal:247if test_programs_artifacts::stdio_is_terminal() {248// Inherit stdio, test asserts it is a tty:249run(P1_STDIO_ISATTY, true).await.unwrap()250}251}252#[test_log::test(tokio::test(flavor = "multi_thread"))]253async fn p1_stdio_not_isatty() {254// Don't inherit stdio, test asserts each is not tty:255run(P1_STDIO_NOT_ISATTY, false).await.unwrap()256}257#[test_log::test(tokio::test(flavor = "multi_thread"))]258async fn p1_symlink_create() {259run(P1_SYMLINK_CREATE, true).await.unwrap()260}261#[test_log::test(tokio::test(flavor = "multi_thread"))]262async fn p1_symlink_filestat() {263run(P1_SYMLINK_FILESTAT, true).await.unwrap()264}265#[test_log::test(tokio::test(flavor = "multi_thread"))]266async fn p1_symlink_loop() {267run(P1_SYMLINK_LOOP, true).await.unwrap()268}269#[test_log::test(tokio::test(flavor = "multi_thread"))]270async fn p1_unlink_file_trailing_slashes() {271run(P1_UNLINK_FILE_TRAILING_SLASHES, true).await.unwrap()272}273#[test_log::test(tokio::test(flavor = "multi_thread"))]274async fn p1_path_open_preopen() {275run(P1_PATH_OPEN_PREOPEN, true).await.unwrap()276}277#[test_log::test(tokio::test(flavor = "multi_thread"))]278async fn p1_unicode_output() {279run(P1_UNICODE_OUTPUT, true).await.unwrap()280}281#[test_log::test(tokio::test(flavor = "multi_thread"))]282async fn p1_file_write() {283run(P1_FILE_WRITE, true).await.unwrap()284}285#[test_log::test(tokio::test(flavor = "multi_thread"))]286async fn p1_path_open_lots() {287run(P1_PATH_OPEN_LOTS, true).await.unwrap()288}289290#[expect(291dead_code,292reason = "tested in the wasi-cli crate, satisfying foreach_api! macro"293)]294fn p1_cli_much_stdout() {}295296297