11//! Tests to check if wasmi's fuel metering works as intended.
22
33use std:: fmt:: Debug ;
4- use wasmi:: { Config , Engine , Error , Func , Linker , Module , Store , TrapCode } ;
4+ use wasmi:: { CompilationMode , Config , Engine , Error , Func , Linker , Module , Store , TrapCode } ;
55
66/// Setup [`Engine`] and [`Store`] for fuel metering.
7- fn test_setup ( ) -> ( Store < ( ) > , Linker < ( ) > ) {
7+ fn test_setup ( mode : CompilationMode ) -> ( Store < ( ) > , Linker < ( ) > ) {
88 let mut config = Config :: default ( ) ;
99 config. consume_fuel ( true ) ;
10- config. compilation_mode ( wasmi :: CompilationMode :: Eager ) ;
10+ config. compilation_mode ( mode ) ;
1111 let engine = Engine :: new ( & config) ;
1212 let store = Store :: new ( & engine, ( ) ) ;
1313 let linker = Linker :: new ( & engine) ;
@@ -24,8 +24,8 @@ fn create_module(store: &Store<()>, bytes: &[u8]) -> Module {
2424}
2525
2626/// Setup [`Store`] and [`Instance`] for fuel metering.
27- fn default_test_setup ( wasm : & [ u8 ] ) -> ( Store < ( ) > , Func ) {
28- let ( mut store, linker) = test_setup ( ) ;
27+ fn default_test_setup ( mode : CompilationMode , wasm : & [ u8 ] ) -> ( Store < ( ) > , Func ) {
28+ let ( mut store, linker) = test_setup ( mode ) ;
2929 let module = create_module ( & store, wasm) ;
3030 let instance = linker. instantiate_and_start ( & mut store, & module) . unwrap ( ) ;
3131 let func = instance. get_func ( & store, "test" ) . unwrap ( ) ;
@@ -38,37 +38,45 @@ fn default_test_setup(wasm: &[u8]) -> (Store<()>, Func) {
3838///
3939/// We just check if the call succeeded, not if the results are correct.
4040/// That is to be determined by another kind of test.
41+ #[ track_caller]
4142fn assert_success < T > ( call_result : Result < T , Error > )
4243where
4344 T : Debug ,
4445{
45- assert ! ( call_result. is_ok( ) ) ;
46+ if let Err ( error) = call_result {
47+ panic ! ( "expected `Ok` but got: {error}" )
48+ }
4649}
4750
4851/// Asserts that the call trapped with [`TrapCode::OutOfFuel`].
52+ #[ track_caller]
4953fn assert_out_of_fuel < T > ( call_result : Result < T , Error > )
5054where
5155 T : Debug ,
5256{
53- assert ! ( matches!(
54- call_result. unwrap_err( ) . as_trap_code( ) ,
55- Some ( TrapCode :: OutOfFuel )
56- ) ) ;
57+ let Err ( error) = call_result else {
58+ panic ! ( "expected `out of fuel` error but got `Ok`" )
59+ } ;
60+ assert_eq ! (
61+ error. as_trap_code( ) ,
62+ Some ( TrapCode :: OutOfFuel ) ,
63+ "expected `out of fuel` but got: {error}"
64+ ) ;
5765}
5866
59- #[ test]
60- fn metered_i32_add ( ) {
61- let wasm = r#"
62- (module
63- (func (export "test") (param $a i32) (param $b i32) (result i32)
64- (i32.add
65- (local.get $a)
66- (local.get $b)
67- )
67+ const WASM_INPUT : & str = r#"
68+ (module
69+ (func (export "test") (param $a i32) (param $b i32) (result i32)
70+ (i32.add
71+ (local.get $a)
72+ (local.get $b)
6873 )
6974 )
70- "# ;
71- let ( mut store, func) = default_test_setup ( wasm. as_bytes ( ) ) ;
75+ )
76+ "# ;
77+
78+ fn run_test ( mode : CompilationMode , final_fuel : u64 ) {
79+ let ( mut store, func) = default_test_setup ( mode, WASM_INPUT . as_bytes ( ) ) ;
7280 let func = func. typed :: < ( i32 , i32 ) , i32 > ( & store) . unwrap ( ) ;
7381 // No fuel -> no success.
7482 assert_out_of_fuel ( func. call ( & mut store, ( 1 , 2 ) ) ) ;
@@ -78,7 +86,22 @@ fn metered_i32_add() {
7886 assert_out_of_fuel ( func. call ( & mut store, ( 1 , 2 ) ) ) ;
7987 assert_eq ! ( store. get_fuel( ) . ok( ) , Some ( 1 ) ) ;
8088 // Now add enough fuel, so execution should succeed.
81- store. set_fuel ( 10 ) . unwrap ( ) ;
89+ store. set_fuel ( 100 ) . unwrap ( ) ;
8290 assert_success ( func. call ( & mut store, ( 1 , 2 ) ) ) ;
83- assert_eq ! ( store. get_fuel( ) . ok( ) , Some ( 7 ) ) ;
91+ assert_eq ! ( store. get_fuel( ) . ok( ) , Some ( final_fuel) ) ;
92+ }
93+
94+ #[ test]
95+ fn metered_i32_add_eager ( ) {
96+ run_test ( CompilationMode :: Eager , 97 )
97+ }
98+
99+ #[ test]
100+ fn metered_i32_add_lazy_translation ( ) {
101+ run_test ( CompilationMode :: LazyTranslation , 48 )
102+ }
103+
104+ #[ test]
105+ fn metered_i32_add_lazy ( ) {
106+ run_test ( CompilationMode :: Lazy , 34 )
84107}
0 commit comments