From ad5ece8ad511504ca92ac4754496c385c032fea9 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 | 54 +++++++++++++++++++++---------------------- src/room.rs | 4 ---- src/tests/iq.rs | 1 - src/tests/presence.rs | 8 ------- 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/component.rs b/src/component.rs index 02f40d8..e47bc8b 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,21 @@ 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, _) => 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()), + }, + None => panic!("Missing matching expected element: {:?}", out), + } + + Ok(()) } } @@ -254,6 +241,17 @@ 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 d62f281..57e5a95 100644 --- a/src/room.rs +++ b/src/room.rs @@ -468,7 +468,6 @@ mod tests { ); room.broadcast_presence(&mut component, &occupant3, &realjid3, BroadcastPresence::Resync).await.unwrap(); - component.assert(); } #[tokio::test] @@ -521,7 +520,6 @@ mod tests { ); room.broadcast_presence(&mut component, &occupant3, &realjid3, BroadcastPresence::Update).await.unwrap(); - component.assert(); } #[tokio::test] @@ -616,7 +614,6 @@ mod tests { ); room.broadcast_presence(&mut component, &occupant3, &realjid3, BroadcastPresence::Join).await.unwrap(); - component.assert(); } #[tokio::test] @@ -681,6 +678,5 @@ mod tests { ); room.broadcast_presence(&mut component, &occupant3, &realjid3, BroadcastPresence::Leave).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 65eff7e..8174149 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), @@ -355,7 +351,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] @@ -395,7 +390,6 @@ async fn test_leave_last_participant() { handle_stanza(&mut component, &mut rooms).await.unwrap(); - component.assert(); assert_eq!(rooms.len(), 0); } @@ -458,7 +452,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), @@ -545,7 +538,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) {