/__w/smoldot/smoldot/repo/lib/src/executor/host/tests/initialization.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 | | use super::super::{ |
19 | | vm, vm::ExecHint, Config, HeapPages, HostVmPrototype, ModuleFormatError, NewErr, |
20 | | }; |
21 | | use super::with_core_version_custom_sections; |
22 | | |
23 | | #[test] |
24 | 1 | fn invalid_wasm() { |
25 | 1 | let module_bytes = &[5, 6, 7, 8, 9, 10]; |
26 | | |
27 | 3 | for exec_hint2 in ExecHint::available_engines() { |
28 | 2 | match HostVmPrototype::new(Config { |
29 | 2 | allow_unresolved_imports: false, |
30 | 2 | exec_hint, |
31 | 2 | heap_pages: HeapPages::new(1024), |
32 | 2 | module: &module_bytes, |
33 | 2 | }) { |
34 | 2 | Err(NewErr::VirtualMachine(vm::NewErr::InvalidWasm(_)) | NewErr::RuntimeVersion(_)) => { |
35 | 2 | } |
36 | 0 | _ => panic!(), |
37 | | } |
38 | | } |
39 | 1 | } |
40 | | |
41 | | #[test] |
42 | 1 | fn invalid_zstd() { |
43 | 1 | let module_bytes = &[82, 188, 83, 118, 70, 219, 142, 5, 6, 7, 8, 9, 10]; |
44 | | |
45 | 3 | for exec_hint2 in ExecHint::available_engines() { |
46 | 2 | match HostVmPrototype::new(Config { |
47 | 2 | allow_unresolved_imports: false, |
48 | 2 | exec_hint, |
49 | 2 | heap_pages: HeapPages::new(1024), |
50 | 2 | module: &module_bytes, |
51 | 2 | }) { |
52 | 2 | Err(NewErr::BadFormat(ModuleFormatError::InvalidZstd)) => {} |
53 | 0 | _ => panic!(), |
54 | | } |
55 | | } |
56 | 1 | } |
57 | | |
58 | | #[test] |
59 | 1 | fn valid_zstd() { |
60 | 1 | // This is a basic zstd-compressed Wasm module, with the Substrate-specific ZSTD magic number |
61 | 1 | // in front. |
62 | 1 | let module_bytes = &[ |
63 | 1 | 82, 188, 83, 118, 70, 219, 142, 5, 40, 181, 47, 253, 36, 109, 181, 2, 0, 50, 197, 18, 25, |
64 | 1 | 144, 135, 13, 122, 232, 155, 145, 241, 185, 162, 153, 81, 5, 153, 131, 230, 210, 156, 69, |
65 | 1 | 219, 162, 218, 18, 233, 3, 173, 12, 68, 129, 51, 22, 104, 151, 128, 214, 170, 230, 60, 46, |
66 | 1 | 85, 25, 214, 129, 147, 224, 47, 217, 88, 156, 129, 89, 184, 59, 150, 0, 231, 131, 39, 204, |
67 | 1 | 152, 159, 32, 120, 53, 213, 28, 43, 139, 37, 242, 223, 180, 241, 1, 2, 0, 79, 17, 216, 120, |
68 | 1 | 224, 12, 143, 94, 27, 50, |
69 | 1 | ]; |
70 | | |
71 | 3 | for exec_hint2 in ExecHint::available_engines() { |
72 | 2 | HostVmPrototype::new(Config { |
73 | 2 | allow_unresolved_imports: false, |
74 | 2 | exec_hint, |
75 | 2 | heap_pages: HeapPages::new(1024), |
76 | 2 | module: &module_bytes, |
77 | 2 | }) |
78 | 2 | .unwrap(); |
79 | 2 | } |
80 | 1 | } |
81 | | |
82 | | #[test] |
83 | 1 | fn no_heap_base() { |
84 | 1 | let module_bytes = with_core_version_custom_sections( |
85 | 1 | wat::parse_str( |
86 | 1 | r#" |
87 | 1 | (module |
88 | 1 | (import "env" "memory" (memory 0)) |
89 | 1 | ) |
90 | 1 | "#, |
91 | 1 | ) |
92 | 1 | .unwrap(), |
93 | 1 | ); |
94 | | |
95 | 3 | for exec_hint2 in ExecHint::available_engines() { |
96 | 2 | match HostVmPrototype::new(Config { |
97 | 2 | allow_unresolved_imports: false, |
98 | 2 | exec_hint, |
99 | 2 | heap_pages: HeapPages::new(1024), |
100 | 2 | module: &module_bytes, |
101 | 2 | }) { |
102 | 2 | Err(NewErr::HeapBaseNotFound) => {} |
103 | 0 | _ => panic!(), |
104 | | } |
105 | | } |
106 | 1 | } |
107 | | |
108 | | #[test] |
109 | 1 | fn memory_max_size_too_low() { |
110 | 1 | let module_bytes = with_core_version_custom_sections( |
111 | 1 | wat::parse_str( |
112 | 1 | r#" |
113 | 1 | (module |
114 | 1 | (import "env" "memory" (memory 0 1023)) |
115 | 1 | (global (export "__heap_base") i32 (i32.const 0)) |
116 | 1 | ) |
117 | 1 | "#, |
118 | 1 | ) |
119 | 1 | .unwrap(), |
120 | 1 | ); |
121 | | |
122 | 3 | for exec_hint2 in ExecHint::available_engines() { |
123 | 2 | match HostVmPrototype::new(Config { |
124 | 2 | allow_unresolved_imports: false, |
125 | 2 | exec_hint, |
126 | 2 | heap_pages: HeapPages::new(1024), |
127 | 2 | module: &module_bytes, |
128 | 2 | }) { |
129 | 2 | Err(NewErr::MemoryMaxSizeTooLow) => {} |
130 | 0 | _ => panic!(), |
131 | | } |
132 | | } |
133 | 1 | } |
134 | | |
135 | | #[test] |
136 | 1 | fn unresolved_host_functions_setting() { |
137 | 1 | let module_bytes = with_core_version_custom_sections( |
138 | 1 | wat::parse_str( |
139 | 1 | r#" |
140 | 1 | (module |
141 | 1 | (import "env" "memory" (memory 0)) |
142 | 1 | (import "env" "thishostfunctiondoesntexist" (func (param i64) (result i64))) |
143 | 1 | (global (export "__heap_base") i32 (i32.const 0)) |
144 | 1 | ) |
145 | 1 | "#, |
146 | 1 | ) |
147 | 1 | .unwrap(), |
148 | 1 | ); |
149 | | |
150 | 3 | for exec_hint2 in ExecHint::available_engines() { |
151 | 2 | match HostVmPrototype::new(Config { |
152 | 2 | allow_unresolved_imports: true, |
153 | 2 | exec_hint, |
154 | 2 | heap_pages: HeapPages::new(1024), |
155 | 2 | module: &module_bytes, |
156 | 2 | }) { |
157 | 2 | Ok(_) => {} |
158 | 0 | _ => panic!(), |
159 | | } |
160 | | |
161 | 2 | match HostVmPrototype::new(Config { |
162 | 2 | allow_unresolved_imports: false, |
163 | 2 | exec_hint, |
164 | 2 | heap_pages: HeapPages::new(1024), |
165 | 2 | module: &module_bytes, |
166 | 2 | }) { |
167 | 2 | Err(NewErr::VirtualMachine(vm::NewErr::UnresolvedFunctionImport { .. })) => {} |
168 | 0 | _ => panic!(), |
169 | | } |
170 | | } |
171 | 1 | } |
172 | | |
173 | | #[test] |
174 | 1 | fn host_function_bad_signature() { |
175 | 1 | // The `ext_allocator_malloc_version_1` host function exists but its actual signature |
176 | 1 | // is `(i32) -> i32`. |
177 | 1 | let module_bytes = with_core_version_custom_sections( |
178 | 1 | wat::parse_str( |
179 | 1 | r#" |
180 | 1 | (module |
181 | 1 | (import "env" "memory" (memory 0)) |
182 | 1 | (import "env" "ext_allocator_malloc_version_1" (func (param i64) (result i64))) |
183 | 1 | (global (export "__heap_base") i32 (i32.const 0)) |
184 | 1 | ) |
185 | 1 | "#, |
186 | 1 | ) |
187 | 1 | .unwrap(), |
188 | 1 | ); |
189 | | |
190 | 3 | for exec_hint2 in ExecHint::available_engines() { |
191 | 2 | match HostVmPrototype::new(Config { |
192 | 2 | allow_unresolved_imports: true, |
193 | 2 | exec_hint, |
194 | 2 | heap_pages: HeapPages::new(1024), |
195 | 2 | module: &module_bytes, |
196 | 2 | }) { |
197 | 2 | Ok(_) => {} |
198 | 0 | _ => panic!(), |
199 | | } |
200 | | |
201 | 2 | match HostVmPrototype::new(Config { |
202 | 2 | allow_unresolved_imports: false, |
203 | 2 | exec_hint, |
204 | 2 | heap_pages: HeapPages::new(1024), |
205 | 2 | module: &module_bytes, |
206 | 2 | }) { |
207 | 2 | Err(NewErr::VirtualMachine(vm::NewErr::UnresolvedFunctionImport { .. })) => {} |
208 | 0 | _ => panic!(), |
209 | | } |
210 | | } |
211 | 1 | } |
212 | | |
213 | | #[test] |
214 | 1 | fn rococo_genesis_works() { |
215 | 1 | // The Rococo genesis runtime has the particularity that it has a `runtime_apis` custom |
216 | 1 | // section but no `runtime_version` custom section. |
217 | 1 | let module_bytes = &include_bytes!("./rococo-genesis.wasm")[..]; |
218 | | |
219 | 3 | for exec_hint2 in ExecHint::available_engines() { |
220 | 2 | assert!(HostVmPrototype::new(Config { |
221 | 2 | allow_unresolved_imports: true, |
222 | 2 | exec_hint, |
223 | 2 | heap_pages: HeapPages::new(1024), |
224 | 2 | module: &module_bytes, |
225 | 2 | }) |
226 | 2 | .is_ok()); |
227 | | } |
228 | 1 | } |
229 | | |
230 | | // TODO: add tests for the runtime version gathering after clarifying the errors in host.rs |