From 1c01f7adef2d184694b5e98a286b7220224b31c3 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 6 Sep 2022 22:36:09 +0200 Subject: [PATCH 1/9] wasmvm: assert_approx_eq macro --- libwasmvm/src/lib.rs | 1 + libwasmvm/src/test_utils.rs | 89 +++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 libwasmvm/src/test_utils.rs diff --git a/libwasmvm/src/lib.rs b/libwasmvm/src/lib.rs index a4608c9b..e2ef48ae 100644 --- a/libwasmvm/src/lib.rs +++ b/libwasmvm/src/lib.rs @@ -14,6 +14,7 @@ mod querier; mod storage; mod tests; mod version; +mod test_utils; // We only interact with this crate via `extern "C"` interfaces, not those public // exports. There are no guarantees those exports are stable. diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs new file mode 100644 index 00000000..90d30385 --- /dev/null +++ b/libwasmvm/src/test_utils.rs @@ -0,0 +1,89 @@ +/// Asserts that two expressions are approximately equal to each other (using [`PartialOrd`]). +/// +/// The ratio argument defines how wide a range of values we accept, and is applied +/// to the **second** argument. +/// +/// On panic, this macro will print the values of the expressions with their +/// debug representations, and info about the acceptable range. +/// +/// Like [`assert!`], this macro has a second form, where a custom +/// panic message can be provided. +/// +/// # Examples +/// +/// ``` +/// let a = 3; +/// let b = 1 + 2; +/// assert_eq!(a, b); +/// +/// assert_eq!(a, b, "we are testing addition with {} and {}", a, b); +/// ``` +#[macro_export] +macro_rules! assert_approx_eq { + ($left:expr, $right:expr, $ratio:expr $(,)?) => {{ + use cosmwasm_std::{Decimal, Uint128}; + use std::str::FromStr as _; + + let left = Uint128::from($left); + let right = Uint128::from($right); + let ratio = Decimal::from_str($ratio).unwrap(); + + let delta = Uint128::from($right) * ratio; + let lower_bound = right - delta; + let upper_bound = right + delta; + + if !(left >= lower_bound && left <= upper_bound) { + panic!( + "{} doesn't belong to the expected range of {} - {}", + left, lower_bound, upper_bound + ); + } + }}; + ($left:expr, $right:expr, $ratio:expr, $($args:tt)+) => {{ + use cosmwasm_std::{Decimal, Uint128}; + use std::str::FromStr as _; + + let left = Uint128::from($left); + let right = Uint128::from($right); + let ratio = Decimal::from_str($ratio).unwrap(); + + let delta = Uint128::from($right) * ratio; + let lower_bound = right - delta; + let upper_bound = right + delta; + + if !(left >= lower_bound && left <= upper_bound) { + panic!( + "{} doesn't belong to the expected range of {} - {}: {}", + left, lower_bound, upper_bound, format!($($args)*) + ); + } + }}; +} + +#[cfg(test)] +mod tests { + #[test] + fn assert_approx() { + assert_approx_eq!(9_u32, 10_u32, "0.12"); + } + + #[test] + #[should_panic(expected = "8 doesn't belong to the expected range of 9 - 11")] + fn assert_approx_fail() { + assert_approx_eq!(8_u32, 10_u32, "0.12"); + } + + #[test] + #[should_panic( + expected = "8 doesn't belong to the expected range of 9 - 11: some extra info about the error" + )] + fn assert_approx_with_custom_panic_msg() { + assert_approx_eq!( + 8_u32, + 10_u32, + "0.12", + "some extra {} about the error", + "info" + ); + } +} From c00dc5cda31b33822d0e49a80a75c14827bdcfad Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 6 Sep 2022 22:51:46 +0200 Subject: [PATCH 2/9] Refactor assert_approx_eq! --- libwasmvm/src/test_utils.rs | 79 ++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index 90d30385..2b82c47d 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -1,66 +1,57 @@ -/// Asserts that two expressions are approximately equal to each other (using [`PartialOrd`]). +#![cfg(test)] + +use cosmwasm_std::{Decimal, Uint128}; +use std::str::FromStr as _; + +/// Asserts that two expressions are approximately equal to each other. /// /// The ratio argument defines how wide a range of values we accept, and is applied -/// to the **second** argument. +/// to the **second** (`right`) argument. /// /// On panic, this macro will print the values of the expressions with their /// debug representations, and info about the acceptable range. /// -/// Like [`assert!`], this macro has a second form, where a custom +/// Like [`assert_eq!`], this macro has a second form, where a custom /// panic message can be provided. -/// -/// # Examples -/// -/// ``` -/// let a = 3; -/// let b = 1 + 2; -/// assert_eq!(a, b); -/// -/// assert_eq!(a, b, "we are testing addition with {} and {}", a, b); -/// ``` #[macro_export] macro_rules! assert_approx_eq { ($left:expr, $right:expr, $ratio:expr $(,)?) => {{ - use cosmwasm_std::{Decimal, Uint128}; - use std::str::FromStr as _; - - let left = Uint128::from($left); - let right = Uint128::from($right); - let ratio = Decimal::from_str($ratio).unwrap(); - - let delta = Uint128::from($right) * ratio; - let lower_bound = right - delta; - let upper_bound = right + delta; - - if !(left >= lower_bound && left <= upper_bound) { - panic!( - "{} doesn't belong to the expected range of {} - {}", - left, lower_bound, upper_bound - ); - } + $crate::test_utils::assert_approx_eq_impl($left, $right, $ratio, None); }}; ($left:expr, $right:expr, $ratio:expr, $($args:tt)+) => {{ - use cosmwasm_std::{Decimal, Uint128}; - use std::str::FromStr as _; + $crate::test_utils::assert_approx_eq_impl($left, $right, $ratio, Some(format!($($args)*))); + }}; +} - let left = Uint128::from($left); - let right = Uint128::from($right); - let ratio = Decimal::from_str($ratio).unwrap(); +#[track_caller] +fn assert_approx_eq_impl( + left: impl Into, + right: impl Into, + ratio: &str, + panic_msg: Option, +) { + let left = left.into(); + let right = right.into(); + let ratio = Decimal::from_str(ratio).unwrap(); - let delta = Uint128::from($right) * ratio; - let lower_bound = right - delta; - let upper_bound = right + delta; + let delta = right * ratio; + let lower_bound = right - delta; + let upper_bound = right + delta; - if !(left >= lower_bound && left <= upper_bound) { - panic!( + if !(left >= lower_bound && left <= upper_bound) { + match panic_msg { + Some(panic_msg) => panic!( "{} doesn't belong to the expected range of {} - {}: {}", - left, lower_bound, upper_bound, format!($($args)*) - ); + left, lower_bound, upper_bound, panic_msg + ), + None => panic!( + "{} doesn't belong to the expected range of {} - {}", + left, lower_bound, upper_bound + ), } - }}; + } } -#[cfg(test)] mod tests { #[test] fn assert_approx() { From a2d04853bb01bd79fc4f1e6bd6ca41d0b2c7f120 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 6 Sep 2022 23:00:21 +0200 Subject: [PATCH 3/9] assert_approx_eq! - panic msgs closer to std --- libwasmvm/src/test_utils.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index 2b82c47d..8d1d8905 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -41,12 +41,12 @@ fn assert_approx_eq_impl( if !(left >= lower_bound && left <= upper_bound) { match panic_msg { Some(panic_msg) => panic!( - "{} doesn't belong to the expected range of {} - {}: {}", - left, lower_bound, upper_bound, panic_msg + "assertion failed: `(left ~= right)`\nleft: {}\nright: {}\nratio applied to right: {}\nacceptable range: {} - {}: {}", + left, right, ratio, lower_bound, upper_bound, panic_msg ), None => panic!( - "{} doesn't belong to the expected range of {} - {}", - left, lower_bound, upper_bound + "assertion failed: `(left ~= right)`\nleft: {}\nright: {}\nratio applied to right: {}\nacceptable range: {} - {}", + left, right, ratio, lower_bound, upper_bound ), } } @@ -59,14 +59,23 @@ mod tests { } #[test] - #[should_panic(expected = "8 doesn't belong to the expected range of 9 - 11")] + fn assert_approx_with_vars() { + let a = 66_u32; + let b = 67_u32; + assert_approx_eq!(a, b, "0.02"); + } + + #[test] + #[should_panic( + expected = "assertion failed: `(left ~= right)`\nleft: 8\nright: 10\nratio applied to right: 0.12\nacceptable range: 9 - 11" + )] fn assert_approx_fail() { assert_approx_eq!(8_u32, 10_u32, "0.12"); } #[test] #[should_panic( - expected = "8 doesn't belong to the expected range of 9 - 11: some extra info about the error" + expected = "assertion failed: `(left ~= right)`\nleft: 8\nright: 10\nratio applied to right: 0.12\nacceptable range: 9 - 11: some extra info about the error" )] fn assert_approx_with_custom_panic_msg() { assert_approx_eq!( From 80eb9eb72d94bedc022c7c66dc04381292acca06 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Tue, 6 Sep 2022 23:21:14 +0200 Subject: [PATCH 4/9] cargo fmt --- libwasmvm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libwasmvm/src/lib.rs b/libwasmvm/src/lib.rs index e2ef48ae..8cf1a0a1 100644 --- a/libwasmvm/src/lib.rs +++ b/libwasmvm/src/lib.rs @@ -12,9 +12,9 @@ mod iterator; mod memory; mod querier; mod storage; +mod test_utils; mod tests; mod version; -mod test_utils; // We only interact with this crate via `extern "C"` interfaces, not those public // exports. There are no guarantees those exports are stable. From 926d2caf1d90a1fa1a534bbe0a9b8ff7d9749355 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 7 Sep 2022 14:49:59 +0200 Subject: [PATCH 5/9] assert_approx_eq: require args to be of one type --- libwasmvm/src/test_utils.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index 8d1d8905..a72bc0d2 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -24,9 +24,9 @@ macro_rules! assert_approx_eq { } #[track_caller] -fn assert_approx_eq_impl( - left: impl Into, - right: impl Into, +fn assert_approx_eq_impl>( + left: U, + right: U, ratio: &str, panic_msg: Option, ) { From 22c1cd4f09d681163b4983584bd7dc6c7c90c60a Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 7 Sep 2022 14:53:59 +0200 Subject: [PATCH 6/9] assert_approx_eq: test more types --- libwasmvm/src/test_utils.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index a72bc0d2..a5de8eac 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -56,6 +56,12 @@ mod tests { #[test] fn assert_approx() { assert_approx_eq!(9_u32, 10_u32, "0.12"); + assert_approx_eq!(9_u64, 10_u64, "0.12"); + assert_approx_eq!( + 9_000_000_000_000_000_000_000_000_000_000_000_000_u128, + 10_000_000_000_000_000_000_000_000_000_000_000_000_u128, + "0.10" + ); } #[test] @@ -63,6 +69,14 @@ mod tests { let a = 66_u32; let b = 67_u32; assert_approx_eq!(a, b, "0.02"); + + let a = 66_u64; + let b = 67_u64; + assert_approx_eq!(a, b, "0.02"); + + let a = 66_u128; + let b = 67_u128; + assert_approx_eq!(a, b, "0.02"); } #[test] From c883151e0b99842e86df60d35bb5bdf673244019 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 7 Sep 2022 15:28:20 +0200 Subject: [PATCH 7/9] assert_approx_eq: make sure arg order doesn't matter --- libwasmvm/src/test_utils.rs | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index a5de8eac..8a23e14c 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -5,21 +5,21 @@ use std::str::FromStr as _; /// Asserts that two expressions are approximately equal to each other. /// -/// The ratio argument defines how wide a range of values we accept, and is applied -/// to the **second** (`right`) argument. +/// The `max_rel_diff` argument defines the maximum relative difference +/// of the `left` and `right` values. /// -/// On panic, this macro will print the values of the expressions with their -/// debug representations, and info about the acceptable range. +/// On panic, this macro will print the values of the arguments and +/// the actual relative difference. /// /// Like [`assert_eq!`], this macro has a second form, where a custom /// panic message can be provided. #[macro_export] macro_rules! assert_approx_eq { - ($left:expr, $right:expr, $ratio:expr $(,)?) => {{ - $crate::test_utils::assert_approx_eq_impl($left, $right, $ratio, None); + ($left:expr, $right:expr, $max_rel_diff:expr $(,)?) => {{ + $crate::test_utils::assert_approx_eq_impl($left, $right, $max_rel_diff, None); }}; - ($left:expr, $right:expr, $ratio:expr, $($args:tt)+) => {{ - $crate::test_utils::assert_approx_eq_impl($left, $right, $ratio, Some(format!($($args)*))); + ($left:expr, $right:expr, $max_rel_diff:expr, $($args:tt)+) => {{ + $crate::test_utils::assert_approx_eq_impl($left, $right, $max_rel_diff, Some(format!($($args)*))); }}; } @@ -27,26 +27,26 @@ macro_rules! assert_approx_eq { fn assert_approx_eq_impl>( left: U, right: U, - ratio: &str, + max_rel_diff: &str, panic_msg: Option, ) { let left = left.into(); let right = right.into(); - let ratio = Decimal::from_str(ratio).unwrap(); + let max_rel_diff = Decimal::from_str(max_rel_diff).unwrap(); - let delta = right * ratio; - let lower_bound = right - delta; - let upper_bound = right + delta; + let largest = std::cmp::max(left, right); + let smallest = std::cmp::min(left, right); + let rel_diff = Decimal::from_ratio(largest - smallest, largest); - if !(left >= lower_bound && left <= upper_bound) { + if rel_diff > max_rel_diff { match panic_msg { Some(panic_msg) => panic!( - "assertion failed: `(left ~= right)`\nleft: {}\nright: {}\nratio applied to right: {}\nacceptable range: {} - {}: {}", - left, right, ratio, lower_bound, upper_bound, panic_msg + "assertion failed: `(left ≈ right)`\nleft: {}\nright: {}\nrelative difference: {}\nmax allowed relative difference: {}\n: {}", + left, right, rel_diff, max_rel_diff, panic_msg ), None => panic!( - "assertion failed: `(left ~= right)`\nleft: {}\nright: {}\nratio applied to right: {}\nacceptable range: {} - {}", - left, right, ratio, lower_bound, upper_bound + "assertion failed: `(left ≈ right)`\nleft: {}\nright: {}\nrelative difference: {}\nmax allowed relative difference: {}\n", + left, right, rel_diff, max_rel_diff ), } } @@ -81,7 +81,7 @@ mod tests { #[test] #[should_panic( - expected = "assertion failed: `(left ~= right)`\nleft: 8\nright: 10\nratio applied to right: 0.12\nacceptable range: 9 - 11" + expected = "assertion failed: `(left ≈ right)`\nleft: 8\nright: 10\nrelative difference: 0.2\nmax allowed relative difference: 0.12\n" )] fn assert_approx_fail() { assert_approx_eq!(8_u32, 10_u32, "0.12"); @@ -89,12 +89,12 @@ mod tests { #[test] #[should_panic( - expected = "assertion failed: `(left ~= right)`\nleft: 8\nright: 10\nratio applied to right: 0.12\nacceptable range: 9 - 11: some extra info about the error" + expected = "assertion failed: `(left ≈ right)`\nleft: 17\nright: 20\nrelative difference: 0.15\nmax allowed relative difference: 0.12\n: some extra info about the error" )] fn assert_approx_with_custom_panic_msg() { assert_approx_eq!( - 8_u32, - 10_u32, + 17_u32, + 20_u32, "0.12", "some extra {} about the error", "info" From c276a8e48ed68c5e05359208d98ca76167e31009 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 7 Sep 2022 16:04:19 +0200 Subject: [PATCH 8/9] test refactor --- libwasmvm/src/cache.rs | 13 ++++++------- libwasmvm/src/test_utils.rs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/libwasmvm/src/cache.rs b/libwasmvm/src/cache.rs index e94b4bd3..93236114 100644 --- a/libwasmvm/src/cache.rs +++ b/libwasmvm/src/cache.rs @@ -328,6 +328,8 @@ pub extern "C" fn release_cache(cache: *mut cache_t) { #[cfg(test)] mod tests { + use crate::assert_approx_eq; + use super::*; use std::iter::FromIterator; use tempfile::TempDir; @@ -711,13 +713,10 @@ mod tests { assert_eq!(misses, 0); assert_eq!(elements_pinned_memory_cache, 1); assert_eq!(elements_memory_cache, 0); - let expected = 5602873; // +/- 20% - assert!( - size_pinned_memory_cache > expected * 80 / 100, - "size_pinned_memory_cache: {size_pinned_memory_cache}" - ); - assert!( - size_pinned_memory_cache < expected * 120 / 100, + assert_approx_eq!( + size_pinned_memory_cache, + 5602873, + "0.2", "size_pinned_memory_cache: {size_pinned_memory_cache}" ); assert_eq!(size_memory_cache, 0); diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index 8a23e14c..105be742 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -24,7 +24,7 @@ macro_rules! assert_approx_eq { } #[track_caller] -fn assert_approx_eq_impl>( +pub fn assert_approx_eq_impl>( left: U, right: U, max_rel_diff: &str, From 765b15ef496d590bfa7251be7896ab2ae3b4faa1 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Wed, 7 Sep 2022 16:52:31 +0200 Subject: [PATCH 9/9] assert_approx_eq! - use abs_diff --- libwasmvm/src/test_utils.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libwasmvm/src/test_utils.rs b/libwasmvm/src/test_utils.rs index 105be742..d6e5f515 100644 --- a/libwasmvm/src/test_utils.rs +++ b/libwasmvm/src/test_utils.rs @@ -35,8 +35,7 @@ pub fn assert_approx_eq_impl>( let max_rel_diff = Decimal::from_str(max_rel_diff).unwrap(); let largest = std::cmp::max(left, right); - let smallest = std::cmp::min(left, right); - let rel_diff = Decimal::from_ratio(largest - smallest, largest); + let rel_diff = Decimal::from_ratio(left.abs_diff(right), largest); if rel_diff > max_rel_diff { match panic_msg {