Coverage Report

Created: 2024-05-16 12:16

/__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