INode class. Publisher, Subscriber, ServiceServer, ServiceClient now accept INode in constructor instead of the bunch of independent params. Self NodeID now being configured via setNodeID() method instead of constructor param

This commit is contained in:
Pavel Kirienko
2014-03-14 19:54:27 +04:00
parent 15cbf96378
commit 613efa49b9
22 changed files with 211 additions and 181 deletions
+6 -14
View File
@@ -7,24 +7,16 @@
#include <uavcan/mavlink/Message.hpp>
#include "../clock.hpp"
#include "../transport/can/can.hpp"
#include "test_node.hpp"
TEST(Publisher, Basic)
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
poolmgr.addPool(&pool);
SystemClockMock clock_mock(100);
CanDriverMock can_driver(2, clock_mock);
TestNode node(can_driver, clock_mock, 1);
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_mock, out_trans_reg, uavcan::NodeID(1));
uavcan::MarshalBufferProvider<> buffer_provider;
uavcan::Publisher<uavcan::mavlink::Message> publisher(sch, buffer_provider);
uavcan::Publisher<uavcan::mavlink::Message> publisher(node);
std::cout <<
"sizeof(uavcan::Publisher<uavcan::mavlink::Message>): " <<
@@ -61,7 +53,7 @@ TEST(Publisher, Basic)
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false
uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 0, true);
node.getNodeID(), uavcan::NodeID::Broadcast, 0, 0, true);
expected_frame.setPayload(expected_transfer_payload, 7);
uavcan::CanFrame expected_can_frame;
@@ -76,7 +68,7 @@ TEST(Publisher, Basic)
ASSERT_LT(0, publisher.broadcast(msg));
expected_frame = uavcan::Frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 1, true);
node.getNodeID(), uavcan::NodeID::Broadcast, 0, 1, true);
expected_frame.setPayload(expected_transfer_payload, 7);
ASSERT_TRUE(expected_frame.compile(expected_can_frame));
@@ -97,7 +89,7 @@ TEST(Publisher, Basic)
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false
uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageUnicast,
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID(0x44), 0, 0, true);
node.getNodeID(), uavcan::NodeID(0x44), 0, 0, true);
expected_frame.setPayload(expected_transfer_payload, 7);
uavcan::CanFrame expected_can_frame;
+2 -1
View File
@@ -33,7 +33,8 @@ TEST(Scheduler, Timers)
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg);
sch.getDispatcher().setNodeID(1);
/*
* Registration
+13 -37
View File
@@ -12,6 +12,7 @@
#include <queue>
#include "../clock.hpp"
#include "../transport/can/can.hpp"
#include "test_node.hpp"
template <typename DataType>
@@ -53,29 +54,6 @@ static void stringServiceServerCallback(const uavcan::ReceivedDataStructure<root
}
struct MakeshiftNode : uavcan::Noncopyable
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
SystemClockDriver clock_driver;
uavcan::MarshalBufferProvider<> buffer_provider;
uavcan::OutgoingTransferRegistry<8> otr;
uavcan::Scheduler scheduler;
MakeshiftNode(uavcan::ICanDriver& can_driver, uavcan::NodeID self_node_id)
: otr(poolmgr)
, scheduler(can_driver, poolmgr, clock_driver, otr, self_node_id)
{
poolmgr.addPool(&pool);
}
void spin(uavcan::MonotonicDuration duration)
{
scheduler.spin(clock_driver.getMonotonic() + duration);
}
};
struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
{
uavcan::ISystemClock& clock;
@@ -144,18 +122,16 @@ struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
TEST(ServiceClient, Basic)
{
SystemClockDriver clock;
PairableCanDriver can_a(clock), can_b(clock);
can_a.linkTogether(&can_b);
MakeshiftNode node_a(can_a, 1), node_b(can_b, 2);
TestNode node_a(can_a, clock, 1), node_b(can_b, clock, 2);
// Type registration
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<root_ns_a::StringService> _registrator;
// Server
uavcan::ServiceServer<root_ns_a::StringService> server(node_a.scheduler, node_a.poolmgr, node_a.buffer_provider);
uavcan::ServiceServer<root_ns_a::StringService> server(node_a);
ASSERT_EQ(1, server.start(stringServiceServerCallback));
{
@@ -165,17 +141,17 @@ TEST(ServiceClient, Basic)
typename ServiceCallResultHandler<root_ns_a::StringService>::Binder > ClientType;
ServiceCallResultHandler<root_ns_a::StringService> handler;
ClientType client1(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
ClientType client2(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
ClientType client3(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
ClientType client1(node_b);
ClientType client2(node_b);
ClientType client3(node_b);
client1.setCallback(handler.bind());
client2.setCallback(client1.getCallback());
client3.setCallback(client1.getCallback());
client3.setRequestTimeout(uavcan::MonotonicDuration::fromMSec(100));
ASSERT_EQ(1, node_a.scheduler.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // NOT listening!
ASSERT_EQ(1, node_a.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // NOT listening!
root_ns_a::StringService::Request request;
request.string_request = "Hello world";
@@ -184,7 +160,7 @@ TEST(ServiceClient, Basic)
ASSERT_LT(0, client2.call(1, request)); // OK
ASSERT_LT(0, client3.call(99, request)); // Will timeout!
ASSERT_EQ(3, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Listening now!
ASSERT_EQ(3, node_b.getDispatcher().getNumServiceResponseListeners()); // Listening now!
ASSERT_TRUE(client1.isPending());
ASSERT_TRUE(client2.isPending());
@@ -193,7 +169,7 @@ TEST(ServiceClient, Basic)
node_a.spin(uavcan::MonotonicDuration::fromMSec(10));
node_b.spin(uavcan::MonotonicDuration::fromMSec(10));
ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third is still listening!
ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners()); // Third is still listening!
ASSERT_FALSE(client1.isPending());
ASSERT_FALSE(client2.isPending());
@@ -211,7 +187,7 @@ TEST(ServiceClient, Basic)
ASSERT_FALSE(client2.isPending());
ASSERT_FALSE(client3.isPending());
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :(
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :(
// Validating
ASSERT_TRUE(handler.match(ResultType::ErrorTimeout, 99, root_ns_a::StringService::Response()));
@@ -219,11 +195,11 @@ TEST(ServiceClient, Basic)
// Stray request
ASSERT_LT(0, client3.call(99, request)); // Will timeout!
ASSERT_TRUE(client3.isPending());
ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners());
ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners());
}
// All destroyed - nobody listening
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners());
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners());
}
+8 -15
View File
@@ -8,6 +8,7 @@
#include <root_ns_a/StringService.hpp>
#include "../clock.hpp"
#include "../transport/can/can.hpp"
#include "test_node.hpp"
struct ServerImpl
@@ -36,30 +37,22 @@ struct ServerImpl
TEST(ServiceServer, Basic)
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
poolmgr.addPool(&pool);
// Manual type registration - we can't rely on the GDTR state
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<root_ns_a::StringService> _registrator;
SystemClockDriver clock_driver;
CanDriverMock can_driver(1, clock_driver);
uavcan::MarshalBufferProvider<> buffer_provider;
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
TestNode node(can_driver, clock_driver, 1);
ServerImpl impl("456");
{
uavcan::ServiceServer<root_ns_a::StringService, ServerImpl::Binder> server(sch, poolmgr, buffer_provider);
uavcan::ServiceServer<root_ns_a::StringService, ServerImpl::Binder> server(node);
ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners());
server.start(impl.bind());
ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners());
/*
* Request frames
@@ -78,7 +71,7 @@ TEST(ServiceServer, Basic)
can_driver.ifaces[0].pushRx(rx_frame);
}
sch.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000));
node.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000));
/*
* Responses (MFT)
@@ -113,7 +106,7 @@ TEST(ServiceServer, Basic)
ASSERT_EQ(0, server.getRequestFailureCount());
ASSERT_EQ(0, server.getResponseFailureCount());
ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners());
}
ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners());
ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners());
}
+23 -43
View File
@@ -9,6 +9,7 @@
#include <root_ns_a/EmptyMessage.hpp>
#include "../clock.hpp"
#include "../transport/can/can.hpp"
#include "test_node.hpp"
template <typename DataType>
@@ -59,27 +60,20 @@ struct SubscriptionListener
TEST(Subscriber, Basic)
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
poolmgr.addPool(&pool);
// Manual type registration - we can't rely on the GDTR state
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<uavcan::mavlink::Message> _registrator;
SystemClockDriver clock_driver;
CanDriverMock can_driver(2, clock_driver);
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
TestNode node(can_driver, clock_driver, 1);
typedef SubscriptionListener<uavcan::mavlink::Message> Listener;
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended(sch, poolmgr);
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended2(sch, poolmgr); // Not used
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple(sch, poolmgr);
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple2(sch, poolmgr); // Not used
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended(node);
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended2(node); // Not used
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple(node);
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple2(node); // Not used
std::cout <<
"sizeof(uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder>): " <<
@@ -115,7 +109,7 @@ TEST(Subscriber, Basic)
{
uavcan::TransferType tt = (i & 1) ? uavcan::TransferTypeMessageUnicast : uavcan::TransferTypeMessageBroadcast;
uavcan::NodeID dni = (tt == uavcan::TransferTypeMessageBroadcast) ?
uavcan::NodeID::Broadcast : sch.getDispatcher().getSelfNodeID();
uavcan::NodeID::Broadcast : node.getDispatcher().getNodeID();
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame
uavcan::Frame frame(uavcan::mavlink::Message::DefaultDataTypeID, tt, uavcan::NodeID(i + 100), dni, 0, i, true);
@@ -127,19 +121,19 @@ TEST(Subscriber, Basic)
/*
* Reception
*/
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
ASSERT_EQ(1, sub_extended.start(listener.bindExtended()));
ASSERT_EQ(1, sub_extended2.start(listener.bindExtended()));
ASSERT_EQ(1, sub_simple.start(listener.bindSimple()));
ASSERT_EQ(1, sub_simple2.start(listener.bindSimple()));
ASSERT_EQ(4, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(4, node.getDispatcher().getNumMessageListeners());
sub_extended2.stop(); // These are not used - making sure they aren't receiving anything
sub_simple2.stop();
ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners());
for (unsigned int i = 0; i < rx_frames.size(); i++)
{
@@ -147,7 +141,7 @@ TEST(Subscriber, Basic)
can_driver.ifaces[1].pushRx(rx_frames[i]);
}
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
/*
* Validation
@@ -175,14 +169,14 @@ TEST(Subscriber, Basic)
/*
* Unregistration
*/
ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners());
sub_extended.stop();
sub_extended2.stop();
sub_simple.stop();
sub_simple2.stop();
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
}
@@ -194,26 +188,19 @@ static void panickingSink(const uavcan::ReceivedDataStructure<uavcan::mavlink::M
TEST(Subscriber, FailureCount)
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
poolmgr.addPool(&pool);
// Manual type registration - we can't rely on the GDTR state
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<uavcan::mavlink::Message> _registrator;
SystemClockDriver clock_driver;
CanDriverMock can_driver(2, clock_driver);
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
TestNode node(can_driver, clock_driver, 1);
{
uavcan::Subscriber<uavcan::mavlink::Message> sub(sch, poolmgr);
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
uavcan::Subscriber<uavcan::mavlink::Message> sub(node);
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
sub.start(panickingSink);
ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners());
ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners());
ASSERT_EQ(0, sub.getFailureCount());
@@ -229,36 +216,29 @@ TEST(Subscriber, FailureCount)
can_driver.ifaces[1].pushRx(rx_frame);
}
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
ASSERT_EQ(4, sub.getFailureCount());
ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); // Still there
ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners()); // Still there
}
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); // Removed
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); // Removed
}
TEST(Subscriber, SingleFrameTransfer)
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
poolmgr.addPool(&pool);
// Manual type registration - we can't rely on the GDTR state
uavcan::GlobalDataTypeRegistry::instance().reset();
uavcan::DefaultDataTypeRegistrator<root_ns_a::EmptyMessage> _registrator;
SystemClockDriver clock_driver;
CanDriverMock can_driver(2, clock_driver);
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
TestNode node(can_driver, clock_driver, 1);
typedef SubscriptionListener<root_ns_a::EmptyMessage> Listener;
uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder> sub(sch, poolmgr);
uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder> sub(node);
std::cout <<
"sizeof(uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder>): " <<
@@ -280,7 +260,7 @@ TEST(Subscriber, SingleFrameTransfer)
can_driver.ifaces[1].pushRx(rx_frame);
}
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
ASSERT_EQ(0, sub.getFailureCount());
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <uavcan/node/abstract_node.hpp>
#include <uavcan/util/lazy_constructor.hpp>
struct TestNode : public uavcan::INode
{
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::PoolManager<1> poolmgr;
uavcan::MarshalBufferProvider<> buffer_provider;
uavcan::OutgoingTransferRegistry<8> otr;
uavcan::Scheduler scheduler;
TestNode(uavcan::ICanDriver& can_driver, uavcan::ISystemClock& clock_driver, uavcan::NodeID self_node_id)
: otr(poolmgr)
, scheduler(can_driver, poolmgr, clock_driver, otr)
{
poolmgr.addPool(&pool);
setNodeID(self_node_id);
}
uavcan::PoolManager<1>& getAllocator() { return poolmgr; }
uavcan::Scheduler& getScheduler() { return scheduler; }
const uavcan::Scheduler& getScheduler() const { return scheduler; }
uavcan::IMarshalBufferProvider& getMarshalBufferProvider() { return buffer_provider; }
};