use wasm_mutate::{ErrorKind, WasmMutate};
use wasmparser::Validator;
fn validate(validator: &mut Validator, bytes: &[u8]) {
let err = match validator.validate_all(bytes) {
Ok(_) => return,
Err(e) => e,
};
drop(std::fs::write("test.wasm", &bytes));
if let Ok(text) = wasmprinter::print_bytes(bytes) {
drop(std::fs::write("test.wat", &text));
}
panic!("Wasm failed to validate: {err:?}");
}
#[test]
fn integration_test() {
let _ = env_logger::try_init();
let wat = r#"
(module
(func (export "exported_func")
nop
i32.const 42
if
i32.const 98
drop
end
)
)
"#;
let original = &wat::parse_str(wat).unwrap();
let mut mutator = WasmMutate::default();
mutator.fuel(1000);
mutator.seed(0);
let start = std::time::Instant::now();
let mut count = 0;
for _ in 0..100 {
let it = match mutator.run(original) {
Ok(it) => it,
Err(e) => match e.kind() {
ErrorKind::NoMutationsApplicable => continue,
ErrorKind::OutOfFuel => break,
_ => panic!("{}", e),
},
};
for mutated in it.take(100) {
let mutated = mutated.unwrap();
let text = wasmprinter::print_bytes(&mutated).unwrap();
println!("{text}");
let mut validator = Validator::new();
validate(&mut validator, &mutated);
count += 1;
}
}
let elapsed = start.elapsed();
println!(
"Generate {} modules in {}.{:03} seconds",
count,
elapsed.as_secs(),
elapsed.subsec_millis()
);
}