diff --git a/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp b/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp index 04e26be3cc..0caa15afd0 100644 --- a/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp @@ -177,12 +177,7 @@ class TransferListener : public TransferListenerBase, Noncopyable void cleanup(uint64_t ts_monotonic) { receivers_.removeWhere(TimedOutReceiverPredicate(ts_monotonic, bufmgr_)); -#if UAVCAN_DEBUG - if (receivers_.isEmpty()) - { - assert(bufmgr_.isEmpty()); - } -#endif + assert(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1); } public: diff --git a/libuavcan/test/transport/transfer_listener.cpp b/libuavcan/test/transport/transfer_listener.cpp index 7a0f4a9e76..f12e336bcc 100644 --- a/libuavcan/test/transport/transfer_listener.cpp +++ b/libuavcan/test/transport/transfer_listener.cpp @@ -489,3 +489,59 @@ TEST(TransferListener, BasicSFT) ASSERT_TRUE(subscriber.isEmpty()); } + + +TEST(TransferListener, Cleanup) +{ + uavcan::DataTypeDescriptor type(uavcan::DATA_TYPE_KIND_MESSAGE, 123, uavcan::DataTypeHash()); + for (int i = 0; i < uavcan::DataTypeHash::NUM_BYTES; i++) + type.hash.value[i] = i | (i << 4); + + uavcan::PoolManager<1> poolmgr; // No dynamic memory + TestSubscriber<256, 1, 2> subscriber(&type, &poolmgr); // Static buffer only, 1 entry + + /* + * Generating transfers + */ + Emulator emulator(subscriber, type); + const Transfer tr_mft = emulator.makeTransfer(uavcan::TRANSFER_TYPE_MESSAGE_BROADCAST, 42, "123456789abcdefghik"); + const Transfer tr_sft = emulator.makeTransfer(uavcan::TRANSFER_TYPE_MESSAGE_UNICAST, 11, "abcd"); + + const std::vector ser_mft = serializeTransfer(tr_mft, 0, type); + const std::vector ser_sft = serializeTransfer(tr_sft, 9, type); + + ASSERT_TRUE(ser_mft.size() > 1); + ASSERT_TRUE(ser_sft.size() == 1); + + const std::vector ser_mft_begin(ser_mft.begin(), ser_mft.begin() + 1); + + /* + * Sending the first part and SFT + */ + std::vector > sers; + sers.push_back(ser_mft_begin); // Only the first part + sers.push_back(ser_sft); + + emulator.send(sers); + + ASSERT_TRUE(subscriber.matchAndPop(tr_sft)); + ASSERT_TRUE(subscriber.isEmpty()); + + /* + * Cleanup with huge timestamp value will remove all entries + */ + static_cast(subscriber).cleanup(100000000); + + /* + * Sending the same transfers again - they will be accepted since registres were cleared + */ + sers.clear(); + sers.push_back(ser_mft); // Complete transfer + sers.push_back(ser_sft); + + emulator.send(sers); + + ASSERT_TRUE(subscriber.matchAndPop(tr_sft)); + ASSERT_TRUE(subscriber.matchAndPop(tr_mft)); + ASSERT_TRUE(subscriber.isEmpty()); +}