Coverage Report

Created: 2024-05-16 12:16

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