test_wasm_encoding.ml
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2022 Trili Tech <contact@trili.tech> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
(** Testing
-------
Component: Tree_encoding
Invocation: dune exec src/lib_scoru_wasm/test/test_scoru_wasm.exe \
-- test "^WASM Encodings$"
Subject: Encoding tests for the tezos-scoru-wasm library
*)
open Tztest
open Tezos_scoru_wasm
open Tezos_webassembly_interpreter
open Test_encodings_util
(** Test serialize/deserialize instructions. *)
let test_instr_roundtrip () =
let open Lwt_result_syntax in
qcheck Ast_generators.instr_gen (fun instr ->
let*! instr' = encode_decode Wasm_encoding.instruction_encoding instr in
assert (instr = instr') ;
return_unit)
let assert_string_equal s1 s2 =
let open Lwt_result_syntax in
if String.equal s1 s2 then return_unit else failwith "Not equal"
(** Test serialize/deserialize modules. *)
let test_module_roundtrip () =
let print = Format.asprintf "%a" Ast_printer.pp_module in
let open Lwt_result_syntax in
let dummy_module_reg =
(* It is ok to use a dummy here, because the module lookup (dereferenceing)
is not important when encoding or decoding. *)
Instance.ModuleMap.create ()
in
qcheck
~print
(Ast_generators.module_gen ~module_reg:dummy_module_reg ())
(fun module1 ->
(* We need to print here in order to force lazy bindings to be evaluated. *)
let module1_str = print module1 in
let*! module2 =
encode_decode Wasm_encoding.module_instance_encoding module1
in
let module2_str = print module2 in
let*! module3 =
encode_decode Wasm_encoding.module_instance_encoding module2
in
let module3_str = print module3 in
(* Check that modules match. *)
let* () = assert_string_equal module1_str module2_str in
assert_string_equal module2_str module3_str)
(** Test serialize/deserialize an encodable values and compare trees.
More formally, test that for all values, encoding, decoding and
re-encoding yields the same tree.
*)
let test_generic_tree ~pp ~gen ~encoding () =
let print = Format.asprintf "%a" pp in
let open Lwt_result_syntax in
let dummy_module_reg =
(* It is ok to use a dummy here, because the module lookup (dereferenceing)
is not important when encoding or decoding. *)
Instance.ModuleMap.create ()
in
let host_funcs = Host_funcs.empty () in
qcheck ~print (gen ~host_funcs ~module_reg:dummy_module_reg) (fun value1 ->
let*! empty_tree = empty_tree () in
(* We need to print here in order to force lazy bindings to be evaluated. *)
let _ = print value1 in
let*! tree1 =
Tree_encoding_runner.encode (encoding ~host_funcs) value1 empty_tree
in
let*! value2 = Tree_encoding_runner.decode (encoding ~host_funcs) tree1 in
(* We need to print here in order to force lazy bindings to be evaluated. *)
let _ = print value2 in
let*! tree2 =
Tree_encoding_runner.encode (encoding ~host_funcs) value2 empty_tree
in
assert (Tree.equal tree1 tree2) ;
return_unit)
(** Test serialize/deserialize modules and compare trees. *)
let test_module_tree =
test_generic_tree
~pp:Ast_printer.pp_module
~gen:(fun ~host_funcs:_ ~module_reg ->
Ast_generators.module_gen ~module_reg ())
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.module_instance_encoding)
(** Test serialize/deserialize frames and compare trees. *)
let test_frame_tree =
test_generic_tree
~pp:Ast_printer.pp_frame
~gen:(fun ~host_funcs:_ -> Ast_generators.frame_gen)
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.frame_encoding)
(** Test serialize/deserialize input buffers and compare trees. *)
let test_input_buffer_tree =
test_generic_tree
~pp:Ast_printer.pp_input_buffer
~gen:(fun ~host_funcs:_ ~module_reg:_ -> Ast_generators.input_buffer_gen)
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.input_buffer_encoding)
(** Test serialize/deserialize output buffers and compare trees. *)
let test_output_buffer_tree =
test_generic_tree
~pp:Ast_printer.pp_output_buffer
~gen:(fun ~host_funcs:_ ~module_reg:_ -> Ast_generators.output_buffer_gen)
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.output_buffer_encoding)
(** Test serialize/deserialize values and compare trees. *)
let test_values_tree =
test_generic_tree
~pp:(Ast_printer.pp_vector Ast_printer.Values.pp_value)
~gen:(fun ~host_funcs:_ ~module_reg:_ ->
QCheck2.Gen.(
map
Lazy_containers.Lazy_vector.Int32Vector.of_list
(list Ast_generators.value_gen)))
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.values_encoding)
(** Test serialize/deserialize administrative instructions and compare trees. *)
let test_admin_instr_tree =
test_generic_tree
~pp:Ast_printer.pp_admin_instr
~gen:(fun ~host_funcs:_ ~module_reg ->
Ast_generators.admin_instr_gen ~module_reg)
~encoding:(fun ~host_funcs:_ -> Wasm_encoding.admin_instr_encoding)
let test_config_tree =
test_generic_tree
~pp:Ast_printer.pp_config
~gen:Ast_generators.config_gen
~encoding:Wasm_encoding.config_encoding
let tests =
[
tztest "Instruction roundtrip" `Quick test_instr_roundtrip;
tztest "Module roundtrip" `Quick test_module_roundtrip;
tztest "Module trees" `Quick test_module_tree;
tztest "Values trees" `Quick test_values_tree;
tztest "Admin_instr trees" `Quick test_admin_instr_tree;
tztest "Input_buffer trees" `Quick test_input_buffer_tree;
tztest "Output_buffer trees" `Quick test_output_buffer_tree;
tztest "Frame trees" `Quick test_frame_tree;
tztest "Config trees" `Quick test_config_tree;
]