Use macro + WAT to make gas injection unit tests more readable.

This commit is contained in:
Jim Posen 2019-07-12 10:15:37 +02:00
parent b5472bcd8f
commit ed7f31ec20

View File

@ -587,136 +587,6 @@ mod tests {
self::wabt::wasm2wat(&binary).unwrap(); self::wabt::wasm2wat(&binary).unwrap();
} }
#[test]
fn simple() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(1),
Call(0),
GetGlobal(0),
End
][..]
);
}
#[test]
fn nested() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(6),
Call(0),
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
][..]
);
}
#[test]
fn ifelse() {
let module = builder::module()
.global()
.value_type().i32()
.build()
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
If(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
Else,
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(3),
Call(0),
GetGlobal(0),
If(elements::BlockType::NoResult),
I32Const(3),
Call(0),
GetGlobal(0),
GetGlobal(0),
GetGlobal(0),
Else,
I32Const(2),
Call(0),
GetGlobal(0),
GetGlobal(0),
End,
GetGlobal(0),
End
][..]
);
}
#[test] #[test]
fn call_index() { fn call_index() {
let module = builder::module() let module = builder::module()
@ -775,7 +645,6 @@ mod tests {
); );
} }
#[test] #[test]
fn forbidden() { fn forbidden() {
let module = builder::module() let module = builder::module()
@ -802,225 +671,247 @@ mod tests {
} }
#[test] fn parse_wat(source: &str) -> elements::Module {
fn branch_innermost() { let module_bytes = wabt::Wat2Wasm::new()
let module = builder::module() .validate(false)
.global() .convert(source)
.value_type().i32() .expect("failed to parse module");
.build() elements::deserialize_buffer(module_bytes.as_ref())
.function() .expect("failed to parse module")
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
Drop,
Br(0),
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(6),
Call(0),
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
Drop,
Br(0),
I32Const(2),
Call(0),
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End
][..]
);
} }
#[test] macro_rules! test_gas_counter_injection {
fn branch_outer_block() { (name = $name:ident; input = $input:expr; expected = $expected:expr) => {
let module = builder::module() #[test]
.global() fn $name() {
.value_type().i32() let input_module = parse_wat($input);
.build() let expected_module = parse_wat($expected);
.function()
.signature().param().i32().build()
.body()
.with_instructions(elements::Instructions::new(
vec![
GetGlobal(0),
Block(elements::BlockType::NoResult),
GetGlobal(0),
If(elements::BlockType::NoResult),
GetGlobal(0),
GetGlobal(0),
Drop,
BrIf(1),
End,
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End,
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); let injected_module = inject_gas_counter(input_module, &Default::default())
.expect("inject_gas_counter call failed");
assert_eq!( let actual_func_body = get_function_body(&injected_module, 0)
get_function_body(&injected_module, 0).unwrap(), .expect("injected module must have a function body");
&vec![ let expected_func_body = get_function_body(&expected_module, 0)
I32Const(5), .expect("post-module must have a function body");
Call(0),
GetGlobal(0), assert_eq!(actual_func_body, expected_func_body);
Block(elements::BlockType::NoResult), }
GetGlobal(0), }
If(elements::BlockType::NoResult),
I32Const(4),
Call(0),
GetGlobal(0),
GetGlobal(0),
Drop,
BrIf(1),
End,
I32Const(2),
Call(0),
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End,
][..]
);
} }
#[test] test_gas_counter_injection! {
fn branch_outer_loop() { name = simple;
let module = builder::module() input = r#"
.global() (module
.value_type().i32() (func (result i32)
.build() (get_global 0)))
.function() "#;
.signature().param().i32().build() expected = r#"
.body() (module
.with_instructions(elements::Instructions::new( (func (result i32)
vec![ (call 0 (i32.const 1))
GetGlobal(0), (get_global 0)))
Loop(elements::BlockType::NoResult), "#
GetGlobal(0),
If(elements::BlockType::NoResult),
GetGlobal(0),
BrIf(0),
Else,
GetGlobal(0),
GetGlobal(0),
Drop,
BrIf(1),
End,
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End,
]
))
.build()
.build()
.build();
let injected_module = inject_gas_counter(module, &Default::default()).unwrap();
assert_eq!(
get_function_body(&injected_module, 0).unwrap(),
&vec![
I32Const(3),
Call(0),
GetGlobal(0),
Loop(elements::BlockType::NoResult),
I32Const(4),
Call(0),
GetGlobal(0),
If(elements::BlockType::NoResult),
I32Const(2),
Call(0),
GetGlobal(0),
BrIf(0),
Else,
I32Const(4),
Call(0),
GetGlobal(0),
GetGlobal(0),
Drop,
BrIf(1),
End,
GetGlobal(0),
Drop,
End,
GetGlobal(0),
End,
][..]
);
} }
#[test] test_gas_counter_injection! {
fn return_from_func() { name = nested;
let module = builder::module() input = r#"
.global() (module
.value_type().i32() (func (result i32)
.build() (get_global 0)
.function() (block
.signature().param().i32().build() (get_global 0)
.body() (get_global 0)
.with_instructions(elements::Instructions::new( (get_global 0))
vec![ (get_global 0)))
GetGlobal(0), "#;
If(elements::BlockType::NoResult), expected = r#"
Return, (module
End, (func (result i32)
GetGlobal(0), (call 0 (i32.const 6))
End, (get_global 0)
] (block
)) (get_global 0)
.build() (get_global 0)
.build() (get_global 0))
.build(); (get_global 0)))
"#
}
let injected_module = inject_gas_counter(module, &Default::default()).unwrap(); test_gas_counter_injection! {
name = ifelse;
input = r#"
(module
(func (result i32)
(get_global 0)
(if
(then
(get_global 0)
(get_global 0)
(get_global 0))
(else
(get_global 0)
(get_global 0)))
(get_global 0)))
"#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 3))
(get_global 0)
(if
(then
(call 0 (i32.const 3))
(get_global 0)
(get_global 0)
(get_global 0))
(else
(call 0 (i32.const 2))
(get_global 0)
(get_global 0)))
(get_global 0)))
"#
}
assert_eq!( test_gas_counter_injection! {
get_function_body(&injected_module, 0).unwrap(), name = branch_innermost;
&vec![ input = r#"
I32Const(2), (module
Call(0), (func (result i32)
GetGlobal(0), (get_global 0)
If(elements::BlockType::NoResult), (block
I32Const(1), (get_global 0)
Call(0), (drop)
Return, (br 0)
End, (get_global 0)
I32Const(1), (drop))
Call(0), (get_global 0)))
GetGlobal(0), "#;
End, expected = r#"
][..] (module
); (func (result i32)
(call 0 (i32.const 6))
(get_global 0)
(block
(get_global 0)
(drop)
(br 0)
(call 0 (i32.const 2))
(get_global 0)
(drop))
(get_global 0)))
"#
}
test_gas_counter_injection! {
name = branch_outer_block;
input = r#"
(module
(func (result i32)
(get_global 0)
(block
(get_global 0)
(if
(then
(get_global 0)
(get_global 0)
(drop)
(br_if 1)))
(get_global 0)
(drop))
(get_global 0)))
"#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 5))
(get_global 0)
(block
(get_global 0)
(if
(then
(call 0 (i32.const 4))
(get_global 0)
(get_global 0)
(drop)
(br_if 1)))
(call 0 (i32.const 2))
(get_global 0)
(drop))
(get_global 0)))
"#
}
test_gas_counter_injection! {
name = branch_outer_loop;
input = r#"
(module
(func (result i32)
(get_global 0)
(loop
(get_global 0)
(if
(then
(get_global 0)
(br_if 0))
(else
(get_global 0)
(get_global 0)
(drop)
(br_if 1)))
(get_global 0)
(drop))
(get_global 0)))
"#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 3))
(get_global 0)
(loop
(call 0 (i32.const 4))
(get_global 0)
(if
(then
(call 0 (i32.const 2))
(get_global 0)
(br_if 0))
(else
(call 0 (i32.const 4))
(get_global 0)
(get_global 0)
(drop)
(br_if 1)))
(get_global 0)
(drop))
(get_global 0)))
"#
}
test_gas_counter_injection! {
name = return_from_func;
input = r#"
(module
(func (result i32)
(get_global 0)
(if
(then
(return)))
(get_global 0)))
"#;
expected = r#"
(module
(func (result i32)
(call 0 (i32.const 2))
(get_global 0)
(if
(then
(call 0 (i32.const 1))
(return)))
(call 0 (i32.const 1))
(get_global 0)))
"#
} }
} }