Stream: wasi

Topic: wasi-testsuite update for wasip3


view this post on Zulip Andy Wingo (Aug 14 2025 at 08:09):

Hello all, I am working on creating a test suite for wasip3. My near-term goal is to reach wasi-http, without sockets. The longer-term goal is a conformance test that will allow an implementation of wasi to be evaluated as actually implementing wasip3.

I will be primarily testing wasmtime but also jco on top of node.

On a suggestion from @Bailey Hayes I am looking at using wasi-testsuite as a base. I will post into this topic as I go, and will probably also poke people for questions :)

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Aug 14 2025 at 08:16):

So, where I'm at:

Now, these are wasip1 tests, and there's no real sense in putting effort into them, but I wonder if there isn't something to be done here; like, fopen-with-no-access asserts that errno is ENOTCAPABLE, which I gather is a very wasmtime-of-a-particular-epoch thing, and that ENOTCAPABLE isn't really a thing any more. Changing to ENOENT is more correct abstractly and allows the test to pass. This isn't limited to the C test suite, there are similar errors in the rust test suite.

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Aug 14 2025 at 08:20):

Going to tag in people that may be interested in the conversation; feel free to unset notifications: @Oscar Spencer @Joel Dice @Till Schneidereit @Alex Crichton @Pat Hickey @Tim Chevalier

view this post on Zulip Andy Wingo (Aug 14 2025 at 08:21):

also @Luke Wagner

view this post on Zulip Andy Wingo (Aug 14 2025 at 08:29):

I think what I will do is, for the C tests, the source will remain the same for wasip3. i will add additional accepted errnos, and the test will remain valid for previous versions of wasi. then i will move the rust tests to a separate wasip1 subdir, because they all use the wasip1 toolchain. then i will add a wasip3 subdir to the rusts tests and start porting simple tests there, before moving on to more interesting inter-component interactions.

view this post on Zulip Ralph (Aug 14 2025 at 12:01):

@Andy Wingo please tag me as well as you go.....

view this post on Zulip Pat Hickey (Aug 14 2025 at 14:53):

ENOTCAPABLE is a wasi preview 1 thing, which had a capability system called "rights" inherited from cloudabi that we decided to get rid of, not a wasmtime of era thing, but no matter. but yes, a fundamental problem here is that the tests were written in the preview 1 era and not updated since.

view this post on Zulip Pat Hickey (Aug 14 2025 at 14:54):

I agree with your approach to add more accepted errnos.

view this post on Zulip Pat Hickey (Aug 14 2025 at 14:55):

in general I was never all that happy with how the wasmtime wasi testsuite tests for behaviors that were pretty dependent on the host operating system shook out. e.g. theres flags to tell the test harness that this host doesnt support hardlinks, this host doesnt support removing nonempty dirs, things like that... basically the "is this windows or not" bit

view this post on Zulip Andy Wingo (Aug 14 2025 at 14:56):

so, after poking at it, i changed the build.sh for the c tests to be a build.py, and then i compile the generic c tests for wasm32-wasip{1,2,3} in separate directories. (wasip3 currently uses the wasip2 target triple.) there is also something to bring in version-specific tests. but to land that i am first going to update the wasi-sdk from 17 to 27, see if tests are green, move around the dirs so i can have version-specific tests, etc

view this post on Zulip Andy Wingo (Aug 14 2025 at 14:57):

i will stack some PRs. i am part of the wasm org i think so i may have some permissions there but who is the wasi-testsuite maintainer? i.e. who can lgtm?

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:00):

also, who uses the daily test results?

view this post on Zulip Pat Hickey (Aug 14 2025 at 15:00):

but, in practice, filesystem behaviors on windows vs elsewhere is the least interesting problem in all of wasi - ive yet to find anyone who cares who isnt just trying to tell their boss every single tests passes, or fuzz for differences between runtimes, neither of which are very interesting things to care about. we made some severe and sometimes regrettable compromises as dan and I banged my way through creating and updating the test suite for wasmtimes needs, and this is a fine time for a reckoning of "we really dont care about minutiae of file link behaviors" when in practice several prominent runtimes that claim to "support wasi" have had filesystem sandbox escapes for many many years and have no real interest in fixing it properly

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:01):

wow :)

view this post on Zulip Pat Hickey (Aug 14 2025 at 15:01):

i think historically marcin was the person to take the wasmtime wasi test suite and move it upstream into the webassembly org repos. I am happy to be your reviewer for things

view this post on Zulip Pat Hickey (Aug 14 2025 at 15:01):

daily test results? first im aware they exist tbh

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:02):

there is a github action or workflow or whatever to run tests nightly and commit the results to a git branch

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:02):

https://github.com/WebAssembly/wasi-testsuite/tree/prod/daily-test-results

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.

view this post on Zulip Pat Hickey (Aug 14 2025 at 15:02):

huh. how about that

view this post on Zulip Pat Hickey (Aug 14 2025 at 15:02):

i suppose lets pull up the git blame on the action and then ask them

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:03):

i'll cc them on the pr

view this post on Zulip Andy Wingo (Aug 14 2025 at 15:24):

https://github.com/WebAssembly/wasi-testsuite/issues/109 for an overview issue

Hello wasi-testsuite hackers, I would like to update wasi-testsuite to support newer versions of WASI. The idea would be that the scope of wasi-testsuite should be to test the versions of WASI that...

view this post on Zulip Andy Wingo (Aug 15 2025 at 09:05):

a small but gnarly issue for @Pat Hickey and @Alex Crichton, https://github.com/WebAssembly/wasi-testsuite/issues/111

In #95, a test was added that pwrite implements POSIX semantics (https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html). Note that Linux deviates from POSIX, ignoring the "offset" a...

view this post on Zulip Ralph (Aug 15 2025 at 09:06):

that IS a sticky wicket

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:24):

the toolchain to create components is very funny. one would hope that that component creation sediments down into the linker at some point

view this post on Zulip Lann Martin (Aug 15 2025 at 12:30):

Like this? https://github.com/bytecodealliance/wasm-component-ld/

Command line linker for creating WebAssembly components - bytecodealliance/wasm-component-ld

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:31):

ooh neat, i did not know that one :)

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:31):

/me comes from the web-targetting side of wasm, not much component model stuff there

view this post on Zulip Lann Martin (Aug 15 2025 at 12:33):

Like this? :slight_smile: https://github.com/bytecodealliance/jco/tree/main/packages/jco-transpile

JavaScript toolchain for working with WebAssembly Components - bytecodealliance/jco

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:33):

i know of jco! :)

view this post on Zulip Lann Martin (Aug 15 2025 at 12:37):

I can't disagree that it's "not much" from the outside, but it sure feels like a lot from the inside!

view this post on Zulip Ralph (Aug 15 2025 at 12:40):

@Andy Wingo gets to re-prove his chops..... :-P

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:41):

ahaha this is an opportunity to be a complete idiot for a while, i am also doing my first rust in anger

view this post on Zulip Ralph (Aug 15 2025 at 12:42):

oh the Rust in anger part never leaves. <insert Bruce Banner I'm always angry that's my secret here />

view this post on Zulip Ralph (Aug 15 2025 at 12:43):

enjoy your idiocy; we're super grateful for your help here.....

view this post on Zulip Andy Wingo (Aug 15 2025 at 12:44):

i'm happy to be here with yall!

view this post on Zulip Alex Crichton (Aug 15 2025 at 14:51):

https://github.com/bytecodealliance/wasm-component-ld/

Ah yeah this should be the default linker for wasm32-wasip2 (and a hypothetical wasm32-wasip3 future target). I'll note though that wasm-component-ld is a glorified wrapper around wasm-ld (the Real Wasm Linker) and wit-component which produces a component from a core module.

The executable should be bundled with wasi-sdk and unused on wasm32-wasip1 but used by default on wasm32-wasip2

view this post on Zulip Andy Wingo (Aug 15 2025 at 14:55):

ah i didn't realize wasm-component-ld was already in the sdk, neat. i think i was looking on https://github.com/bytecodealliance/wit-bindgen?tab=readme-ov-file#guest-cc which is probably out of date

A language binding generator for WebAssembly interface types - bytecodealliance/wit-bindgen

view this post on Zulip Alex Crichton (Aug 15 2025 at 14:57):

Ah yes sorry those docs are out of date

view this post on Zulip Alex Crichton (Aug 15 2025 at 14:57):

nowadays with wasm32-wasip2 no further steps are needed after clang

view this post on Zulip Andy Wingo (Aug 15 2025 at 14:57):

does one still need -mexec-model=reactor ?

view this post on Zulip Alex Crichton (Aug 15 2025 at 14:58):

to avoid an int main entrypoint, yes

view this post on Zulip Andy Wingo (Aug 18 2025 at 14:23):

current status, working on getting some rust-based wasip3 components into wasi-testsuite. needed to brush up on the rust components toolchain; close to done. hopefully i can send some prs tomorrow.

view this post on Zulip Andy Wingo (Aug 18 2025 at 14:26):

actually, talking through this a bit -- so wasi-http depends on wasi-clocks. i will probably first try to test wasi-clocks. what is the deal with the clocks-timezone feature, will that be part of wasip3 ?

view this post on Zulip Andy Wingo (Aug 18 2025 at 14:30):

and then, for testing clocks: there is no guarantee that the clock under test corresponds to the real time. (and in some ways it would be nice in a test if the clock could tick as fast as possible; i guess i will punt on that.) anyway as regards wasmtime, will one monotonic-clock second be equal to a real second when i run tests?

view this post on Zulip Andy Wingo (Aug 18 2025 at 14:32):

and are there wasmtime tests for wasi-clocks? i was looking but haven't seen them so far

view this post on Zulip Joel Dice (Aug 18 2025 at 14:41):

wasmtime-wasi's host API allows you to override the default clock implementations for the wall clock and monotonic clock, which we test here and here. There's also a very simple test for the default implementations here, but it doesn't assert anything very interesting at the moment.

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Andy Wingo (Aug 18 2025 at 14:42):

praise be, thank you!

view this post on Zulip Joel Dice (Aug 18 2025 at 14:45):

Regarding the timezone feature: looks like it's still an unstable feature in 0.3.0: https://github.com/WebAssembly/wasi-clocks/blob/main/wit-0.3.0-draft/timezone.wit. It could be stabilized as part of 0.3.0 or even before that in a 0.2.x release, but I don't know if anyone's working on that.

Clocks API for WASI. Contribute to WebAssembly/wasi-clocks development by creating an account on GitHub.

view this post on Zulip Joel Dice (Aug 18 2025 at 14:46):

In any case, I don't think we need to include it as part of the wasi-http-centric testing.

view this post on Zulip Bailey Hayes (Aug 18 2025 at 19:54):

Andy Wingo said:

actually, talking through this a bit -- so wasi-http depends on wasi-clocks. i will probably first try to test wasi-clocks. what is the deal with the clocks-timezone feature, will that be part of wasip3 ?

It is very likely that timezones will be stabilized by p3. Chatter here about steps needed before stabilization: https://github.com/WebAssembly/wasi-clocks/pull/79 @Colin D Murphy is working on updating impls and tests

This is the renaming part of #71 by @ptomato applied to the new wit-0.3.0-draft directory. (Edit: as well as some other changes prompted by discussion below.) As discussed in #69 (comment), the use...

view this post on Zulip Ralph (Aug 19 2025 at 06:43):

thanks @Colin D Murphy !!!

view this post on Zulip Andy Wingo (Aug 19 2025 at 12:49):

i have stupid questions

view this post on Zulip Andy Wingo (Aug 19 2025 at 12:49):

  1. what is the benefit of allowing cargo to build component-using code for the native target (not wasm32-wasip2)? it's obvious when it happens, i think anyway, but it's a weird outcome

view this post on Zulip Andy Wingo (Aug 19 2025 at 12:51):

  1. is it at all sensible to want to avoid cargo-component ? with wit-bindgen's inline WIT facility, i don't need to pre-build bindings, and i can have the WIT right next to the code i am testing. but perhaps cargo-component does some unavoidable wasm-tools magic

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:04):

  1. i realize this is the topic of the channel and project but what is the story for "cargo test" of wasm components written in rust? i suppose specifically for integration tests. i don't see anything in cargo to let you "wrap" binaries in some kind of runner script; it is probably there but i just haven't found it yet

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:13):

regarding (2), it would seem that building cdylibs with --target=wasm32-wasip2 makes components just fine, so no need for cargo-component.

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:14):

  1. how should wasi-testsuite import wasi packages, e.g. wasi:clocks? git submodule? or does wit-bindgen have an appropriate search path that for some reason i haven't populated yet

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:15):

@Andy Wingo you can definitely get by without cargo component, yes. Either by just using the p2 target, or even by targeting p1 and then using a combo of wasm-tools component embed and wasm-tools component new

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:16):

oh, and regarding (1), there are tools that don't yet support components. An example we're heavily reliant on with StarlingMonkey is wizer. For those cases, targeting p1, running the additional tools, then componentizing is the way to go

The WebAssembly Pre-Initializer. Contribute to bytecodealliance/wizer development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:23):

understood regarding -wasip1 but my comment was more about, say, x86_64-linux; weird that wit-bindgen's macros work on that target :)

view this post on Zulip Joel Dice (Aug 19 2025 at 13:24):

I think at least one of the reasons is being able to run e.g. cargo check or cargo clippy without having to specify a target.

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:25):

ah, I see! You're right that currently there are few uses for this. But not none! @Christof Petig has done a lot of work on making WIT work as an IDL for native code, for example

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:26):

regarding (3), I think this should work?

CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime [cli args as needed]" cargo test

I haven't tested this in a while myself though, so needs some experimentation for sure

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:26):

ooh neat

view this post on Zulip Lann Martin (Aug 19 2025 at 13:26):

You can also put this ^ in .cargo/config.toml

view this post on Zulip Lann Martin (Aug 19 2025 at 13:27):

Here's one from something I wrote recently (freshly tested!)

[build]
target = "wasm32-wasip2"
[target.wasm32-wasip2]
runner = "wasmtime run -D address-map"
[env]
WASMTIME_BACKTRACE_DETAILS = "1"

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:28):

thanks!

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:33):

Andy Wingo said:

  1. how should wasi-testsuite import wasi packages, e.g. wasi:clocks? git submodule? or does wit-bindgen have an appropriate search path that for some reason i haven't populated yet

ok what about this one :)

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:33):

what are you all doing in your wasip3-using packages

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:34):

I think wkg is the way to go for that?

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:35):

ahahaha i keep learning about new parts of the toolchain

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:35):

thanks!!

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:36):

which is obviously entirely on you, and not due to any properties of this ecosystem :halo:

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:36):

wellllllll a little of column a, a little of column b ;)

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:37):

okay, I'll accept that: it's probably 10:90 instead of 0:100

view this post on Zulip Lann Martin (Aug 19 2025 at 13:37):

The wkg UX is somewhat under-baked; if you want a full dependency tree you'll need a particular incantation combined with wasm-tools

view this post on Zulip Till Schneidereit (Aug 19 2025 at 13:40):

@Lann Martin do you think we can share that incantation, or is that still a well guarded trade secret?

view this post on Zulip Lann Martin (Aug 19 2025 at 13:42):

Working on it :slight_smile:

view this post on Zulip Lann Martin (Aug 19 2025 at 13:48):

# This will fetch the latest version w/o deps by default
$ wkg get wasi:http
No version specified; fetching version list...
Getting wasi:http@0.3.0-rc-2025-08-15...
Wrote './wasi_http@0.3.0-rc-2025-08-15.wit'

# Deps are included in the binary encoding...
$ wkg get wasi:http@0.3.0-rc-2025-08-15 -o wasi-http.wasm
Getting wasi:http@0.3.0-rc-2025-08-15...
Wrote 'wasi-http.wasm'

# ...which can be turned into a source tree with wasm-tools
$ wasm-tools component wit wasi-http.wasm --out-dir wit
Writing: wit/deps/clocks.wit
Writing: wit/deps/random.wit
Writing: wit/deps/cli.wit
Writing: wit/http.wit

view this post on Zulip Lann Martin (Aug 19 2025 at 13:49):

(wkg get should learn --out-dir)

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:58):

am a little surprised there isn't a stream<u8> to future<wasi:http/headers> method somewhere in wasi:http

view this post on Zulip Andy Wingo (Aug 19 2025 at 13:58):

one less thing to test :)

view this post on Zulip Lann Martin (Aug 19 2025 at 14:00):

Could you say more about what that method would do? wasi:http tries to abstract over protocol details

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:02):

afaics something outside wasi:http has to turn the byte stream into http headers. i.e. you provide the headers as structured data when making a request or response

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:02):

so you couldn't hook a wasi:http/handler right up to a socket, you need to write a little parser. fair enough, and it matches how some embedders will want to use it

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:02):

could be i'm holding the thing wrong tho

view this post on Zulip Lann Martin (Aug 19 2025 at 14:03):

Yeah, correct. In practice so far its mostly "whatever hyper does".

view this post on Zulip Lann Martin (Aug 19 2025 at 14:04):

The rough idea has been that wasi:http only deals with things that are in the HTTP Semantics spec, not anything specific to HTTP/1.1,2,3+

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:05):

ah yes, makes sense. i admit i have only ever implemented http/1.1

view this post on Zulip Lann Martin (Aug 19 2025 at 14:06):

In that case I'd highly recommend staring at this specific section: httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#field.host

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:24):

so, i am poking in a little playground repository. i have inline wit in my src/lib.rs:

wit_bindgen::generate!({inline: r"
  package test:playground;

  world the-world {
            import wasi:http/handler;
            //...
  }", path="wit"});

// ...

I have imported wasi:http into wit/http.wit as above:

Writing: wit/deps/clocks.wit
Writing: wit/deps/random.wit
Writing: wit/deps/cli.wit
Writing: wit/http.wit

Firstly it would seem that it's necessary to set path in the bindgen options, otherwise cargo / wit-bindgen don't search anywhere, despite the wit-bindgen docs saying there is a default path.

Secondly, the import fails in a funny way:

error: package 'wasi:http' not found. known packages:
           wasi:cli@0.3.0-rc-2025-08-15
           wasi:clocks@0.3.0-rc-2025-08-15
           wasi:random@0.3.0-rc-2025-08-15
           wasi:http@0.3.0-rc-2025-08-15
           test:playground

            --> macro-input:5:20
             |
           5 |             import wasi:http/handler;
             |                    ^--------
  --> src/lib.rs:3:1

I.e. you can see that it found wasi:http@0.3.0-rc-2025-08-15, and doesn't think that fulfills wasi:http. is wit-bindgen helpfully preventing me from using a prerelease wasip3 ?

view this post on Zulip Lann Martin (Aug 19 2025 at 14:28):

I think you need the version in the import

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:28):

yeah, import wasi:http/handler@0.3.0-rc...;

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:29):

despite the wit-bindgen docs saying there is a default path

This confuses me, your syntax of path = "wit" should have failed since it should be path: "wit", but also "wit" should be the default search location (relative to the crate root)

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:30):

ah, i had put the version after the handler, and didn't parse the error message correctly

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:31):

Alex Crichton said:

despite the wit-bindgen docs saying there is a default path

This confuses me, your syntax of path = "wit" should have failed since it should be path: "wit", but also "wit" should be the default search location (relative to the crate root)

sorry, that was a retype bug: i had path: "wit". but without path: "wit", at least with this inline wit, cargo does not look in the wit/ directory

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:31):

do you have a repo/branch I could repro on?

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:32):

(bug hunting adventure for me)

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:32):

sure i can throw it up somewhere

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:35):

https://wingolog.org/priv/playground.tar.gz, extracts to playground/, repro with cargo build --target=wasm32-wasip2

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:38):

aha ok inline disables the default path as otherwise if you used inline you'd have to ensure a wit directory exists -- either should update the documentation or keep the default wit path but don't require it to exist when inline is specified and path isn't specified

view this post on Zulip Andy Wingo (Aug 19 2025 at 14:40):

to be fair, who knows if inline will get much real use; but it seems nice for testing

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:40):

that's the reason for existence though, it's used all the time in testing wit-bindgen itself and a few places throughout wasmtime too

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:40):

basically it's too-damn-useful heh

view this post on Zulip Alex Crichton (Aug 19 2025 at 14:53):

https://github.com/bytecodealliance/wit-bindgen/pull/1356

This commit updates handling of the inline attribute in the generate! macro of the Rust bindings generator. Previously if inline was specified it would by default lookup nothing on the filesystem u...

view this post on Zulip Ralph (Aug 19 2025 at 14:54):

Till Schneidereit said:

ah, I see! You're right that currently there are few uses for this. But not none! Christof Petig has done a lot of work on making WIT work as an IDL for native code, for example

FWIW, there is experimental work at my megacorp doing something like this as well....

view this post on Zulip Pat Hickey (Aug 19 2025 at 16:57):

#wasi > wasi-testsuite update for wasip3 @ 💬 re turning raw streams into wasi-http, our hope is that for users who want to do that, there can be a component that provides that as library code. no need for the embedder to support it

view this post on Zulip Pat Hickey (Aug 19 2025 at 16:58):

the component could be implemented internally with hyper, or with whatever other http implementation is suitable

view this post on Zulip Lann Martin (Aug 19 2025 at 17:01):

It would be great to have a stable reference implementation for conformance testing

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:10):

so, we are testing wasi implementations more than the component model itself, so i think many tests can be made just with a single component implementing wasi:cli/run. and i guess i should be able to make run() async

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:11):

just as an ongoing log, a minimal test looks like this:

extern crate wit_bindgen;

wit_bindgen::generate!({inline: r"
  package test:playground;

  world the-world {
            include wasi:cli/command@0.3.0-rc-2025-08-15;
  }
", path: "wit", generate_all});

use wasi::clocks::monotonic_clock;

struct Test;

impl exports::wasi::cli::run::Guest for Test {
    fn run() -> Result<(), ()> {
        let start = monotonic_clock::now();
        let end = monotonic_clock::now();
        assert!(end <= start);
        Ok(())
    }
}

export!(Test);

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:12):

then you have to compile wasmtime via cargo build --features component-model-async, otherwise the wit linker won't find wasip3 interfaces; and then you have to run wasmtime with -Sp3=y to enable wasip3 at run-time

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:13):

this test fails as written, i had reversed end and start, just to see what would happen

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:13):

now that i can build components and run them, i will start adding some to wasi-testsuite

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:21):

also, a note, i am not sure how to use wkg to import a number of different packages; if you import wasi:httpas in #wasi > wasi-testsuite update for wasip3 @ 💬, it will residualize some parts of wasi:clocks in wit/deps/clocks.wit; then if you import wasi:cli, it will residualize a different set of wasi:clocks into wit/deps/clocks.wit

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:22):

in this current case i solved the issue by just importing wasi:cli, but that won't work once i start testing wasi:http

view this post on Zulip Andy Wingo (Aug 20 2025 at 08:26):

i suppose some of this weirdness is that i compiled a cdylib component; perhaps there are some ergonomic niceties for compiling implementations of wasi:cli/run if you make binary targets instead of libraries

view this post on Zulip Ralph (Aug 20 2025 at 08:48):

Andy Wingo said:

also, a note, i am not sure how to use wkg to import a number of different packages; if you import wasi:httpas in #wasi > wasi-testsuite update for wasip3 @ 💬, it will residualize some parts of wasi:clocks in wit/deps/clocks.wit; then if you import wasi:cli, it will residualize a different set of wasi:clocks into wit/deps/clocks.wit

this is probably an issue to file on wkg....

view this post on Zulip Milan (rajsite) (Aug 20 2025 at 09:00):

I've been using wkg fetch against a dummy package / world which seems to fetch all wit dependencies of the world to write to disk. Not sure how that compares to the wkg get <interface> -o <dummy>.wasm + wasm-tools component wit <dummy>.wasm workflow.

view this post on Zulip Lann Martin (Aug 20 2025 at 12:11):

If you manage your world in a wit/*.wit file then wkg wit fetch will indeed fetch and write deps appropriately.

view this post on Zulip Andy Wingo (Aug 20 2025 at 13:35):

tx milan & lann. for testing, where each test can define its own world inline, it would be nice to be able to fetch "all of wasi:clocks, all of wasi:sockets, ..." etc. even, all of wasip3, or wasi 1.0, ...
as it is with a dummy package, it seems i need to include each world in wasi:clocks by name

view this post on Zulip Lann Martin (Aug 20 2025 at 14:12):

You could have a wit file that imports the root interfaces you need just for the purposes of fetching dependencies. I _think_ inline would still pick up wit/deps/ in that scenario but I can never remember the exact behaviors there

view this post on Zulip Andy Wingo (Aug 20 2025 at 14:17):

it would seem that this is enough to get all of wasi:

world wasip3 {
    include wasi:cli/command@0.3.0-rc-2025-08-15;
    include wasi:clocks/imports@0.3.0-rc-2025-08-15;
    include wasi:filesystem/imports@0.3.0-rc-2025-08-15;
    include wasi:http/imports@0.3.0-rc-2025-08-15;
    include wasi:http/proxy@0.3.0-rc-2025-08-15;
    include wasi:random/imports@0.3.0-rc-2025-08-15;
    include wasi:sockets/imports@0.3.0-rc-2025-08-15;
}

view this post on Zulip Andy Wingo (Aug 20 2025 at 14:37):

can just include http/proxy, it pulls in http/imports (as cli/command imports cli/imports)

view this post on Zulip Andy Wingo (Aug 20 2025 at 14:53):

anyway, more toolchain weirdness:

mkdir wasi-test
cd wasi-test
cargo init
cargo add wit-bindgen

ok, make a dummy wit file and fetch the wits:

mkdir wit
cat > wit/wasip3.wit <<EOF
package test:dummy;
world wasip3 {
    include wasi:cli/command@0.3.0-rc-2025-08-15;
    include wasi:clocks/imports@0.3.0-rc-2025-08-15;
    include wasi:filesystem/imports@0.3.0-rc-2025-08-15;
    include wasi:http/proxy@0.3.0-rc-2025-08-15;
    include wasi:random/imports@0.3.0-rc-2025-08-15;
    include wasi:sockets/imports@0.3.0-rc-2025-08-15;
}
EOF
wkg wit fetch

It takes a little time but does make some wit files:

$ find wit
wit
wit/wasip3.wit
wit/deps
wit/deps/wasi-sockets-0.3.0-rc-2025-08-15
wit/deps/wasi-sockets-0.3.0-rc-2025-08-15/package.wit
wit/deps/wasi-random-0.3.0-rc-2025-08-15
wit/deps/wasi-random-0.3.0-rc-2025-08-15/package.wit
wit/deps/wasi-http-0.3.0-rc-2025-08-15
wit/deps/wasi-http-0.3.0-rc-2025-08-15/package.wit
wit/deps/wasi-clocks-0.3.0-rc-2025-08-15
wit/deps/wasi-clocks-0.3.0-rc-2025-08-15/package.wit
wit/deps/wasi-filesystem-0.3.0-rc-2025-08-15
wit/deps/wasi-filesystem-0.3.0-rc-2025-08-15/package.wit
wit/deps/wasi-cli-0.3.0-rc-2025-08-15
wit/deps/wasi-cli-0.3.0-rc-2025-08-15/package.wit

Now make src/main.rs:

extern crate wit_bindgen;

wit_bindgen::generate!({inline: r"
  package test:test;

  world test {
      include wasi:clocks/imports@0.3.0-rc-2025-08-15;
  }
", path: "wit", generate_all});

use wasi::clocks::monotonic_clock;

fn main() {
    let start = monotonic_clock::now();
    let end = monotonic_clock::now();
    assert!(start <= end);
}

Try to build:

cargo build --release --target=wasm32-wasip2

Failures in wit-bindgen:

error: failed to resolve directory while parsing WIT for path [/home/wingo/src/wasip3/wasi-test/wit]

       Caused by:
         interface not found in package
            --> /home/wingo/src/wasip3/wasi-test/wit/deps/wasi-cli-0.3.0-rc-2025-08-15/package.wit:157:22
             |
         157 |   import wasi:clocks/timezone@0.3.0-rc-2025-08-15;
             |                      ^-------
...

Which is weird because timezones are behind an unstable feature? OK, add features: ["clocks-timezone"] to the generate! invocation:

wit_bindgen::generate!({inline: r"
  package test:test;

  world test {
      include wasi:clocks/imports@0.3.0-rc-2025-08-15;
  }
", path: "wit", features: ["clocks-timezone"], generate_all});

Another weird wit-bindgen error:

error: multiple packages have a world, must specify which to use

Which, fair, there are other packages in wit/, but I gave it inline WIT, it should know to choose that world. Once you do this, it works:

wit_bindgen::generate!({inline: r"
  package test:test;

  world test {
      include wasi:clocks/imports@0.3.0-rc-2025-08-15;
  }
", path: "wit", features: ["clocks-timezone"], world: "test:test/test", generate_all});

And with that, it's the shortest sync test I can make. The resulting component still imports some wasip2 interfaces, so this is not a pure wasip3 test:

$ wasm-tools component wit target/wasm32-wasip2/release/playground.wasm
package root:component;

world root {
  import wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15;
  import wasi:cli/environment@0.2.3;
  import wasi:cli/exit@0.2.3;
  import wasi:io/error@0.2.3;
  import wasi:io/streams@0.2.3;
  import wasi:cli/stdin@0.2.3;
  import wasi:cli/stdout@0.2.3;
  import wasi:cli/stderr@0.2.3;
  import wasi:clocks/wall-clock@0.2.3;
  import wasi:filesystem/types@0.2.3;
  import wasi:filesystem/preopens@0.2.3;

  export wasi:cli/run@0.2.3;
}

But, fair enough, there isn't even a wasm32-wasip3 target for rustc yet.

view this post on Zulip Andy Wingo (Aug 20 2025 at 14:53):

cc @Alex Crichton for some of the wit-bindgen oddness

view this post on Zulip Alex Crichton (Aug 20 2025 at 14:56):

interface not found in package

We've had a lot of historical weirdness around include and feature-gated interfaces so this might be a legitimate bug there. If you avoid include-ing the imports interface and import the relevant ones directly I think it might work?

multiple packages have a world, must specify which to use

I think that may be due to my fix yesterday where with path plus inline it's thinking that there's two "root packages" to choose worlds from, I'll double check the behavior.

The resulting component still imports some wasip2 interfaces, so this is not a pure wasip3 test:

That's expected yeah, you're running into Rust's usage of WASIp1 in the standard library which gets adapted to WASIp2 through the adapter baked into wasm-component-ld

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:03):

Alex Crichton said:

interface not found in package

We've had a lot of historical weirdness around include and feature-gated interfaces so this might be a legitimate bug there. If you avoid include-ing the imports interface and import the relevant ones directly I think it might work?

Seems to not work; if after fetching I remove the wasip3.wit and change the inline wit to import wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15; instead of including, I still get the same error, which actually originates inside the wkg-imported package:

         interface not found in package
            --> /home/wingo/src/wasip3/wasi-test/wit/deps/wasi-cli-0.3.0-rc-2025-08-15/package.wit:157:22
             |
         157 |   import wasi:clocks/timezone@0.3.0-rc-2025-08-15;

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:03):

hm there may be other packages doing include wasi:clocks/imports maybe, I'll try to dig in in a bit (I need to learn wkg myself...)

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:05):

https://github.com/WebAssembly/wasi-cli/blob/965cbde225ac2d8bd5e3a5aa976c2840242d7b8d/wit-0.3.0-draft/imports.wit#L6

Command-Line Interface (CLI) World for WASI. Contribute to WebAssembly/wasi-cli development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:08):

(i wasn't sure if wkg would mangle the wit to either fabricate or elide the "include", but in this case it does seem to preserve the include)

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:14):

yeah I'll need to double-check how unstable things all work here, what you're doing should work but unstable features have been a thorn in our side for quite awhile

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:14):

it is not a blocker for me, i just wanted to write it down so i won't forget :)

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:15):

indeed, and thanks!

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:15):

thank you!

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:17):

otherwise today i talked a bit with @Marcin Kolny regarding wasi-testsuite organization, we seem to be on the same page regarding making wasi-testsuite useful for wasip3 and the broad lines of how to get there. will have some prs up tomorrow.

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:20):

avoiding the need to specify world:"..." when you've also specified inline should be fixed in https://github.com/bytecodealliance/wit-bindgen/pull/1358

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:23):

stupid question: would async fn main() make sense in wasip3, for binary targets? (of course it doesn't work. but it seems like it would be nice)

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:24):

it would, yeah, but probably won't get native language support for awhile

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:24):

i guess this would involve more work on the rustc toolchain, whereas building cdylibs can be a library thing

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:24):

what we could get working though is:

#[wit_bindgen::main]
async fn main() { ... }

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:25):

which is similar to #[tokio::main] used in a number of locations

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:25):

ah interesting

view this post on Zulip Lann Martin (Aug 20 2025 at 15:26):

Presumably you'd still have to build that as cdylib?

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:27):

would you? binary targets seem to produce working components without any special annotation in the Cargo.toml

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:27):

technically you wouldn't have to, but you likely would yeah

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:27):

(which makes my idea probably not work)

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:27):

it'd produce a workable component but it'd be "async stackful" in a sense instead of "async callback"

view this post on Zulip Andy Wingo (Aug 20 2025 at 15:28):

/me nod

view this post on Zulip Joel Dice (Aug 20 2025 at 15:30):

In case it's not obvious, you can certainly export an async wasi:cli/run#run function using wit-bindgen today with a bit of boilerplate, e.g. https://github.com/bytecodealliance/wasmtime/blob/main/crates/test-programs/src/bin/p3_cli.rs

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:32):

ok the other unstable-related issue is confirmed and minimized as:

package a:b1;

world the-world {
  include a:b2/the-world;
}

package a:b2 {
  world the-world {
    @unstable(feature = disabled)
    import a:b3/thing;
  }
}

package a:b3 {
  @unstable(feature = disabled)
  interface thing {}
}

(that fails as input to wasm-tools component wit)

view this post on Zulip Lann Martin (Aug 20 2025 at 15:34):

Would it be possible to have a

#[wit_bindgen::test]
async fn test_xxx { ... }

?

view this post on Zulip Alex Crichton (Aug 20 2025 at 15:36):

yeah we could probably get that working

view this post on Zulip Alex Crichton (Aug 20 2025 at 16:09):

(filed a bug here)

This input: package a:b1; world the-world { include a:b2/the-world; } package a:b2 { world the-world { @unstable(feature = disabled) import a:b3/thing; } } package a:b3 { @unstable(feature = disabl...

view this post on Zulip Andy Wingo (Aug 21 2025 at 14:09):

so, wasi-testsuite and wasmtime: there are some tests that fail on rust for --target=wasm32-wasip1. i triaged here: https://github.com/WebAssembly/wasi-testsuite/issues/101#issuecomment-3210744361. if there is a kind soul who is able to triage, that would be helpful

The "Daily runtime validation" workflow shows 9 failures on Wasmtime, which matches the behavior I see when running the tests locally. Is this a problem with the testsuite or with Wasmtime?

view this post on Zulip Andy Wingo (Aug 21 2025 at 14:32):

daily status: spent some time prepping wasi-testsuite for wasip3 tests: https://github.com/WebAssembly/wasi-testsuite/issues/109#issuecomment-3210363725. following up on marcin's review comments.
in the process i triaged the wasip1 tests mentioned in #wasi > wasi-testsuite update for wasip3 @ 💬

Hello wasi-testsuite hackers, I would like to update wasi-testsuite to support newer versions of WASI. The idea would be that the scope of wasi-testsuite should be to test the versions of WASI that...

view this post on Zulip Andy Wingo (Aug 21 2025 at 14:45):

so, it was a day of plumbing. but, fine, hopefully tomorrow i add the wasip3 things

view this post on Zulip Andy Wingo (Aug 22 2025 at 08:02):

https://github.com/WebAssembly/wasi-testsuite/issues/117

Summary I propose that if there are failing tests related to the WASI preview 1 rights API, that we modify or delete those tests to remove those assertions. Problem Wasmtime fails some tests curren...

view this post on Zulip Andy Wingo (Aug 22 2025 at 11:30):

so, is wasi-testsuite the right place for wasip3 tests?

view this post on Zulip Andy Wingo (Aug 22 2025 at 11:31):

i want to focus on wasip3 tests and there has probably too much "making space for wasip3" so far

view this post on Zulip Till Schneidereit (Aug 22 2025 at 11:32):

I think it might be okay to focus on wasip3 for expedience's sake for now, but long-term, it definitely is the right place, yes: once published, p3 will be the latest version of WASI, which should be reflected in the standard's test suite :slight_smile:

view this post on Zulip Andy Wingo (Aug 22 2025 at 11:35):

ok. i will just keep piling up the prs, hopefully one day things will go faster

view this post on Zulip Marcin Kolny (Aug 22 2025 at 11:37):

I think some refactoring is required at the beginning as wasi-testsuite wasn't designed initially for multiple wasi versions. Once we'll go through that phase, further development should be easier.

view this post on Zulip Andy Wingo (Aug 22 2025 at 12:01):

wasip1 tests found a nice wasmtime bug: https://github.com/WebAssembly/wasi-testsuite/issues/101#issuecomment-3214123363

The "Daily runtime validation" workflow shows 9 failures on Wasmtime, which matches the behavior I see when running the tests locally. Is this a problem with the testsuite or with Wasmtime?

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:12):

hmm, i am a bit perplexed. consider this file:

extern crate wit_bindgen;

wit_bindgen::generate!({
    inline: r"
  package test:test;

  world test {
      include wasi:clocks/imports@0.3.0-rc-2025-08-15;
      include wasi:cli/command@0.3.0-rc-2025-08-15;
  }
",
    // Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
    features:["clocks-timezone"],
    async: [
        "wasi:cli/run@0.3.0-rc-2025-08-15#run",
    ],
    generate_all
});

use wasi::clocks::monotonic_clock;

struct Component;
export!(Component);

impl exports::wasi::cli::run::Guest for Component {
    async fn run() -> Result<(), ()> {
        monotonic_clock::wait_for(50_000u64).await;
        Ok(())
    }
}

fn main() {}

placed in src/bin/minimal.rs, there are the needed wit files in wit/. Build via cargo build --target=wasm32-wasip2 --release --bin minimal, with wit-bindgen from git. It has an error:

[dev-env] wingo@beastie ~/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3$ cargo build --target=wasm32-wasip2 --release --bin minimal
   Compiling test-wasm32-wasip3 v0.1.0 (/home/wingo/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3)
error: linking with `wasm-component-ld` failed: exit status: 1
  |
  = note:  "wasm-component-ld" "-flavor" "wasm" "--export" "[async-lift]wasi:cli/run@0.3.0-rc-2025-08-15#run" "--export" "[callback][async-lift]wasi:cli/run@0.3.0-rc-2025-08-15#run" "--export" "__main_void" "--export" "cabi_realloc" "-z" "stack-size=1048576" "--stack-first" "--allow-undefined" "--no-demangle" "<sysroot>/lib/rustlib/wasm32-wasip2/lib/self-contained/crt1-command.o" "<2 object files omitted>" "/home/wingo/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3/target/wasm32-wasip2/release/deps/{libwit_bindgen-d3f7658c15e3bc1f.rlib,libwit_bindgen_rt-e215225e28d37754.rlib,libfutures-1e3aa9526458c95b.rlib,libfutures_executor-4c14e82b92128eea.rlib,libfutures_util-d4d1ebf3054ace8e.rlib,libmemchr-2857ac1428ecf686.rlib,libfutures_io-bd6f5f056e177761.rlib,libslab-b3944246b67457c3.rlib,libfutures_channel-af04b86abb9667b5.rlib,libpin_project_lite-38e8286ac72dc06c.rlib,libfutures_sink-87533dcfb4185e08.rlib,libfutures_task-4934eebbf3d64f90.rlib,libpin_utils-1407d4781aab0b76.rlib,libfutures_core-c2a2480a6530cd71.rlib,libbitflags-77083259b2ec5fc4.rlib}.rlib" "<sysroot>/lib/rustlib/wasm32-wasip2/lib/{libstd-*,libpanic_abort-*,libwasi-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*}.rlib" "-l" "c" "<sysroot>/lib/rustlib/wasm32-wasip2/lib/{librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-L" "/home/wingo/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3/target/wasm32-wasip2/release/build/wit-bindgen-rt-f69b726d7f89fc43/out" "-L" "<sysroot>/lib/rustlib/wasm32-wasip2/lib/self-contained" "-o" "/home/wingo/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3/target/wasm32-wasip2/release/deps/minimal-83a77969722bd283.wasm" "--gc-sections" "-O3" "--strip-debug"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: error: failed to encode component

          Caused by:
              0: failed to decode world from module
              1: module was not valid
              2: failed to resolve import `wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15::[async-lower][async]wait-for`
              3: failed to validate import interface `wasi:clocks/monotonic-clock@0.3.0-rc-2025-08-15`
              4: type mismatch for function `[async]wait-for`: expected `[I32, I32] -> [I32]` but found `[I64] -> [I32]`

If i switch to simple assertions about monotonic_clock::now(), that works, so it's not a linking error for sync bindings. In what is probably a second problem, the resulting file fails to run:

$ "$HOME/src/wasip3/wasmtime/target/release/wasmtime" -Sp3=y target/wasm32-wasip2/release/minimal.wasm
Error: failed to parse WebAssembly module

Caused by:
    `task.return` requires the component model async feature (at offset 0x17b99)

Which is odd because I built wasmtime with --features component-model-async. I will try building this as a cdylib instead, perhaps that will help.

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:24):

right, I get the same result for a minimal cdylib:

extern crate wit_bindgen;

wit_bindgen::generate!({
    inline: r"
  package test:playground;

  world the-world {
            include wasi:cli/command@0.3.0-rc-2025-08-15;
  }
",
    path: "wit",
    async: [
        "wasi:cli/run@0.3.0-rc-2025-08-15#run",
    ],
    generate_all
});

struct Test;

impl exports::wasi::cli::run::Guest for Test {
    async fn run() -> Result<(), ()> {
        Ok(())
    }
}

export!(Test);

view this post on Zulip Lann Martin (Aug 25 2025 at 12:28):

task.return requires the component model async feature

I believe this requires wasmtime -W component-model-async (runtime feature gate too)

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:42):

oh funny, i didn't think to look there, like "wasm" was a lower-level thing than wasi / component-model. thanks!

view this post on Zulip Lann Martin (Aug 25 2025 at 12:43):

Yeah we aren't generally very precise in distinguishing these things but technically component model is a wasm proposal while wasi is its own separate (dependent) spec

view this post on Zulip Lann Martin (Aug 25 2025 at 12:44):

since they are developed in parallel it is convenient to do lockstep-ish releases and they both end up in the "p3" bucket

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:45):

what do i need to enable to fix invalid leading byte (0x25) for canonical function (at offset 0x16a4a) ?

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:45):

i had tried all-proposals=y in addition to component-model-async=y but that wasn't the trick

view this post on Zulip Lann Martin (Aug 25 2025 at 12:46):

Ah I just encountered that one. I believe that is caused by a mismatched wasm-component-ld version

view this post on Zulip Lann Martin (Aug 25 2025 at 12:46):

I fixed it by switching to a recent rust nightly

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:46):

oh :)

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:47):

wouldn't that be something in wasi-sdk?

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:49):

ah perhaps i wasn't running my cargo builds in an environment that had my fresh wasi-sdk

view this post on Zulip Lann Martin (Aug 25 2025 at 12:49):

wasi-sdk shouldn't have anything to do with binary encoding

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:49):

well wasm-component-ld is there

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:50):

but maybe wasi-sdk is only for c?

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:50):

weird stuff

view this post on Zulip Lann Martin (Aug 25 2025 at 12:51):

ah wasi-sdk might include wasm-component-ld to make sure you get a compatible version

view this post on Zulip Lann Martin (Aug 25 2025 at 12:52):

wasi-sdk can be used by any guest language that can do C ffi in wasm

view this post on Zulip Lann Martin (Aug 25 2025 at 12:53):

its basically wasi-libc plus a compatible toolchain

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:54):

well many thanks lann, after rustupping to a nightly, things are working now

view this post on Zulip Andy Wingo (Aug 25 2025 at 12:57):

nice, all problems fixed. ready to make tests, finally ;)

view this post on Zulip Andy Wingo (Aug 25 2025 at 14:30):

a first async test at https://github.com/WebAssembly/wasi-testsuite/pull/120, grumble about github and stacked pr's tho

Depends on #114. Adds wasm32-wasip3 Rust test directory, with a first Rust-based test. Test runner not yet updated; requires passing Wcomponent-model-async=y -Sp3=y to wasmtime. Building the was...

view this post on Zulip Andy Wingo (Aug 29 2025 at 12:27):

/me files a spicy bug https://github.com/WebAssembly/wasi-http/issues/179

Contribute to WebAssembly/wasi-http development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Aug 29 2025 at 12:40):

just as a summary of where i'm at:

Apologies for the clownshoes, ptal @loganek !
Depends on #114. Adds wasm32-wasip3 Rust test directory, with a first Rust-based test. Test runner not yet updated; requires passing Wcomponent-model-async=y -Sp3=y to wasmtime. Building the was...
Stacked on #120.

view this post on Zulip Pat Hickey (Aug 29 2025 at 17:15):

thanks for lots of great work and great questions, andy!

view this post on Zulip Andy Wingo (Sep 05 2025 at 06:21):

good morning :) i would like to merge https://github.com/WebAssembly/wasi-testsuite/pull/120 today

Depends on #114. Adds wasm32-wasip3 Rust test directory, with a first Rust-based test. Test runner not yet updated; requires passing Wcomponent-model-async=y -Sp3=y to wasmtime. Building the was...

view this post on Zulip Andy Wingo (Sep 05 2025 at 06:22):

how should i proceed here @Marcin Kolny ?

view this post on Zulip Andy Wingo (Sep 08 2025 at 12:37):

status: i have a 60%-done test for wasi:filesystem, but am not posting a pr yet because i am waiting on https://github.com/WebAssembly/wasi-testsuite/pull/120; otherwise there is nowhere to put it

Depends on #114. Adds wasm32-wasip3 Rust test directory, with a first Rust-based test. Test runner not yet updated; requires passing Wcomponent-model-async=y -Sp3=y to wasmtime. Building the was...

view this post on Zulip Andy Wingo (Sep 09 2025 at 15:06):

current status: slogging away at https://github.com/WebAssembly/wasi-testsuite/pull/130/files. i have done almost everything that doesn't require streams. starting streams now; found a fun wasmtime bug: https://github.com/bytecodealliance/wasmtime/issues/11652. will continue tomorrow

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.
Test case use std::process; extern crate wit_bindgen; wit_bindgen::generate!({ inline: r" package test:test; world test { include wasi:filesystem/imports@0.3.0-rc-2025-08-15; include wasi:cli/comma...

view this post on Zulip Alex Crichton (Sep 09 2025 at 20:13):

As a status update on the wasmtime side of things, Andy now wasi:http bits are all landed in Wasmtime so the dev release should be suitable for testing all of WASIp3

view this post on Zulip Andy Wingo (Sep 11 2025 at 07:43):

@Joel Dice no idea how, but the stream/future host API refactor (https://github.com/bytecodealliance/wasmtime/pull/11515) fixed my iloop in readdir (https://github.com/bytecodealliance/wasmtime/issues/11652#issuecomment-3278931677). Weird!

This changes the host APIs for dealing with futures and streams from a "rendezvous"-style API to a callback-oriented one. Previously you would create e.g. a StreamReader/StreamWriter pair...
Test case use std::process; extern crate wit_bindgen; wit_bindgen::generate!({ inline: r" package test:test; world test { include wasi:filesystem/imports@0.3.0-rc-2025-08-15; include wasi:cli/comma...

view this post on Zulip Andy Wingo (Sep 11 2025 at 11:38):

hoo, read-from-stream's prototype is weird

view this post on Zulip Andy Wingo (Sep 11 2025 at 11:40):

i guess it is to be expected that this hangs:

let (stream, future) = fd.read_via_stream(0);
future.await

view this post on Zulip Lann Martin (Sep 11 2025 at 11:58):

I have had the same confusion recently. I think in general we expect to read the stream until it's dropped, then poll the future.

view this post on Zulip Lann Martin (Sep 11 2025 at 11:58):

(or do both concurrently)

view this post on Zulip Andy Wingo (Sep 11 2025 at 12:12):

one of the weird things is that it's tricky to test that read-via-stream(u64::MAX) fails, because if you drop the stream immediately, the future doesn't necessarily resolve to an error

view this post on Zulip Andy Wingo (Sep 11 2025 at 12:15):

do zero-length reads still allow the stream to start?

view this post on Zulip Andy Wingo (Sep 11 2025 at 12:22):

it seems not

view this post on Zulip Lann Martin (Sep 11 2025 at 12:58):

I think they're supposed to, or at least were supposed to in some design iteration

view this post on Zulip Lann Martin (Sep 11 2025 at 13:04):

The doc comment in wasmtime main right now says that a zero length read will only return pending if it "expects" that a non-zero-length read would also return pending.

view this post on Zulip Lann Martin (Sep 11 2025 at 13:06):

That's for host streams in general; the filesystem impl might not be up-to-date with that interpretation

view this post on Zulip Joel Dice (Sep 11 2025 at 13:25):

Andy Wingo said:

no idea how, but the stream/future host API refactor (https://github.com/bytecodealliance/wasmtime/pull/11515) fixed my iloop in readdir

That's not totally surprising; that refactor was primarily motivated by the need for finer-grained, more predictable, control of streams and futures in wasmtime-wasi[-http], and it also forced us to think more precisely about how we wanted them to behave.

view this post on Zulip Alex Crichton (Sep 11 2025 at 14:35):

Zero-length reads/writes are a bit weird because they're used for readiness checks where possible, but a 1-byte read at u64::MAX - 1 should deterministically fail

view this post on Zulip Andy Wingo (Sep 12 2025 at 08:24):

AbiBuffer is odd: its remaining() method would seem to duplicate StreamResult::Complete. as a user you get both values. i get the reason but it's weird

view this post on Zulip Andy Wingo (Sep 12 2025 at 08:57):

and my goodness, writing to a stream is gnarly

view this post on Zulip Andy Wingo (Sep 12 2025 at 08:58):

so. component-model-knowers. i initially wrote this to test write-via-stream:

async fn pwrite(fd: &Descriptor, offset: u64, data: &[u8]) -> Result<usize, ErrorCode> {
    let (mut tx, rx) = wit_stream::new();
    let success = fd.write_via_stream(rx, offset);
    let len = data.len();
    let mut written: usize = 0;
    let (mut result, mut buf) = tx.write(data.to_vec()).await;
    loop {
        match result {
            StreamResult::Complete(n) => {
                assert!(n <= len - written);
                written += n;
                assert_eq!(buf.remaining(), len - written);
                if buf.remaining() != 0 {
                    (result, buf) = tx.write_buf(buf).await;
                } else {
                    break;
                }
            },
            StreamResult::Dropped => {
                panic!("receiver dropped the stream?");
            },
            StreamResult::Cancelled => {
                break;
            }
        }
    }
    assert_eq!(buf.remaining(), len - written);
    drop(tx);
    match success.await {
        Ok(()) => Ok(written),
        Err(err) => Err(err)
    }
}

view this post on Zulip Andy Wingo (Sep 12 2025 at 09:00):

could be buggy, excuse my bad rust form, etc; anyway, when running this, wasmtime deadlocks. helpfully it detects the deadlock; but it is not clear to me why it should deadlock at all. i wrote this from the spec and docs, but now looking at wasmtime tests it would seem that it wants me to wait in parallel on the individual stream writes, at the same time as i wait on the write-via-stream results: https://github.com/bytecodealliance/wasmtime/blob/main/crates/test-programs/src/bin/p3_file_write.rs#L45

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Andy Wingo (Sep 12 2025 at 09:02):

but why is this? if there is an error, why wouldn't the receiving end cancel the stream and cause the future to complete with a failure?

view this post on Zulip Andy Wingo (Sep 12 2025 at 09:05):

the deadlock occurs at the tx.write(data.to_vec()).await line

view this post on Zulip Andy Wingo (Sep 12 2025 at 09:22):

Lann Martin said:

I have had the same confusion recently. I think in general we expect to read the stream until it's dropped, then poll the future.

this is what I was expecting for the write case, then: write the stream until complete or cancelled, then poll the future. is it necessarily not that way?

view this post on Zulip Lann Martin (Sep 12 2025 at 12:43):

Just to clarify terminology, completed and cancelled are the two stream results that - maybe confusingly - don't terminate the stream. Otherwise yes, my expectation is that you write to the stream until you either get a dropped result (typically because of a write error) or you drop it yourself (because you are done), then await the future.

view this post on Zulip Andy Wingo (Sep 12 2025 at 13:47):

hoo, i did not realize that cancelled doesn't terminate the stream

view this post on Zulip Lann Martin (Sep 12 2025 at 13:48):

yeah it is just cancelling the one active operation on the stream

view this post on Zulip Lann Martin (Sep 12 2025 at 13:56):

Take this with a grain of salt until Joel/Alex/Luke can confirm but I believe the state diagram is basically this: https://gist.github.com/lann/d8dbc6feaf36eb70a17e9506e3c06597

GitHub Gist: instantly share code, notes, and snippets.

view this post on Zulip Joel Dice (Sep 12 2025 at 13:56):

@Andy Wingo I'm not sure what's causing the deadlock. Would you mind providing instructions for reproducing the issue, e.g. a complete Rust file I can run using wasmtime run? BTW, you could use StreamWriter::write_all and avoid the loop.

view this post on Zulip Joel Dice (Sep 12 2025 at 14:01):

@Lann Martin your diagram looks roughly accurate, but note that the read and write ends of a stream are dropped separately, so a stream could be in one of three states: where neither end is dropped, the write end is dropped, or the read end is dropped. And when both ends are dropped it ceases to exist entirely.

view this post on Zulip Lann Martin (Sep 12 2025 at 14:01):

Yeah I should clarify that I was only trying to represent the writer's perspective there.

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:50):

as a user you get both values. i get the reason but it's weird

This is trying to expose what the component model is giving us in that the return code of an async operation indicates how many items were transferred and the end-result status of the operation. In many cases dropped == 0 items taken for example but that's not guaranteed.

and my goodness, writing to a stream is gnarly

IMO I'd view this operation as a kernel-like operation. Managing epoll and/or trying to use io-uring would also be quite gnarly and I wouldn't expect those to be simple. I'd think of raw CM streams similarly.

I've tried to add a few helper methods like write_all and such and if you end up having other common operations it's fine to add more helper methods too.

when running this, wasmtime deadlocks

This is a subtle difference between Rust & JS, calling fd.write_via_stream(rx, offset) doesn't actually do anything. You have to actually poll the future, which in this example only happens at the end of the function during success.await, for anything to happen. The reason your example deadlocks is that functionally what's happening is you created a stream and then wrote to it, but nothing is reading from it because the host API hasn't actually been called yet.

In the test in Rust you'll find usage of a futures::join! macro which is the current solution for this. It represents "do these two things at the same time" which is what you want here, one end calls success.await and the other ened does the writing.

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:51):

Joel/Alex/Luke can confirm but I believe the state diagram is basically this: https://gist.github.com/lann/d8dbc6feaf36eb70a17e9506e3c06597

FWIW that looks right to me

view this post on Zulip Lann Martin (Sep 12 2025 at 14:52):

Yeah to your point above, in that state diagram all of the results are implicitly from polling something.

view this post on Zulip Andy Wingo (Sep 15 2025 at 08:12):

Alex Crichton said:

as a user you get both values. i get the reason but it's weird

This is trying to expose what the component model is giving us in that the return code of an async operation indicates how many items were transferred and the end-result status of the operation. In many cases dropped == 0 items taken for example but that's not guaranteed.

So let's say you have a stream, you have a vector of total-count items to write the stream, and the receiver consumes those items in a number of batches.

My question: from the transmitter's perspective (i.e., when it is active and not suspended), could we calculate the AbiBuffer's remaining() as the total-count minus the sum of the previously-received StreamResult::Complete(n) values? That is what I meant by duplication. But you seem to be suggesting that no, if the stream result is Dropped, that the previous write may have only been partially consumed, and that the remaining() is the real source of truth? I would have expected a Complete(n) for the partial write, then a Dropped.

and my goodness, writing to a stream is gnarly

IMO I'd view this operation as a kernel-like operation. Managing epoll and/or trying to use io-uring would also be quite gnarly and I wouldn't expect those to be simple. I'd think of raw CM streams similarly.

I've tried to add a few helper methods like write_all and such and if you end up having other common operations it's fine to add more helper methods too.

I would certainly recommend the write_all methods to others, but I am just trying to get a feel for how things can break when there are drops and cancels and so on :)

when running this, wasmtime deadlocks

This is a subtle difference between Rust & JS, calling fd.write_via_stream(rx, offset) doesn't actually do anything. You have to actually poll the future, which in this example only happens at the end of the function during success.await, for anything to happen.

This is indeed subtle, thank you for the hint! This entirely explains it. I had no idea about this aspect of Rust, the systems I have worked with all begin execution of the subtask immediately and only suspend if necessary. Thanks again for the generous close read.

view this post on Zulip Andy Wingo (Sep 15 2025 at 08:13):

Joel Dice said:

Andy Wingo I'm not sure what's causing the deadlock. Would you mind providing instructions for reproducing the issue, e.g. a complete Rust file I can run using wasmtime run? BTW, you could use StreamWriter::write_all and avoid the loop.

I had just finished preparing the example when Alex corrected my misunderstanding, no need now. Thank you though.

view this post on Zulip Andy Wingo (Sep 15 2025 at 09:06):

@Alex Crichton question, how do you know that in Rust, fd.read_via_stream won't have to poll the future before the sender will be active?

view this post on Zulip Andy Wingo (Sep 15 2025 at 09:07):

i assume that the whole pre-poll sendable Future thing is a rust-only concern: it would seem that on a component-model async ABI level, calling an async import actually starts the task (as in JS, C#, etc)

view this post on Zulip Till Schneidereit (Sep 15 2025 at 11:15):

Should you be interested, I think this classic blog post by Aaron Turon still gives a pretty good explanation for the design of Rust Futures

view this post on Zulip Andy Wingo (Sep 15 2025 at 12:53):

i also enjoyed the blandy/orendorff/tindall chapter on asyncs

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:11):

finishing filesystem tests. i am mostly assuming i can read my own writes, that writes to a descriptor within a component are immediately visible to reads within that component without sync, both for data and stat().size

view this post on Zulip Lann Martin (Sep 15 2025 at 13:12):

Andy Wingo said:

i assume that the whole pre-poll sendable Future thing is a rust-only concern: it would seem that on a component-model async ABI level, calling an async import actually starts the task (as in JS, C#, etc)

I think this is understood but just to be completely clear: in your example the import isn't called until the Rust Future is polled. If you are more familiar with JS you can think of Rust async functions as generators.

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:13):

i know that wasi isn't much able to specify this but maybe tests can nudge implementations in the right direction, i.e. that adding buffering on the host side is a bad thing

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:14):

Lann Martin said:

Andy Wingo said:

i assume that the whole pre-poll sendable Future thing is a rust-only concern: it would seem that on a component-model async ABI level, calling an async import actually starts the task (as in JS, C#, etc)

I think this is understood but just to be completely clear: in your example the import isn't called until the Rust Future is polled. If you are more familiar with JS you can think of Rust async functions as generators.

i did not understand this before but after alex's comment i do now!

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:15):

(don't js generators actually get to run a bit immediately? i can't remember, and i implemented them in spidermonkey and v8.. ;)

view this post on Zulip Lann Martin (Sep 15 2025 at 13:15):

They do not (I had to verify in the console :sweat_smile:)

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:15):

live and learn (and forget, and learn...) :)

view this post on Zulip Lann Martin (Sep 15 2025 at 13:17):

I guess more to your question of whether its a "rust-only concern", that depends on whether any other languages also treat async functions as generators. I think Python might (edit: it does)? But if you are just asking about the ABI, yes once the async call reaches the ABI the task starts immediately.

view this post on Zulip Lann Martin (Sep 15 2025 at 13:20):

Andy Wingo said:

finishing filesystem tests. i am mostly assuming i can read my own writes, that writes to a descriptor within a component are immediately visible to reads within that component without sync, both for data and stat().size
i know that wasi isn't much able to specify this but maybe tests can nudge implementations in the right direction, i.e. that adding buffering on the host side is a bad thing

My non-authoritative take would be that for a single descriptor yes you should be able to read your own writes.

view this post on Zulip Andy Wingo (Sep 15 2025 at 13:21):

(feedback welcome re the sync/buffering thing)

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:11):

So let's say you have a stream, you have a vector of total-count items to write the stream, and the receiver consumes those items in a number of batches.

I'm not entirely sure how to respond to your question here in that I'm not totally sure I understand it. That being said I'm going to make a statement here which you may already be aware of but in case you weren't it might reframe your questions here: if a writer writes 10 items, and a reader then reads 4 items, the writer will receive a notification that 4 items were read. The writer doesn't, for example, say blocked until all 10 items are read.

There's room in the CM spec to allow the reader to keep reading before a notification is delivered (e.g. you read one-item-at-a-time in a loop and we batch all the notifications for the writer) but that's not implemented in Wasmtime right now.

if the stream result is Dropped, that the previous write may have only been partially consumed, and that the remaining() is the real source of truth?

This is indeed a possibility, yeah. Although reading over the APIs again it's a bug that Dropped doesn't have a usize payload on it, that definitely should.

With that combo of words, does that answer your original question? I fear it may not... Let me know though!

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:13):

how do you know that in Rust, fd.read_via_stream won't have to poll the future before the sender will be active?

Can confirm others' answers here, it's purely a Rust thing. When you do foo() where it was defined as async fn foo() { println!("hi") } that does nothing and prints nothing. All it does is construct a future on the stack that, when polled, will actually print. Once we hit the CM, however, then everything happens in the background similar to JS/etc and pollling in Rust need not happen other than to actually acquire the result of the operation when it's done.

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:14):

also I totally empathize with you implementing JS generators, my friend and I wrote a JIT for lua in college and I don't actually know anything about writing lua

view this post on Zulip Joel Dice (Sep 15 2025 at 14:16):

Alex Crichton said:

There's room in the CM spec to allow the reader to keep reading before a notification is delivered (e.g. you read one-item-at-a-time in a loop and we batch all the notifications for the writer) but that's not implemented in Wasmtime right now.

I believe it is implemented, per https://github.com/bytecodealliance/wasip3-prototyping/issues/162 and https://github.com/bytecodealliance/wasip3-prototyping/pull/168

As currently specified, if one component does a stream.read and another component does a stream.write that doesn't completely fill the stream.read's buffer, until the STREAM_READ event is delivered...
Plus docs, comments, and minor code cleanup.

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:16):

oh nice!

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:16):

I thought that was just some hypothetical future thing we would do at some point

view this post on Zulip Joel Dice (Sep 15 2025 at 14:17):

I think the hypothetical future thing is to allow you to start multiple reads or writes on the same stream without waiting for previous ones to complete, which is different.

view this post on Zulip Joel Dice (Sep 15 2025 at 14:18):

i.e. you can start a new read for a write you already read from, but only after you get notification that the previous read completed

view this post on Zulip Joel Dice (Sep 15 2025 at 14:19):

(and assuming the writer hasn't received their notification yet, at which point the reader will need to wait for a new write)

view this post on Zulip Andy Wingo (Sep 15 2025 at 14:21):

Regarding what Alex Crichton said, I think I was missing that Dropped logically has a usize associated with it:

if the stream result is Dropped, that the previous write may have only been partially consumed, and that the remaining() is the real source of truth?

This is indeed a possibility, yeah. Although reading over the APIs again it's a bug that Dropped doesn't have a usize payload on it, that definitely should.

view this post on Zulip Joel Dice (Sep 15 2025 at 14:22):

Alex Crichton said:

Once we hit the CM, however, then everything happens in the background similar to JS/etc and pollling in Rust need not happen other than to actually acquire the result of the operation when it's done.

To clarify, though: it's all still cooperative, so if the caller goes into an infinite loop without yielding, the callee will not have a chance to make progress. I.e. "in the background" means, "when nothing else is monopolizing the single thread of control".

view this post on Zulip Andy Wingo (Sep 15 2025 at 14:23):

is the cooperative nature observable? can progress be made on a cross-component async call in another thread, invisible to other components?

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:24):

observable, yes, cross-thread, no

view this post on Zulip Andy Wingo (Sep 15 2025 at 14:24):

ack

view this post on Zulip Andy Wingo (Sep 16 2025 at 09:41):

ok! added my filesystem tests, i think especially as regards the actual streaming i/o there can be more tests, but at least all the api is covered. a bunch of similar draft pr's up at https://github.com/WebAssembly/wasi-testsuite/pulls, but only one marked as ready, so that changes from that review can be replicated in the others: https://github.com/WebAssembly/wasi-testsuite/pull/131

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.
We read every piece of feedback, and take your input very seriously.

view this post on Zulip Andy Wingo (Sep 16 2025 at 09:42):

the tests get compiled nightly but are not run yet. now that wasi-testsuite actually has wasip3 tests, i need to wire up that bit of the CI.

view this post on Zulip Andy Wingo (Sep 16 2025 at 09:42):

will see what i can do with http, now that it's in.

view this post on Zulip Andy Wingo (Sep 22 2025 at 14:36):

review welcome on the wasi:filesystem tests: https://github.com/WebAssembly/wasi-testsuite/pulls

WASI Testsuite. Contribute to WebAssembly/wasi-testsuite development by creating an account on GitHub.

view this post on Zulip Andy Wingo (Sep 24 2025 at 15:00):

OK, quick status: the wasi-testsuite runner tests multiple runtimes at once and skips e.g. WASIp3 tests on a runtime that just does WASIp1. Working on filing off some sharp edges. Tomorrow I will add a jco adapter. There are tests basically only for wasi:clocks and wasi:filesystem currently, and most of the filesystem ones are out for review still; I have held off on http until https://github.com/bytecodealliance/wasmtime/issues/11736 is fixed.

Hello, Running wasmtime run on a component that uses wasi:http fails: [dev-env] wingo@beastie ~/src/wasip3/wasi-testsuite/tests/rust/wasm32-wasip3$ ~/src/wasip3/wasmtime/target/release/wasmtime -Wc...

view this post on Zulip Andy Wingo (Sep 24 2025 at 15:01):

but generally speaking see https://github.com/WebAssembly/wasi-testsuite/pull/162 for an idea of status

Refactor to make runtime adapters declare the WASI versions they support, and for test suites to declare the WASI version they are. By default, skip tests whose WASI version is not supported by th...

Last updated: Dec 06 2025 at 06:05 UTC