From 36dda9c0175f2eb4f9dd7ea772f01a2bf62baa67 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 17 May 2015 13:49:40 +0300 Subject: [PATCH] NodeInfoRetriever basic test --- .../uavcan/protocol/node_info_retriever.hpp | 15 ++++ .../test/protocol/node_info_retriever.cpp | 70 +++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp index ceffa9bf28..4a10321e11 100644 --- a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp +++ b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp @@ -172,6 +172,8 @@ private: if (!TimerBase::isRunning()) { TimerBase::startPeriodic(getTimerPollInterval()); + UAVCAN_TRACE("NodeInfoRetriever", "Timer started, interval %ld ms", + static_cast(getTimerPollInterval().toMSec())); } } @@ -230,6 +232,7 @@ private: if (!requests_needed) { TimerBase::stop(); + UAVCAN_TRACE("NodeInfoRetriever", "Timer stopped"); } } } @@ -398,6 +401,18 @@ public: { max_concurrent_requests_ = max(static_cast(1), num); } + + /** + * These methods are needed mostly for testing. + */ + bool isRetrievingInProgress() const { return TimerBase::isRunning(); } + + uint8_t getNumPendingRequests() const + { + const unsigned num = get_node_info_client_.getNumPendingCalls(); + UAVCAN_ASSERT(num <= 0xFF); + return static_cast(num); + } }; } diff --git a/libuavcan/test/protocol/node_info_retriever.cpp b/libuavcan/test/protocol/node_info_retriever.cpp index 04f2d346ac..2b8f92d5d9 100644 --- a/libuavcan/test/protocol/node_info_retriever.cpp +++ b/libuavcan/test/protocol/node_info_retriever.cpp @@ -54,7 +54,8 @@ struct NodeInfoListener : public uavcan::INodeInfoListener virtual void handleNodeStatusChange(const uavcan::NodeStatusMonitor::NodeStatusChangeEvent& event) { - (void)event; + std::cout << "NODE " << int(event.node_id.get()) << " STATUS CHANGE: " + << int(event.old_status.status_code) << " --> " << int(event.status.status_code) << std::endl; status_change_cnt++; } @@ -102,10 +103,16 @@ TEST(NodeInfoRetriever, Basic) ASSERT_LE(0, provider->startAndPublish()); + ASSERT_FALSE(retr.isRetrievingInProgress()); + ASSERT_EQ(0, retr.getNumPendingRequests()); + /* * Waiting for discovery */ - nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1600)); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(50)); + ASSERT_TRUE(retr.isRetrievingInProgress()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1500)); + ASSERT_FALSE(retr.isRetrievingInProgress()); ASSERT_EQ(2, listener.status_message_cnt); ASSERT_EQ(1, listener.status_change_cnt); @@ -120,6 +127,8 @@ TEST(NodeInfoRetriever, Basic) /* * Declaring a bunch of different nodes that don't support GetNodeInfo */ + ASSERT_FALSE(retr.isRetrievingInProgress()); + retr.setNumRequestAttempts(3); uavcan::TransferID tid; @@ -128,12 +137,65 @@ TEST(NodeInfoRetriever, Basic) publishNodeStatus(nodes.can_a, uavcan::NodeID(11), 0, 10, tid); publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 10, tid); - nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(2100)); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(1, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(2, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(3, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1000)); + ASSERT_TRUE(retr.isRetrievingInProgress()); tid.increment(); publishNodeStatus(nodes.can_a, uavcan::NodeID(10), 0, 11, tid); publishNodeStatus(nodes.can_a, uavcan::NodeID(11), 0, 11, tid); publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 11, tid); - // TODO finish the test when the logic is fixed + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(1, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(2, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(3, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1000)); + ASSERT_TRUE(retr.isRetrievingInProgress()); + + tid.increment(); + publishNodeStatus(nodes.can_a, uavcan::NodeID(10), 0, 12, tid); + publishNodeStatus(nodes.can_a, uavcan::NodeID(11), 0, 12, tid); + publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 10, tid); // Reset + + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(1, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(2, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(3, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1000)); + ASSERT_TRUE(retr.isRetrievingInProgress()); + + EXPECT_EQ(11, listener.status_message_cnt); + EXPECT_EQ(5, listener.status_change_cnt); // node 2 online/offline + 3 test nodes above + EXPECT_EQ(2, listener.info_unavailable_cnt); + + tid.increment(); + publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 11, tid); + + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(1, retr.getNumPendingRequests()); + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(110)); + ASSERT_EQ(1, retr.getNumPendingRequests()); // Still one because two went offline + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1200)); + ASSERT_TRUE(retr.isRetrievingInProgress()); + + tid.increment(); + publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 12, tid); + + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(1200)); + ASSERT_FALSE(retr.isRetrievingInProgress()); // Out of attempts, stopping + ASSERT_EQ(0, retr.getNumPendingRequests()); + + EXPECT_EQ(13, listener.status_message_cnt); + EXPECT_EQ(7, listener.status_change_cnt); // node 2 online/offline + 2 test nodes above online/offline + 1 + EXPECT_EQ(3, listener.info_unavailable_cnt); }