From 8a110e4b136c1dcfd178133f893d2e91eb27c358 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Fri, 21 Feb 2020 13:51:44 -0800 Subject: [PATCH] first pass at splitting out a test, making ctx/errno reusable --- tests/ctx.rs | 34 ++++++++++++++++++++++++++ tests/errno.witx | 8 ++++++ tests/main.rs | 34 +++----------------------- tests/test.witx | 12 +-------- tests/trivial.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++ tests/trivial.witx | 8 ++++++ 6 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 tests/ctx.rs create mode 100644 tests/errno.witx create mode 100644 tests/trivial.rs create mode 100644 tests/trivial.witx diff --git a/tests/ctx.rs b/tests/ctx.rs new file mode 100644 index 0000000000..b521dbaa40 --- /dev/null +++ b/tests/ctx.rs @@ -0,0 +1,34 @@ +use wiggle_runtime::GuestError; + +pub struct WasiCtx { + pub guest_errors: Vec, +} + +impl WasiCtx { + pub fn new() -> Self { + Self { + guest_errors: vec![], + } + } +} + +// Errno is used as a first return value in the functions above, therefore +// it must implement GuestErrorType with type Context = WasiCtx. +// The context type should let you do logging or debugging or whatever you need +// with these errors. We just push them to vecs. +#[macro_export] +macro_rules! impl_errno { + ( $errno:ty ) => { + impl wiggle_runtime::GuestErrorType for $errno { + type Context = WasiCtx; + fn success() -> $errno { + <$errno>::Ok + } + fn from_error(e: GuestError, ctx: &mut WasiCtx) -> $errno { + eprintln!("GUEST ERROR: {:?}", e); + ctx.guest_errors.push(e); + types::Errno::InvalidArg + } + } + }; +} diff --git a/tests/errno.witx b/tests/errno.witx new file mode 100644 index 0000000000..5197c2c224 --- /dev/null +++ b/tests/errno.witx @@ -0,0 +1,8 @@ +(typename $errno + (enum u32 + $ok + $invalid_arg + $dont_want_to + $physically_unable + $picket_line)) + diff --git a/tests/main.rs b/tests/main.rs index 9b09d9bf69..836a20c659 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -11,24 +11,12 @@ wiggle_generate::from_witx!({ ctx: WasiCtx, }); -pub struct WasiCtx { - guest_errors: Vec, -} +mod ctx; +use ctx::WasiCtx; -impl WasiCtx { - pub fn new() -> Self { - Self { - guest_errors: vec![], - } - } -} +impl_errno!(types::Errno); impl foo::Foo for WasiCtx { - fn bar(&mut self, an_int: u32, an_float: f32) -> Result<(), types::Errno> { - println!("BAR: {} {}", an_int, an_float); - Ok(()) - } - fn baz( &mut self, input1: types::Excuse, @@ -154,22 +142,6 @@ impl foo::Foo for WasiCtx { Ok(res) } } -// Errno is used as a first return value in the functions above, therefore -// it must implement GuestErrorType with type Context = WasiCtx. -// The context type should let you do logging or debugging or whatever you need -// with these errors. We just push them to vecs. -impl GuestErrorType for types::Errno { - type Context = WasiCtx; - fn success() -> types::Errno { - types::Errno::Ok - } - fn from_error(e: GuestError, ctx: &mut WasiCtx) -> types::Errno { - eprintln!("GUEST ERROR: {:?}", e); - ctx.guest_errors.push(e); - types::Errno::InvalidArg - } -} - #[derive(Debug)] struct BatExercise { pub input: u32, diff --git a/tests/test.witx b/tests/test.witx index 4a0930a616..78f69a3276 100644 --- a/tests/test.witx +++ b/tests/test.witx @@ -1,10 +1,4 @@ -(typename $errno - (enum u32 - $ok - $invalid_arg - $dont_want_to - $physically_unable - $picket_line)) +(use "errno.witx") (typename $excuse (enum u8 @@ -44,10 +38,6 @@ (typename $excuse_array (array (@witx pointer $excuse))) (module $foo - (@interface func (export "bar") - (param $an_int u32) - (param $an_float f32) - (result $error $errno)) (@interface func (export "baz") (param $an_excuse $excuse) (param $an_excuse_by_reference (@witx pointer $excuse)) diff --git a/tests/trivial.rs b/tests/trivial.rs new file mode 100644 index 0000000000..8eb8fdccfe --- /dev/null +++ b/tests/trivial.rs @@ -0,0 +1,61 @@ +use proptest::prelude::*; +use std::convert::TryFrom; +use wiggle_runtime::{ + GuestArray, GuestError, GuestErrorType, GuestPtr, GuestPtrMut, GuestRef, GuestRefMut, +}; +use wiggle_test::{HostMemory, MemArea}; + +mod ctx; +use ctx::WasiCtx; + +wiggle_generate::from_witx!({ + witx: ["tests/trivial.witx"], + ctx: WasiCtx, +}); + +impl_errno!(types::Errno); + +impl trivial::Trivial for WasiCtx { + fn int_float_args(&mut self, an_int: u32, an_float: f32) -> Result<(), types::Errno> { + println!("INT FLOAT ARGS: {} {}", an_int, an_float); + Ok(()) + } +} + +// There's nothing meaningful to test here - this just demonstrates the test machinery + +#[derive(Debug)] +struct IntFloatExercise { + pub an_int: u32, + pub an_float: f32, +} + +impl IntFloatExercise { + pub fn test(&self) { + let mut ctx = WasiCtx::new(); + let mut host_memory = HostMemory::new(); + let mut guest_memory = host_memory.guest_memory(); + + let e = trivial::int_float_args( + &mut ctx, + &mut guest_memory, + self.an_int as i32, + self.an_float, + ); + + assert_eq!(e, types::Errno::Ok.into(), "int_float_args error"); + } + + pub fn strat() -> BoxedStrategy { + (prop::num::u32::ANY, prop::num::f32::ANY) + .prop_map(|(an_int, an_float)| IntFloatExercise { an_int, an_float }) + .boxed() + } +} + +proptest! { + #[test] + fn int_float_exercise(e in IntFloatExercise::strat()) { + e.test() + } +} diff --git a/tests/trivial.witx b/tests/trivial.witx new file mode 100644 index 0000000000..3fbbf13e5c --- /dev/null +++ b/tests/trivial.witx @@ -0,0 +1,8 @@ +(use "errno.witx") + +(module $trivial + (@interface func (export "int_float_args") + (param $an_int u32) + (param $an_float f32) + (result $error $errno)) +)