cluster_manager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <gtest/gtest.h>
7 #include "../event_tracer.hpp"
8 #include "../../helpers.hpp"
9 #include "../memory_storage_backend.hpp"
10 
11 TEST(dynamic_node_id_server_ClusterManager, Initialization)
12 {
14 
15  const unsigned MaxClusterSize =
16  uavcan::protocol::dynamic_node_id::server::Discovery::FieldTypes::known_nodes::MaxSize;
17 
20 
21  EventTracer tracer;
22 
23  /*
24  * Simple initialization
25  */
26  {
27  MemoryStorageBackend storage;
28  Log log(storage, tracer);
30 
31  ClusterManager mgr(nodes.a, storage, log, tracer);
32 
33  // Too big
34  ASSERT_GT(0, mgr.init(MaxClusterSize + 1, uavcan::TransferPriority::OneHigherThanLowest));
35  ASSERT_EQ(0, storage.getNumKeys());
36 
37  // OK
39  ASSERT_EQ(1, storage.getNumKeys());
40  ASSERT_EQ("5", storage.get("cluster_size"));
41 
42  // Testing other states
43  ASSERT_EQ(0, mgr.getNumKnownServers());
44  ASSERT_EQ(5, mgr.getClusterSize());
45  ASSERT_EQ(3, mgr.getQuorumSize());
46  ASSERT_FALSE(mgr.getRemoteServerNodeIDAtIndex(0).isValid());
47  }
48  /*
49  * Recovery from the storage
50  */
51  {
52  MemoryStorageBackend storage;
53  Log log(storage, tracer);
55 
56  ClusterManager mgr(nodes.a, storage, log, tracer);
57 
58  // Not configured
60  ASSERT_EQ(0, storage.getNumKeys());
61 
62  // OK
63  storage.set("cluster_size", "5");
65  ASSERT_EQ(1, storage.getNumKeys());
66  }
67 }
68 
69 
70 TEST(dynamic_node_id_server_ClusterManager, OneServer)
71 {
73 
76 
77  EventTracer tracer;
78  MemoryStorageBackend storage;
79  Log log(storage, tracer);
81 
82  ClusterManager mgr(nodes.a, storage, log, tracer);
83 
84  /*
85  * Pub and sub
86  */
89 
90  ASSERT_LE(0, sub.start());
91  ASSERT_LE(0, pub.init());
92 
93  /*
94  * Starting
95  */
97 
98  ASSERT_EQ(0, mgr.getNumKnownServers());
99  ASSERT_TRUE(mgr.isClusterDiscovered());
100 
101  ASSERT_EQ(0, nodes.a.internal_failure_count);
102 
103  /*
104  * Broadcasting discovery with wrong cluster size, it will be reported as internal failure
105  */
106  uavcan::protocol::dynamic_node_id::server::Discovery msg;
107  msg.configured_cluster_size = 2;
108  msg.known_nodes.push_back(2U);
109  ASSERT_LE(0, pub.broadcast(msg));
110 
112 
113  ASSERT_EQ(1, nodes.a.internal_failure_count);
114 
115  /*
116  * Discovery rate limiting test
117  */
118  ASSERT_FALSE(sub.collector.msg.get());
119 
120  msg = uavcan::protocol::dynamic_node_id::server::Discovery();
121  msg.configured_cluster_size = 1; // Correct value
122  ASSERT_LE(0, pub.broadcast(msg)); // List of known nodes is empty, intentionally
123 
125  ASSERT_FALSE(sub.collector.msg.get());
127  ASSERT_TRUE(sub.collector.msg.get());
128  ASSERT_EQ(1, sub.collector.msg->configured_cluster_size);
129  ASSERT_EQ(1, sub.collector.msg->known_nodes.size());
130  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
131  sub.collector.msg.reset();
132 
133  // Rinse repeat
134  ASSERT_LE(0, pub.broadcast(msg));
135 
137  ASSERT_FALSE(sub.collector.msg.get());
139  ASSERT_TRUE(sub.collector.msg.get());
140  ASSERT_EQ(1, sub.collector.msg->configured_cluster_size);
141  ASSERT_EQ(1, sub.collector.msg->known_nodes.size());
142  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
143  sub.collector.msg.reset();
144 }
145 
146 
147 TEST(dynamic_node_id_server_ClusterManager, ThreeServers)
148 {
150 
153 
154  EventTracer tracer;
155  MemoryStorageBackend storage;
156  Log log(storage, tracer);
158 
159  ClusterManager mgr(nodes.a, storage, log, tracer);
160 
161  /*
162  * Pub and sub
163  */
166 
167  ASSERT_LE(0, sub.start());
168  ASSERT_LE(0, pub.init());
169 
170  /*
171  * Starting
172  */
174 
175  ASSERT_EQ(0, mgr.getNumKnownServers());
176  ASSERT_FALSE(mgr.isClusterDiscovered());
177 
178  /*
179  * Discovery publishing rate check
180  */
182  ASSERT_FALSE(sub.collector.msg.get());
184  ASSERT_TRUE(sub.collector.msg.get());
185  ASSERT_EQ(3, sub.collector.msg->configured_cluster_size);
186  ASSERT_EQ(1, sub.collector.msg->known_nodes.size());
187  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
188  sub.collector.msg.reset();
189 
191  ASSERT_FALSE(sub.collector.msg.get());
193  ASSERT_TRUE(sub.collector.msg.get());
194  ASSERT_EQ(3, sub.collector.msg->configured_cluster_size);
195  ASSERT_EQ(1, sub.collector.msg->known_nodes.size());
196  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
197  sub.collector.msg.reset();
198 
199  /*
200  * Discovering other nodes
201  */
202  uavcan::protocol::dynamic_node_id::server::Discovery msg;
203  msg.configured_cluster_size = 3;
204  msg.known_nodes.push_back(2U);
205  ASSERT_LE(0, pub.broadcast(msg));
206 
208  ASSERT_TRUE(sub.collector.msg.get());
209  ASSERT_EQ(3, sub.collector.msg->configured_cluster_size);
210  ASSERT_EQ(2, sub.collector.msg->known_nodes.size());
211  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
212  ASSERT_EQ(2, sub.collector.msg->known_nodes[1]);
213  sub.collector.msg.reset();
214 
215  ASSERT_FALSE(mgr.isClusterDiscovered());
216 
217  // This will complete the discovery
218  msg.known_nodes.push_back(127U);
219  ASSERT_LE(0, pub.broadcast(msg));
220 
222  ASSERT_TRUE(sub.collector.msg.get());
223  ASSERT_EQ(3, sub.collector.msg->configured_cluster_size);
224  ASSERT_EQ(3, sub.collector.msg->known_nodes.size());
225  ASSERT_EQ(1, sub.collector.msg->known_nodes[0]);
226  ASSERT_EQ(2, sub.collector.msg->known_nodes[1]);
227  ASSERT_EQ(127, sub.collector.msg->known_nodes[2]);
228  sub.collector.msg.reset();
229 
230  // Making sure discovery is now terminated
232  ASSERT_FALSE(sub.collector.msg.get());
233 
234  /*
235  * Checking Raft states
236  */
237  ASSERT_EQ(uavcan::NodeID(2), mgr.getRemoteServerNodeIDAtIndex(0));
238  ASSERT_EQ(uavcan::NodeID(127), mgr.getRemoteServerNodeIDAtIndex(1));
239  ASSERT_EQ(uavcan::NodeID(), mgr.getRemoteServerNodeIDAtIndex(2));
240 
241  ASSERT_EQ(0, mgr.getServerMatchIndex(2));
242  ASSERT_EQ(0, mgr.getServerMatchIndex(127));
243 
244  ASSERT_EQ(log.getLastIndex() + 1, mgr.getServerNextIndex(2));
245  ASSERT_EQ(log.getLastIndex() + 1, mgr.getServerNextIndex(127));
246 
247  mgr.setServerMatchIndex(2, 10);
248  ASSERT_EQ(10, mgr.getServerMatchIndex(2));
249 
250  mgr.incrementServerNextIndexBy(2, 5);
251  ASSERT_EQ(log.getLastIndex() + 1 + 5, mgr.getServerNextIndex(2));
253  ASSERT_EQ(log.getLastIndex() + 1 + 5 - 1, mgr.getServerNextIndex(2));
254 
255  mgr.resetAllServerIndices();
256 
257  ASSERT_EQ(0, mgr.getServerMatchIndex(2));
258  ASSERT_EQ(0, mgr.getServerMatchIndex(127));
259 
260  ASSERT_EQ(log.getLastIndex() + 1, mgr.getServerNextIndex(2));
261  ASSERT_EQ(log.getLastIndex() + 1, mgr.getServerNextIndex(127));
262 }
uavcan::dynamic_node_id_server::distributed::ClusterManager::getClusterSize
uint8_t getClusterSize() const
Definition: cluster_manager.hpp:423
uavcan::dynamic_node_id_server::distributed::ClusterManager::isClusterDiscovered
bool isClusterDiscovered() const
Definition: cluster_manager.hpp:426
TestNode::internal_failure_count
uint64_t internal_failure_count
Definition: test_node.hpp:30
uavcan::NodeID::isValid
bool isValid() const
Definition: transfer.hpp:134
uavcan::DefaultDataTypeRegistrator
Definition: global_data_type_registry.hpp:186
uavcan::Publisher
Definition: publisher.hpp:18
uavcan::dynamic_node_id_server::distributed::ClusterManager::decrementServerNextIndex
void decrementServerNextIndex(NodeID server_node_id)
Definition: cluster_manager.hpp:362
SubscriberWithCollector
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:33
uavcan::dynamic_node_id_server::distributed::ClusterManager::getRemoteServerNodeIDAtIndex
NodeID getRemoteServerNodeIDAtIndex(uint8_t index) const
Definition: cluster_manager.hpp:326
uavcan::NodeID
Definition: transfer.hpp:112
uavcan::DurationBase< MonotonicDuration >::fromMSec
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
uavcan::dynamic_node_id_server::distributed::ClusterManager::getServerNextIndex
Log::Index getServerNextIndex(NodeID server_node_id) const
Definition: cluster_manager.hpp:338
SubscriberWithCollector::start
int start()
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:45
uavcan::dynamic_node_id_server::distributed::ClusterManager::incrementServerNextIndexBy
void incrementServerNextIndexBy(NodeID server_node_id, Log::Index increment)
Definition: cluster_manager.hpp:349
uavcan::dynamic_node_id_server::distributed::ClusterManager::getServerMatchIndex
Log::Index getServerMatchIndex(NodeID server_node_id) const
Definition: cluster_manager.hpp:378
cluster_manager.hpp
uavcan::TransferPriority::OneHigherThanLowest
static const TransferPriority OneHigherThanLowest
Definition: transfer.hpp:40
MemoryStorageBackend::set
virtual void set(const String &key, const String &value)
Definition: memory_storage_backend.hpp:32
uavcan::dynamic_node_id_server::distributed::ClusterManager::resetAllServerIndices
void resetAllServerIndices()
Definition: cluster_manager.hpp:405
InterlinkedTestNodes
Definition: test_node.hpp:149
SubscriberWithCollector::collector
Collector collector
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:38
uavcan::GenericPublisher< DataType_, DataType_ >::init
int init()
Definition: generic_publisher.hpp:118
MemoryStorageBackend::get
virtual String get(const String &key) const
Definition: memory_storage_backend.hpp:22
InterlinkedTestNodes::a
TestNode a
Definition: test_node.hpp:155
SubscriptionCollector::msg
std::unique_ptr< DataType > msg
Definition: libuavcan/libuavcan/test/protocol/helpers.hpp:23
InterlinkedTestNodes::spinBoth
int spinBoth(uavcan::MonotonicDuration duration)
Definition: test_node.hpp:176
uavcan::dynamic_node_id_server::distributed
Definition: cluster_manager.hpp:25
uavcan::dynamic_node_id_server::distributed::ClusterManager::init
int init(const uint8_t init_cluster_size, const TransferPriority priority)
Definition: cluster_manager.hpp:210
uavcan::dynamic_node_id_server::distributed::ClusterManager::setServerMatchIndex
void setServerMatchIndex(NodeID server_node_id, Log::Index match_index)
Definition: cluster_manager.hpp:389
MemoryStorageBackend
Definition: memory_storage_backend.hpp:10
uavcan::Publisher::broadcast
int broadcast(const DataType &message)
Definition: publisher.hpp:52
uavcan::dynamic_node_id_server::distributed::ClusterManager::getQuorumSize
uint8_t getQuorumSize() const
Definition: cluster_manager.hpp:424
uavcan::dynamic_node_id_server::distributed::Log
Definition: log.hpp:25
uavcan::dynamic_node_id_server::distributed::ClusterManager::getNumKnownServers
uint8_t getNumKnownServers() const
Definition: cluster_manager.hpp:418
uavcan::GlobalDataTypeRegistry::instance
static GlobalDataTypeRegistry & instance()
Definition: uc_global_data_type_registry.cpp:128
TEST
TEST(dynamic_node_id_server_ClusterManager, Initialization)
Definition: cluster_manager.cpp:11
MemoryStorageBackend::getNumKeys
unsigned getNumKeys() const
Definition: memory_storage_backend.hpp:44
InterlinkedTestNodes::b
TestNode b
Definition: test_node.hpp:156
uavcan::dynamic_node_id_server::distributed::ClusterManager
Definition: cluster_manager.hpp:30
uavcan::dynamic_node_id_server::distributed::Log::getLastIndex
Index getLastIndex() const
Definition: log.hpp:291


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