Skip to content

Commit d4fd229

Browse files
authored
Reorganize wasi-misc-tests. (#575)
* Reorganize wasi-misc-tests. Move wasi-misc-tests out of wasi-common, to break a dependency cycle; previously, wasmtime-* depended on wasi-common, but wasi-common dev-dependended on wasmtime-*. Now, wasi-common no longer dev-depends on wasmtime-*; instead, the tests are in their own crate which depends on wasi-common and on wasmtime-*. Also, rename wasi-misc-tests to wasi-tests for simplicity. This also removes the "wasm_tests" feature; it's replaced by the "test-programs" feature. * Update the CI script to use the new feature name. * Update the CI script to use the new feature name in one more place. * Change a `write!` to a `writeln!`.
1 parent b0f558a commit d4fd229

49 files changed

Lines changed: 328 additions & 337 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ jobs:
102102
- run: cargo fetch
103103

104104
# Build and test all features except for lightbeam
105-
- run: cargo test --features wasi-common/wasm_tests --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py -- --nocapture
105+
- run: cargo test --features test-programs --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py -- --nocapture
106106
env:
107107
RUST_BACKTRACE: 1
108108

@@ -219,7 +219,7 @@ jobs:
219219
- run: $CENTOS cargo build --release --manifest-path crates/api/Cargo.toml
220220
shell: bash
221221
# Test what we just built
222-
- run: $CENTOS cargo test --features wasi-common/wasm_tests --release --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py --exclude wasmtime
222+
- run: $CENTOS cargo test --features test-programs --release --all --exclude lightbeam --exclude wasmtime-wasi-c --exclude wasmtime-py --exclude wasmtime
223223
shell: bash
224224
env:
225225
RUST_BACKTRACE: 1

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ libc = "0.2.60"
4141
rayon = "1.1"
4242
wasm-webidl-bindings = "0.6"
4343
more-asserts = "0.2.1"
44+
# This feature requires the wasm32-wasi target be installed. It enables
45+
# wasm32-wasi integration tests. To enable, run
46+
# `cargo test --features test-programs`.
47+
test-programs = { path = "crates/test-programs", optional = true }
4448

4549
[build-dependencies]
4650
anyhow = "1.0.19"
@@ -51,8 +55,6 @@ members = [
5155
"crates/misc/py",
5256
]
5357

54-
exclude = ["crates/wasi-common/wasi-misc-tests"]
55-
5658
[features]
5759
lightbeam = [
5860
"wasmtime-environ/lightbeam",

crates/test-programs/Cargo.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "test-programs"
3+
version = "0.0.0"
4+
authors = ["The Wasmtime Project Developers"]
5+
readme = "README.md"
6+
edition = "2018"
7+
publish = false
8+
9+
[build-dependencies]
10+
cfg-if = "0.1.9"
11+
12+
[dev-dependencies]
13+
wasi-common = { path = "../wasi-common" }
14+
wasmtime-runtime = { path = "../runtime" }
15+
wasmtime-environ = { path = "../environ" }
16+
wasmtime-jit = { path = "../jit" }
17+
wasmtime-wasi = { path = "../wasi" }
18+
wasmtime = { path = "../api" }
19+
cranelift-codegen = "0.50.0"
20+
target-lexicon = "0.9.0"
21+
pretty_env_logger = "0.3.0"
22+
tempfile = "3.1.0"
23+
os_pipe = "0.9"
24+
anyhow = "1.0.19"

crates/test-programs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This is the `test-programs` crate, which builds and runs whole programs
2+
compiled to wasm32-wasi.

crates/test-programs/build.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//! Build program to generate a program which runs all the testsuites.
2+
//!
3+
//! By generating a separate `#[test]` test for each file, we allow cargo test
4+
//! to automatically run the files in parallel.
5+
6+
use std::env;
7+
use std::fs::{read_dir, DirEntry, File};
8+
use std::io::{self, Write};
9+
use std::path::{Path, PathBuf};
10+
use std::process::{Command, Stdio};
11+
12+
fn main() {
13+
build_and_generate_tests()
14+
}
15+
16+
fn build_and_generate_tests() {
17+
// Validate if any of test sources are present and if they changed
18+
// This should always work since there is no submodule to init anymore
19+
let bin_tests = std::fs::read_dir("wasi-tests/src/bin").unwrap();
20+
for test in bin_tests {
21+
if let Ok(test_file) = test {
22+
let test_file_path = test_file
23+
.path()
24+
.into_os_string()
25+
.into_string()
26+
.expect("test file path");
27+
println!("cargo:rerun-if-changed={}", test_file_path);
28+
}
29+
}
30+
// Build tests to OUT_DIR (target/*/build/wasi-common-*/out/wasm32-wasi/release/*.wasm)
31+
let out_dir =
32+
PathBuf::from(env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set"));
33+
let mut out =
34+
File::create(out_dir.join("wasi_tests.rs")).expect("error generating test source file");
35+
build_tests("wasi-tests", &out_dir).expect("building tests");
36+
test_directory(&mut out, "wasi-tests", &out_dir).expect("generating tests");
37+
}
38+
39+
fn build_tests(testsuite: &str, out_dir: &Path) -> io::Result<()> {
40+
let mut cmd = Command::new("cargo");
41+
cmd.args(&[
42+
"build",
43+
"--release",
44+
"--target=wasm32-wasi",
45+
"--target-dir",
46+
out_dir.to_str().unwrap(),
47+
])
48+
.stdout(Stdio::inherit())
49+
.stderr(Stdio::inherit())
50+
.current_dir(testsuite);
51+
let output = cmd.output()?;
52+
53+
let status = output.status;
54+
if !status.success() {
55+
panic!(
56+
"Building tests failed: exit code: {}",
57+
status.code().unwrap()
58+
);
59+
}
60+
61+
Ok(())
62+
}
63+
64+
fn test_directory(out: &mut File, testsuite: &str, out_dir: &Path) -> io::Result<()> {
65+
let mut dir_entries: Vec<_> = read_dir(out_dir.join("wasm32-wasi/release"))
66+
.expect("reading testsuite directory")
67+
.map(|r| r.expect("reading testsuite directory entry"))
68+
.filter(|dir_entry| {
69+
let p = dir_entry.path();
70+
if let Some(ext) = p.extension() {
71+
// Only look at wast files.
72+
if ext == "wasm" {
73+
// Ignore files starting with `.`, which could be editor temporary files
74+
if let Some(stem) = p.file_stem() {
75+
if let Some(stemstr) = stem.to_str() {
76+
if !stemstr.starts_with('.') {
77+
return true;
78+
}
79+
}
80+
}
81+
}
82+
}
83+
false
84+
})
85+
.collect();
86+
87+
dir_entries.sort_by_key(|dir| dir.path());
88+
89+
writeln!(
90+
out,
91+
"mod {} {{",
92+
Path::new(testsuite)
93+
.file_stem()
94+
.expect("testsuite filename should have a stem")
95+
.to_str()
96+
.expect("testsuite filename should be representable as a string")
97+
.replace("-", "_")
98+
)?;
99+
writeln!(out, " use super::{{runtime, utils, setup_log}};")?;
100+
for dir_entry in dir_entries {
101+
write_testsuite_tests(out, dir_entry, testsuite)?;
102+
}
103+
writeln!(out, "}}")?;
104+
Ok(())
105+
}
106+
107+
fn write_testsuite_tests(out: &mut File, dir_entry: DirEntry, testsuite: &str) -> io::Result<()> {
108+
let path = dir_entry.path();
109+
let stemstr = path
110+
.file_stem()
111+
.expect("file_stem")
112+
.to_str()
113+
.expect("to_str");
114+
115+
writeln!(out, " #[test]")?;
116+
if ignore(testsuite, stemstr) {
117+
writeln!(out, " #[ignore]")?;
118+
}
119+
writeln!(
120+
out,
121+
" fn r#{}() -> anyhow::Result<()> {{",
122+
&stemstr.replace("-", "_")
123+
)?;
124+
writeln!(out, " setup_log();")?;
125+
writeln!(
126+
out,
127+
" let path = std::path::Path::new(r#\"{}\"#);",
128+
path.display()
129+
)?;
130+
writeln!(out, " let data = utils::read_wasm(path)?;")?;
131+
writeln!(
132+
out,
133+
" let bin_name = utils::extract_exec_name_from_path(path)?;"
134+
)?;
135+
let workspace = if no_preopens(testsuite, stemstr) {
136+
"None"
137+
} else {
138+
writeln!(
139+
out,
140+
" let workspace = utils::prepare_workspace(&bin_name)?;"
141+
)?;
142+
"Some(workspace.path())"
143+
};
144+
writeln!(
145+
out,
146+
" runtime::instantiate(&data, &bin_name, {})",
147+
workspace
148+
)?;
149+
writeln!(out, " }}")?;
150+
writeln!(out)?;
151+
Ok(())
152+
}
153+
154+
cfg_if::cfg_if! {
155+
if #[cfg(not(windows))] {
156+
/// Ignore tests that aren't supported yet.
157+
fn ignore(_testsuite: &str, _name: &str) -> bool {
158+
false
159+
}
160+
} else {
161+
/// Ignore tests that aren't supported yet.
162+
fn ignore(testsuite: &str, name: &str) -> bool {
163+
if testsuite == "wasi-tests" {
164+
match name {
165+
"readlink_no_buffer" => true,
166+
"dangling_symlink" => true,
167+
"symlink_loop" => true,
168+
"truncation_rights" => true,
169+
"poll_oneoff" => true,
170+
"path_link" => true,
171+
_ => false,
172+
}
173+
} else {
174+
unreachable!()
175+
}
176+
}
177+
}
178+
}
179+
180+
/// Mark tests which do not require preopens
181+
fn no_preopens(testsuite: &str, name: &str) -> bool {
182+
if testsuite == "wasi-tests" {
183+
match name {
184+
"big_random_buf" => true,
185+
"clock_time_get" => true,
186+
"sched_yield" => true,
187+
_ => false,
188+
}
189+
} else {
190+
unreachable!()
191+
}
192+
}

crates/test-programs/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This crate doesn't contain any code; it just exists to run tests for
2+
// other crates in the workspace.

crates/wasi-common/tests/wasm_tests/main.rs renamed to crates/test-programs/tests/wasm_tests/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![cfg(feature = "wasm_tests")]
2-
31
mod runtime;
42
mod utils;
53

@@ -13,4 +11,4 @@ fn setup_log() {
1311
})
1412
}
1513

16-
include!(concat!(env!("OUT_DIR"), "/wasi_misc_tests.rs"));
14+
include!(concat!(env!("OUT_DIR"), "/wasi_tests.rs"));
File renamed without changes.
File renamed without changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "wasi-tests"
3+
version = "0.0.0"
4+
authors = ["The Wasmtime Project Developers"]
5+
readme = "README.md"
6+
edition = "2018"
7+
publish = false
8+
9+
[dependencies]
10+
libc = "0.2.65"
11+
wasi = "0.7.0"
12+
more-asserts = "0.2.1"
13+
14+
# This crate is built with the wasm32-wasi target, so it's separate
15+
# from the main Wasmtime build, so use this directive to exclude it
16+
# from the parent directory's workspace.
17+
[workspace]

0 commit comments

Comments
 (0)