summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/tinywasm/Cargo.toml2
-rw-r--r--crates/tinywasm/tests/test-mvp.rs2
-rw-r--r--crates/tinywasm/tests/test-wast.rs21
-rw-r--r--crates/tinywasm/tests/testsuite/mod.rs2
-rw-r--r--crates/tinywasm/tests/testsuite/run.rs268
5 files changed, 158 insertions, 137 deletions
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index 852c31c..86b65eb 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -20,7 +20,7 @@ tinywasm-types={version="0.0.6-alpha.0", path="../types", default-features=false
[dev-dependencies]
wasm-testsuite={path="../wasm-testsuite"}
wast={version="69.0"}
-owo-colors={version="3.5"}
+owo-colors={version="4.0"}
eyre={version="0.6"}
serde_json={version="1.0"}
serde={version="1.0", features=["derive"]}
diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs
index eab372b..fdd043d 100644
--- a/crates/tinywasm/tests/test-mvp.rs
+++ b/crates/tinywasm/tests/test-mvp.rs
@@ -9,7 +9,7 @@ fn main() -> Result<()> {
fn test_mvp() -> Result<()> {
let mut test_suite = TestSuite::new();
- test_suite.run(wasm_testsuite::MVP_TESTS)?;
+ test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?;
test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?;
if test_suite.failed() {
diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs
index 47e7d95..0770cb6 100644
--- a/crates/tinywasm/tests/test-wast.rs
+++ b/crates/tinywasm/tests/test-wast.rs
@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
use eyre::{bail, Result};
use testsuite::TestSuite;
@@ -9,8 +11,20 @@ fn main() -> Result<()> {
bail!("usage: cargo test-wast <wast-file>")
}
- let wast_file = &args[1];
- test_wast(wast_file)?;
+ // cwd for relative paths, absolute paths are kept as-is
+ let cwd = std::env::current_dir()?;
+
+ // if current dir is crates/tinywasm, then we want to go up 2 levels
+ let mut wast_file = if cwd.ends_with("crates/tinywasm") {
+ PathBuf::from("../../")
+ } else {
+ PathBuf::from("./")
+ };
+
+ wast_file.push(&args[1]);
+ let wast_file = cwd.join(wast_file);
+
+ test_wast(wast_file.to_str().expect("wast_file is not a valid path"))?;
Ok(())
}
@@ -19,7 +33,8 @@ fn test_wast(wast_file: &str) -> Result<()> {
println!("args: {:?}", args);
let mut test_suite = TestSuite::new();
- test_suite.run(&[wast_file])?;
+ println!("running wast file: {}", wast_file);
+ test_suite.run_paths(&[wast_file])?;
if test_suite.failed() {
eprintln!("\n\nfailed one or more tests:\n{:#?}", test_suite);
diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs
index d5cde5f..2a9cf4e 100644
--- a/crates/tinywasm/tests/testsuite/mod.rs
+++ b/crates/tinywasm/tests/testsuite/mod.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)] // rust analyzer doesn't recognize that code is used by tests without harness
+
use eyre::Result;
use std::io::{BufRead, Seek, SeekFrom};
use std::{
diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs
index 23c470c..afac117 100644
--- a/crates/tinywasm/tests/testsuite/run.rs
+++ b/crates/tinywasm/tests/testsuite/run.rs
@@ -7,165 +7,169 @@ use tinywasm_types::TinyWasmModule;
use wast::{lexer::Lexer, parser::ParseBuffer, Wast};
impl TestSuite {
- pub fn run(&mut self, tests: &[&str]) -> Result<()> {
+ pub fn run_paths(&mut self, tests: &[&str]) -> Result<()> {
tests.iter().for_each(|group| {
- let test_group = self.test_group(group);
+ let group_wast = std::fs::read(group).expect("failed to read test wast");
+ let group_wast = Cow::Owned(group_wast);
+ self.run_group(group, group_wast).expect("failed to run group");
+ });
- let wast = if group.starts_with("./") {
- let file = std::fs::read(group).expect("failed to read test wast");
- Cow::Owned(file)
- } else {
- wasm_testsuite::get_test_wast(group).expect("failed to get test wast")
- };
+ Ok(())
+ }
- let wast = std::str::from_utf8(&wast).expect("failed to convert wast to utf8");
+ pub fn run_spec_group(&mut self, tests: &[&str]) -> Result<()> {
+ tests.iter().for_each(|group| {
+ let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast");
+ self.run_group(group, group_wast).expect("failed to run group");
+ });
- let mut lexer = Lexer::new(wast);
- // we need to allow confusing unicode characters since they are technically valid wasm
- lexer.allow_confusing_unicode(true);
+ Ok(())
+ }
- let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer");
- let wast_data = wast::parser::parse::<Wast>(&buf).expect("failed to parse wat");
+ pub fn run_group(&mut self, group_name: &str, group_wast: Cow<'_, [u8]>) -> Result<()> {
+ let test_group = self.test_group(group_name);
+ let wast = std::str::from_utf8(&group_wast).expect("failed to convert wast to utf8");
- let mut last_module: Option<TinyWasmModule> = None;
- for (i, directive) in wast_data.directives.into_iter().enumerate() {
- let span = directive.span();
- use wast::WastDirective::*;
- let name = format!("{}-{}", group, i);
+ let mut lexer = Lexer::new(wast);
+ // we need to allow confusing unicode characters since they are technically valid wasm
+ lexer.allow_confusing_unicode(true);
- match directive {
- // TODO: needs to support more binary sections
- Wat(mut module) => {
- let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
+ let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer");
+ let wast_data = wast::parser::parse::<Wast>(&buf).expect("failed to parse wat");
- match &result {
- Err(_) => last_module = None,
- Ok(m) => last_module = Some(m.clone()),
- }
+ let mut last_module: Option<TinyWasmModule> = None;
+ for (i, directive) in wast_data.directives.into_iter().enumerate() {
+ let span = directive.span();
+ use wast::WastDirective::*;
+ let name = format!("{}-{}", group_name, i);
- test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ()));
+ match directive {
+ Wat(mut module) => {
+ let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
+
+ match &result {
+ Err(_) => last_module = None,
+ Ok(m) => last_module = Some(m.clone()),
}
- AssertMalformed {
- span,
- mut module,
- message: _,
- } => {
- let Ok(module) = module.encode() else {
- test_group.add_result(&format!("{}-malformed", name), span, Ok(()));
- continue;
- };
+ test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ()));
+ }
- let res = catch_unwind_silent(|| parse_module_bytes(&module))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
+ AssertMalformed {
+ span,
+ mut module,
+ message: _,
+ } => {
+ let Ok(module) = module.encode() else {
+ test_group.add_result(&format!("{}-malformed", name), span, Ok(()));
+ continue;
+ };
- test_group.add_result(
- &format!("{}-malformed", name),
- span,
- match res {
- Ok(_) => Err(eyre!("expected module to be malformed")),
- Err(_) => Ok(()),
- },
- );
- }
+ let res = catch_unwind_silent(|| parse_module_bytes(&module))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
- AssertInvalid {
+ test_group.add_result(
+ &format!("{}-malformed", name),
span,
- mut module,
- message: _,
- } => {
- let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
-
- test_group.add_result(
- &format!("{}-invalid", name),
- span,
- match res {
- Ok(_) => Err(eyre!("expected module to be invalid")),
- Err(_) => Ok(()),
- },
- );
- }
+ match res {
+ Ok(_) => Err(eyre!("expected module to be malformed")),
+ Err(_) => Ok(()),
+ },
+ );
+ }
- AssertTrap { exec, message: _, span } => {
- let res: Result<tinywasm::Result<()>, _> = catch_unwind_silent(|| {
- let (module, name) = match exec {
- wast::WastExecute::Wat(_wat) => unimplemented!("wat"),
- wast::WastExecute::Get { module: _, global: _ } => unimplemented!("get"),
- wast::WastExecute::Invoke(invoke) => (last_module.as_ref(), invoke.name),
- };
- exec_fn(module, name, &[]).map(|_| ())
- });
+ AssertInvalid {
+ span,
+ mut module,
+ message: _,
+ } => {
+ let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
+ test_group.add_result(
+ &format!("{}-invalid", name),
+ span,
match res {
- Err(err) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("test panicked: {:?}", err)),
- ),
- Ok(Err(tinywasm::Error::Trap(_))) => {
- test_group.add_result(&format!("{}-trap", name), span, Ok(()))
- }
- Ok(Err(err)) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("expected trap, got error: {:?}", err)),
- ),
- Ok(Ok(())) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("expected trap, got ok")),
- ),
+ Ok(_) => Err(eyre!("expected module to be invalid")),
+ Err(_) => Ok(()),
+ },
+ );
+ }
+
+ AssertTrap { exec, message: _, span } => {
+ let res: Result<tinywasm::Result<()>, _> = catch_unwind_silent(|| {
+ let (module, name) = match exec {
+ wast::WastExecute::Wat(_wat) => unimplemented!("wat"),
+ wast::WastExecute::Get { module: _, global: _ } => unimplemented!("get"),
+ wast::WastExecute::Invoke(invoke) => (last_module.as_ref(), invoke.name),
+ };
+ exec_fn(module, name, &[]).map(|_| ())
+ });
+
+ match res {
+ Err(err) => test_group.add_result(
+ &format!("{}-trap", name),
+ span,
+ Err(eyre!("test panicked: {:?}", err)),
+ ),
+ Ok(Err(tinywasm::Error::Trap(_))) => {
+ test_group.add_result(&format!("{}-trap", name), span, Ok(()))
+ }
+ Ok(Err(err)) => test_group.add_result(
+ &format!("{}-trap", name),
+ span,
+ Err(eyre!("expected trap, got error: {:?}", err)),
+ ),
+ Ok(Ok(())) => {
+ test_group.add_result(&format!("{}-trap", name), span, Err(eyre!("expected trap, got ok")))
}
}
+ }
- AssertReturn { span, exec, results } => {
- let res: Result<Result<()>, _> = catch_unwind_silent(|| {
- let invoke = match exec {
- wast::WastExecute::Wat(_) => unimplemented!("wat"),
- wast::WastExecute::Get { module: _, global: _ } => {
- return Err(eyre!("get not supported"))
- }
- wast::WastExecute::Invoke(invoke) => invoke,
- };
+ AssertReturn { span, exec, results } => {
+ let res: Result<Result<()>, _> = catch_unwind_silent(|| {
+ let invoke = match exec {
+ wast::WastExecute::Wat(_) => unimplemented!("wat"),
+ wast::WastExecute::Get { module: _, global: _ } => return Err(eyre!("get not supported")),
+ wast::WastExecute::Invoke(invoke) => invoke,
+ };
- let args = invoke
- .args
- .into_iter()
- .map(wastarg2tinywasmvalue)
- .collect::<Result<Vec<_>>>()?;
+ let args = invoke
+ .args
+ .into_iter()
+ .map(wastarg2tinywasmvalue)
+ .collect::<Result<Vec<_>>>()?;
- let outcomes = exec_fn(last_module.as_ref(), invoke.name, &args)?;
- let expected = results
- .into_iter()
- .map(wastret2tinywasmvalue)
- .collect::<Result<Vec<_>>>()?;
+ let outcomes = exec_fn(last_module.as_ref(), invoke.name, &args)?;
+ let expected = results
+ .into_iter()
+ .map(wastret2tinywasmvalue)
+ .collect::<Result<Vec<_>>>()?;
- if outcomes.len() != expected.len() {
- return Err(eyre!("expected {} results, got {}", expected.len(), outcomes.len()));
- }
- outcomes
- .iter()
- .zip(expected)
- .enumerate()
- .try_for_each(|(i, (outcome, exp))| {
- (outcome == &exp)
- .then_some(())
- .ok_or_else(|| eyre!("result {} did not match: {:?} != {:?}", i, outcome, exp))
- })
- });
+ if outcomes.len() != expected.len() {
+ return Err(eyre!("expected {} results, got {}", expected.len(), outcomes.len()));
+ }
+ outcomes
+ .iter()
+ .zip(expected)
+ .enumerate()
+ .try_for_each(|(i, (outcome, exp))| {
+ (outcome == &exp)
+ .then_some(())
+ .ok_or_else(|| eyre!("result {} did not match: {:?} != {:?}", i, outcome, exp))
+ })
+ });
- let res = res.map_err(|e| eyre!("test panicked: {:?}", e)).and_then(|r| r);
- test_group.add_result(&format!("{}-return", name), span, res);
- }
- _ => test_group.add_result(&format!("{}-unknown", name), span, Err(eyre!("unsupported directive"))),
+ let res = res.map_err(|e| eyre!("test panicked: {:?}", e)).and_then(|r| r);
+ test_group.add_result(&format!("{}-return", name), span, res);
}
+ _ => test_group.add_result(&format!("{}-unknown", name), span, Err(eyre!("unsupported directive"))),
}
- });
+ }
Ok(())
}