GlobalTimeSyncSlave message validation test

This commit is contained in:
Pavel Kirienko
2014-03-24 16:24:40 +04:00
parent 31ed44ff5c
commit b40ee02383
2 changed files with 114 additions and 1 deletions
@@ -163,3 +163,114 @@ TEST(GlobalTimeSyncSlave, Basic)
ASSERT_FALSE(gtss.isActive());
ASSERT_FALSE(gtss.getMasterNodeID().isValid());
}
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || (BYTE_ORDER != LITTLE_ENDIAN)
# error "This test cannot be executed on this platform"
#endif
static uavcan::Frame makeSyncMsg(uavcan::uint64_t usec, uavcan::NodeID snid, uavcan::TransferID tid)
{
uavcan::Frame frame(uavcan::protocol::GlobalTimeSync::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
snid, uavcan::NodeID::Broadcast, 0, tid, true);
EXPECT_EQ(8, frame.setPayload(reinterpret_cast<uint8_t*>(&usec), 8)); // Assuming little endian
return frame;
}
static void broadcastSyncMsg(CanIfaceMock& iface, uavcan::uint64_t usec, uavcan::NodeID snid, uavcan::TransferID tid)
{
const uavcan::Frame frame = makeSyncMsg(usec, snid, tid);
uavcan::CanFrame can_frame;
ASSERT_TRUE(frame.compile(can_frame));
iface.pushRx(can_frame);
}
TEST(GlobalTimeSyncSlave, Validation)
{
SystemClockMock slave_clock;
slave_clock.monotonic = 1000000;
slave_clock.preserve_utc = true;
CanDriverMock slave_can(3, slave_clock);
for (int i = 0; i < slave_can.getNumIfaces(); i++)
{
slave_can.ifaces.at(i).enable_utc_timestamping = true;
}
TestNode node(slave_can, slave_clock, 64);
uavcan::GlobalTimeSyncSlave gtss(node);
uavcan::Publisher<uavcan::protocol::GlobalTimeSync> gts_pub(node);
ASSERT_LE(0, gtss.start());
ASSERT_FALSE(gtss.isActive());
ASSERT_FALSE(gtss.getMasterNodeID().isValid());
ASSERT_EQ(0, slave_clock.utc);
/*
* Update/adjust/update
*/
broadcastSyncMsg(slave_can.ifaces.at(0), 0, 8, 0); // Locked on this
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 0); // Ignored
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
broadcastSyncMsg(slave_can.ifaces.at(0), 1000, 8, 1); // Adjust 1000 ahead
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 1); // Ignored
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_TRUE(gtss.isActive());
ASSERT_EQ(8, gtss.getMasterNodeID().get());
ASSERT_EQ(1000, slave_clock.utc);
broadcastSyncMsg(slave_can.ifaces.at(0), 2000, 8, 2); // Update
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_EQ(1000, slave_clock.utc);
std::cout << slave_clock.monotonic << std::endl;
/*
* TID jump simulates a frame loss
*/
broadcastSyncMsg(slave_can.ifaces.at(0), 3000, 8, 4); // Adjustment skipped - expected TID 3, update instead
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_TRUE(gtss.isActive());
ASSERT_EQ(8, gtss.getMasterNodeID().get());
ASSERT_EQ(1000, slave_clock.utc);
std::cout << slave_clock.monotonic << std::endl;
/*
* Valid adjustment - continuing from TID 4
*/
broadcastSyncMsg(slave_can.ifaces.at(0), 3000, 8, 5); // Slave UTC was 1000, master reports 3000 --> shift ahead
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 5);
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_TRUE(gtss.isActive());
ASSERT_EQ(8, gtss.getMasterNodeID().get());
ASSERT_EQ(3000, slave_clock.utc);
std::cout << slave_clock.monotonic << std::endl;
/*
* Update, then very long delay with correct TID
*/
broadcastSyncMsg(slave_can.ifaces.at(0), 2000, 8, 6); // Valid update, slave UTC is 3000
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 6);
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
slave_clock.monotonic += 5000000;
broadcastSyncMsg(slave_can.ifaces.at(0), 5000, 8, 7); // Adjustment skipped
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 7);
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
broadcastSyncMsg(slave_can.ifaces.at(0), 5000, 8, 0); // Valid adjustment now
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 0);
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
ASSERT_TRUE(gtss.isActive());
ASSERT_EQ(8, gtss.getMasterNodeID().get());
ASSERT_EQ(5000, slave_clock.utc);
std::cout << slave_clock.monotonic << std::endl;
}
+3 -1
View File
@@ -42,6 +42,7 @@ public:
bool rx_failure;
uint64_t num_errors;
uavcan::ISystemClock& iclock;
bool enable_utc_timestamping;
CanIfaceMock(uavcan::ISystemClock& iclock)
: writeable(true)
@@ -49,6 +50,7 @@ public:
, rx_failure(false)
, num_errors(0)
, iclock(iclock)
, enable_utc_timestamping(false)
{ }
void pushRx(const uavcan::CanFrame& frame)
@@ -131,7 +133,7 @@ public:
out_frame = frame.frame;
out_ts_monotonic = frame.time;
}
out_ts_utc = uavcan::UtcTime();
out_ts_utc = enable_utc_timestamping ? iclock.getUtc() : uavcan::UtcTime();
return 1;
}