Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UAVCAN UAVCAN_Subscriber
server.cpp
00001 /* 00002 * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #if __GNUC__ 00006 // We need auto_ptr for compatibility reasons 00007 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00008 # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 00009 #endif 00010 00011 #include <gtest/gtest.h> 00012 #include <memory> 00013 #include <uavcan/protocol/dynamic_node_id_server/distributed.hpp> 00014 #include <uavcan/protocol/dynamic_node_id_client.hpp> 00015 #include "../event_tracer.hpp" 00016 #include "../../helpers.hpp" 00017 #include "../memory_storage_backend.hpp" 00018 00019 using uavcan::dynamic_node_id_server::UniqueID; 00020 00021 00022 class CommitHandler : public uavcan::dynamic_node_id_server::distributed::IRaftLeaderMonitor 00023 { 00024 const std::string id_; 00025 00026 virtual void handleLogCommitOnLeader(const uavcan::protocol::dynamic_node_id::server::Entry& entry) 00027 { 00028 std::cout << "ENTRY COMMITTED [" << id_ << "]\n" << entry << std::endl; 00029 } 00030 00031 virtual void handleLocalLeadershipChange(bool local_node_is_leader) 00032 { 00033 std::cout << "I AM LEADER [" << id_ << "]: " << (local_node_is_leader ? "YES" : "NOT ANYMORE") << std::endl; 00034 } 00035 00036 public: 00037 CommitHandler(const std::string& id) : id_(id) { } 00038 }; 00039 00040 00041 TEST(dynamic_node_id_server_RaftCore, Basic) 00042 { 00043 using namespace uavcan::dynamic_node_id_server::distributed; 00044 using namespace uavcan::protocol::dynamic_node_id::server; 00045 00046 uavcan::GlobalDataTypeRegistry::instance().reset(); 00047 uavcan::DefaultDataTypeRegistrator<Discovery> _reg1; 00048 uavcan::DefaultDataTypeRegistrator<AppendEntries> _reg2; 00049 uavcan::DefaultDataTypeRegistrator<RequestVote> _reg3; 00050 00051 EventTracer tracer_a("a"); 00052 EventTracer tracer_b("b"); 00053 MemoryStorageBackend storage_a; 00054 MemoryStorageBackend storage_b; 00055 CommitHandler commit_handler_a("a"); 00056 CommitHandler commit_handler_b("b"); 00057 00058 InterlinkedTestNodesWithSysClock nodes; 00059 00060 std::auto_ptr<RaftCore> raft_a(new RaftCore(nodes.a, storage_a, tracer_a, commit_handler_a)); 00061 std::auto_ptr<RaftCore> raft_b(new RaftCore(nodes.b, storage_b, tracer_b, commit_handler_b)); 00062 00063 /* 00064 * Initialization 00065 */ 00066 ASSERT_LE(0, raft_a->init(2, uavcan::TransferPriority::OneHigherThanLowest)); 00067 ASSERT_LE(0, raft_b->init(2, uavcan::TransferPriority::OneHigherThanLowest)); 00068 00069 /* 00070 * Running and trying not to fall 00071 */ 00072 nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(9000)); 00073 00074 // Either must become a leader 00075 ASSERT_TRUE(raft_a->isLeader() || raft_b->isLeader()); 00076 00077 ASSERT_EQ(0, raft_a->getCommitIndex()); 00078 ASSERT_EQ(0, raft_b->getCommitIndex()); 00079 00080 /* 00081 * Adding some stuff 00082 */ 00083 Entry::FieldTypes::unique_id unique_id; 00084 uavcan::fill_n(unique_id.begin(), 16, uint8_t(0xAA)); 00085 00086 (raft_a->isLeader() ? raft_a : raft_b)->appendLog(unique_id, uavcan::NodeID(1)); 00087 00088 nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(6000)); 00089 00090 ASSERT_EQ(1, raft_a->getCommitIndex()); 00091 ASSERT_EQ(1, raft_b->getCommitIndex()); 00092 00093 /* 00094 * Terminating the leader 00095 */ 00096 raft_a.reset(); 00097 00098 nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(6000)); 00099 00100 /* 00101 * Reinitializing the leader - current Follower will become the new Leader 00102 */ 00103 storage_a.reset(); 00104 00105 raft_a.reset(new RaftCore(nodes.a, storage_a, tracer_a, commit_handler_a)); 00106 ASSERT_LE(0, raft_a->init(2, uavcan::TransferPriority::OneHigherThanLowest)); 00107 ASSERT_EQ(0, raft_a->getCommitIndex()); 00108 00109 nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(9000)); 00110 00111 ASSERT_FALSE(raft_a->isLeader()); 00112 ASSERT_TRUE(raft_b->isLeader()); 00113 00114 ASSERT_EQ(1, raft_a->getCommitIndex()); 00115 ASSERT_EQ(1, raft_b->getCommitIndex()); 00116 } 00117 00118 00119 TEST(dynamic_node_id_server_Server, Basic) 00120 { 00121 using namespace uavcan::dynamic_node_id_server; 00122 using namespace uavcan::protocol::dynamic_node_id; 00123 using namespace uavcan::protocol::dynamic_node_id::server; 00124 00125 uavcan::GlobalDataTypeRegistry::instance().reset(); 00126 uavcan::DefaultDataTypeRegistrator<Discovery> _reg1; 00127 uavcan::DefaultDataTypeRegistrator<AppendEntries> _reg2; 00128 uavcan::DefaultDataTypeRegistrator<RequestVote> _reg3; 00129 uavcan::DefaultDataTypeRegistrator<Allocation> _reg4; 00130 uavcan::DefaultDataTypeRegistrator<uavcan::protocol::GetNodeInfo> _reg5; 00131 uavcan::DefaultDataTypeRegistrator<uavcan::protocol::NodeStatus> _reg6; 00132 00133 EventTracer tracer; 00134 MemoryStorageBackend storage; 00135 00136 // Node A is Allocator, Node B is Allocatee 00137 InterlinkedTestNodesWithSysClock nodes(uavcan::NodeID(10), uavcan::NodeID::Broadcast); 00138 00139 UniqueID own_unique_id; 00140 own_unique_id[0] = 0xAA; 00141 own_unique_id[3] = 0xCC; 00142 own_unique_id[7] = 0xEE; 00143 own_unique_id[9] = 0xBB; 00144 00145 /* 00146 * Server 00147 */ 00148 DistributedServer server(nodes.a, storage, tracer); 00149 00150 ASSERT_LE(0, server.init(own_unique_id, 1)); 00151 00152 ASSERT_EQ(0, server.getNumAllocations()); 00153 00154 /* 00155 * Client 00156 */ 00157 uavcan::DynamicNodeIDClient client(nodes.b); 00158 uavcan::protocol::HardwareVersion::FieldTypes::unique_id unique_id; 00159 for (uavcan::uint8_t i = 0; i < unique_id.size(); i++) 00160 { 00161 unique_id[i] = i; 00162 } 00163 const uavcan::NodeID PreferredNodeID = 42; 00164 ASSERT_LE(0, client.start(unique_id, PreferredNodeID)); 00165 00166 /* 00167 * Fire 00168 */ 00169 nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(15000)); 00170 00171 ASSERT_TRUE(client.isAllocationComplete()); 00172 ASSERT_EQ(PreferredNodeID, client.getAllocatedNodeID()); 00173 00174 ASSERT_EQ(2, server.getNumAllocations()); // Server's own node ID + client 00175 } 00176 00177 00178 TEST(dynamic_node_id_server, ObjectSizes) 00179 { 00180 using namespace uavcan; 00181 using namespace uavcan::protocol::dynamic_node_id::server; 00182 using namespace uavcan::dynamic_node_id_server; 00183 00184 std::cout << "distributed::Log: " << sizeof(distributed::Log) << std::endl; 00185 std::cout << "distributed::PersistentState: " << sizeof(distributed::PersistentState) << std::endl; 00186 std::cout << "distributed::ClusterManager: " << sizeof(distributed::ClusterManager) << std::endl; 00187 std::cout << "distributed::RaftCore: " << sizeof(distributed::RaftCore) << std::endl; 00188 std::cout << "distributed::Server: " << sizeof(distributed::Server) << std::endl; 00189 std::cout << "AllocationRequestManager: " << sizeof(AllocationRequestManager) << std::endl; 00190 00191 std::cout << "ServiceServer<AppendEntries>: " << sizeof(ServiceServer<AppendEntries>) << std::endl; 00192 std::cout << "ServiceClient<AppendEntries>: " << sizeof(ServiceClient<AppendEntries>) << std::endl; 00193 std::cout << "ServiceServer<RequestVote>: " << sizeof(ServiceServer<RequestVote>) << std::endl; 00194 std::cout << "ServiceClient<RequestVote>: " << sizeof(ServiceClient<RequestVote>) << std::endl; 00195 }
Generated on Tue Jul 12 2022 17:17:34 by
