diff --git a/libuavcan/src/protocol/uc_dynamic_node_id_allocation_server.cpp b/libuavcan/src/protocol/uc_dynamic_node_id_allocation_server.cpp index 4638ac75fb..98b0ef0106 100644 --- a/libuavcan/src/protocol/uc_dynamic_node_id_allocation_server.cpp +++ b/libuavcan/src/protocol/uc_dynamic_node_id_allocation_server.cpp @@ -952,8 +952,6 @@ void RaftCore::updateCandidate() trace(TraceError, res); } } - - UAVCAN_ASSERT(res >= 0); } } @@ -1374,7 +1372,7 @@ void RaftCore::handleRequestVoteResponse(const ServiceCallResult& r void RaftCore::handleTimerEvent(const TimerEvent&) { - if (cluster_.hadDiscoveryActivity()) + if (cluster_.hadDiscoveryActivity() && isLeader()) { setActiveMode(true); } @@ -1448,6 +1446,7 @@ int RaftCore::init(uint8_t cluster_size) { return res; } + append_entries_client_.setCallback(AppendEntriesResponseCallback(this, &RaftCore::handleAppendEntriesResponse)); append_entries_client_.setRequestTimeout(update_interval_); for (uint8_t i = 0; i < NumRequestVoteClients; i++) @@ -1457,6 +1456,7 @@ int RaftCore::init(uint8_t cluster_size) { return res; } + request_vote_clients_[i]->setCallback(RequestVoteResponseCallback(this, &RaftCore::handleRequestVoteResponse)); request_vote_clients_[i]->setRequestTimeout(update_interval_); } diff --git a/libuavcan/test/protocol/dynamic_node_id_allocation_server.cpp b/libuavcan/test/protocol/dynamic_node_id_allocation_server.cpp index e852f488d6..55a74f93f4 100644 --- a/libuavcan/test/protocol/dynamic_node_id_allocation_server.cpp +++ b/libuavcan/test/protocol/dynamic_node_id_allocation_server.cpp @@ -55,10 +55,31 @@ public: class EventTracer : public uavcan::IDynamicNodeIDAllocationServerEventTracer { + const std::string id_; + virtual void onEvent(uavcan::uint16_t event_code, uavcan::int64_t event_argument) { - std::cout << "Event\t" << event_code << "\t" << event_argument << std::endl; + std::cout << "EVENT [" << id_ << "]\t" << event_code << "\t" << event_argument << std::endl; } + +public: + EventTracer() { } + + EventTracer(const std::string& id) : id_(id) { } +}; + + +class CommitHandler : public uavcan::dynamic_node_id_server_impl::ILeaderLogCommitHandler +{ + const std::string id_; + + virtual void onEntryCommitted(const uavcan::protocol::dynamic_node_id::server::Entry& entry) + { + std::cout << "ENTRY COMMITTED [" << id_ << "]\n" << entry << std::endl; + } + +public: + CommitHandler(const std::string& id) : id_(id) { } }; @@ -817,6 +838,42 @@ TEST(DynamicNodeIDAllocationServer, ClusterManagerThreeServers) } +TEST(DynamicNodeIDAllocationServer, RaftCoreBasic) +{ + uavcan::GlobalDataTypeRegistry::instance().reset(); + uavcan::DefaultDataTypeRegistrator _reg1; + uavcan::DefaultDataTypeRegistrator _reg2; + uavcan::DefaultDataTypeRegistrator _reg3; + + EventTracer tracer_a("a"); + EventTracer tracer_b("b"); + StorageBackend storage_a; + StorageBackend storage_b; + CommitHandler commit_handler_a("a"); + CommitHandler commit_handler_b("b"); + + InterlinkedTestNodesWithSysClock nodes; + + uavcan::dynamic_node_id_server_impl::RaftCore raft_a(nodes.a, storage_a, tracer_a, commit_handler_a); + uavcan::dynamic_node_id_server_impl::RaftCore raft_b(nodes.b, storage_b, tracer_b, commit_handler_b); + + /* + * Initialization + */ + ASSERT_LE(0, raft_a.init(2)); + ASSERT_LE(0, raft_b.init(2)); + + /* + * Running and trying not to fall + */ + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(5000)); + + // The one with lower node ID must become a leader + ASSERT_TRUE(raft_a.isLeader()); + ASSERT_FALSE(raft_b.isLeader()); +} + + TEST(DynamicNodeIDAllocationServer, ObjectSizes) { std::cout << "Log: " << sizeof(uavcan::dynamic_node_id_server_impl::Log) << std::endl;