Skip to content
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

[fix] #3928: Make failing the wasm tests actually fail the CI #3933

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/iroha2-dev-pr-wasm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
- name: Install iroha_wasm_test_runner
run: cd .. && cargo install --path tools/wasm_test_runner
- name: Run tests
run: mold --run cargo test --tests --no-fail-fast --quiet
12 changes: 10 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ members = [
"tools/parity_scale_decoder",
"tools/swarm",
"tools/wasm_builder_cli",
"tools/wasm_test_runner",
"version",
"version/derive",
"wasm_codec",
Expand Down
1 change: 0 additions & 1 deletion Dockerfile.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ RUN rustup component add llvm-tools-preview clippy
RUN rustup component add rust-src
RUN rustup component add rustfmt
RUN rustup target add wasm32-unknown-unknown
RUN cargo install webassembly-test-runner
RUN cargo install cargo-llvm-cov

# TODO: Figure out a way to pull in libgit2, which doesn't crash if this useless variable is gone.
Expand Down
1 change: 0 additions & 1 deletion Dockerfile.build.glibc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ RUN rustup component add llvm-tools-preview clippy
RUN rustup component add rust-src
RUN rustup component add rustfmt
RUN rustup target add wasm32-unknown-unknown
RUN cargo install webassembly-test-runner
RUN cargo install cargo-llvm-cov

# TODO: Figure out a way to pull in libgit2, which doesn't crash if this useless variable is gone.
Expand Down
2 changes: 1 addition & 1 deletion ffi/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[target.wasm32-unknown-unknown]
runner = "webassembly-test-runner"
runner = "iroha_wasm_test_runner"
16 changes: 16 additions & 0 deletions tools/wasm_test_runner/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "iroha_wasm_test_runner"

edition.workspace = true
version.workspace = true
authors.workspace = true
license.workspace = true

[lints]
workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
wasmtime = { workspace = true }
anyhow = "1.0.75"
82 changes: 82 additions & 0 deletions tools/wasm_test_runner/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! A tool to run `WebAssembly` tests
//!
//! This copies functionality of `webassembly-test-runner`, but with an ability to indicate failure with an exit code.

use std::process::ExitCode;

use anyhow::{bail, Result};
pesterev marked this conversation as resolved.
Show resolved Hide resolved
use wasmtime::{Engine, Instance, Module, Store};

struct TestMeta<'a> {
name: &'a str,
ignore: bool,
}

fn main() -> Result<ExitCode> {
let argv0 = std::env::args().next().unwrap();

let file = match std::env::args().nth(1) {
Some(it) => it,
None => {
bail!("usage: {} tests.wasm", argv0);
}
};
// Modules can be compiled through either the text or binary format
let engine = Engine::default();
let module = Module::from_file(&engine, &file)?;
let mut tests = Vec::new();
for export in module.exports() {
if let Some(name) = export.name().strip_prefix("$webassembly-test$") {
let mut ignore = true;
let name = name.strip_prefix("ignore$").unwrap_or_else(|| {
ignore = false;
name
});
tests.push((export, TestMeta { name, ignore }));
}
}
let total = tests.len();

eprintln!("\nrunning {} tests", total);
let mut store = Store::new(&engine, ());
let mut instance = Instance::new(&mut store, &module, &[])?;
let mut passed = 0;
let mut failed = 0;
let mut ignored = 0;
for (export, meta) in tests {
eprint!("test {} ...", meta.name);
if meta.ignore {
ignored += 1;
eprintln!(" ignored")
} else {
let f = instance.get_typed_func::<(), ()>(&mut store, export.name())?;

let pass = f.call(&mut store, ()).is_ok();
if pass {
passed += 1;
eprintln!(" ok")
} else {
// Reset instance on test failure. WASM uses `panic=abort`, so
// `Drop`s are not called after test failures, and a failed test
// might leave an instance in an inconsistent state.
store = Store::new(&engine, ());
instance = Instance::new(&mut store, &module, &[])?;

failed += 1;
eprintln!(" FAILED")
}
}
}
eprintln!(
"\ntest result: {}. {} passed; {} failed; {} ignored;",
if failed > 0 { "FAILED" } else { "ok" },
passed,
failed,
ignored,
);
Ok(if failed > 0 {
ExitCode::FAILURE
} else {
ExitCode::SUCCESS
})
}
2 changes: 1 addition & 1 deletion wasm/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
target = "wasm32-unknown-unknown"

[target.wasm32-unknown-unknown]
runner = "webassembly-test-runner"
runner = "iroha_wasm_test_runner"
4 changes: 2 additions & 2 deletions wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Check the [WASM section of our tutorial](https://hyperledger.github.io/iroha-2-d

## Running tests

To be able to run tests compiled for `wasm32-unknown-unknown` target install `webassembly-test-runner`:
To be able to run tests compiled for `wasm32-unknown-unknown` target install `iroha_wasm_test_runner` from the root of the iroha repository:

```bash
cargo install webassembly-test-runner
cargo install --path tools/wasm_test_runner
```

Then run tests:
Expand Down
8 changes: 5 additions & 3 deletions wasm/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,17 @@ mod tests {

use webassembly_test::webassembly_test;

use crate::_decode_from_raw;

fn get_dbg_message() -> &'static str {
"dbg_message"
}

#[no_mangle]
pub unsafe extern "C" fn _dbg_mock(ptr: *const u8, len: usize) {
assert_eq!(_decode_from_raw::<String>(ptr, len), get_dbg_message());
use parity_scale_codec::DecodeAll;

// can't use _decode_from_raw here, because we must NOT take the ownership
let bytes = core::slice::from_raw_parts(ptr, len);
assert_eq!(String::decode_all(&mut &*bytes).unwrap(), get_dbg_message());
}

#[webassembly_test]
Expand Down
2 changes: 1 addition & 1 deletion wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ mod tests {
}

fn get_test_expression() -> EvaluatesTo<NumericValue> {
Add::new(1_u32, 2_u32).into()
Add::new(2_u32, 3_u32).into()
}

#[no_mangle]
Expand Down
5 changes: 3 additions & 2 deletions wasm/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,16 @@ mod tests {
use webassembly_test::webassembly_test;

use super::*;
use crate::_decode_from_raw;

fn get_log_message() -> &'static str {
"log_message"
}

#[no_mangle]
pub unsafe extern "C" fn _log_mock(ptr: *const u8, len: usize) {
let (log_level, msg) = _decode_from_raw::<(u8, String)>(ptr, len);
// can't use _decode_from_raw here, because we must NOT take the ownership
let bytes = core::slice::from_raw_parts(ptr, len);
let (log_level, msg) = <(u8, String)>::decode_all(&mut &*bytes).unwrap();
assert_eq!(log_level, 3);
assert_eq!(msg, get_log_message());
}
Expand Down
Loading