Skip to content

Commit

Permalink
Refactor test coverage enabling in proc-macros to crate feature
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Nov 28, 2024
1 parent 09bda50 commit b650488
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 81 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95", default-featu
"atomics",
] }

[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), wasm_bindgen_unstable_test_coverage))'.dependencies]
wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95", default-features = false, features = [
"coverage",
] }

[dev-dependencies]
wasm-bindgen-test = { path = 'crates/test' }

Expand Down
4 changes: 1 addition & 3 deletions crates/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ version = "0.2.95"

[features]
atomics = []
coverage = []
default = ["std"]
extra-traits = ["syn/extra-traits"]
spans = []
Expand All @@ -28,6 +29,3 @@ proc-macro2 = "1.0"
quote = '1.0'
syn = { version = '2.0', features = ['full'] }
wasm-bindgen-shared = { path = "../shared", version = "=0.2.95" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }
43 changes: 13 additions & 30 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,7 @@ impl ToTokens for ast::Struct {
let free_fn = Ident::new(&shared::free_function(&name_str), Span::call_site());
let unwrap_fn = Ident::new(&shared::unwrap_function(&name_str), Span::call_site());
let wasm_bindgen = &self.wasm_bindgen;
let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let maybe_no_coverage = coverage();
(quote! {
#[automatically_derived]
impl #wasm_bindgen::describe::WasmDescribe for #name {
Expand Down Expand Up @@ -481,11 +477,7 @@ impl ToTokens for ast::StructField {
quote! { assert_copy::<#ty>() }
};
let maybe_assert_copy = respan(maybe_assert_copy, ty);
let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let maybe_no_coverage = coverage();

// Split this out so that it isn't affected by `quote_spanned!`.
//
Expand Down Expand Up @@ -797,11 +789,7 @@ impl TryToTokens for ast::Export {
quote! {}
};

let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let maybe_no_coverage = coverage();

(quote! {
#[automatically_derived]
Expand Down Expand Up @@ -1172,11 +1160,7 @@ impl ToTokens for ast::StringEnum {
let hole = variant_count + 1;
let attrs = &self.rust_attrs;

let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let maybe_no_coverage = coverage();

let invalid_to_str_msg = format!(
"Converting an invalid string enum ({}) back to a string is currently not supported",
Expand Down Expand Up @@ -1558,16 +1542,12 @@ impl ToTokens for ast::Enum {
let name_len = name_str.len() as u32;
let name_chars = name_str.chars().map(|c| c as u32);
let hole = &self.hole;
let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let underlying = if self.signed {
quote! { i32 }
} else {
quote! { u32 }
};
let maybe_no_coverage = coverage();
let cast_clauses = self.variants.iter().map(|variant| {
let variant_name = &variant.name;
quote! {
Expand Down Expand Up @@ -1880,11 +1860,7 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> {
return;
}

let maybe_no_coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
Some(quote! { #[coverage(off)] })
} else {
None
};
let maybe_no_coverage = coverage();

let name = Ident::new(&format!("__wbindgen_describe_{}", ident), ident.span());
let inner = &self.inner;
Expand Down Expand Up @@ -1988,3 +1964,10 @@ fn respan(input: TokenStream, span: &dyn ToTokens) -> TokenStream {
}
new_tokens.into_iter().collect()
}

fn coverage() -> Option<TokenStream> {
#[cfg(feature = "coverage")]
return Some(quote! { #[coverage(off)] });
#[cfg(not(feature = "coverage"))]
None
}
1 change: 1 addition & 0 deletions crates/macro-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ version = "0.2.95"

[features]
atomics = ["wasm-bindgen-backend/atomics"]
coverage = ["wasm-bindgen-backend/coverage"]
default = ["std"]
extra-traits = ["syn/extra-traits"]
spans = ["wasm-bindgen-backend/spans"]
Expand Down
4 changes: 1 addition & 3 deletions crates/macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ proc-macro = true

[features]
atomics = ["wasm-bindgen-macro-support/atomics"]
coverage = ["wasm-bindgen-macro-support/coverage"]
default = ["std"]
spans = ["wasm-bindgen-macro-support/spans"]
std = ["wasm-bindgen-macro-support/std"]
Expand All @@ -34,6 +35,3 @@ trybuild = "1.0"
wasm-bindgen = { path = "../.." }
wasm-bindgen-futures = { path = "../futures" }
web-sys = { path = "../web-sys", features = ["Worker"] }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }
20 changes: 4 additions & 16 deletions crates/macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-macro/0.2")]
#![cfg_attr(
any(
wasm_bindgen_unstable_test_coverage,
all(not(feature = "std"), feature = "atomics")
),
any(feature = "coverage", all(not(feature = "std"), feature = "atomics")),
feature(allow_internal_unstable),
allow(internal_features)
)]
Expand All @@ -14,10 +11,7 @@ use proc_macro::TokenStream;
use quote::quote;

#[proc_macro_attribute]
#[cfg_attr(
wasm_bindgen_unstable_test_coverage,
allow_internal_unstable(coverage_attribute)
)]
#[cfg_attr(feature = "coverage", allow_internal_unstable(coverage_attribute))]
#[cfg_attr(
all(not(feature = "std"), feature = "atomics"),
allow_internal_unstable(thread_local)
Expand Down Expand Up @@ -48,10 +42,7 @@ pub fn wasm_bindgen(attr: TokenStream, input: TokenStream) -> TokenStream {
/// let worker = Worker::new(&wasm_bindgen::link_to!(module = "/src/worker.js"));
/// ```
#[proc_macro]
#[cfg_attr(
wasm_bindgen_unstable_test_coverage,
allow_internal_unstable(coverage_attribute)
)]
#[cfg_attr(feature = "coverage", allow_internal_unstable(coverage_attribute))]
pub fn link_to(input: TokenStream) -> TokenStream {
match wasm_bindgen_macro_support::expand_link_to(input.into()) {
Ok(tokens) => {
Expand All @@ -68,10 +59,7 @@ pub fn link_to(input: TokenStream) -> TokenStream {
}

#[proc_macro_attribute]
#[cfg_attr(
wasm_bindgen_unstable_test_coverage,
allow_internal_unstable(coverage_attribute)
)]
#[cfg_attr(feature = "coverage", allow_internal_unstable(coverage_attribute))]
pub fn __wasm_bindgen_class_marker(attr: TokenStream, input: TokenStream) -> TokenStream {
match wasm_bindgen_macro_support::expand_class_marker(attr.into(), input.into()) {
Ok(tokens) => {
Expand Down
6 changes: 3 additions & 3 deletions crates/test-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ version = "0.3.45"
[lib]
proc-macro = true

[features]
coverage = []

[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
Expand All @@ -26,6 +29,3 @@ syn = { version = "2.0", default-features = false, features = [
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
trybuild = "1.0"
wasm-bindgen-test = { path = "../test" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }
9 changes: 3 additions & 6 deletions crates/test-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! going on here.

#![cfg_attr(
wasm_bindgen_unstable_test_coverage,
feature = "coverage",
feature(allow_internal_unstable),
allow(internal_features)
)]
Expand All @@ -18,10 +18,7 @@ use std::sync::atomic::*;
static CNT: AtomicUsize = AtomicUsize::new(0);

#[proc_macro_attribute]
#[cfg_attr(
wasm_bindgen_unstable_test_coverage,
allow_internal_unstable(coverage_attribute)
)]
#[cfg_attr(feature = "coverage", allow_internal_unstable(coverage_attribute))]
pub fn wasm_bindgen_test(
attr: proc_macro::TokenStream,
body: proc_macro::TokenStream,
Expand Down Expand Up @@ -109,7 +106,7 @@ pub fn wasm_bindgen_test(
// main test harness. This is the entry point for all tests.
let name = format_ident!("__wbgt_{}_{}", ident, CNT.fetch_add(1, Ordering::SeqCst));
let wasm_bindgen_path = attributes.wasm_bindgen_path;
let coverage = if cfg!(wasm_bindgen_unstable_test_coverage) {
let coverage = if cfg!(feature = "coverage") {
Some(quote! { #[coverage(off)] })
} else {
None
Expand Down
1 change: 1 addition & 0 deletions crates/test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ wasm-bindgen-test-macro = { path = '../test-macro', version = '=0.3.45' }

[target.'cfg(all(target_arch = "wasm32", wasm_bindgen_unstable_test_coverage))'.dependencies]
minicov = "0.3"
wasm-bindgen-test-macro = { path = '../test-macro', version = '=0.3.45', features = ["coverage"] }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }
Expand Down
31 changes: 11 additions & 20 deletions guide/src/wasm-bindgen-test/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ You can ask the runner to generate coverage data from functions marked as `#[was

## Enabling the feature

To enable this feature, you need to set `cfg(wasm_bindgen_unstable_test_coverage)` for `wasm-bindgen-test` and its dependencies.

Currently it is particularly difficult to [deliver compile-line arguments to proc-macros when cross-compiling with Cargo][1]. To circumvent this [host-config] can be used.

[1]: https://github.com/rust-lang/cargo/issues/4423
[host-config]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#host-config
To enable this feature, you need to enable `cfg(wasm_bindgen_unstable_test_coverage)`.

## Generating the data

Expand All @@ -26,18 +21,18 @@ Due to the current limitation of `llvm-cov`, we can't collect profiling symbols

### Arguments to the test runner

The following environment variables can be used to control the coverage output when [executing the test runner][2]:
The following environment variables can be used to control the coverage output when [executing the test runner][1]:

- `WASM_BINDGEN_UNSTABLE_TEST_PROFRAW_OUT` to control the file name of the profraw or the directory in which it is placed
- `WASM_BINDGEN_UNSTABLE_TEST_PROFRAW_OUT` to control the file name of the profraw or the directory in which it is placed. It might be necessary to provide the full path if e.g. running tests in a workspace.
- `WASM_BINDGEN_UNSTABLE_TEST_PROFRAW_PREFIX` to add a custom prefix to the profraw files. This can be useful if you're running the tests automatically in succession.

[2]: usage.html#appendix-using-wasm-bindgen-test-without-wasm-pack
[1]: usage.html#appendix-using-wasm-bindgen-test-without-wasm-pack

### Target features

This feature relies on the [minicov] crate, which provides a profiling runtime for WebAssembly. It in turn uses [cc] to compile the runtime to Wasm, which [currently doesn't support accounting for target feature][3]. Use e.g. `CFLAGS_wasm32_unknown_unknown="-matomics -mbulk-memory"` to account for that.
This feature relies on the [minicov] crate, which provides a profiling runtime for WebAssembly. It in turn uses [cc] to compile the runtime to Wasm, which [currently doesn't support accounting for target feature][2]. Use e.g. `CFLAGS_wasm32_unknown_unknown="-matomics -mbulk-memory"` to account for that.

[3]: https://github.com/rust-lang/cc-rs/issues/268
[2]: https://github.com/rust-lang/cc-rs/issues/268
[cc]: https://crates.io/crates/cc
[minicov]: https://crates.io/crates/minicov

Expand All @@ -47,13 +42,10 @@ This adapts code taken from the [Rustc book], see that for more examples and gen

```sh
# Run the tests:
# - `CARGO_HOST_RUSTFLAGS` to pass the configuration to `wasm-bindgen-macro`.
# - `-Ztarget-applies-to-host -Zhost-config` to enable `CARGO_HOST_RUSTFLAGS`.
# - `--tests` to not run documentation tests, which is currently not supported.
CARGO_HOST_RUSTFLAGS=--cfg=wasm_bindgen_unstable_test_coverage \
# `--tests` to not run documentation tests, which is currently not supported.
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir --cfg=wasm_bindgen_unstable_test_coverage" \
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner \
cargo +nightly test -Ztarget-applies-to-host -Zhost-config --tests
cargo +nightly test --tests
# Compile to object files:
# - Extract a list of compiled artifacts from Cargo and filter them with `jq`.
# - Figure out the path to the LLVM IR file corresponding to an artifact.
Expand All @@ -62,9 +54,8 @@ crate_name=name_of_the_tested_crate_in_snake_case
objects=()
IFS=$'\n'
for file in $(
CARGO_HOST_RUSTFLAGS=--cfg=wasm_bindgen_unstable_test_coverage \
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir --cfg=wasm_bindgen_unstable_test_coverage" \
cargo +nightly test -Ztarget-applies-to-host -Zhost-config --tests --no-run --message-format=json | \
cargo +nightly test --tests --no-run --message-format=json | \
jq -r "select(.reason == \"compiler-artifact\") | (select(.target.kind == [\"test\"]) // select(.target.name == \"$crate_name\")) | .filenames[0]"
)
do
Expand All @@ -89,7 +80,7 @@ llvm-cov-19 show -show-instantiations=false -Xdemangler=rustfilt -output-dir cov

## Attribution

These methods have originally been pioneered by [Hacken OÜ], see [their guide][4] as well.
These methods have originally been pioneered by [Hacken OÜ], see [their guide][3] as well.

[4]: https://hknio.github.io/wasmcov
[3]: https://hknio.github.io/wasmcov
[Hacken OÜ]: https://hacken.io

0 comments on commit b650488

Please sign in to comment.