-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WASI testsuite #9
Comments
Is there an official testsuit currently available? Even very simple. |
There's a testsuite for the wasi-sdk, which is perhaps the closest we have right now. I'm not sure it'd make sense to do something more directly for WASI itself (as opposed to the libc abstraction on top of it, which wasi-sdk uses) right now: once WASI is defined in terms of Interface Types[1], I think the tests would probably have to look somewhat different. [1]: see the last paragraph in the design principle doc's section on security. |
I didn't realise these are separate; but yeah, the testsuite of wasi-sdk looks pretty comprehensive. Do you think it's something that could be extracted into a separate submodule that other implementations could rely on / contribute to independently from wasi-sdk implementation? |
Maybe I rushed with "comprehensive" bit; looking through the suite, it doesn't seem to test most of filesystem operations, for example, or randomness, or timers. https://github.com/devsnek/node-wasi/tree/master/test/c by @devsnek, referenced from one of related issues above, seems better in this regard. |
We've got more tests now: https://github.com/nodejs/node/tree/master/test/wasi/c |
This is exactly what I want to express, there are many wasm vm implementations in the world, and they all have their own wasi test cases, which seems inconsistent. I think we can write a unified testsuit, these testcases are not so platform-dependent, and which can ensure that the data structure, function signature and function logic are correct. Some existing test cases are too complicated, I mean "not so much like unit tests". For example, when I want to testing (import "wasi_unstable" "proc_exit" (func $__wasi_proc_exit (type 2)))
(import "wasi_unstable" "fd_readdir" (func $__wasi_fd_readdir (type 3)))
(import "wasi_unstable" "fd_close" (func $__wasi_fd_close (type 4)))
(import "wasi_unstable" "fd_fdstat_get" (func $__wasi_fd_fdstat_get (type 5)))
(import "wasi_unstable" "path_open" (func $__wasi_path_open (type 6)))
(import "wasi_unstable" "args_sizes_get" (func $__wasi_args_sizes_get (type 5)))
(import "wasi_unstable" "args_get" (func $__wasi_args_get (type 5)))
(import "wasi_unstable" "fd_prestat_get" (func $__wasi_fd_prestat_get (type 5)))
(import "wasi_unstable" "fd_prestat_dir_name" (func $__wasi_fd_prestat_dir_name (type 0)))
(import "wasi_unstable" "fd_seek" (func $__wasi_fd_seek (type 7)))
(import "wasi_unstable" "fd_write" (func $__wasi_fd_write (type 8))) |
I have some tests for Deno's std/wasi implementation here and there are some legacy tests for libc in the pre-merge repository I haven't brought over; overall fairly similar coverage to @devsnek's tests, looks like I go a bit overboard on explicitly testing stdio 🤔 . Ultimately I'd like to have a bunch of tests in the WebAssembly text format (for sharing between toolchains) that test the snapshots directly rather than relying fully on integration tests. |
Tests written in wat are great because they easily work in many engines and don't require users to have various compilers for various languages installed in order to run them. So if people have tests of this form and/or are interesting in writing such tests, it'd be great to collect them. That said though, tests written in wat directly, and targeting WASI APIs directly, are often very verbose and difficult to maintain, so it'd be good to collect compiled tests as well. Ideally we'd have the original Rust/C/etc. source files in the repository, so that people with the appropriate toolchains installed can edit and debug, and also the compiled output in the repository, in either wat or wasm format, so that it's possible for others to run the tests without having the toolchains installed. |
I agree with @sunfishcode .. I don't think we should require that tests be authored in wat. Writing them in C or rust and providing supplying the compiled output in wat/wasm format should be fine. |
Sounds like merging Node & Deno tests and precompiling to WAT alongside existing C files would be a good start then. @devsnek & @caspervonb do you want to uh talk to each other? :) |
Another alternative could be to generate wat files from another language, JS/Python. We've done that for a few proposals now, see https://github.com/WebAssembly/bulk-memory-operations/tree/master/test/meta and https://github.com/WebAssembly/simd/tree/master/test/core/simd/meta as examples. |
I was working on a test generator (written in JS) to that effect, and I came to the conclusion that it's simpler to just write the tests in rust/c/wat/etc and keep the compiled versions in the source tree. |
@devsnek that makes sense. It's a bit sad because those examples go from ~300 byte C files to ~30k wasm files. But I can definitely understand that the burden of writing in wat with or without a generator may outweigh this slight debugging cost. |
Don't forget the wasi-sdk tests (https://github.com/WebAssembly/wasi-sdk/tree/master/tests).. (i've not looked at how they compare to the node or deno tests but just wanted to make sure they don't get fogotten). |
I've mentioned them above:
There are couple of useful tests, but mostly things seem to be better covered by other, more comprehensive, testsuites. |
Started extracting Deno's test suite here |
Personally I would rather see the testsuite written in C, since the syscall API being tested is so low level. It seems like a better match to me. I also imagine the resulting wat/wasm files from the tests would be smaller and closer the source code that way (maybe I'm wrong about that?). But I'm also probably showing my bias not being a rust person myself. Do you have some reason to prefer rust over C for this task? |
I think we need a mix of raw wat/wasm files and output from popular compilers, to verify both the theoretical conformance of an implementation and its ability to handle real world programs. |
Looking at the tests, it also looks like they are not actually written against the wasi API at all, but rather against some higher liker |
@devsnek, sure, I guess that makes sense. I do think its important to have a set of low level unit tests though that are written directly against the wasi API. The C language seems like the sweet spot for authoring those. If we have higher level test in addition that is fine with me. |
Just happened to be the way we went forward given Deno's CI setup, it is fairly tedious to get at certain syscalls, the libc crate does not even expose errno 🤔 Plan now is to clean up the old C tests from deno-wasi and merge them in, the extra rust coverage doesn't hurt, at-least we know that rustc and rust's std works as expected and they run in a second (1.5s to be exact on my machine). Same goes for C++ new std::filesystem APIs, doesn't hurt to have some coverage. Directory structure is meant to reflect this approach, rs for rust, c for c, etc.
Most are still fairly 1:1 in implementation but yeah need more coverage in general. |
Having just looked at the wasi-sdk tests again I realize they are also written against wasi-libc higher level APIs, not directly against wasi APIs :( |
FWIW Rust is equally low-level as a language, and there's nothing you can express in C but not in Rust. I do agree though that testing syscalls directly would be better than stdlib APIs (regardless of the language tests are written in). When using low-level APIs directly, the resulting binary sizes should be ~same across languages as well. |
one could theoretically target extern "C" {
fn wasi_whatever() {}
}
fn main() {
assert!(wasi_whatever(invalid) == wasi_some_error)
} I just want to make sure we're both testing both that the individual wasi functions behave correctly (across ranges of valid and invalid inputs, etc., basically unit testing) and that we have test cases of them being used together (output from rust/c++ std, etc., basically integration testing) |
@devsnek Yeah, that's basically what I meant (note that you'll need I don't have anything against them written in C either, just wanted to respond to the comment above and clarify that language doesn't really matter here, as long as we avoid stdlib/libc and go for low-level APIs. |
Merged most of the C tests from https://github.com/caspervonb/deno-wasi into https://github.com/caspervonb/wasi-test and threw together a quick test runner. Most pass but runtimes are in disagreement about a couple of tests. Adding Deno and Node to this runner later, Wasmtime and Wasmer just happened to have nearly identical command line interfaces so they got in first. Any other major runtimes that makes sense to be included in this kind of compatibility check? Still expecting runtimes to bring their own test runner but will eventually generate some sort of compat table on the CI from this. |
Where do we think the final version of this testsuite should live? I'm guessing in sub-directory within the wasi repo itself, or in a new wasi-testsuite repo? |
Should be as frictionless as possible to keep it as a submodule or subtree so I'd vote for a standalone repository. |
That's nice for integrating into other projects, but there's also value in having it synchronized with spec changes. You could always keep a separate repo that is copied from the main repo too (like we do with WebAssembly/testsuite). I don't have a preference really, just thought I'd mention it. |
Right, we need to weigh the balance of those two use cases:
|
@caspervonb thank you for leading the way on creating a test suite! I agree it is badly needed and the discussion here has been excellent. The WebAssembly/WASI repository itself is pretty lightweight and doesn't have a ton of churn, so I'd support having the test suite live in this repository as well. |
I like the @binji's idea here the most - if we can easily automate a mirror in a separate repo, that seems like best of both worlds. |
@caspervonb would you mind reporting bugs you found at https://github.com/nodejs/node/issues/?
For ECMAScript, we make spec changes in https://github.com/tc39/ecma262, and test changes in https://github.com/tc39/test262, and it hasn't been a big issue afaik. |
That reminds me, should track lucet compatibility as-well 😉
So, for WebAssembly this makes a lot of sense since there's a reference implementation. Actually when I think about it I'm a bit unsure about what the new proposals scheme and modularisation mean for future versions of the ABI, are we still going to be snapshotting?
Yep working down my way down the list of current failures... |
Lucet and Wasmtime use the same wasi-common under the hood so just wasmtime is sufficient to track. Snapshots are intended to be immutable. However, the way in which we specify them does change sometimes - we have some fuzzy plans to change the way the witx language works as part of the evolution towards interface types, and will change the witx documents for the snapshots accordingly. I've reconsidered and I believe it is likely that the test suite will need to contain tools that refer to the witx documents in the spec repo (even if transitively) - e.g. the rust wasi crate both refers to the spec via a submodule relationship. So, we could avoid having a circular dependency on the spec repo by putting spec tests in a separate repo. |
Been a bit under the weather so progress has been a bit slow but still working on this.
So had a bit of churn and things have changed, I've embraced Cargo for this instead of an ad-hoc build script and brought in the wasi crate as a dependency for testing against the ABI (landing soon'ish). So yes, as of a few commits ago this would be an indirect circular dependency if it went into the spec repo. |
Landed a bunch of miscellaneous tests against the ABI yesterday, it's by no means exhaustive or complete coverage but it's a start on testing WASI directly. I'd also like to welcome pull requests at this point 😉 |
So a little update, the test suite has moved here for the time being so it's not on my personal account and contributors can be added (hint hint). We've merged the prebuilt test-suite into Deno which is working out great and I just published a little compatibility table over at https://khronosproject.github.io/wasi-compat-table. I saw @sunfishcode mentioned this to the agenda of yesterday's meeting as-well. Anything I should be in the loop about? |
@caspervonb Is the plan still to have .wasm files committed to the repo? I'm not sure everyone would want to rebuild the .rs files. |
Yep @RReverser! Prebuilt is at https://github.com/khronosproject/wasi-test-suite which is what Deno pulls in as a submodule. |
Ah great, thanks! To double-check - does this testsuite already include Node.js tests as well or only yours? So far I've been using the ones copied from Node.js in my WASI implementation, I wonder if I can just switch to this new repo instead, or need to combine both. |
Node's C tests are not included at the moment I did have my initial batch of C tests for a while but diverged in favor of doing direct tests against wasi syscalls which is still a work in progress. For libc i've been thinking its better to just bring in, or adapt libc-test than rolling our ad-hoc set of tests for it. TLDR; for a little while it may be beneficial to combine both; because deno/wasi is a sandbox within deno's sandbox conditions that would result in |
Ah, right, that makes sense. Perhaps we could at least make sure that equivalent syscalls / arguments are covered in the new repo, then the Node's tests could migrate fairly easily? |
(Catching up here, appologies for being slow). I have an experimental adaptation of musl's libc-test that I've tested WASI libc with here, in case it's useful: https://github.com/CraneStation/wasi-libc-test. I wrote my own harness instead of using the provided Makefile, which may or may not be the best approach, but it made it easier to customize things. It hasn't moved into the WebAssembly organization yet because libc-test contains code with a variety of licenses, which I expect would require approval. |
Went through Node's tests and currently wasi-test-suite is lacking equivalents of these tests:
With the exception of poll they more or less equate to one assertion so I'll try to get those taken care of today; if not today, really soon (Deno release tomorrow and I have things pending merge 😉). |
Good to know; I'll take a proper look once I've got full coverage for direct wasi syscall tests 👍 The way I'm envisioning this is that straight ABI tests should be the source of truth; where-as libc, libc++ and libstd (as in rust libstd) tests are nice to have optional smoke tests. |
I started work integrating https://github.com/khronosproject/wasi-test-suite into emscripten: emscripten-core/emscripten#12704 Once most tests are passing (not yet) I will update https://github.com/khronosproject/wasi-test 's compat.py to include an emscripten test function! |
A little update: I've been meaning to split the tests into sub repositories for a while and finally got around to it a couple of days ago, then I wasn't happy with the harness so I did it again. The wasi-test repository is going the way of the dodo, it was trying to be a crate but it just made it convoluted to work with. There are currently three source repositories: These get built and merged into (https://github.com/caspervonb/wasi-testsuite); work in progress so coverage there is actually a bit less. I've dropped the json preludes from the source files and instead gone with a simple file matching approach very similar to what is in wasi-sdk; meaning that each binary may have any of the following auxiliary files next to it:
Intend to expand it with a couple of more auxiliary files and directories as I rewrite the old tests including but not limited to:
A preliminary test runner used in the source repositories can be found at https://github.com/caspervonb/wasi-test-tools. Heads up, it's bare bones, just enough to run the tests in CI. At this point I'm pretty much accidentally converging with what we discussed earlier so going forward so I don't see much point in continuing this work outside of the webassembly/wasi-* repositories as I'm just starting on the rewrite so I'll start topping up @sunfishcode's review queue. However, it seems however that the restructure still is not complete but I suppose that doesn't really interfere with this. |
See discussion in WebAssembly#9. Fixes WebAssembly#9.
It would be nice to have a standard testsuite for the WASI API
The text was updated successfully, but these errors were encountered: