-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Code Coverage in wasm-bindgen-test? #2276
Comments
To some degree WebAssembly instrumentation and coverage should be easier in theory than native binaries because it's easy to change/inject instructions into a binary (e.g. at the top/end of all blocks). That would require work investing into some sort of wasm transform, however, which would require a side table (like dwarf info) about what instruction corresponds to what. Otherwise LLVM's infrastructure may work with tweaks, but AFAIK no work has been done towards that. I would suspect you'd probably want to start out with wasm32-wasi since it'll be easier as many things already "just work", but if something works there seems reasonable to try to extend it to wasm-bindgen! |
Makes sense and thanks for the advice! I am skimming https://motley-coder.com/2019/03/31/webassembly-coverage/ and it looks like compiler-rt support for the target is the main thing. |
You could try using minicov which embeds a stripped down version of the LLVM profiling runtime. It has no dependencies on libc or any external code so it should compile on WASM. You'll need to write out the profraw file yourself though (see the README). |
Hey. I've created a tutorial how to generate code coverage for webassembly projects. This one is dedicated for blockchains using WASM VM, however I think it may be useful to you - https://github.com/hknio/code-coverage-for-webassembly |
Hi, is there any updates? Thanks! |
I looked into this a bit and tried to simply compile a test using wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[cfg(test)]
mod test {
#[wasm_bindgen_test::wasm_bindgen_test]
async fn test_foo() {
assert!(true);
}
} then run Output:
The last function to be called
We need a way to skip these functions since they are irrelevant to the unit under test. First approaches are having complications with keeping the stack properly in order. If we can skip through these functions and make it to the point where the generated wasm is actually mounted by the node/chrome/firefox, then we can see how to retrieve the coverage from minicov. |
I believe that the issue is that we are trying to measure coverage of the |
I compiled rustc locally and removed the feature gate of I can now at least run my code with coverage profiles. Will now look into getting the coverage information back out of the tests. |
I've been able to create a coverage report for a test (yay). However I simply printed the profdata to stdout and parsed it afterwards from there. The remaining crucial question is how to best save the profdata during the tests. We need to call The @alexcrichton are you aware of any ways to do this? We can't write to a file from a browser. Is it maybe possible to inject a hook to a function on the host which can write to a file? Otherwise we would probably have to set up a local server which receives the data and writes it to a file. Otherwise the workflow is very close to what's specified in https://github.com/hknio/code-coverage-for-webassembly
|
We could built that into I'm happy to review a proposal and a subsequent PR. EDIT: The |
Oh, that's convenient. I'll add two endpoints then. One that is run after every test that appends the coverage data to a Vec and one that is run when all tests are done that dumps the Vec into a file. Then we only have to generate a single file which should improve performance significantly compared to having a file for each test - not only when running the tests but also when merging the profraws into a profdata.
I think stabilizing the feature wouldn't be much of an issue. Someone just has to go to the effort of creating the stabilization PR and starting the Final Comment Period. However, I wasn't able to get the results I wanted with this approach. Maybe I was still missing the annotation in some places. It's a small implementation detail we can discuss in the PR when we get there. |
Great to hear! Before making a PR it would be great if you put together a more detailed plan so we can get this approved before putting in any significant coding work. |
Motivation
I'd like to be able to use
-Zprofile
when building my wasm-bindgen tests with wasm-pack and have those tests produce coverage files. I currently run my tests in a headless browser with wasm-pack and an ideal solution would have a clear integration story there with a good out of the box experience.Proposed Solution
The instrumentation emitted by default writes coverage profiling data to disk in a location relative to the binary being run. If there's a nice way to override those callbacks for a single binary/target then wasm-bindgen could presumably collect the coverage buffers in its JS test harness and forward them to the CLI for persisting to disk.
Alternatives
I'm still looking at LLVM's coverage docs and I'm not sure if it's straightforward to override the instrumentation collection buffers like that. If it's not then I'd be willing to compile in a larger (wasi?) runtime into my tests to provide the needed filesystem I/O. I think the LLVM instrumentation at least offers environment variables to control the paths where data is written.
Additional Context
I looked for related issues and couldn't find any. I think that "test artifact extraction" from wasm tests might also be useful for supporting snapshot testing but I'm not familiar enough with relevant internals to say for sure.
The text was updated successfully, but these errors were encountered: