libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers node_status_provider.cpp Source File

node_status_provider.cpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <gtest/gtest.h>
00006 #include <uavcan/protocol/node_status_provider.hpp>
00007 #include "helpers.hpp"
00008 
00009 
00010 struct AdHocNodeStatusUpdater : public uavcan::IAdHocNodeStatusUpdater
00011 {
00012     uavcan::uint64_t invokations;
00013 
00014     AdHocNodeStatusUpdater() : invokations(0) { }
00015 
00016     virtual void updateNodeStatus()
00017     {
00018         invokations++;
00019     }
00020 };
00021 
00022 
00023 TEST(NodeStatusProvider, Basic)
00024 {
00025     InterlinkedTestNodesWithSysClock nodes;
00026 
00027     uavcan::NodeStatusProvider nsp(nodes.a);
00028 
00029     /*
00030      * Initialization
00031      */
00032     uavcan::protocol::HardwareVersion hwver;
00033     hwver.major = 3;
00034     hwver.minor = 14;
00035 
00036     uavcan::protocol::SoftwareVersion swver;
00037     swver.major = 2;
00038     swver.minor = 18;
00039     swver.vcs_commit = 0x600DF00D;
00040 
00041     nsp.setHardwareVersion(hwver);
00042     nsp.setSoftwareVersion(swver);
00043 
00044     ASSERT_TRUE(nsp.getName().empty());
00045     nsp.setName("superluminal_communication_unit");
00046     ASSERT_STREQ("superluminal_communication_unit", nsp.getName().c_str());
00047 
00048     ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_OK, nsp.getHealth());
00049     ASSERT_EQ(uavcan::protocol::NodeStatus::MODE_INITIALIZATION, nsp.getMode());
00050     nsp.setHealthError();
00051     nsp.setModeOperational();
00052     ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, nsp.getHealth());
00053     ASSERT_EQ(uavcan::protocol::NodeStatus::MODE_OPERATIONAL, nsp.getMode());
00054 
00055     // Will fail - types are not registered
00056     uavcan::GlobalDataTypeRegistry::instance().reset();
00057     ASSERT_GT(0, nsp.startAndPublish());
00058 
00059     uavcan::GlobalDataTypeRegistry::instance().reset();
00060     uavcan::DefaultDataTypeRegistrator<uavcan::protocol::NodeStatus> _reg1;
00061     uavcan::DefaultDataTypeRegistrator<uavcan::protocol::GetNodeInfo> _reg2;
00062     ASSERT_LE(0, nsp.startAndPublish());
00063 
00064     // Checking the publishing rate settings
00065     ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS),
00066               nsp.getStatusPublicationPeriod());
00067 
00068     nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration());
00069     ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MIN_BROADCASTING_PERIOD_MS),
00070               nsp.getStatusPublicationPeriod());
00071 
00072     nsp.setStatusPublicationPeriod(uavcan::MonotonicDuration::fromMSec(3600 * 1000 * 24));
00073     ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS),
00074               nsp.getStatusPublicationPeriod());
00075 
00076     AdHocNodeStatusUpdater ad_hoc;
00077     ASSERT_EQ(UAVCAN_NULLPTR, nsp.getAdHocNodeStatusUpdater());
00078     nsp.setAdHocNodeStatusUpdater(&ad_hoc);
00079     ASSERT_EQ(&ad_hoc, nsp.getAdHocNodeStatusUpdater());
00080 
00081     /*
00082      * Initial status publication
00083      */
00084     SubscriberWithCollector<uavcan::protocol::NodeStatus> status_sub(nodes.b);
00085 
00086     ASSERT_LE(0, status_sub.start());
00087     ASSERT_FALSE(status_sub.collector.msg.get());  // No data yet
00088 
00089     nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
00090 
00091     ASSERT_TRUE(status_sub.collector.msg.get());  // Was published at startup
00092     ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, status_sub.collector.msg->health);
00093     ASSERT_EQ(0, status_sub.collector.msg->vendor_specific_status_code);
00094     ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
00095 
00096     ASSERT_EQ(0, ad_hoc.invokations);   // Not invoked from startAndPublish()
00097 
00098     /*
00099      * Altering the vendor-specific status code, forcePublish()-ing it and checking the result
00100      */
00101     ASSERT_EQ(0, nsp.getVendorSpecificStatusCode());
00102     nsp.setVendorSpecificStatusCode(1234);
00103     ASSERT_EQ(1234, nsp.getVendorSpecificStatusCode());
00104 
00105     ASSERT_LE(0, nsp.forcePublish());
00106 
00107     nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
00108 
00109     ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_ERROR, status_sub.collector.msg->health);
00110     ASSERT_EQ(1234, status_sub.collector.msg->vendor_specific_status_code);
00111     ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
00112 
00113     ASSERT_EQ(0, ad_hoc.invokations);   // Not invoked from forcePublish()
00114 
00115     /*
00116      * Explicit node info request
00117      */
00118     ServiceClientWithCollector<uavcan::protocol::GetNodeInfo> gni_cln(nodes.b);
00119 
00120     nsp.setHealthCritical();
00121 
00122     ASSERT_FALSE(gni_cln.collector.result.get());  // No data yet
00123     ASSERT_LE(0, gni_cln.call(1, uavcan::protocol::GetNodeInfo::Request()));
00124 
00125     nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
00126     ASSERT_TRUE(gni_cln.collector.result.get());   // Response must have been delivered
00127 
00128     ASSERT_TRUE(gni_cln.collector.result->isSuccessful());
00129     ASSERT_EQ(1, gni_cln.collector.result->getCallID().server_node_id.get());
00130 
00131     ASSERT_EQ(uavcan::protocol::NodeStatus::HEALTH_CRITICAL,
00132               gni_cln.collector.result->getResponse().status.health);
00133 
00134     ASSERT_TRUE(hwver == gni_cln.collector.result->getResponse().hardware_version);
00135     ASSERT_TRUE(swver == gni_cln.collector.result->getResponse().software_version);
00136 
00137     ASSERT_EQ("superluminal_communication_unit", gni_cln.collector.result->getResponse().name);
00138 
00139     ASSERT_EQ(0, ad_hoc.invokations);   // No timer-triggered publications happened yet
00140 
00141     /*
00142      * Timer triggered publication
00143      */
00144     EXPECT_EQ(3, nodes.a.getDispatcher().getTransferPerfCounter().getTxTransferCount());
00145 
00146     nodes.spinBoth(nsp.getStatusPublicationPeriod());
00147 
00148     EXPECT_EQ(1, ad_hoc.invokations);   // No timer-triggered publications happened yet
00149     EXPECT_EQ(4, nodes.a.getDispatcher().getTransferPerfCounter().getTxTransferCount());
00150 }