/__w/smoldot/smoldot/repo/lib/src/executor/host/tests.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Smoldot |
2 | | // Copyright (C) 2023 Pierre Krieger |
3 | | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 |
4 | | |
5 | | // This program is free software: you can redistribute it and/or modify |
6 | | // it under the terms of the GNU General Public License as published by |
7 | | // the Free Software Foundation, either version 3 of the License, or |
8 | | // (at your option) any later version. |
9 | | |
10 | | // This program is distributed in the hope that it will be useful, |
11 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | // GNU General Public License for more details. |
14 | | |
15 | | // You should have received a copy of the GNU General Public License |
16 | | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | |
18 | | #![cfg(test)] |
19 | | |
20 | | use super::{vm::ExecHint, Config, HeapPages, HostVm, HostVmPrototype, StorageProofSizeBehavior}; |
21 | | |
22 | | mod hash_algorithms; |
23 | | mod initialization; |
24 | | mod run; |
25 | | |
26 | | /* |
27 | | |
28 | | The Wasm fixtures in the tests have been generated by compiling various Rust codes with the |
29 | | following compilation options: |
30 | | > rustc --crate-type cdylib -C opt-level=z --target wasm32-unknown-unknown ./foo.rs |
31 | | |
32 | | */ |
33 | | |
34 | | // TODO: test all host functions |
35 | | |
36 | | /// Adds to the provided Wasm bytecode the custom sections containing the runtime version and |
37 | | /// runtime APIs, that the module wants to find in the Wasm module. |
38 | 21 | fn with_core_version_custom_sections(mut wasm: Vec<u8>) -> Vec<u8> { |
39 | 21 | let spec_name = "foo".to_string(); |
40 | 21 | let impl_name = "bar".to_string(); |
41 | 21 | let authoring_version = 0; |
42 | 21 | let spec_version = 0; |
43 | 21 | let impl_version = 0; |
44 | 21 | let transaction_version = 0; |
45 | 21 | let state_version = 0; |
46 | 21 | |
47 | 21 | let mut core_version = Vec::new(); |
48 | 21 | core_version |
49 | 21 | .extend_from_slice(crate::util::encode_scale_compact_usize(spec_name.len()).as_ref()); |
50 | 21 | core_version.extend_from_slice(spec_name.as_bytes()); |
51 | 21 | core_version |
52 | 21 | .extend_from_slice(crate::util::encode_scale_compact_usize(impl_name.len()).as_ref()); |
53 | 21 | core_version.extend_from_slice(impl_name.as_bytes()); |
54 | 21 | core_version.extend_from_slice(&u32::to_le_bytes(authoring_version)); |
55 | 21 | core_version.extend_from_slice(&u32::to_le_bytes(spec_version)); |
56 | 21 | core_version.extend_from_slice(&u32::to_le_bytes(impl_version)); |
57 | 21 | core_version.extend_from_slice(crate::util::encode_scale_compact_usize(0).as_ref()); |
58 | 21 | core_version.extend_from_slice(&u32::to_le_bytes(transaction_version)); |
59 | 21 | core_version.extend_from_slice(&u8::to_le_bytes(state_version)); |
60 | 21 | |
61 | 21 | let mut core_version_section = Vec::new(); |
62 | 21 | core_version_section.extend(crate::util::leb128::encode_usize(b"runtime_version".len())); |
63 | 21 | core_version_section.extend_from_slice(b"runtime_version"); |
64 | 21 | core_version_section.extend_from_slice(&core_version); |
65 | 21 | |
66 | 21 | let mut core_apis_section = Vec::new(); |
67 | 21 | core_apis_section.extend(crate::util::leb128::encode_usize(b"runtime_apis".len())); |
68 | 21 | core_apis_section.extend_from_slice(b"runtime_apis"); |
69 | 21 | |
70 | 21 | wasm.push(0); |
71 | 21 | wasm.extend(crate::util::leb128::encode_usize( |
72 | 21 | core_version_section.len(), |
73 | 21 | )); |
74 | 21 | wasm.extend_from_slice(&core_version_section); |
75 | 21 | |
76 | 21 | wasm.push(0); |
77 | 21 | wasm.extend(crate::util::leb128::encode_usize(core_apis_section.len())); |
78 | 21 | wasm.extend_from_slice(&core_apis_section); |
79 | 21 | |
80 | 21 | wasm |
81 | 21 | } |
82 | | |
83 | | #[test] |
84 | 1 | fn is_send() { |
85 | 1 | fn req<T: Send>() {} |
86 | 1 | req::<HostVm>(); |
87 | 1 | } |
88 | | |
89 | | #[test] |
90 | 1 | fn basic_core_version() { |
91 | 3 | for exec_hint2 in ExecHint::available_engines() { |
92 | 2 | let proto = HostVmPrototype::new(Config { |
93 | 2 | module: &include_bytes!("./westend-runtime-v9300.wasm")[..], |
94 | 2 | heap_pages: HeapPages::new(2048), |
95 | 2 | exec_hint, |
96 | 2 | allow_unresolved_imports: true, |
97 | 2 | }) |
98 | 2 | .unwrap(); |
99 | 2 | |
100 | 2 | let mut vm = proto |
101 | 2 | .run_no_param( |
102 | 2 | "Core_version", |
103 | 2 | StorageProofSizeBehavior::proof_recording_disabled(), |
104 | 2 | ) |
105 | 2 | .unwrap() |
106 | 2 | .run(); |
107 | 6 | loop { |
108 | 6 | match vm { |
109 | 2 | HostVm::ReadyToRun(r) => vm = r.run(), |
110 | 0 | HostVm::Error { error, .. } => panic!("{error:?}"), |
111 | 2 | HostVm::Finished(_) => break, |
112 | 2 | HostVm::GetMaxLogLevel(r) => vm = r.resume(0), |
113 | 0 | _ => unreachable!(), |
114 | | } |
115 | | } |
116 | | } |
117 | 1 | } |
118 | | |
119 | | #[test] |
120 | 1 | fn min_requirements() { |
121 | 1 | // This module showcases minimum requirements in order for a Wasm module to be accepted. |
122 | 1 | // This test exists mostly here in order to provide a template that can be copied for other |
123 | 1 | // tests. |
124 | 1 | // Note that this is no way a baseline. It is for example also possible to export the memory |
125 | 1 | // instead of importing it, or to provide the runtime version through a runtime call. |
126 | 1 | let module_bytes = with_core_version_custom_sections( |
127 | 1 | wat::parse_str( |
128 | 1 | r#" |
129 | 1 | (module |
130 | 1 | (import "env" "memory" (memory 0)) |
131 | 1 | (global (export "__heap_base") i32 (i32.const 0)) |
132 | 1 | ) |
133 | 1 | "#, |
134 | 1 | ) |
135 | 1 | .unwrap(), |
136 | 1 | ); |
137 | | |
138 | 3 | for exec_hint2 in ExecHint::available_engines() { |
139 | 2 | HostVmPrototype::new(Config { |
140 | 2 | allow_unresolved_imports: false, |
141 | 2 | exec_hint, |
142 | 2 | heap_pages: HeapPages::new(1024), |
143 | 2 | module: &module_bytes, |
144 | 2 | }) |
145 | 2 | .unwrap(); |
146 | 2 | } |
147 | 1 | } |
148 | | |
149 | | // TODO: test more things |