lucet_runtime_internals/module/
sparse_page_data.rs

1#[macro_export]
2macro_rules! sparse_page_data_tests {
3    ( $TestRegion:path ) => {
4        use std::sync::Arc;
5        use $TestRegion as TestRegion;
6        use $crate::alloc::{host_page_size, Limits};
7        use $crate::instance::InstanceInternal;
8        use $crate::module::{MockModuleBuilder, Module};
9        use $crate::region::Region;
10
11        const FIRST_MESSAGE: &'static [u8] = b"hello from mock_sparse_module!";
12        const SECOND_MESSAGE: &'static [u8] = b"hello again from mock_sparse_module!";
13
14        fn mock_sparse_module() -> Arc<dyn Module> {
15            let mut initial_heap = FIRST_MESSAGE.to_vec();
16            // zero remainder of the first page, and the whole second page
17            initial_heap.resize(4096 * 2, 0);
18            let mut third_page = SECOND_MESSAGE.to_vec();
19            third_page.resize(4096, 0);
20            initial_heap.append(&mut third_page);
21            MockModuleBuilder::new()
22                .with_initial_heap(initial_heap.as_slice())
23                .build()
24        }
25
26        #[test]
27        fn valid_sparse_page_data() {
28            let module = mock_sparse_module();
29
30            assert_eq!(module.sparse_page_data_len(), 3);
31
32            let mut first_page_expected: Vec<u8> = FIRST_MESSAGE.to_vec();
33            first_page_expected.resize(host_page_size(), 0);
34            let mut third_page_expected: Vec<u8> = SECOND_MESSAGE.to_vec();
35            third_page_expected.resize(host_page_size(), 0);
36
37            let first_page: &[u8] = module.get_sparse_page_data(0).unwrap();
38            assert_eq!(first_page, first_page_expected.as_slice());
39
40            assert!(module.get_sparse_page_data(1).is_none());
41
42            let third_page: &[u8] = module.get_sparse_page_data(2).unwrap();
43            assert_eq!(third_page, third_page_expected.as_slice());
44        }
45
46        #[test]
47        fn instantiate_valid_sparse_data() {
48            let module = mock_sparse_module();
49            let region = TestRegion::create(1, &Limits::default()).expect("region can be created");
50            let inst = region
51                .new_instance(module)
52                .expect("instance can be created");
53
54            // The test data initializers result in two strings getting copied into linear memory; see
55            // `lucet-runtime-c/test/data_segment/valid_data_seg.c` for details
56            let heap = unsafe { inst.alloc().heap() };
57            assert_eq!(&heap[0..FIRST_MESSAGE.len()], FIRST_MESSAGE.as_ref());
58            let second_message_start = 2 * host_page_size();
59            assert_eq!(
60                &heap[second_message_start..second_message_start + SECOND_MESSAGE.len()],
61                SECOND_MESSAGE.as_ref()
62            );
63        }
64    };
65}
66
67#[cfg(test)]
68mod tests {
69    sparse_page_data_tests!(crate::region::mmap::MmapRegion);
70}