From ae6ee12c24cf5f0e554daabcf0191344bbd35f63 Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Wed, 1 Sep 2021 18:52:59 +0200 Subject: [PATCH] chore: test helper arbitrary ordering for 2 (#3762) * chore: add arbitrary order macro for more resilient subsystem tests * move to subsystem-test-helpers --- node/subsystem-test-helpers/src/lib.rs | 48 +++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/node/subsystem-test-helpers/src/lib.rs b/node/subsystem-test-helpers/src/lib.rs index f3fc16e85..4090b0bd3 100644 --- a/node/subsystem-test-helpers/src/lib.rs +++ b/node/subsystem-test-helpers/src/lib.rs @@ -240,7 +240,7 @@ pub struct TestSubsystemContextHandle { } impl TestSubsystemContextHandle { - /// Send a message or signal to the subsystem. This resolves at the point in time where the + /// Send a message or signal to the subsystem. This resolves at the point in time when the /// subsystem has _read_ the message. pub async fn send(&mut self, from_overseer: FromOverseer) { self.tx.send(from_overseer).await.expect("Test subsystem no longer live"); @@ -334,6 +334,36 @@ where } } +/// Asserts that two patterns match, yet only one +#[macro_export] +macro_rules! arbitrary_order { + ($rx:expr; $p1:pat => $e1:expr; $p2:pat => $e2:expr) => { + // If i.e. a enum has only two variants, `_` is unreachable. + match $rx { + $p1 => { + let __ret1 = { $e1 }; + let __ret2 = match $rx { + $p2 => $e2, + #[allow(unreachable_patterns)] + _ => unreachable!("first pattern matched, second pattern did not"), + }; + (__ret1, __ret2) + }, + $p2 => { + let __ret2 = { $e2 }; + let __ret1 = match $rx { + $p1 => $e1, + #[allow(unreachable_patterns)] + _ => unreachable!("second pattern matched, first pattern did not"), + }; + (__ret1, __ret2) + }, + #[allow(unreachable_patterns)] + _ => unreachable!("neither first nor second pattern matched"), + } + }; +} + #[cfg(test)] mod tests { use super::*; @@ -373,4 +403,20 @@ mod tests { CollatorProtocolMessage::CollateOn(_) )); } + + #[test] + fn macro_arbitrary_order() { + let mut vals = vec![Some(15_usize), None]; + let (first, second) = arbitrary_order!(vals.pop().unwrap(); Some(fx) => fx; None => 0); + assert_eq!(first, 15_usize); + assert_eq!(second, 0_usize); + } + + #[test] + fn macro_arbitrary_order_swapped() { + let mut vals = vec![None, Some(11_usize)]; + let (first, second) = arbitrary_order!(vals.pop().unwrap(); Some(fx) => fx; None => 0); + assert_eq!(first, 11_usize); + assert_eq!(second, 0); + } }