1 #[macro_export]
2 macro_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)]
68 mod tests {
69     sparse_page_data_tests!(crate::region::mmap::MmapRegion);
70 }
71