diff --git a/rs/execution_environment/src/hypervisor/tests.rs b/rs/execution_environment/tests/hypervisor.rs similarity index 98% rename from rs/execution_environment/src/hypervisor/tests.rs rename to rs/execution_environment/tests/hypervisor.rs index 107c546af0ec..c086091fd290 100644 --- a/rs/execution_environment/src/hypervisor/tests.rs +++ b/rs/execution_environment/tests/hypervisor.rs @@ -1,4 +1,3 @@ -use crate::hypervisor::tests::WasmResult::Reply; use assert_matches::assert_matches; use candid::{Decode, Encode}; use ic_base_types::{NumSeconds, PrincipalId}; @@ -3961,77 +3960,77 @@ fn random_operations( prop::collection::vec(operation, 1..num_operations) } -// #[test] -// #[cfg(not(all(target_arch = "aarch64", target_vendor = "apple")))] -// fn random_memory_accesses() { -// // Limit the number of cases to keep the running time low. -// let config = ProptestConfig { -// cases: 20, -// failure_persistence: None, -// ..ProptestConfig::default() -// }; -// let algorithm = config.rng_algorithm; -// let mut runner = TestRunner::new_with_rng(config, TestRng::deterministic_rng(algorithm)); -// runner -// .run(&random_operations(10, 100), |operations| { -// const PAGES_PER_WASM_PAGE: i32 = WASM_PAGE_SIZE / 4096; -// let mut pages = vec![0_u8; 10 * PAGES_PER_WASM_PAGE as usize]; -// let mut dirty = vec![false; 10 * PAGES_PER_WASM_PAGE as usize]; -// let mut memory_accessor = MemoryAccessor::new(10); -// for op in operations { -// match op { -// Operation::Read(page) => { -// prop_assert_eq!( -// vec![pages[page as usize]; 4096], -// memory_accessor.read(page * 4096, 4096) -// ); -// // Read uses the first page as a scratchpad for arguments. -// dirty[0] = true; -// } -// Operation::Write(page, value) => { -// // Pages are already zero initialized, so writing zero -// // doesn't necessarily dirty them. Avoid zeros to make -// // dirty page tracking in the test precise. -// prop_assert!(value > 0); -// memory_accessor.write(page * 4096, &[value; 4096]); - -// // Confirm that the write was correct by reading the page. -// prop_assert_eq!(vec![value; 4096], memory_accessor.read(page * 4096, 4096)); -// pages[page as usize] = value; -// dirty[page as usize] = true; -// // Write uses the first page as a scratchpad for arguments. -// dirty[0] = true; -// } -// Operation::GrowAndRead => { -// prop_assert_eq!(vec![0; 65536], memory_accessor.grow_and_read()); -// pages.extend(vec![0_u8; PAGES_PER_WASM_PAGE as usize]); -// dirty.extend(vec![false; PAGES_PER_WASM_PAGE as usize]); -// // Read uses the first page as a scratchpad for arguments. -// dirty[0] = true; -// } -// Operation::GrowAndWrite(value) => { -// // Pages are already zero initialized, so writing zero -// // doesn't necessarily dirty them. Avoid zeros to make -// // dirty page tracking in the test precise. -// prop_assert!(value > 0); -// memory_accessor.grow_and_write(&[value; WASM_PAGE_SIZE as usize]); -// // Confirm that the write was correct by reading the pages. -// prop_assert_eq!( -// vec![value; WASM_PAGE_SIZE as usize], -// memory_accessor.read(pages.len() as i32 * 4096, WASM_PAGE_SIZE) -// ); -// pages.extend(vec![value; PAGES_PER_WASM_PAGE as usize]); -// dirty.extend(vec![true; PAGES_PER_WASM_PAGE as usize]); -// // Write uses the first page as a scratchpad for arguments. -// dirty[0] = true; -// } -// } -// } -// memory_accessor.verify_dirty_pages(&dirty); -// Ok(()) -// }) -// .unwrap(); -// } +#[test] +#[cfg(not(all(target_arch = "aarch64", target_vendor = "apple")))] +fn random_memory_accesses() { + // Limit the number of cases to keep the running time low. + let config = ProptestConfig { + cases: 20, + failure_persistence: None, + ..ProptestConfig::default() + }; + let algorithm = config.rng_algorithm; + let mut runner = TestRunner::new_with_rng(config, TestRng::deterministic_rng(algorithm)); + runner + .run(&random_operations(10, 100), |operations| { + const PAGES_PER_WASM_PAGE: i32 = WASM_PAGE_SIZE / 4096; + let mut pages = vec![0_u8; 10 * PAGES_PER_WASM_PAGE as usize]; + let mut dirty = vec![false; 10 * PAGES_PER_WASM_PAGE as usize]; + let mut memory_accessor = MemoryAccessor::new(10); + for op in operations { + match op { + Operation::Read(page) => { + prop_assert_eq!( + vec![pages[page as usize]; 4096], + memory_accessor.read(page * 4096, 4096) + ); + // Read uses the first page as a scratchpad for arguments. + dirty[0] = true; + } + Operation::Write(page, value) => { + // Pages are already zero initialized, so writing zero + // doesn't necessarily dirty them. Avoid zeros to make + // dirty page tracking in the test precise. + prop_assert!(value > 0); + memory_accessor.write(page * 4096, &[value; 4096]); + + // Confirm that the write was correct by reading the page. + prop_assert_eq!(vec![value; 4096], memory_accessor.read(page * 4096, 4096)); + pages[page as usize] = value; + dirty[page as usize] = true; + // Write uses the first page as a scratchpad for arguments. + dirty[0] = true; + } + Operation::GrowAndRead => { + prop_assert_eq!(vec![0; 65536], memory_accessor.grow_and_read()); + pages.extend(vec![0_u8; PAGES_PER_WASM_PAGE as usize]); + dirty.extend(vec![false; PAGES_PER_WASM_PAGE as usize]); + // Read uses the first page as a scratchpad for arguments. + dirty[0] = true; + } + Operation::GrowAndWrite(value) => { + // Pages are already zero initialized, so writing zero + // doesn't necessarily dirty them. Avoid zeros to make + // dirty page tracking in the test precise. + prop_assert!(value > 0); + memory_accessor.grow_and_write(&[value; WASM_PAGE_SIZE as usize]); + // Confirm that the write was correct by reading the pages. + prop_assert_eq!( + vec![value; WASM_PAGE_SIZE as usize], + memory_accessor.read(pages.len() as i32 * 4096, WASM_PAGE_SIZE) + ); + pages.extend(vec![value; PAGES_PER_WASM_PAGE as usize]); + dirty.extend(vec![true; PAGES_PER_WASM_PAGE as usize]); + // Write uses the first page as a scratchpad for arguments. + dirty[0] = true; + } + } + } + memory_accessor.verify_dirty_pages(&dirty); + Ok(()) + }) + .unwrap(); +} // Verify that the `memory.fill` instruction has cost linear with it's size // argument. @@ -4114,7 +4113,7 @@ fn can_extract_exported_custom_sections() { // Custom start=0x00028de2 end=0x00028dfc (size=0x0000001a) "icp:private candid:args" // Custom start=0x00028e02 end=0x00028e30 (size=0x0000002e) "icp:private motoko:stable-types" - let binary = include_bytes!("../../tests/test-data/custom_sections.wasm").to_vec(); + let binary = include_bytes!("test-data/custom_sections.wasm").to_vec(); let canister_id = test.canister_from_binary(binary).unwrap(); let execution_state = test.execution_state(canister_id); @@ -5470,7 +5469,7 @@ fn call_with_best_effort_response_succeeds() { ) .unwrap(); - assert_eq!(result, Reply(vec![])); + assert_eq!(result, WasmResult::Reply(vec![])); } #[test]