From 1b7efa45f5ac7e0c0a52573efbb45ea5d8f1cb5c Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 9 Mar 2014 19:37:07 +0400 Subject: [PATCH] Subscriber: proper destruction, tests for that, tests for getFailureCount() --- libuavcan/include/uavcan/subscriber.hpp | 2 + libuavcan/test/subscriber.cpp | 73 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/libuavcan/include/uavcan/subscriber.hpp b/libuavcan/include/uavcan/subscriber.hpp index 5aa896570d..8316bf80cc 100644 --- a/libuavcan/include/uavcan/subscriber.hpp +++ b/libuavcan/include/uavcan/subscriber.hpp @@ -119,6 +119,8 @@ public: StaticAssert::check(); } + virtual ~Subscriber() { stop(); } + int start(Callback callback) { stop(); diff --git a/libuavcan/test/subscriber.cpp b/libuavcan/test/subscriber.cpp index 69f8dd19cc..89dfe2147c 100644 --- a/libuavcan/test/subscriber.cpp +++ b/libuavcan/test/subscriber.cpp @@ -66,6 +66,7 @@ static bool operator==(const uavcan::mavlink::Message& a, const uavcan::mavlink: a.payload == b.payload; } + TEST(Subscriber, Basic) { uavcan::PoolAllocator pool; @@ -132,14 +133,20 @@ TEST(Subscriber, Basic) /* * Reception */ + ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(1, sub_extended.start(listener.bindExtended())); ASSERT_EQ(1, sub_extended2.start(listener.bindExtended())); ASSERT_EQ(1, sub_simple.start(listener.bindSimple())); ASSERT_EQ(1, sub_simple2.start(listener.bindSimple())); + ASSERT_EQ(4, sch.getDispatcher().getNumMessageListeners()); + sub_extended2.stop(); // These are not used - making sure they aren't receiving anything sub_simple2.stop(); + ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners()); + for (unsigned int i = 0; i < rx_frames.size(); i++) { can_driver.ifaces[0].pushRx(rx_frames[i]); @@ -170,4 +177,70 @@ TEST(Subscriber, Basic) ASSERT_EQ(0, sub_extended.getFailureCount()); ASSERT_EQ(0, sub_simple.getFailureCount()); + + /* + * Unregistration + */ + ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners()); + + sub_extended.stop(); + sub_extended2.stop(); + sub_simple.stop(); + sub_simple2.stop(); + + ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); +} + + +static void panickingSink(const uavcan::ReceivedDataStructure&) +{ + FAIL() << "I just went mad"; +} + + +TEST(Subscriber, FailureCount) +{ + uavcan::PoolAllocator pool; + uavcan::PoolManager<1> poolmgr; + poolmgr.addPool(&pool); + + // Manual type registration - we can't rely on the GDTR state + uavcan::GlobalDataTypeRegistry::instance().reset(); + uavcan::DefaultDataTypeRegistrator _registrator; + + SystemClockDriver clock_driver; + CanDriverMock can_driver(2, clock_driver); + + uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + + uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + + { + uavcan::Subscriber sub(sch, poolmgr); + ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); + sub.start(panickingSink); + ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); + + ASSERT_EQ(0, sub.getFailureCount()); + + for (int i = 0; i < 4; i++) + { + // uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, + // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame + uavcan::Frame frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast, + uavcan::NodeID(i + 100), uavcan::NodeID::Broadcast, 0, i, true); + // No payload - broken transfer + uavcan::RxFrame rx_frame(frame, clock_driver.getMonotonicMicroseconds(), + clock_driver.getUtcMicroseconds(), 0); + can_driver.ifaces[0].pushRx(rx_frame); + can_driver.ifaces[1].pushRx(rx_frame); + } + + ASSERT_LE(0, sch.spin(clock_driver.getMonotonicMicroseconds() + 10000)); + + ASSERT_EQ(4, sub.getFailureCount()); + + ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); // Still there + } + ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); // Removed }