test_input.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: Lib_scoru_wasm input
Invocation: dune exec src/lib_scoru_wasm/test/test_scoru_wasm.exe \
-- test "^Input$"
Subject: Input tests for the tezos-scoru-wasm library
*)
open Tztest
open Lazy_containers
open Tezos_webassembly_interpreter
open Tezos_scoru_wasm
let write_input () =
let open Lwt.Syntax in
let input = Input_buffer.alloc () in
let* () =
Input_buffer.enqueue
input
{
rtype = 1l;
raw_level = 2l;
message_counter = Z.of_int 2;
payload = Bytes.of_string "hello";
}
in
let* () =
Input_buffer.enqueue
input
{
rtype = 1l;
raw_level = 2l;
message_counter = Z.of_int 3;
payload = Bytes.of_string "hello";
}
in
assert (Input_buffer.num_elements input = Z.of_int 2) ;
let* () =
Lwt.try_bind
(fun () ->
Input_buffer.enqueue
input
{
rtype = 1l;
raw_level = 2l;
message_counter = Z.of_int 2;
payload = Bytes.of_string "hello";
})
(fun _ -> assert false)
(function
| Input_buffer.Cannot_store_an_earlier_message -> Lwt.return ()
| _ -> assert false)
in
Lwt.return Result.return_unit
let read_input () =
let open Lwt.Syntax in
let lim = Types.(MemoryType {min = 100l; max = Some 1000l}) in
let memory = Memory.alloc lim in
let input_buffer = Input_buffer.alloc () in
let output_buffer = Output_buffer.alloc () in
let* () =
Input_buffer.enqueue
input_buffer
{
rtype = 1l;
raw_level = 2l;
message_counter = Z.of_int 2;
payload = Bytes.of_string "hello";
}
in
assert (Input_buffer.num_elements input_buffer = Z.one) ;
let* result =
Host_funcs.Internal_for_tests.aux_write_input_in_memory
~input_buffer
~output_buffer
~memory
~rtype_offset:0l
~level_offset:4l
~id_offset:10l
~dst:50l
~max_bytes:36000l
in
let* output_level, output_id = Output_buffer.get_id output_buffer in
assert (output_level = 2l) ;
assert (output_id = Z.of_int (-1)) ;
assert (Input_buffer.num_elements input_buffer = Z.zero) ;
assert (result = 5) ;
let* m = Memory.load_bytes memory 0l 1 in
assert (m = "\001") ;
let* m = Memory.load_bytes memory 4l 1 in
assert (m = "\002") ;
let* m = Memory.load_bytes memory 10l 1 in
assert (m = "\002") ;
let* m = Memory.load_bytes memory 50l 5 in
assert (m = "hello") ;
Lwt.return @@ Result.return_unit
let read_input_no_messages () =
let open Lwt.Syntax in
let lim = Types.(MemoryType {min = 100l; max = Some 1000l}) in
let memory = Memory.alloc lim in
let input_buffer = Input_buffer.alloc () in
let output_buffer = Output_buffer.alloc () in
assert (Input_buffer.num_elements input_buffer = Z.zero) ;
let* result =
Host_funcs.Internal_for_tests.aux_write_input_in_memory
~input_buffer
~output_buffer
~memory
~rtype_offset:0l
~level_offset:4l
~id_offset:10l
~dst:50l
~max_bytes:36000l
in
assert (Input_buffer.num_elements input_buffer = Z.zero) ;
assert (result = 0) ;
Lwt.return @@ Result.return_unit
let test_host_fun () =
let open Lwt.Syntax in
let input = Input_buffer.alloc () in
let* () =
Input_buffer.enqueue
input
{
rtype = 1l;
raw_level = 2l;
message_counter = Z.of_int 2;
payload = Bytes.of_string "hello";
}
in
let module_inst = Tezos_webassembly_interpreter.Instance.empty_module_inst in
let memories =
Lazy_vector.Int32Vector.cons
(Memory.alloc (MemoryType Types.{min = 20l; max = Some 3600l}))
module_inst.memories
in
let module_inst = {module_inst with memories} in
let values =
Values.
[
Num (I32 0l); Num (I32 4l); Num (I32 10l); Num (I32 50l); Num (I32 3600l);
]
in
let host_funcs_registry = Tezos_webassembly_interpreter.Host_funcs.empty () in
Host_funcs.register_host_funcs host_funcs_registry ;
let module_reg = Instance.ModuleMap.create () in
let module_key = Instance.Module_key "test" in
Instance.update_module_ref module_reg module_key module_inst ;
let* result =
Eval.invoke
~module_reg
~caller:module_key
host_funcs_registry
~input
Host_funcs.Internal_for_tests.read_input
values
in
let* module_inst = Instance.resolve_module_ref module_reg module_key in
let* memory = Lazy_vector.Int32Vector.get 0l module_inst.memories in
assert (Input_buffer.num_elements input = Z.zero) ;
let* m = Memory.load_bytes memory 0l 1 in
assert (m = "\001") ;
let* m = Memory.load_bytes memory 4l 1 in
assert (m = "\002") ;
let* m = Memory.load_bytes memory 10l 1 in
assert (m = "\002") ;
let* m = Memory.load_bytes memory 50l 5 in
assert (m = "hello") ;
assert (result = Values.[Num (I32 5l)]) ;
Lwt.return @@ Result.return_unit
let tests =
[
tztest "Write input" `Quick write_input;
tztest "Read input" `Quick read_input;
tztest "Read input no messages" `Quick read_input_no_messages;
tztest "Host read input" `Quick test_host_fun;
]