Skip to content

Commit 2943424

Browse files
authored
Move all async tests to general folder (#1651)
* Move all async tests to general folder WASIp3 and component-model-async have shipped and are stable, so these are no longer expected to fail. * Try to fix CI failure * Try to fix Go in CI * Fix codegen test expectation * Another round of attempting ignores * Disable broken tests I'm tired of trying to work around them, just disable them. * Tweak CI configuration
1 parent 8936365 commit 2943424

155 files changed

Lines changed: 175 additions & 38 deletions

File tree

Some content is hidden

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

.github/actions/install-wasi-sdk/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ runs:
3434
- name: Setup `wasm-tools`
3535
uses: bytecodealliance/actions/wasm-tools/setup@v1
3636
with:
37-
version: "1.247.0"
37+
version: "1.252.0"
3838
- name: Setup `wasmtime`
3939
uses: bytecodealliance/actions/wasmtime/setup@v1
4040
with:
41-
version: "44.0.0"
41+
version: "46.0.1"

.github/workflows/main.yml

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,22 @@ jobs:
104104
dotnet-version: '9.x'
105105
if: matrix.lang == 'csharp'
106106

107+
# As of this writing async tests require [a patched build of
108+
# Go](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle).
109+
# Install this on Linux to get coverage, but don't install it on
110+
# macOS/Windows to also get coverage for test-without-a-patched-toolchain.
111+
- name: Install Patched Go
112+
run: |
113+
curl -OL https://github.com/dicej/go/releases/download/go1.25.5-wasi-on-idle/go-linux-amd64-bootstrap.tbz
114+
tar xf go-linux-amd64-bootstrap.tbz
115+
echo "$(pwd)/go-linux-amd64-bootstrap/bin" >> $GITHUB_PATH
116+
if: matrix.lang == 'go' && matrix.os == 'ubuntu-latest'
117+
107118
- name: Setup Go
108119
uses: actions/setup-go@v5
109120
with:
110121
go-version: 1.25.4
111-
if: matrix.lang == 'go'
122+
if: matrix.lang == 'go' && matrix.os != 'ubuntu-latest'
112123

113124
# Hacky work-around for https://github.com/dotnet/runtime/issues/80619
114125
- run: dotnet new console -o /tmp/foo
@@ -130,17 +141,17 @@ jobs:
130141
--artifacts target/artifacts \
131142
--rust-wit-bindgen-path ./crates/guest-rust
132143
133-
# Run all runtime tests for this language, and also enable Rust in case this
134-
# language only implements either the runner or test component
144+
# Run all runtime tests for this language, and also enable Rust & C in case
145+
# this language only implements either the runner or test component
135146
- run: |
136-
cargo run test --languages rust,${{ matrix.lang }} tests/runtime \
147+
cargo run test --languages rust,c,${{ matrix.lang }} tests/runtime \
137148
--artifacts target/artifacts \
138149
--rust-wit-bindgen-path ./crates/guest-rust
139150
140-
# While async is off-by-default and toolchains are percolating this is a
151+
# While threading is off-by-default and toolchains are percolating this is a
141152
# separate job to get configured slightly differently.
142-
async:
143-
name: Test Async (allowed to fail)
153+
threading:
154+
name: Test WASIp3 Threading (allowed to fail)
144155
runs-on: ubuntu-latest
145156
steps:
146157
- uses: actions/checkout@v4
@@ -151,18 +162,9 @@ jobs:
151162
run: rustup update stable --no-self-update && rustup default stable
152163
- run: rustup target add wasm32-wasip2
153164

154-
# As of this writing, we need [a patched build of
155-
# Go](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle) to
156-
# support async.
157-
- name: Install Patched Go
158-
run: |
159-
curl -OL https://github.com/dicej/go/releases/download/go1.25.5-wasi-on-idle/go-linux-amd64-bootstrap.tbz
160-
tar xf go-linux-amd64-bootstrap.tbz
161-
echo "$(pwd)/go-linux-amd64-bootstrap/bin" >> $GITHUB_PATH
162-
163165
- uses: ./.github/actions/install-wasi-sdk
164166
- run: |
165-
cargo run test --languages rust,c,go tests/runtime-async \
167+
cargo run test --languages rust,c,go tests/threading \
166168
--artifacts target/artifacts \
167169
--rust-wit-bindgen-path ./crates/guest-rust
168170
@@ -287,7 +289,6 @@ jobs:
287289
- verify-publish
288290
- check
289291
- msrv
290-
# - async
291292
if: always()
292293

293294
steps:

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/test/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ log = "0.4.26"
2626
regex = "1.11.1"
2727
serde = { workspace = true }
2828
toml = "1.1.2"
29-
wasi-preview1-component-adapter-provider = "45.0.1"
29+
wasi-preview1-component-adapter-provider = "46.0.1"
3030
wac-parser = "0.10.0"
3131
wac-types = "0.10.0"
3232
wac-graph = "0.10.0"

crates/test/src/c.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ impl LanguageMethods for C {
5252

5353
fn should_fail_verify(
5454
&self,
55+
_runner: &Runner,
5556
name: &str,
5657
config: &crate::config::WitConfig,
5758
_args: &[String],

crates/test/src/cpp.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl LanguageMethods for Cpp {
4141

4242
fn should_fail_verify(
4343
&self,
44+
_runner: &Runner,
4445
name: &str,
4546
config: &crate::config::WitConfig,
4647
_args: &[String],

crates/test/src/csharp.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl LanguageMethods for Csharp {
3636

3737
fn should_fail_verify(
3838
&self,
39+
_runner: &Runner,
3940
name: &str,
4041
_config: &crate::config::WitConfig,
4142
_args: &[String],

crates/test/src/custom.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ impl LanguageMethods for Language {
101101

102102
fn should_fail_verify(
103103
&self,
104+
_runner: &Runner,
104105
_name: &str,
105106
_config: &crate::config::WitConfig,
106107
_args: &[String],

crates/test/src/go.rs

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ use std::process::Command;
77

88
pub struct Go;
99

10+
/// Go-specific state, stored in `Runner`, detected during `prepare`.
11+
pub struct State {
12+
/// Whether the Go toolchain in use supports the `runtime.wasiOnIdle` hook
13+
/// required for component model async support.
14+
async_supported: bool,
15+
}
16+
17+
impl Runner {
18+
fn go_async_supported(&self) -> bool {
19+
self.go_state
20+
.as_ref()
21+
.map(|s| s.async_supported)
22+
.unwrap_or(false)
23+
}
24+
}
25+
1026
impl LanguageMethods for Go {
1127
fn display(&self) -> &str {
1228
"go"
@@ -18,19 +34,43 @@ impl LanguageMethods for Go {
1834

1935
fn should_fail_verify(
2036
&self,
37+
runner: &Runner,
2138
name: &str,
2239
config: &crate::config::WitConfig,
2340
_args: &[String],
2441
) -> bool {
25-
// TODO: We _do_ support async, but only with a build of Go that has
26-
// [this
27-
// patch](https://github.com/dicej/go/commit/40fc123d5bce6448fc4e4601fd33bad4250b36a5).
28-
// Once we upstream something equivalent, we can remove the ` || name ==
29-
// "async-trait-function.wit"` here.
30-
config.error_context
31-
|| name == "async-trait-function.wit"
32-
|| name == "named-fixed-length-list.wit"
33-
|| name == "issue-1598.wit"
42+
if config.error_context {
43+
return true;
44+
}
45+
if name == "named-fixed-length-list.wit" {
46+
return true;
47+
}
48+
if !runner.go_async_supported() {
49+
return name == "async-trait-function.wit" || name == "issue-1598.wit";
50+
}
51+
52+
false
53+
}
54+
55+
fn should_fail_compile(
56+
&self,
57+
runner: &Runner,
58+
path: &Path,
59+
config: &crate::config::WitConfig,
60+
) -> bool {
61+
// This test, even though it's part of async, compiles on any
62+
// toolchain.
63+
if path.ends_with("incomplete-writes/leaf.go") {
64+
return false;
65+
}
66+
67+
// Bindings for async tests rely on `runtime.wasiOnIdle` (see `prepare`
68+
// below) and fail to link without a toolchain that provides it.
69+
if !runner.go_async_supported() {
70+
return config.async_;
71+
}
72+
73+
false
3474
}
3575

3676
fn default_bindgen_args_for_codegen(&self) -> &[&str] {
@@ -56,7 +96,45 @@ impl LanguageMethods for Go {
5696
.arg("build")
5797
.arg("-buildmode=c-shared")
5898
.arg("-ldflags=-checklinkname=0"),
59-
)
99+
)?;
100+
101+
// Component model async support requires a `runtime.wasiOnIdle` hook
102+
// which, as of the time of this writing, is only available in a
103+
// patched build of Go. Detect whether the toolchain in use has
104+
// this hook by building a program that links against it, and if not
105+
// then async tests are expected to fail to build.
106+
println!("Testing if `go` supports `runtime.wasiOnIdle`...");
107+
let probe_dir = dir.join("wasi-on-idle-probe");
108+
super::write_if_different(
109+
&probe_dir.join("main.go"),
110+
r#"package main
111+
112+
import _ "unsafe"
113+
114+
//go:linkname wasiOnIdle runtime.wasiOnIdle
115+
func wasiOnIdle(callback func() bool)
116+
func init() { defer wasiOnIdle(func() bool { return false }) }
117+
func main() {}
118+
"#,
119+
)?;
120+
super::write_if_different(&probe_dir.join("go.mod"), "module probe\n\ngo 1.25")?;
121+
let async_supported = runner
122+
.run_command(
123+
Command::new("go")
124+
.current_dir(&probe_dir)
125+
.env("GOOS", "wasip1")
126+
.env("GOARCH", "wasm")
127+
.arg("build")
128+
.arg("-o")
129+
.arg("probe.wasm")
130+
.arg("-buildmode=c-shared")
131+
.arg("-ldflags=-checklinkname=0"),
132+
)
133+
.is_ok();
134+
println!("`runtime.wasiOnIdle` supported: {async_supported}");
135+
runner.go_state = Some(State { async_supported });
136+
137+
Ok(())
60138
}
61139

62140
fn compile(&self, runner: &Runner, compile: &Compile<'_>) -> Result<()> {

crates/test/src/lib.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ impl Opts {
137137
Runner {
138138
opts: self.clone(),
139139
rust_state: None,
140+
go_state: None,
140141
wit_bindgen: wit_bindgen.to_path_buf(),
141142
test_runner: runner::TestRunner::new(&self.runner)?,
142143
}
@@ -254,6 +255,7 @@ struct Verify<'a> {
254255
struct Runner {
255256
opts: Opts,
256257
rust_state: Option<rust::State>,
258+
go_state: Option<go::State>,
257259
wit_bindgen: PathBuf,
258260
test_runner: runner::TestRunner,
259261
}
@@ -578,7 +580,7 @@ impl Runner {
578580
let me = self.clone();
579581
let should_fail = language
580582
.obj()
581-
.should_fail_verify(&args_kind, &config, &args);
583+
.should_fail_verify(self, &args_kind, &config, &args);
582584

583585
let name = format!("{language} {args_kind} {test:?}");
584586
Trial::test(&name, move || {
@@ -703,17 +705,23 @@ impl Runner {
703705
let compilations = compilations.clone();
704706
let test = test.clone();
705707
let component = component.clone();
708+
let should_fail = component.language.obj().should_fail_compile(
709+
self,
710+
&component.path,
711+
&component.bindgen.wit_config,
712+
);
706713
Trial::test(&component.path.display().to_string(), move || {
707714
let result = me.compile_component(&test, &component).with_context(|| {
708715
format!("failed to compile component {:?}", component.path)
709716
});
710717
match result {
711-
Ok(path) => {
718+
Ok(path) if !should_fail => {
712719
compilations.lock().unwrap().push((test, component, path));
713720
Ok(())
714721
}
715-
Err(e) => me.render_error(
716-
StepResult::new(Err(e))
722+
other => me.render_error(
723+
StepResult::new(other.map(|_| ()))
724+
.should_fail(should_fail)
717725
.metadata("component", &component.name)
718726
.metadata("path", component.path.display()),
719727
),
@@ -1280,7 +1288,25 @@ trait LanguageMethods {
12801288

12811289
/// Returns whether this language is supposed to fail this codegen tests
12821290
/// given the `config` and `args` for the test.
1283-
fn should_fail_verify(&self, name: &str, config: &config::WitConfig, args: &[String]) -> bool;
1291+
fn should_fail_verify(
1292+
&self,
1293+
runner: &Runner,
1294+
name: &str,
1295+
config: &config::WitConfig,
1296+
args: &[String],
1297+
) -> bool;
1298+
1299+
/// Returns whether this language is expected to fail to compile the
1300+
/// runtime test component described by `config`.
1301+
fn should_fail_compile(
1302+
&self,
1303+
runner: &Runner,
1304+
path: &Path,
1305+
config: &config::WitConfig,
1306+
) -> bool {
1307+
let _ = (runner, path, config);
1308+
false
1309+
}
12841310

12851311
/// Performs a "check" or a verify that the generated bindings described by
12861312
/// `Verify` are indeed valid.

0 commit comments

Comments
 (0)