libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers data_type_info_provider.cpp Source File

data_type_info_provider.cpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <gtest/gtest.h>
00006 #include <uavcan/node/publisher.hpp>
00007 #include <uavcan/protocol/data_type_info_provider.hpp>
00008 #include <uavcan/protocol/NodeStatus.hpp>
00009 #include "helpers.hpp"
00010 
00011 using uavcan::protocol::GetDataTypeInfo;
00012 using uavcan::protocol::NodeStatus;
00013 using uavcan::protocol::DataTypeKind;
00014 using uavcan::ServiceCallResult;
00015 using uavcan::DataTypeInfoProvider;
00016 using uavcan::GlobalDataTypeRegistry;
00017 using uavcan::DefaultDataTypeRegistrator;
00018 using uavcan::MonotonicDuration;
00019 
00020 template <typename DataType>
00021 static bool validateDataTypeInfoResponse(const std::auto_ptr<ServiceCallResultCollector<GetDataTypeInfo>::Result>& resp,
00022                                          unsigned flags)
00023 {
00024     if (!resp.get())
00025     {
00026         std::cout << "Null response" << std::endl;
00027         return false;
00028     }
00029     if (!resp->isSuccessful())
00030     {
00031         std::cout << "Request was not successful" << std::endl;
00032         return false;
00033     }
00034     if (resp->getResponse().name != DataType::getDataTypeFullName())
00035     {
00036         std::cout << "Type name mismatch: '"
00037             << resp->getResponse().name.c_str() << "' '"
00038             << DataType::getDataTypeFullName() << "'" << std::endl;
00039         return false;
00040     }
00041     if (DataType::getDataTypeSignature().get() != resp->getResponse().signature)
00042     {
00043         std::cout << "Signature mismatch" << std::endl;
00044         return false;
00045     }
00046     if (resp->getResponse().flags != flags)
00047     {
00048         std::cout << "Mask mismatch" << std::endl;
00049         return false;
00050     }
00051     if (resp->getResponse().kind.value != DataType::DataTypeKind)
00052     {
00053         std::cout << "Kind mismatch" << std::endl;
00054         return false;
00055     }
00056     if (resp->getResponse().id != DataType::DefaultDataTypeID)
00057     {
00058         std::cout << "DTID mismatch" << std::endl;
00059         return false;
00060     }
00061     return true;
00062 }
00063 
00064 
00065 TEST(DataTypeInfoProvider, Basic)
00066 {
00067     InterlinkedTestNodesWithSysClock nodes;
00068 
00069     DataTypeInfoProvider dtip(nodes.a);
00070 
00071     GlobalDataTypeRegistry::instance().reset();
00072     DefaultDataTypeRegistrator<GetDataTypeInfo> _reg1;
00073     DefaultDataTypeRegistrator<NodeStatus> _reg3;
00074 
00075     ASSERT_LE(0, dtip.start());
00076 
00077     ServiceClientWithCollector<GetDataTypeInfo> gdti_cln(nodes.b);
00078 
00079     /*
00080      * GetDataTypeInfo request for GetDataTypeInfo
00081      */
00082     GetDataTypeInfo::Request gdti_request;
00083     gdti_request.id = GetDataTypeInfo::DefaultDataTypeID;
00084     gdti_request.kind.value = DataTypeKind::SERVICE;
00085     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00086     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00087 
00088     ASSERT_TRUE(validateDataTypeInfoResponse<GetDataTypeInfo>(gdti_cln.collector.result,
00089                                                               GetDataTypeInfo::Response::FLAG_KNOWN |
00090                                                               GetDataTypeInfo::Response::FLAG_SERVING));
00091     ASSERT_EQ(1, gdti_cln.collector.result->getCallID().server_node_id.get());
00092 
00093     /*
00094      * GetDataTypeInfo request for GetDataTypeInfo by name
00095      */
00096     gdti_request = GetDataTypeInfo::Request();
00097     gdti_request.id = 999;                             // Intentionally wrong
00098     gdti_request.kind.value = DataTypeKind::MESSAGE;   // Intentionally wrong
00099     gdti_request.name = "uavcan.protocol.GetDataTypeInfo";
00100     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00101     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00102 
00103     ASSERT_TRUE(validateDataTypeInfoResponse<GetDataTypeInfo>(gdti_cln.collector.result,
00104                                                               GetDataTypeInfo::Response::FLAG_KNOWN |
00105                                                               GetDataTypeInfo::Response::FLAG_SERVING));
00106     ASSERT_EQ(1, gdti_cln.collector.result->getCallID().server_node_id.get());
00107 
00108     /*
00109      * GetDataTypeInfo request for NodeStatus - not used yet
00110      */
00111     gdti_request = GetDataTypeInfo::Request();
00112     gdti_request.id = NodeStatus::DefaultDataTypeID;
00113     gdti_request.kind.value = DataTypeKind::MESSAGE;
00114     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00115     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00116 
00117     ASSERT_TRUE(validateDataTypeInfoResponse<NodeStatus>(gdti_cln.collector.result,
00118                                                          GetDataTypeInfo::Response::FLAG_KNOWN));
00119 
00120     /*
00121      * Starting publisher and subscriber for NodeStatus, requesting info again
00122      */
00123     uavcan::Publisher<NodeStatus> ns_pub(nodes.a);
00124     SubscriberWithCollector<NodeStatus> ns_sub(nodes.a);
00125 
00126     ASSERT_LE(0, ns_pub.broadcast(NodeStatus()));
00127     ASSERT_LE(0, ns_sub.start());
00128 
00129     // Request again
00130     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00131     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00132 
00133     ASSERT_TRUE(validateDataTypeInfoResponse<NodeStatus>(gdti_cln.collector.result,
00134                                                          GetDataTypeInfo::Response::FLAG_KNOWN |
00135                                                          GetDataTypeInfo::Response::FLAG_PUBLISHING |
00136                                                          GetDataTypeInfo::Response::FLAG_SUBSCRIBED));
00137 
00138     /*
00139      * Requesting a non-existent type
00140      */
00141     gdti_request = GetDataTypeInfo::Request();
00142     gdti_request.id = 20000;
00143     gdti_request.kind.value = 3;                 // INVALID VALUE
00144     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00145     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00146 
00147     ASSERT_TRUE(gdti_cln.collector.result.get());
00148     ASSERT_TRUE(gdti_cln.collector.result->isSuccessful());
00149     ASSERT_EQ(1, gdti_cln.collector.result->getCallID().server_node_id.get());
00150     ASSERT_EQ(0, gdti_cln.collector.result->getResponse().flags);
00151     ASSERT_TRUE(gdti_cln.collector.result->getResponse().name.empty());  // Empty name
00152     ASSERT_EQ(gdti_request.id, gdti_cln.collector.result->getResponse().id);
00153     ASSERT_EQ(gdti_request.kind.value, gdti_cln.collector.result->getResponse().kind.value);
00154 
00155     /*
00156      * Requesting a non-existent type by name
00157      */
00158     gdti_request = GetDataTypeInfo::Request();
00159     gdti_request.id = 999;                        // Intentionally wrong
00160     gdti_request.kind.value = 3;                  // Intentionally wrong
00161     gdti_request.name = "uavcan.equipment.gnss.Fix";
00162     ASSERT_LE(0, gdti_cln.call(1, gdti_request));
00163     nodes.spinBoth(MonotonicDuration::fromMSec(10));
00164 
00165     ASSERT_TRUE(gdti_cln.collector.result.get());
00166     ASSERT_TRUE(gdti_cln.collector.result->isSuccessful());
00167     ASSERT_EQ(1, gdti_cln.collector.result->getCallID().server_node_id.get());
00168     ASSERT_EQ(0, gdti_cln.collector.result->getResponse().flags);
00169     ASSERT_EQ("uavcan.equipment.gnss.Fix", gdti_cln.collector.result->getResponse().name);
00170     ASSERT_EQ(0, gdti_cln.collector.result->getResponse().id);
00171     ASSERT_EQ(0, gdti_cln.collector.result->getResponse().kind.value);
00172 }