1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
use anyhow::Result;
use tempfile::TempDir;
use wasmtime::{
component::{Component, Linker, ResourceTable},
Engine, Store,
};
use wasmtime_wasi::preview1::WasiP1Ctx;
use wasmtime_wasi::{
pipe::MemoryOutputPipe, DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView,
};
struct Ctx {
stdout: MemoryOutputPipe,
stderr: MemoryOutputPipe,
wasi: WasiP1Ctx,
}
impl WasiView for Ctx {
fn table(&mut self) -> &mut ResourceTable {
self.wasi.table()
}
fn ctx(&mut self) -> &mut WasiCtx {
self.wasi.ctx()
}
}
fn prepare_workspace(exe_name: &str) -> Result<TempDir> {
let prefix = format!("wasi_components_{exe_name}_");
let tempdir = tempfile::Builder::new().prefix(&prefix).tempdir()?;
Ok(tempdir)
}
fn store(
engine: &Engine,
name: &str,
configure: impl FnOnce(&mut WasiCtxBuilder),
) -> Result<(Store<Ctx>, TempDir)> {
let stdout = MemoryOutputPipe::new(4096);
let stderr = MemoryOutputPipe::new(4096);
let workspace = prepare_workspace(name)?;
// Create our wasi context.
let mut builder = WasiCtxBuilder::new();
builder.stdout(stdout.clone()).stderr(stderr.clone());
builder
.args(&[name, "."])
.inherit_network()
.allow_ip_name_lookup(true);
println!("preopen: {workspace:?}");
builder.preopened_dir(workspace.path(), ".", DirPerms::all(), FilePerms::all())?;
for (var, val) in test_programs_artifacts::wasi_tests_environment() {
builder.env(var, val);
}
configure(&mut builder);
let ctx = Ctx {
wasi: builder.build_p1(),
stderr,
stdout,
};
Ok((Store::new(&engine, ctx), workspace))
}
impl Drop for Ctx {
fn drop(&mut self) {
let stdout = self.stdout.contents();
if !stdout.is_empty() {
println!("[guest] stdout:\n{}\n===", String::from_utf8_lossy(&stdout));
}
let stderr = self.stderr.contents();
if !stderr.is_empty() {
println!("[guest] stderr:\n{}\n===", String::from_utf8_lossy(&stderr));
}
}
}
// Assert that each of `sync` and `async` below are testing everything through
// assertion of the existence of the test function itself.
macro_rules! assert_test_exists {
($name:ident) => {
#[allow(unused_imports)]
use self::$name as _;
};
}
mod api;
mod async_;
mod preview1;
mod sync;
|