Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Commit

Permalink
Add wasmldr integration test(s)
Browse files Browse the repository at this point in the history
We can run wasm inside keeps now - let's prove it!

Here's what this patch does:

* Move wasm sources (*.wat) from internal/wasmldr/fixtures to tests/wasm
  * Copy .wat contents into wasmldr unittests and build inside the test
  * Remove wasmldr build.rs and update Cargo.toml
* Build tests/wasm/*.wat to OUT_DIR/bin/*.wasm in build.rs
* Add tests/wasmldr_tests.rs, which runs the .wasm test binaries

The intent is that we should be adding more wasm tests over time; this
gives us a place to put them and a harness to run them.

The tricky bit was getting Rust to pass the module to the
child process, since right now the only way we have to do that is to
pass it on FD3 - but Rust doesn't have `dup2()` and it *really* wants to
set FD_CLOEXEC on everything it opens, so we have to do some unsafe
things to actually pass FDs to a child process.

This isn't pretty, but it's a start.

Signed-off-by: Will Woods <[email protected]>
  • Loading branch information
wgwoods committed Oct 5, 2021
1 parent bcfcfa7 commit 6d6c487
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 52 deletions.
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ default = ["backend-kvm", "backend-sgx", "wasmldr"]

backend-kvm = ["x86_64", "kvm-bindings", "kvm-ioctls"]
backend-sgx = ["x86_64", "sgx"]
wasmldr = []
wasmldr = ["wat"]

[dependencies]
sgx = { git = "https://github.com/enarx/sgx", rev = "57df3753a0ea1777963dbf3023452993df2edb8c", features = ["openssl"], optional = true }
Expand Down Expand Up @@ -55,6 +55,7 @@ vdso = "0.1"

[build-dependencies]
cc = "1.0"
wat = { version = "1.0", optional = true }
walkdir = "2"
protobuf-codegen-pure = "2.25"
sallyport = { git = "https://github.com/enarx/sallyport", rev = "a567a22665c7e5ba88a8c4acd64ab43ee32b4681", features = [ "asm" ] }
Expand Down
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ fn build_cc_tests(in_path: &Path, out_path: &Path) {
}
}

#[cfg(feature = "wasmldr")]
fn build_wasm_tests(in_path: &Path, out_path: &Path) {
for wat in find_files_with_extensions(&["wat"], &in_path) {
let wasm = out_path
.join(wat.file_stem().unwrap())
.with_extension("wasm");
let bin = wat::parse_file(&wat).unwrap_or_else(|_| panic!("failed to compile {:?}", &wat));
std::fs::write(&wasm, &bin).unwrap_or_else(|_| panic!("failed to write {:?}", &wasm));
println!("cargo:rerun-if-changed={}", &wat.display());
}
}

// Build a binary named `bin_name` from the crate located at `in_dir`,
// targeting `target_name`, then strip the resulting binary and place it
// at `out_dir`/bin/`bin_name`.
Expand Down Expand Up @@ -235,6 +247,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

build_cc_tests(&Path::new(CRATE).join(TEST_BINS_IN), &out_dir_bin);
build_rs_tests(&Path::new(CRATE).join(TEST_BINS_IN), &out_dir_bin);
#[cfg(feature = "wasmldr")]
build_wasm_tests(&Path::new(CRATE).join("tests/wasm"), &out_dir_bin);

let target = "x86_64-unknown-linux-musl";

Expand Down
2 changes: 1 addition & 1 deletion internal/wasmldr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ anyhow = "1.0"
env_logger = { version = "0.9", default-features = false }
log = "0.4"

[build-dependencies]
[dev-dependencies]
wat = "1.0"

[profile.release]
Expand Down
26 changes: 0 additions & 26 deletions internal/wasmldr/build.rs

This file was deleted.

8 changes: 0 additions & 8 deletions internal/wasmldr/fixtures/bundle/config.yaml

This file was deleted.

1 change: 0 additions & 1 deletion internal/wasmldr/fixtures/bundle/stdin.txt

This file was deleted.

76 changes: 61 additions & 15 deletions internal/wasmldr/src/workload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,57 @@ pub(crate) mod test {
use crate::workload;
use std::iter::empty;

const NO_EXPORT_WAT: &'static str = r#"(module
(memory (export "") 1)
)"#;

const RETURN_1_WAT: &'static str = r#"(module
(func (export "") (result i32) i32.const 1)
)"#;

const WASI_COUNT_ARGS_WAT: &'static str = r#"(module
(import "wasi_snapshot_preview1" "args_sizes_get"
(func $__wasi_args_sizes_get (param i32 i32) (result i32)))
(func (export "_start") (result i32)
(i32.store (i32.const 0) (i32.const 0))
(i32.store (i32.const 4) (i32.const 0))
(call $__wasi_args_sizes_get (i32.const 0) (i32.const 4))
drop
(i32.load (i32.const 0))
)
(memory 1)
(export "memory" (memory 0))
)"#;

const HELLO_WASI_WAT: &'static str = r#"(module
(import "wasi_snapshot_preview1" "proc_exit"
(func $__wasi_proc_exit (param i32)))
(import "wasi_snapshot_preview1" "fd_write"
(func $__wasi_fd_write (param i32 i32 i32 i32) (result i32)))
(func $_start
(i32.store (i32.const 24) (i32.const 14))
(i32.store (i32.const 20) (i32.const 0))
(block
(br_if 0
(call $__wasi_fd_write
(i32.const 1)
(i32.const 20)
(i32.const 1)
(i32.const 16)))
(br_if 0 (i32.ne (i32.load (i32.const 16)) (i32.const 14)))
(br 1)
)
(call $__wasi_proc_exit (i32.const 1))
)
(memory 1)
(export "memory" (memory 0))
(export "_start" (func $_start))
(data (i32.const 0) "Hello, world!\0a")
)"#;

#[test]
fn workload_run_return_1() {
let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/fixtures/return_1.wasm")).to_vec();
let bytes = wat::parse_str(RETURN_1_WAT).expect("error parsing wat");

let results: Vec<i32> =
workload::run(&bytes, empty::<String>(), empty::<(String, String)>())
Expand All @@ -130,7 +178,7 @@ pub(crate) mod test {

#[test]
fn workload_run_no_export() {
let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/fixtures/no_export.wasm")).to_vec();
let bytes = wat::parse_str(NO_EXPORT_WAT).expect("error parsing wat");

match workload::run(&bytes, empty::<String>(), empty::<(String, String)>()) {
Err(workload::Error::ExportNotFound) => {}
Expand All @@ -139,9 +187,8 @@ pub(crate) mod test {
}

#[test]
fn workload_run_wasi_snapshot1() {
let bytes =
include_bytes!(concat!(env!("OUT_DIR"), "/fixtures/wasi_snapshot1.wasm")).to_vec();
fn workload_run_wasi_count_args() {
let bytes = wat::parse_str(WASI_COUNT_ARGS_WAT).expect("error parsing wat");

let results: Vec<i32> = workload::run(
&bytes,
Expand All @@ -156,18 +203,17 @@ pub(crate) mod test {
assert_eq!(results, vec![3]);
}

#[cfg(bundle_tests)]
#[test]
fn workload_run_bundled() {
let bytes = include_bytes!(concat!(
env!("OUT_DIR"),
"/fixtures/hello_wasi_snapshot1.bundled.wasm"
))
.to_vec();
fn workload_run_hello_wasi() {
let bytes = wat::parse_str(HELLO_WASI_WAT).expect("error parsing wat");
let args: Vec<String> = vec![];
let envs: Vec<(String, String)> = vec![];

let results = workload::run(&bytes, args, envs).unwrap();

workload::run(&bytes, empty::<&str>(), empty::<(&str, &str)>()).unwrap();
assert_eq!(results.len(), 0);

let output = std::fs::read("stdout.txt").unwrap();
assert_eq!(output, "Hello, world!\n".to_string().into_bytes());
// TODO/FIXME: we need a way to configure WASI stdout so we can capture
// and check it here...
}
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 6d6c487

Please sign in to comment.