Path: blob/main/crates/wiggle/tests/pointers.rs
1692 views
use proptest::prelude::*;1use wiggle::{GuestMemory, GuestPtr};2use wiggle_test::{HostMemory, MemArea, WasiCtx, impl_errno};34wiggle::from_witx!({5witx: ["tests/pointers.witx"],6});78impl_errno!(types::Errno);910impl<'a> pointers::Pointers for WasiCtx<'a> {11fn pointers_and_enums(12&mut self,13memory: &mut GuestMemory<'_>,14input1: types::Excuse,15input2_ptr: GuestPtr<types::Excuse>,16input3_ptr: GuestPtr<types::Excuse>,17input4_ptr_ptr: GuestPtr<GuestPtr<types::Excuse>>,18) -> Result<(), types::Errno> {19println!("BAZ input1 {input1:?}");20let input2: types::Excuse = memory.read(input2_ptr).map_err(|e| {21eprintln!("input2_ptr error: {e}");22types::Errno::InvalidArg23})?;24println!("input2 {input2:?}");2526// Read enum value from immutable ptr:27let input3 = memory.read(input3_ptr).map_err(|e| {28eprintln!("input3_ptr error: {e}");29types::Errno::InvalidArg30})?;31println!("input3 {input3:?}");3233// Write enum to mutable ptr:34memory.write(input2_ptr, input3).map_err(|e| {35eprintln!("input2_ptr error: {e}");36types::Errno::InvalidArg37})?;38println!("wrote to input2_ref {input3:?}");3940// Read ptr value from mutable ptr:41let input4_ptr: GuestPtr<types::Excuse> = memory.read(input4_ptr_ptr).map_err(|e| {42eprintln!("input4_ptr_ptr error: {e}");43types::Errno::InvalidArg44})?;4546// Read enum value from that ptr:47let input4: types::Excuse = memory.read(input4_ptr).map_err(|e| {48eprintln!("input4_ptr error: {e}");49types::Errno::InvalidArg50})?;51println!("input4 {input4:?}");5253// Write ptr value to mutable ptr:54memory.write(input4_ptr_ptr, input2_ptr).map_err(|e| {55eprintln!("input4_ptr_ptr error: {e}");56types::Errno::InvalidArg57})?;5859Ok(())60}61}6263fn excuse_strat() -> impl Strategy<Value = types::Excuse> {64prop_oneof![65Just(types::Excuse::DogAte),66Just(types::Excuse::Traffic),67Just(types::Excuse::Sleeping),68]69.boxed()70}7172#[derive(Debug)]73struct PointersAndEnumsExercise {74pub input1: types::Excuse,75pub input2: types::Excuse,76pub input2_loc: MemArea,77pub input3: types::Excuse,78pub input3_loc: MemArea,79pub input4: types::Excuse,80pub input4_loc: MemArea,81pub input4_ptr_loc: MemArea,82}8384impl PointersAndEnumsExercise {85pub fn strat() -> BoxedStrategy<Self> {86(87excuse_strat(),88excuse_strat(),89HostMemory::mem_area_strat(4),90excuse_strat(),91HostMemory::mem_area_strat(4),92excuse_strat(),93HostMemory::mem_area_strat(4),94HostMemory::mem_area_strat(4),95)96.prop_map(97|(98input1,99input2,100input2_loc,101input3,102input3_loc,103input4,104input4_loc,105input4_ptr_loc,106)| PointersAndEnumsExercise {107input1,108input2,109input2_loc,110input3,111input3_loc,112input4,113input4_loc,114input4_ptr_loc,115},116)117.prop_filter("non-overlapping pointers", |e| {118MemArea::non_overlapping_set(&[119e.input2_loc,120e.input3_loc,121e.input4_loc,122e.input4_ptr_loc,123])124})125.boxed()126}127pub fn test(&self) {128let mut ctx = WasiCtx::new();129let mut host_memory = HostMemory::new();130let mut memory = host_memory.guest_memory();131132memory133.write(GuestPtr::new(self.input2_loc.ptr), self.input2)134.expect("input2 ref_mut");135136memory137.write(GuestPtr::new(self.input3_loc.ptr), self.input3)138.expect("input3 ref_mut");139140memory141.write(GuestPtr::new(self.input4_loc.ptr), self.input4)142.expect("input4 ref_mut");143144memory145.write(GuestPtr::new(self.input4_ptr_loc.ptr), self.input4_loc.ptr)146.expect("input4 ptr ref_mut");147148let e = pointers::pointers_and_enums(149&mut ctx,150&mut memory,151self.input1 as i32,152self.input2_loc.ptr as i32,153self.input3_loc.ptr as i32,154self.input4_ptr_loc.ptr as i32,155)156.unwrap();157assert_eq!(e, types::Errno::Ok as i32, "errno");158159// Implementation of pointers_and_enums writes input3 to the input2_loc:160let written_to_input2_loc: i32 = memory161.read(GuestPtr::new(self.input2_loc.ptr))162.expect("input2 ref");163164assert_eq!(165written_to_input2_loc, self.input3 as i32,166"pointers_and_enums written to input2"167);168169// Implementation of pointers_and_enums writes input2_loc to input4_ptr_loc:170let written_to_input4_ptr: u32 = memory171.read(GuestPtr::new(self.input4_ptr_loc.ptr))172.expect("input4_ptr_loc ref");173174assert_eq!(175written_to_input4_ptr, self.input2_loc.ptr,176"pointers_and_enums written to input4_ptr"177);178}179}180proptest! {181#[test]182fn pointers_and_enums(e in PointersAndEnumsExercise::strat()) {183e.test();184}185}186187188