/* * Copyright (C) 2014 Pavel Kirienko */ #include #include #include "helpers.hpp" TEST(NodeStatusProvider, Basic) { InterlinkedTestNodesWithSysClock nodes; uavcan::NodeStatusProvider nsp(nodes.a); /* * Initialization */ uavcan::protocol::HardwareVersion hwver; hwver.major = 3; hwver.minor = 14; uavcan::protocol::SoftwareVersion swver; swver.major = 2; swver.minor = 18; swver.vcs_commit = 0x600DF00D; nsp.setHardwareVersion(hwver); nsp.setSoftwareVersion(swver); ASSERT_TRUE(nsp.getName().empty()); nsp.setName("superluminal_communication_unit"); ASSERT_STREQ("superluminal_communication_unit", nsp.getName().c_str()); ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_OK, nsp.getHealth()); ASSERT_EQ(uavcan::protocol::NodeStatus::MODE_INITIALIZATION, nsp.getMode()); nsp.setHealthError(); nsp.setModeOperational(); ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, nsp.getHealth()); ASSERT_EQ(uavcan::protocol::NodeStatus::MODE_OPERATIONAL, nsp.getMode()); // Will fail - types are not registered uavcan::GlobalDataTypeRegistry::instance().reset(); ASSERT_GT(0, nsp.startAndPublish()); uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _reg1; uavcan::DefaultDataTypeRegistrator _reg2; ASSERT_LE(0, nsp.startAndPublish()); // Checking the publishing rate settings ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS), nsp.getStatusPublicationPeriod()); nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration()); ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MIN_BROADCASTING_PERIOD_MS), nsp.getStatusPublicationPeriod()); nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration::fromMSec(3600 * 1000 * 24)); ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS), nsp.getStatusPublicationPeriod()); /* * Initial status publication */ SubscriberWithCollector status_sub(nodes.b); ASSERT_LE(0, status_sub.start()); ASSERT_FALSE(status_sub.collector.msg.get()); // No data yet nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)); ASSERT_TRUE(status_sub.collector.msg.get()); // Was published at startup ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, status_sub.collector.msg->health); ASSERT_EQ(0, status_sub.collector.msg->vendor_specific_status_code); ASSERT_GE(1, status_sub.collector.msg->uptime_sec); /* * Altering the vendor-specific status code, forcePublish()-ing it and checking the result */ ASSERT_EQ(0, nsp.getVendorSpecificStatusCode()); nsp.setVendorSpecificStatusCode(1234); ASSERT_EQ(1234, nsp.getVendorSpecificStatusCode()); ASSERT_LE(0, nsp.forcePublish()); nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)); ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, status_sub.collector.msg->health); ASSERT_EQ(1234, status_sub.collector.msg->vendor_specific_status_code); ASSERT_GE(1, status_sub.collector.msg->uptime_sec); /* * Explicit node info request */ ServiceClientWithCollector gni_cln(nodes.b); nsp.setHealthCritical(); ASSERT_FALSE(gni_cln.collector.result.get()); // No data yet ASSERT_LE(0, gni_cln.call(1, uavcan::protocol::GetNodeInfo::Request())); nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10)); ASSERT_TRUE(gni_cln.collector.result.get()); // Response must have been delivered ASSERT_TRUE(gni_cln.collector.result->isSuccessful()); ASSERT_EQ(1, gni_cln.collector.result->getCallID().server_node_id.get()); ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_CRITICAL, gni_cln.collector.result->getResponse().status.health); ASSERT_TRUE(hwver == gni_cln.collector.result->getResponse().hardware_version); ASSERT_TRUE(swver == gni_cln.collector.result->getResponse().software_version); ASSERT_EQ("superluminal_communication_unit", gni_cln.collector.result->getResponse().name); }