From c438402b15f3288a0c65fe717cef1e457587604b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Fri, 23 Sep 2022 17:22:32 +0200 Subject: [PATCH] TestComponent: assert closer to callsite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempts to assert closer to callsite to make it easier to debug. This requires that we also pay attention to remaining items in the expect_buffer. This check is done on Drop. Signed-off-by: Maxime “pep” Buquet --- src/component.rs | 76 +++++++++++++++++++++++++++---------------- src/room.rs | 4 --- src/tests/iq.rs | 1 - src/tests/presence.rs | 8 ----- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/component.rs b/src/component.rs index 02f40d8..3262387 100644 --- a/src/component.rs +++ b/src/component.rs @@ -12,6 +12,7 @@ use std::marker::Send; use std::ops::{Deref, DerefMut}; use std::pin::Pin; use std::task::Context; +use std::thread; use async_trait::async_trait; use futures::{task::Poll, Stream}; @@ -162,7 +163,6 @@ impl From for TestElement { #[derive(Debug)] pub struct TestComponent { in_buffer: VecDeque, - out_buffer: VecDeque, expect_buffer: VecDeque, } @@ -175,7 +175,6 @@ impl TestComponent { .map(|el| TestElement(el)) .collect::>(), ), - out_buffer: VecDeque::new(), expect_buffer: VecDeque::new(), } } @@ -212,33 +211,39 @@ impl TestComponent { .push_back(Expect::Presence(Box::new(callback), desc.into())) } - /// Asserts expected output and actual output are the same - pub fn assert(&mut self) { - loop { - let out = self.out_buffer.pop_front(); - let expected = self.expect_buffer.pop_front(); - - match (out, expected) { - (None, None) => break, - (Some(out), Some(expected)) => match expected { - Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)), - Expect::Iq(cb, _) => cb(Iq::try_from(out.0).unwrap()), - Expect::Message(cb, _) => cb(Message::try_from(out.0).unwrap()), - Expect::Presence(cb, _) => cb(Presence::try_from(out.0).unwrap()), - }, - (Some(out), None) => panic!("Missing matching expected element: {:?}", out), - (None, Some(expected)) => match expected { - Expect::Element(el) => panic!("Missing matching sent element: {:?}", el), - Expect::Iq(_, desc) => panic!("Missing iq: {}", desc), - Expect::Message(_, desc) => panic!("Missing message: {}", desc), - Expect::Presence(_, desc) => panic!("Missing presence: {}", desc), - }, - } - } - } - fn _send_stanza + Send>(&mut self, el: E) -> Result<(), Error> { - Ok(self.out_buffer.push_back(el.into())) + let out: TestElement = el.into(); + let expected = self.expect_buffer.pop_front(); + + match expected { + Some(expected) => match expected { + Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)), + Expect::Iq(cb, _) => match Iq::try_from(out.0.clone()) { + Ok(iq) => cb(iq), + _ => panic!( + "Mismatch stanza type. Expected iq, got: {}", + String::from(&out) + ), + }, + Expect::Message(cb, _) => match Message::try_from(out.0.clone()) { + Ok(message) => cb(message), + _ => panic!( + "Mismatch stanza type. Expected message, got: {}", + String::from(&out) + ), + }, + Expect::Presence(cb, _) => match Presence::try_from(out.0.clone()) { + Ok(presence) => cb(presence), + _ => panic!( + "Mismatch stanza type. Expected presence, got: {}", + String::from(&out) + ), + }, + }, + None => panic!("Missing matching expected element: {:?}", out), + } + + Ok(()) } } @@ -254,6 +259,21 @@ impl Stream for TestComponent { } } +impl Drop for TestComponent { + fn drop(&mut self) { + // Don't assert if we're already panicking. Rustc displays a huge backtrace when "panicked + // while panicking" even when nobody asks for it (RUST_BACKTRACE unset). Let the error + // appear if there isn't any other error. + if !thread::panicking() { + assert_eq!( + self.expect_buffer.len(), + 0, + "Remaining expected elements in the buffer" + ); + } + } +} + #[async_trait] impl ComponentTrait for TestComponent { async fn send_stanza + Send>(&mut self, el: E) -> Result<(), Error> { diff --git a/src/room.rs b/src/room.rs index 19e5d54..fe1f898 100644 --- a/src/room.rs +++ b/src/room.rs @@ -473,7 +473,6 @@ mod tests { ) .await .unwrap(); - component.assert(); } #[tokio::test] @@ -534,7 +533,6 @@ mod tests { ) .await .unwrap(); - component.assert(); } #[tokio::test] @@ -634,7 +632,6 @@ mod tests { ) .await .unwrap(); - component.assert(); } #[tokio::test] @@ -706,6 +703,5 @@ mod tests { ) .await .unwrap(); - component.assert(); } } diff --git a/src/tests/iq.rs b/src/tests/iq.rs index 97f0324..afbb2bf 100644 --- a/src/tests/iq.rs +++ b/src/tests/iq.rs @@ -61,5 +61,4 @@ async fn test_iq_unimplemented() { component.expect(reply); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); } diff --git a/src/tests/presence.rs b/src/tests/presence.rs index 2498df0..995c0bc 100644 --- a/src/tests/presence.rs +++ b/src/tests/presence.rs @@ -106,7 +106,6 @@ async fn test_join_presence_empty_room() { }, "Room subject to participant1"); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); assert_eq!(rooms.len(), 1); match rooms.get(&roomjid) { @@ -160,7 +159,6 @@ async fn test_join_presence_nick_already_assigned() { ); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); match rooms.get(&roomjid) { Some(room) => assert_eq!(room.occupants.len(), 1), @@ -263,7 +261,6 @@ async fn test_join_presence_existing_room() { }, "Subject for participant2"); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); match rooms.get(&roomjid) { Some(room) => assert_eq!(room.occupants.len(), 2), @@ -330,7 +327,6 @@ async fn test_presence_resync() { ); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); match rooms.get(&roomjid) { Some(room) => assert_eq!(room.occupants.len(), 2), @@ -354,7 +350,6 @@ async fn test_leave_non_existing_room() { let mut rooms: HashMap = HashMap::new(); handle_stanza(&mut component, &mut rooms).await.unwrap(); // The leave should be ignored, there should be no output at all. - component.assert(); } #[tokio::test] @@ -394,7 +389,6 @@ async fn test_leave_last_participant() { handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); assert_eq!(rooms.len(), 0); } @@ -457,7 +451,6 @@ async fn test_leave_room_not_last() { ); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); assert_eq!(rooms.len(), 1); match rooms.get(&roomjid) { Some(room) => assert_eq!(room.occupants.len(), 1), @@ -547,7 +540,6 @@ async fn test_join_msn() { component.expect_message(|_| (), "Subject message for participant2"); handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); assert_eq!(rooms.len(), 1); match rooms.get(&roomjid) {