node_status_monitor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <gtest/gtest.h>
8 #include "helpers.hpp"
9 
11  uavcan::uint8_t health, uavcan::uint8_t mode,
12  uavcan::uint32_t uptime_sec, uavcan::TransferID tid)
13 {
14  uavcan::protocol::NodeStatus msg;
15  msg.health = health;
16  msg.mode = mode;
17  msg.uptime_sec = uptime_sec;
18  emulateSingleFrameBroadcastTransfer(can, node_id, msg, tid);
19 }
20 
21 
22 static void shortSpin(TestNode& node)
23 {
24  ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(10)));
25 }
26 
27 
28 TEST(NodeStatusMonitor, Basic)
29 {
30  using uavcan::protocol::NodeStatus;
31  using uavcan::NodeID;
32 
33  SystemClockMock clock_mock(100);
34  clock_mock.monotonic_auto_advance = 1000;
35 
36  CanDriverMock can(2, clock_mock);
37 
38  TestNode node(can, clock_mock, 64);
39 
42 
44  ASSERT_LE(0, nsm.start());
45 
46  ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(10)));
47 
48  /*
49  * Empty NSM, no nodes were registered yet
50  */
51  ASSERT_FALSE(nsm.findNodeWithWorstHealth().isValid());
52 
53  ASSERT_FALSE(nsm.isNodeKnown(uavcan::NodeID(123)));
54  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(123)).mode);
55 
56  /*
57  * Some new status messages
58  */
59  publishNodeStatus(can, 10, NodeStatus::HEALTH_OK, NodeStatus::MODE_OPERATIONAL, 12, 0);
60  shortSpin(node);
61  ASSERT_EQ(NodeID(10), nsm.findNodeWithWorstHealth());
62 
63  publishNodeStatus(can, 9, NodeStatus::HEALTH_WARNING, NodeStatus::MODE_INITIALIZATION, 0, 0);
64  shortSpin(node);
65  ASSERT_EQ(NodeID(9), nsm.findNodeWithWorstHealth());
66 
67  publishNodeStatus(can, 11, NodeStatus::HEALTH_CRITICAL, NodeStatus::MODE_MAINTENANCE, 999, 0);
68  shortSpin(node);
69  ASSERT_EQ(NodeID(11), nsm.findNodeWithWorstHealth());
70 
71  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(10)));
72  ASSERT_EQ(NodeStatus::MODE_OPERATIONAL, nsm.getNodeStatus(uavcan::NodeID(10)).mode);
73  ASSERT_EQ(NodeStatus::HEALTH_OK, nsm.getNodeStatus(uavcan::NodeID(10)).health);
74 
75  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(9)));
76  ASSERT_EQ(NodeStatus::MODE_INITIALIZATION, nsm.getNodeStatus(uavcan::NodeID(9)).mode);
77  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(9)).health);
78 
79  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(11)));
80  ASSERT_EQ(NodeStatus::MODE_MAINTENANCE, nsm.getNodeStatus(uavcan::NodeID(11)).mode);
81  ASSERT_EQ(NodeStatus::HEALTH_CRITICAL, nsm.getNodeStatus(uavcan::NodeID(11)).health);
82 
83  /*
84  * Timeout
85  */
86  std::cout << "Starting timeout test, current monotime is " << clock_mock.monotonic << std::endl;
87 
88  clock_mock.advance(500000);
89  shortSpin(node);
90  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(10)));
91  ASSERT_EQ(NodeStatus::MODE_OPERATIONAL, nsm.getNodeStatus(uavcan::NodeID(10)).mode);
92  ASSERT_EQ(NodeStatus::HEALTH_OK, nsm.getNodeStatus(uavcan::NodeID(10)).health);
93 
94  clock_mock.advance(500000);
95  shortSpin(node);
96  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(9)));
97  ASSERT_EQ(NodeStatus::MODE_INITIALIZATION, nsm.getNodeStatus(uavcan::NodeID(9)).mode);
98  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(9)).health);
99 
100  clock_mock.advance(500000);
101  shortSpin(node);
102  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(11)));
103  ASSERT_EQ(NodeStatus::MODE_MAINTENANCE, nsm.getNodeStatus(uavcan::NodeID(11)).mode);
104  ASSERT_EQ(NodeStatus::HEALTH_CRITICAL, nsm.getNodeStatus(uavcan::NodeID(11)).health);
105 
106  /*
107  * Will timeout now
108  */
109  clock_mock.advance(4000000);
110  shortSpin(node);
111 
112  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(10)));
113  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(10)).mode);
114  ASSERT_EQ(NodeStatus::HEALTH_OK, nsm.getNodeStatus(uavcan::NodeID(10)).health);
115 
116  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(9)));
117  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(9)).mode);
118  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(9)).health);
119 
120  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(11)));
121  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(11)).mode);
122  ASSERT_EQ(NodeStatus::HEALTH_CRITICAL, nsm.getNodeStatus(uavcan::NodeID(11)).health);
123 
124  /*
125  * Recovering one node, adding two extra
126  */
127  publishNodeStatus(can, 11, NodeStatus::HEALTH_WARNING, NodeStatus::MODE_OPERATIONAL, 999, 1);
128  shortSpin(node);
129 
130  publishNodeStatus(can, 127, NodeStatus::HEALTH_WARNING, NodeStatus::MODE_OPERATIONAL, 9999, 1);
131  shortSpin(node);
132 
133  publishNodeStatus(can, 1, NodeStatus::HEALTH_OK, NodeStatus::MODE_OPERATIONAL, 1234, 1);
134  shortSpin(node);
135 
136  /*
137  * Making sure OFFLINE is still worst status
138  */
139  ASSERT_EQ(NodeID(9), nsm.findNodeWithWorstHealth());
140 
141  /*
142  * Final validation
143  */
144  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(10)));
145  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(10)).mode);
146  ASSERT_EQ(NodeStatus::HEALTH_OK, nsm.getNodeStatus(uavcan::NodeID(10)).health);
147 
148  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(9)));
149  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(9)).mode);
150  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(9)).health);
151 
152  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(11)));
153  ASSERT_EQ(NodeStatus::MODE_OPERATIONAL, nsm.getNodeStatus(uavcan::NodeID(11)).mode);
154  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(11)).health);
155 
156  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(127)));
157  ASSERT_EQ(NodeStatus::MODE_OPERATIONAL, nsm.getNodeStatus(uavcan::NodeID(127)).mode);
158  ASSERT_EQ(NodeStatus::HEALTH_WARNING, nsm.getNodeStatus(uavcan::NodeID(127)).health);
159 
160  ASSERT_TRUE(nsm.isNodeKnown(uavcan::NodeID(1)));
161  ASSERT_EQ(NodeStatus::MODE_OPERATIONAL, nsm.getNodeStatus(uavcan::NodeID(1)).mode);
162  ASSERT_EQ(NodeStatus::HEALTH_OK, nsm.getNodeStatus(uavcan::NodeID(1)).health);
163 
164  /*
165  * Forgetting
166  */
167  nsm.forgetNode(127);
168  ASSERT_FALSE(nsm.isNodeKnown(uavcan::NodeID(127)));
169  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(127)).mode);
170  ASSERT_EQ(NodeStatus::HEALTH_CRITICAL, nsm.getNodeStatus(uavcan::NodeID(127)).health);
171 
172  nsm.forgetNode(9);
173  ASSERT_FALSE(nsm.isNodeKnown(uavcan::NodeID(9)));
174  ASSERT_EQ(NodeStatus::MODE_OFFLINE, nsm.getNodeStatus(uavcan::NodeID(9)).mode);
175  ASSERT_EQ(NodeStatus::HEALTH_CRITICAL, nsm.getNodeStatus(uavcan::NodeID(9)).health);
176 }
emulateSingleFrameBroadcastTransfer
static void emulateSingleFrameBroadcastTransfer(CanDriver &can, uavcan::NodeID node_id, const MessageType &message, uavcan::TransferID tid)
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:135
publishNodeStatus
static void publishNodeStatus(CanDriverMock &can, uavcan::NodeID node_id, uavcan::uint8_t health, uavcan::uint8_t mode, uavcan::uint32_t uptime_sec, uavcan::TransferID tid)
Definition: node_status_monitor.cpp:10
uavcan::NodeID::isValid
bool isValid() const
Definition: transfer.hpp:134
uavcan::DefaultDataTypeRegistrator
Definition: global_data_type_registry.hpp:186
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
SystemClockMock::advance
void advance(uint64_t usec) const
Definition: libuavcan/libuavcan/test/clock.hpp:28
uavcan::NodeID
Definition: transfer.hpp:112
uavcan::DurationBase< MonotonicDuration >::fromMSec
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
TEST
TEST(NodeStatusMonitor, Basic)
Definition: node_status_monitor.cpp:28
SystemClockMock::monotonic
uint64_t monotonic
Definition: libuavcan/libuavcan/test/clock.hpp:15
uavcan::NodeStatusMonitor
Definition: node_status_monitor.hpp:22
uavcan::NodeStatusMonitor::NodeStatus::mode
uint8_t mode
Definition: node_status_monitor.hpp:28
TestNode
Definition: test_node.hpp:20
uavcan::TransferID
Definition: transfer.hpp:71
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
node_status_monitor.hpp
helpers.hpp
uavcan::NodeStatusMonitor::isNodeKnown
bool isNodeKnown(NodeID node_id) const
Definition: node_status_monitor.hpp:262
uavcan::NodeStatusMonitor::findNodeWithWorstHealth
NodeID findNodeWithWorstHealth() const
Definition: node_status_monitor.hpp:277
uavcan::NodeStatusMonitor::forgetNode
void forgetNode(NodeID node_id)
Definition: node_status_monitor.hpp:210
uavcan::NodeStatusMonitor::getNodeStatus
NodeStatus getNodeStatus(NodeID node_id) const
Definition: node_status_monitor.hpp:239
CanDriverMock
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:190
shortSpin
static void shortSpin(TestNode &node)
Definition: node_status_monitor.cpp:22
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
SystemClockMock
Definition: libuavcan/libuavcan/test/clock.hpp:12
uavcan::GlobalDataTypeRegistry::instance
static GlobalDataTypeRegistry & instance()
Definition: uc_global_data_type_registry.cpp:128
SystemClockMock::monotonic_auto_advance
uint64_t monotonic_auto_advance
Definition: libuavcan/libuavcan/test/clock.hpp:18
uavcan::NodeStatusMonitor::NodeStatus::health
uint8_t health
Definition: node_status_monitor.hpp:27
node_status_provider.hpp
uavcan::NodeStatusMonitor::start
int start()
Definition: node_status_monitor.hpp:196


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02