#[cfg(test)]
mod simple_tests {
use std::io::prelude::*;
use std::fs::{File, read_dir};
use std::path::PathBuf;
use parser::{WasmDecoder, Parser, ParserState, ParserInput, SectionCode, Operator};
use validator::{ValidatingParser, ValidatingParserConfig, OperatorValidatorConfig};
const VALIDATOR_CONFIG: Option<ValidatingParserConfig> =
Some(ValidatingParserConfig {
operator_config: OperatorValidatorConfig { enable_threads: true },
});
fn read_file_data(path: &PathBuf) -> Vec<u8> {
println!("Parsing {:?}", path);
let mut data = Vec::new();
let mut f = File::open(path).ok().unwrap();
f.read_to_end(&mut data).unwrap();
data
}
#[test]
fn it_works() {
for entry in read_dir("tests").unwrap() {
let dir = entry.unwrap();
if !dir.file_type().unwrap().is_file() {
continue;
}
let data = read_file_data(&dir.path());
let mut parser = Parser::new(data.as_slice());
let mut max_iteration = 100000000;
loop {
let state = parser.read();
match *state {
ParserState::EndWasm => break,
ParserState::Error(err) => panic!("Error: {:?}", err),
_ => (),
}
max_iteration -= 1;
if max_iteration == 0 {
panic!("Max iterations exceeded");
}
}
}
}
#[test]
fn validator_not_fails() {
for entry in read_dir("tests").unwrap() {
let dir = entry.unwrap();
if !dir.file_type().unwrap().is_file() {
continue;
}
let data = read_file_data(&dir.path());
let mut parser = ValidatingParser::new(data.as_slice(), VALIDATOR_CONFIG);
let mut max_iteration = 100000000;
loop {
let state = parser.read();
match *state {
ParserState::EndWasm => break,
ParserState::Error(err) => panic!("Error: {:?}", err),
_ => (),
}
max_iteration -= 1;
if max_iteration == 0 {
panic!("Max iterations exceeded");
}
}
}
}
#[test]
fn validator_fails() {
for entry in read_dir("tests/invalid").unwrap() {
let dir = entry.unwrap();
if !dir.file_type().unwrap().is_file() {
continue;
}
let data = read_file_data(&dir.path());
let mut parser = ValidatingParser::new(data.as_slice(), VALIDATOR_CONFIG);
let mut max_iteration = 100000000;
let mut error = false;
loop {
let state = parser.read();
if let ParserState::Error(_) = *state {
error = true;
break;
}
if let ParserState::EndWasm = *state {
break;
}
max_iteration -= 1;
if max_iteration == 0 {
panic!("Max iterations exceeded");
}
}
if !error {
panic!("fail is expected");
}
}
}
macro_rules! expect_state {
($state:expr, $expected:pat) => ({{
let state: &ParserState = $state;
match *state {
$expected => (),
_ => panic!("Unexpected state during testing: {:?}", state)
}
}});
}
#[test]
fn default_read() {
let data = read_file_data(&PathBuf::from("tests/simple.wasm"));
let mut parser = Parser::new(data.as_slice());
expect_state!(parser.read(), ParserState::BeginWasm { .. });
expect_state!(parser.read(), ParserState::BeginSection { code: SectionCode::Type, .. });
expect_state!(parser.read(), ParserState::TypeSectionEntry(_));
expect_state!(parser.read(), ParserState::EndSection);
expect_state!(parser.read(), ParserState::BeginSection { code: SectionCode::Function, .. });
expect_state!(parser.read(), ParserState::FunctionSectionEntry(_));
expect_state!(parser.read(), ParserState::EndSection);
expect_state!(parser.read(), ParserState::BeginSection { code: SectionCode::Code, .. });
expect_state!(parser.read(), ParserState::BeginFunctionBody { .. });
expect_state!(parser.read(), ParserState::FunctionBodyLocals { .. });
expect_state!(parser.read(), ParserState::CodeOperator(_));
expect_state!(parser.read(), ParserState::CodeOperator(Operator::End));
expect_state!(parser.read(), ParserState::EndFunctionBody);
expect_state!(parser.read(), ParserState::EndSection);
expect_state!(parser.read(), ParserState::EndWasm);
}
#[test]
fn default_read_with_input() {
let data = read_file_data(&PathBuf::from("tests/simple.wasm"));
let mut parser = Parser::new(data.as_slice());
expect_state!(parser.read(), ParserState::BeginWasm { .. });
expect_state!(parser.read_with_input(ParserInput::Default),
ParserState::BeginSection { code: SectionCode::Type, .. });
expect_state!(parser.read(), ParserState::TypeSectionEntry(_));
expect_state!(parser.read(), ParserState::EndSection);
expect_state!(parser.read(), ParserState::BeginSection { code: SectionCode::Function, ..});
expect_state!(parser.read_with_input(ParserInput::ReadSectionRawData),
ParserState::SectionRawData(_));
expect_state!(parser.read(), ParserState::EndSection);
expect_state!(parser.read(), ParserState::BeginSection { code: SectionCode::Code, .. });
expect_state!(parser.read(), ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::EndSection);
expect_state!(parser.read(), ParserState::EndWasm);
}
#[test]
fn skipping() {
let data = read_file_data(&PathBuf::from("tests/naming.wasm"));
let mut parser = Parser::new(data.as_slice());
expect_state!(parser.read(),
ParserState::BeginWasm { .. });
expect_state!(parser.read_with_input(ParserInput::Default),
ParserState::BeginSection { code: SectionCode::Type, .. });
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Import, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Function, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Global, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Export, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Element, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Code, .. });
expect_state!(parser.read(),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::BeginFunctionBody { .. });
expect_state!(parser.read_with_input(ParserInput::SkipFunctionBody),
ParserState::EndSection);
expect_state!(parser.read(),
ParserState::BeginSection { code: SectionCode::Custom { .. }, ..});
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::BeginSection { code: SectionCode::Custom { .. }, .. });
expect_state!(parser.read_with_input(ParserInput::SkipSection),
ParserState::EndWasm);
}
}