libuav original
Dependents: UAVCAN UAVCAN_Subscriber
transfer_listener.cpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #include <gtest/gtest.h> 00006 #include "transfer_test_helpers.hpp" 00007 #include "../clock.hpp" 00008 00009 00010 class TransferListenerEmulator : public IncomingTransferEmulatorBase 00011 { 00012 uavcan::TransferListener& target_; 00013 const uavcan::DataTypeDescriptor data_type_; 00014 00015 public: 00016 TransferListenerEmulator(uavcan::TransferListener& target, const uavcan::DataTypeDescriptor& type, 00017 uavcan::NodeID dst_node_id = 127) 00018 : IncomingTransferEmulatorBase(dst_node_id) 00019 , target_(target) 00020 , data_type_(type) 00021 { } 00022 00023 void sendOneFrame(const uavcan::RxFrame& frame) { target_.handleFrame(frame); } 00024 00025 Transfer makeTransfer(uavcan::TransferPriority priority, uavcan::TransferType transfer_type, 00026 uint8_t source_node_id, const std::string& payload) 00027 { 00028 return IncomingTransferEmulatorBase::makeTransfer(priority, transfer_type, source_node_id, payload, data_type_); 00029 } 00030 }; 00031 00032 00033 TEST(TransferListener, BasicMFT) 00034 { 00035 const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); 00036 00037 static const int NUM_POOL_BLOCKS = 100; 00038 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> pool; 00039 00040 uavcan::TransferPerfCounter perf; 00041 TestListener subscriber(perf, type, 256, pool); 00042 00043 /* 00044 * Test data 00045 */ 00046 static const std::string DATA[] = 00047 { 00048 "Build a man a fire, and he'll be warm for a day. " 00049 "Set a man on fire, and he'll be warm for the rest of his life.", 00050 00051 "123456789", 00052 00053 "In the beginning there was nothing, which exploded.", 00054 00055 "The USSR, which they'd begun to renovate and improve at about the time when Tatarsky decided to " 00056 "change his profession, improved so much that it ceased to exist", 00057 00058 "BEWARE JET BLAST" 00059 }; 00060 00061 for (unsigned i = 0; i < sizeof(DATA) / sizeof(DATA[0]); i++) 00062 { 00063 std::cout << "Size of test data chunk " << i << ": " << DATA[i].length() << std::endl; 00064 } 00065 00066 TransferListenerEmulator emulator(subscriber, type); 00067 const Transfer transfers[] = 00068 { 00069 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 1, DATA[0]), 00070 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 2, DATA[1]), // Same NID 00071 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 3, DATA[2]), 00072 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 4, DATA[3]), 00073 emulator.makeTransfer(16, uavcan::TransferTypeServiceResponse, 5, DATA[4]), 00074 }; 00075 00076 /* 00077 * Sending concurrently 00078 * Expected reception order: 1, 4, 2, 0, 3 00079 */ 00080 emulator.send(transfers); 00081 00082 ASSERT_TRUE(subscriber.matchAndPop(transfers[1])); 00083 ASSERT_TRUE(subscriber.matchAndPop(transfers[4])); 00084 ASSERT_TRUE(subscriber.matchAndPop(transfers[2])); 00085 ASSERT_TRUE(subscriber.matchAndPop(transfers[0])); 00086 ASSERT_TRUE(subscriber.matchAndPop(transfers[3])); 00087 00088 ASSERT_TRUE(subscriber.isEmpty()); 00089 } 00090 00091 00092 TEST(TransferListener, CrcFailure) 00093 { 00094 const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); 00095 00096 static const int NUM_POOL_BLOCKS = 100; 00097 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; 00098 uavcan::TransferPerfCounter perf; 00099 TestListener subscriber(perf, type, 256, poolmgr); // Static buffer only, 2 entries 00100 00101 /* 00102 * Generating transfers with damaged payload (CRC is not valid) 00103 */ 00104 TransferListenerEmulator emulator(subscriber, type); 00105 const Transfer tr_mft = emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 42, "123456789abcdefghik"); 00106 const Transfer tr_sft = emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 11, "abcd"); 00107 00108 std::vector<uavcan::RxFrame> ser_mft = serializeTransfer(tr_mft); 00109 std::vector<uavcan::RxFrame> ser_sft = serializeTransfer(tr_sft); 00110 00111 ASSERT_TRUE(ser_mft.size() > 1); 00112 ASSERT_TRUE(ser_sft.size() == 1); 00113 00114 const_cast<uint8_t*>(ser_mft[1].getPayloadPtr())[1] = uint8_t(~ser_mft[1].getPayloadPtr()[1]); // CRC invalid now 00115 const_cast<uint8_t*>(ser_sft[0].getPayloadPtr())[2] = uint8_t(~ser_sft[0].getPayloadPtr()[2]); // no CRC here 00116 00117 /* 00118 * Sending and making sure that MFT was not received, but SFT was. 00119 */ 00120 std::vector<std::vector<uavcan::RxFrame> > sers; 00121 sers.push_back(ser_mft); 00122 sers.push_back(ser_sft); 00123 sers.push_back(ser_mft); // Ignored 00124 sers.push_back(ser_sft); // Ignored 00125 00126 emulator.send(sers); 00127 00128 Transfer tr_sft_damaged = tr_sft; 00129 tr_sft_damaged.payload[2] = char(~tr_sft.payload[2]); // Damaging the data similarly, so that it can be matched 00130 00131 ASSERT_TRUE(subscriber.matchAndPop(tr_sft_damaged)); 00132 ASSERT_TRUE(subscriber.isEmpty()); 00133 } 00134 00135 00136 TEST(TransferListener, BasicSFT) 00137 { 00138 const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); 00139 00140 static const int NUM_POOL_BLOCKS = 100; 00141 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; 00142 uavcan::TransferPerfCounter perf; 00143 TestListener subscriber(perf, type, 0, poolmgr); // Max buf size is 0, i.e. SFT-only 00144 00145 TransferListenerEmulator emulator(subscriber, type); 00146 const Transfer transfers[] = 00147 { 00148 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 1, "123"), 00149 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 1, "456"), // Same NID 00150 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 2, ""), 00151 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 3, "abc"), 00152 emulator.makeTransfer(16, uavcan::TransferTypeServiceResponse, 4, ""), 00153 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 2, "foo"), // Same as 2, not ignored 00154 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 2, "123456789abc"), // Same as 2, not SFT - ignore 00155 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 2, "bar"), // Same as 2, not ignored 00156 }; 00157 00158 emulator.send(transfers); 00159 00160 ASSERT_TRUE(subscriber.matchAndPop(transfers[0])); 00161 ASSERT_TRUE(subscriber.matchAndPop(transfers[1])); 00162 ASSERT_TRUE(subscriber.matchAndPop(transfers[2])); 00163 ASSERT_TRUE(subscriber.matchAndPop(transfers[3])); 00164 ASSERT_TRUE(subscriber.matchAndPop(transfers[4])); 00165 ASSERT_TRUE(subscriber.matchAndPop(transfers[5])); 00166 ASSERT_TRUE(subscriber.matchAndPop(transfers[7])); 00167 00168 ASSERT_TRUE(subscriber.isEmpty()); 00169 } 00170 00171 00172 TEST(TransferListener, Cleanup) 00173 { 00174 const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); 00175 00176 static const int NUM_POOL_BLOCKS = 100; 00177 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; 00178 uavcan::TransferPerfCounter perf; 00179 TestListener subscriber(perf, type, 256, poolmgr); 00180 00181 /* 00182 * Generating transfers 00183 */ 00184 TransferListenerEmulator emulator(subscriber, type); 00185 const Transfer tr_mft = emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 42, "123456789abcdefghik"); 00186 const Transfer tr_sft = emulator.makeTransfer(16, uavcan::TransferTypeServiceResponse, 11, "abcd"); 00187 00188 const std::vector<uavcan::RxFrame> ser_mft = serializeTransfer(tr_mft); 00189 const std::vector<uavcan::RxFrame> ser_sft = serializeTransfer(tr_sft); 00190 00191 ASSERT_TRUE(ser_mft.size() > 1); 00192 ASSERT_TRUE(ser_sft.size() == 1); 00193 00194 const std::vector<uavcan::RxFrame> ser_mft_begin(ser_mft.begin(), ser_mft.begin() + 1); 00195 00196 /* 00197 * Sending the first part and SFT 00198 */ 00199 std::vector<std::vector<uavcan::RxFrame> > sers; 00200 sers.push_back(ser_mft_begin); // Only the first part 00201 sers.push_back(ser_sft); 00202 00203 emulator.send(sers); 00204 00205 ASSERT_TRUE(subscriber.matchAndPop(tr_sft)); 00206 ASSERT_TRUE(subscriber.isEmpty()); 00207 00208 /* 00209 * Cleanup with huge timestamp value will remove all entries 00210 */ 00211 static_cast<uavcan::TransferListener&>(subscriber).cleanup(tsMono(100000000)); 00212 00213 /* 00214 * Sending the same transfers again - they will be accepted since registres were cleared 00215 */ 00216 sers.clear(); 00217 sers.push_back(ser_mft); // Complete transfer 00218 sers.push_back(ser_sft); 00219 00220 emulator.send(sers); 00221 00222 ASSERT_TRUE(subscriber.matchAndPop(tr_sft)); 00223 ASSERT_TRUE(subscriber.matchAndPop(tr_mft)); 00224 ASSERT_TRUE(subscriber.isEmpty()); 00225 } 00226 00227 00228 TEST(TransferListener, AnonymousTransfers) 00229 { 00230 const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); 00231 00232 static const int NUM_POOL_BLOCKS = 100; 00233 uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; 00234 uavcan::TransferPerfCounter perf; 00235 TestListener subscriber(perf, type, 0, poolmgr); 00236 00237 TransferListenerEmulator emulator(subscriber, type); 00238 const Transfer transfers[] = 00239 { 00240 emulator.makeTransfer(16, uavcan::TransferTypeServiceRequest, 0, "1234567"), // Invalid - not broadcast 00241 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 0, "1234567"), // Valid 00242 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 0, "12345678"), // Invalid - not SFT 00243 emulator.makeTransfer(16, uavcan::TransferTypeMessageBroadcast, 0, "") // Valid 00244 }; 00245 00246 emulator.send(transfers); 00247 00248 // Nothing will be received, because anonymous transfers are disabled by default 00249 ASSERT_TRUE(subscriber.isEmpty()); 00250 00251 subscriber.allowAnonymousTransfers(); 00252 00253 // Re-send everything again 00254 emulator.send(transfers); 00255 00256 // Now the anonymous transfers are enabled 00257 ASSERT_TRUE(subscriber.matchAndPop(transfers[1])); // Only SFT broadcast will be accepted 00258 ASSERT_TRUE(subscriber.matchAndPop(transfers[3])); 00259 00260 ASSERT_TRUE(subscriber.isEmpty()); 00261 } 00262 00263 TEST(TransferListener, Sizes) 00264 { 00265 using namespace uavcan; 00266 00267 std::cout << "sizeof(TransferListener): " << sizeof(TransferListener) << std::endl; 00268 }
Generated on Tue Jul 12 2022 17:17:35 by 1.7.2