Passing all tests now

This commit is contained in:
Pavel Kirienko
2015-04-30 10:55:52 +03:00
parent 2843c0a35e
commit b8c5613522
6 changed files with 305 additions and 63 deletions
+13 -3
View File
@@ -114,8 +114,8 @@ bool Frame::parse(const CanFrame& can_frame)
* CAN ID parsing
*/
const uint32_t id = can_frame.id & CanFrame::MaskExtID;
transfer_id_ = uint8_t(bitunpack<0, 3>(id));
last_frame_ = bitunpack<3, 1>(id) != 0;
transfer_id_ = uint8_t(bitunpack<0, 3>(id));
last_frame_ = bitunpack<3, 1>(id) != 0;
// TT-specific fields skipped
transfer_priority_ = TransferPriority(bitunpack<27, 2>(id));
@@ -283,7 +283,7 @@ bool Frame::compile(CanFrame& out_can_frame) const
{
sum = static_cast<uint8_t>(sum + payload_[i]);
}
out_can_frame.id &= ~bitpack<0, 8>(sum); // Setting the checksum
out_can_frame.id |= bitpack<0, 8>(sum); // Setting the checksum
}
return true;
@@ -296,11 +296,13 @@ bool Frame::isValid() const
*/
if (frame_index_ > getMaxIndex())
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
if ((frame_index_ == getMaxIndex()) && !last_frame_)
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -310,12 +312,14 @@ bool Frame::isValid() const
if (!src_node_id_.isValid() ||
!dst_node_id_.isValid())
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
if (src_node_id_.isUnicast() &&
(src_node_id_ == dst_node_id_))
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -324,11 +328,13 @@ bool Frame::isValid() const
*/
if (transfer_type_ >= NumTransferTypes)
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
if ((transfer_type_ == TransferTypeMessageBroadcast) != dst_node_id_.isBroadcast())
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -344,6 +350,7 @@ bool Frame::isValid() const
*/
if (static_cast<int>(payload_len_) > getMaxPayloadLen())
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -352,6 +359,7 @@ bool Frame::isValid() const
*/
if (!data_type_id_.isValidForDataTypeKind(getDataTypeKindForTransferType(transfer_type_)))
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -360,6 +368,7 @@ bool Frame::isValid() const
*/
if (transfer_priority_ >= NumTransferPriorities)
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
@@ -368,6 +377,7 @@ bool Frame::isValid() const
{
if (transfer_priority_ != TransferPriorityService)
{
UAVCAN_TRACE("Frame", "Validness check failed at line %d", __LINE__);
return false;
}
}
@@ -177,7 +177,8 @@ TEST(DataTypeInfoProvider, Basic)
*/
ComputeAggregateTypeSignature::Request cats_request;
cats_request.kind.value = DataTypeKind::MESSAGE;
cats_request.known_ids.set(); // Assuming we have all 1023 types
cats_request.known_ids.resize(2048);
cats_request.known_ids.set(); // Assuming we have all 2048 types
ASSERT_LE(0, cats_cln.call(1, cats_request));
nodes.spinBoth(MonotonicDuration::fromMSec(10));
@@ -193,7 +194,7 @@ TEST(DataTypeInfoProvider, Basic)
* ComputeAggregateTypeSignature test for a non-existent type
*/
cats_request.kind.value = 0xFF; // INVALID
cats_request.known_ids.set(); // Assuming we have all 1023 types
cats_request.known_ids.set(); // Assuming we have all 2048 types
ASSERT_LE(0, cats_cln.call(1, cats_request));
nodes.spinBoth(MonotonicDuration::fromMSec(10));
+12 -9
View File
@@ -78,34 +78,37 @@ TEST(Dispatcher, Reception)
static const std::string DATA[6] =
{
"Yes, man is mortal, but that would be only half the trouble. "
"The worst of it is that he's sometimes unexpectedly mortal - there's the trick!",
"Yes, man is mortal, but that would be only half the trouble. ",
"In fact, I'm beginning to fear that this confusion will go on for a long time. "
"And all because he writes down what I said incorrectly.",
"In fact, I'm beginning to fear that this confusion will go on for a long time. ",
"I had the pleasure of meeting that young man at the Patriarch's Ponds. "
"He almost drove me mad myself, proving to me that I don't exist.",
"I had the pleasure of meeting that young man at the Patriarch's Ponds. ",
"He was a dreamer, a thinker, a speculative philosopher... or, as his wife would have it, an idiot.",
// This one is too long to use in message transfers
"The only way to get ideas for stories is to drink way too much coffee and buy a desk that doesn't "
"collapse when you beat your head against it",
""
};
for (unsigned i = 0; i < sizeof(DATA) / sizeof(DATA[0]); i++)
{
std::cout << "Size of test data chunk " << i << ": " << DATA[i].length() << std::endl;
}
const Transfer transfers[9] =
{
emulator.makeTransfer(uavcan::TransferTypeMessageBroadcast, 10, DATA[0], TYPES[0]),
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 11, DATA[1], TYPES[1]),
emulator.makeTransfer(uavcan::TransferTypeServiceRequest, 12, DATA[2], TYPES[2]),
emulator.makeTransfer(uavcan::TransferTypeServiceResponse, 13, DATA[3], TYPES[3]),
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 14, DATA[4], TYPES[0]),
emulator.makeTransfer(uavcan::TransferTypeServiceResponse, 13, DATA[4], TYPES[3]),
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 14, DATA[3], TYPES[0]),
emulator.makeTransfer(uavcan::TransferTypeMessageBroadcast, 15, DATA[5], TYPES[1]),
// Wrongly addressed:
emulator.makeTransfer(uavcan::TransferTypeServiceResponse, 10, DATA[0], TYPES[3], 100),
emulator.makeTransfer(uavcan::TransferTypeServiceRequest, 11, DATA[1], TYPES[2], 101),
emulator.makeTransfer(uavcan::TransferTypeServiceRequest, 11, DATA[4], TYPES[2], 101),
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 12, DATA[2], TYPES[1], 102)
};
+261 -40
View File
@@ -9,7 +9,7 @@
#include "can/can.hpp"
TEST(Frame, FrameParseCompile)
TEST(Frame, MessageParseCompile)
{
using uavcan::Frame;
using uavcan::CanFrame;
@@ -18,13 +18,23 @@ TEST(Frame, FrameParseCompile)
Frame frame;
/*
* Priority (LOW, NORMAL, HIGH)
* Message Type ID
* Source Node ID
* BroadcastNotUnicast
* Frame Index
* Last Frame
* Transfer ID
*/
const uint32_t can_id =
(2 << 0) | // Transfer ID
(1 << 3) | // Last Frame
(29 << 4) | // Frame Index
(42 << 10) | // Source Node ID
(uavcan::TransferTypeMessageBroadcast << 17) |
(456 << 19); // Data Type ID
(1 << 27) | // Priority
(2000 << 16) | // Message Type ID
(42 << 9) | // Source Node ID
(1 << 8) | // BroadcastNotUnicast
(11 << 4) | // Frame Index
(1 << 3) | // Last Frame
(2 << 0); // Transfer ID
const std::string payload_string = "hello";
@@ -40,15 +50,19 @@ TEST(Frame, FrameParseCompile)
EXPECT_EQ(TransferID(2), frame.getTransferID());
EXPECT_TRUE(frame.isLast());
EXPECT_EQ(29, frame.getIndex());
EXPECT_EQ(11, frame.getIndex());
EXPECT_EQ(uavcan::NodeID(42), frame.getSrcNodeID());
EXPECT_TRUE(frame.getDstNodeID().isBroadcast());
EXPECT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
EXPECT_EQ(456, frame.getDataTypeID().get());
EXPECT_EQ(2000, frame.getDataTypeID().get());
EXPECT_EQ(uavcan::TransferPriorityNormal, frame.getPriority());
EXPECT_EQ(payload_string.length(), frame.getPayloadLen());
EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
payload_string.begin()));
std::cout << frame.toString() << std::endl;
/*
* Compile
*/
@@ -72,6 +86,159 @@ TEST(Frame, FrameParseCompile)
}
TEST(Frame, ServiceParseCompile)
{
using uavcan::Frame;
using uavcan::CanFrame;
using uavcan::TransferID;
using uavcan::TransferType;
Frame frame;
/*
* Priority = SERVICE
* RequestNotResponse
* Service Type ID
* Source Node ID
* Frame Index
* Last Frame
* Transfer ID
*/
const uint32_t can_id =
(2 << 27) | // Priority (Service)
(1 << 26) | // RequestNotResponse
(500 << 17) | // Service Type ID
(42 << 10) | // Source Node ID
(60 << 4) | // Frame Index
(1 << 3) | // Last Frame
(5 << 0); // Transfer ID
const std::string payload_string = "\x42hello"; // dst = 0x42
/*
* Parse
*/
// Invalid CAN frames
ASSERT_FALSE(frame.parse(CanFrame(can_id | CanFrame::FlagRTR, (const uint8_t*)"", 0)));
ASSERT_FALSE(frame.parse(makeCanFrame(can_id, payload_string, STD)));
// Valid
ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));
EXPECT_EQ(TransferID(5), frame.getTransferID());
EXPECT_TRUE(frame.isLast());
EXPECT_EQ(60, frame.getIndex());
EXPECT_EQ(uavcan::NodeID(42), frame.getSrcNodeID());
EXPECT_EQ(uavcan::NodeID(0x42), frame.getDstNodeID());
EXPECT_EQ(uavcan::TransferTypeServiceRequest, frame.getTransferType());
EXPECT_EQ(500, frame.getDataTypeID().get());
EXPECT_EQ(uavcan::TransferPriorityService, frame.getPriority());
EXPECT_EQ(payload_string.length(), frame.getPayloadLen() + 1);
EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
payload_string.begin() + 1));
std::cout << frame.toString() << std::endl;
/*
* Compile
*/
CanFrame can_frame;
ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));
ASSERT_TRUE(frame.compile(can_frame));
ASSERT_EQ(can_frame, makeCanFrame(can_id, payload_string, EXT));
EXPECT_EQ(payload_string.length(), can_frame.dlc);
EXPECT_TRUE(std::equal(can_frame.data, can_frame.data + can_frame.dlc, payload_string.begin()));
/*
* Comparison
*/
ASSERT_FALSE(Frame() == frame);
ASSERT_TRUE(Frame() != frame);
frame = Frame();
ASSERT_TRUE(Frame() == frame);
ASSERT_FALSE(Frame() != frame);
}
TEST(Frame, AnonymousParseCompile)
{
using uavcan::Frame;
using uavcan::CanFrame;
using uavcan::TransferID;
using uavcan::TransferType;
Frame frame;
/*
* Priority (LOW, NORMAL, HIGH)
* Message Type ID
* Source Node ID
* BroadcastNotUnicast
* Frame Index
* Last Frame
* Transfer ID
*/
const uint32_t can_id =
(0 << 27) | // Priority (high)
(2000 << 16) | // Message Type ID
(0 << 9) | // Source Node ID
(1 << 8) | // BroadcastNotUnicast
(11 << 4) | // Frame Index (will be ignored)
(1 << 3) | // Last Frame (will be ignored)
(2 << 0); // Transfer ID (will be ignored)
const std::string payload_string = "\x01\x02\x03\x04";
const uint8_t payload_sum = 1 + 2 + 3 + 4;
/*
* Parse
*/
ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));
EXPECT_EQ(TransferID(0), frame.getTransferID());
EXPECT_TRUE(frame.isLast());
EXPECT_EQ(0, frame.getIndex());
EXPECT_TRUE(frame.getSrcNodeID().isBroadcast());
EXPECT_TRUE(frame.getDstNodeID().isBroadcast());
EXPECT_EQ(uavcan::TransferTypeMessageBroadcast, frame.getTransferType());
EXPECT_EQ(2000, frame.getDataTypeID().get());
EXPECT_EQ(uavcan::TransferPriorityHigh, frame.getPriority());
EXPECT_EQ(payload_string.length(), frame.getPayloadLen());
EXPECT_TRUE(std::equal(frame.getPayloadPtr(), frame.getPayloadPtr() + frame.getPayloadLen(),
payload_string.begin()));
std::cout << frame.toString() << std::endl;
/*
* Compile
*/
CanFrame can_frame;
ASSERT_TRUE(frame.parse(makeCanFrame(can_id, payload_string, EXT)));
ASSERT_TRUE(frame.compile(can_frame));
ASSERT_EQ(can_id & 0xFFFFFF00 & uavcan::CanFrame::MaskExtID,
can_frame.id & 0xFFFFFF00 & uavcan::CanFrame::MaskExtID);
EXPECT_EQ(payload_string.length(), can_frame.dlc);
EXPECT_TRUE(std::equal(can_frame.data, can_frame.data + can_frame.dlc, payload_string.begin()));
ASSERT_EQ(payload_sum, can_frame.id & 0xFF);
/*
* Comparison
*/
ASSERT_FALSE(Frame() == frame);
ASSERT_TRUE(Frame() != frame);
frame = Frame();
ASSERT_TRUE(Frame() == frame);
ASSERT_FALSE(Frame() != frame);
}
TEST(Frame, FrameParsing)
{
using uavcan::Frame;
@@ -88,17 +255,42 @@ TEST(Frame, FrameParsing)
can.data[i] = uint8_t(i | (i << 4));
}
// CAN ID field order: Transfer ID, Last Frame, Frame Index, Source Node ID, Transfer Type, Data Type ID
/*
* Message CAN ID fields and offsets:
* 27 Priority (LOW=3, NORMAL=1, HIGH=0)
* 16 Message Type ID
* 9 Source Node ID
* 8 BroadcastNotUnicast
* 4 Frame Index
* 3 Last Frame
* 0 Transfer ID
*
* Service CAN ID fields and offsets:
* 27 Priority (SERVICE=2)
* 26 RequestNotResponse
* 17 Service Type ID
* 10 Source Node ID
* 4 Frame Index
* 3 Last Frame
* 0 Transfer ID
*/
/*
* SFT broadcast
* SFT message broadcast
*/
can.id = CanFrame::FlagEFF |
(2 << 0) | (1 << 3) | (0 << 4) | (42 << 10) | (uavcan::TransferTypeMessageBroadcast << 17) | (456 << 19);
(2 << 0) |
(1 << 3) |
(0 << 4) |
(1 << 8) |
(42 << 9) |
(456 << 16) |
(1 << 27);
ASSERT_TRUE(frame.parse(can));
ASSERT_TRUE(frame.isFirst());
ASSERT_TRUE(frame.isLast());
ASSERT_EQ(uavcan::TransferPriorityNormal, frame.getPriority());
ASSERT_EQ(0, frame.getIndex());
ASSERT_EQ(NodeID(42), frame.getSrcNodeID());
ASSERT_EQ(NodeID::Broadcast, frame.getDstNodeID());
@@ -108,10 +300,16 @@ TEST(Frame, FrameParsing)
ASSERT_EQ(sizeof(CanFrame::data), frame.getMaxPayloadLen());
/*
* SFT addressed
* SFT message unicast
*/
can.id = CanFrame::FlagEFF |
(2 << 0) | (1 << 3) | (0 << 4) | (42 << 10) | (uavcan::TransferTypeMessageUnicast << 17) | (456 << 19);
(2 << 0) |
(1 << 3) | // Last Frame
(0 << 4) | // Frame Index
(0 << 8) |
(42 << 9) |
(456 << 16) |
(0 << 27);
ASSERT_FALSE(frame.parse(can)); // No payload - failure
@@ -124,6 +322,7 @@ TEST(Frame, FrameParsing)
ASSERT_TRUE(frame.isFirst());
ASSERT_TRUE(frame.isLast());
ASSERT_EQ(uavcan::TransferPriorityHigh, frame.getPriority());
ASSERT_EQ(0, frame.getIndex());
ASSERT_EQ(NodeID(42), frame.getSrcNodeID());
ASSERT_EQ(NodeID(127), frame.getDstNodeID());
@@ -133,20 +332,32 @@ TEST(Frame, FrameParsing)
ASSERT_EQ(sizeof(CanFrame::data) - 1, frame.getMaxPayloadLen());
/*
* MFT invalid - unterminated transfer
* MFT message unicast
* Invalid - unterminated transfer
*/
can.id = CanFrame::FlagEFF |
(2 << 0) | (0 << 3) |
(unsigned(Frame::getMaxIndexForTransferType(uavcan::TransferTypeMessageUnicast)) << 4) | (42 << 10) |
(uavcan::TransferTypeMessageUnicast << 17) | (456 << 19);
(2 << 0) |
(0 << 3) |
(15 << 4) |
(0 << 8) |
(42 << 9) |
(456 << 16) |
(0 << 27);
ASSERT_FALSE(frame.parse(can));
/*
* MFT invalid - invalid frame index
* MFT service request
* Invalid frame index
*/
can.id = CanFrame::FlagEFF |
(2 << 0) | (0 << 3) | (63 << 4) | (42 << 10) | (uavcan::TransferTypeMessageUnicast << 17) | (456 << 19);
(2 << 27) | // Priority (Service)
(1 << 26) | // RequestNotResponse
(500 << 17) | // Service Type ID
(42 << 10) | // Source Node ID
(63 << 4) | // Frame Index
(1 << 3) | // Last Frame
(5 << 0); // Transfer ID
ASSERT_FALSE(frame.parse(can));
@@ -154,27 +365,37 @@ TEST(Frame, FrameParsing)
* Malformed frames
*/
can.id = CanFrame::FlagEFF |
(2 << 0) | (1 << 3) | (0 << 4) | (42 << 10) | (uavcan::TransferTypeMessageUnicast << 17) | (456 << 19);
(2 << 0) |
(1 << 3) |
(15 << 4) |
(0 << 8) |
(42 << 9) |
(456 << 16) |
(3 << 27);
can.dlc = 3;
can.data[0] = 42;
ASSERT_FALSE(frame.parse(can)); // Src == Dst Node ID
can.data[0] = 41;
ASSERT_TRUE(frame.parse(can));
can.id = CanFrame::FlagEFF | // cppcheck-suppress duplicateExpression
(2 << 0) | (1 << 3) | (0 << 4) | (0 << 10) | (uavcan::TransferTypeMessageUnicast << 17) | (456 << 19);
ASSERT_FALSE(frame.parse(can)); // Broadcast Src Node ID with unicast transfer
can.id = CanFrame::FlagEFF | // cppcheck-suppress duplicateExpression
(2 << 0) | (0 << 3) | (0 << 4) | (0 << 10) | (uavcan::TransferTypeMessageBroadcast << 17) | (456 << 19);
ASSERT_FALSE(frame.parse(can)); // Broadcast Src Node ID with multiframe broadcast transfer
ASSERT_EQ(uavcan::TransferPriorityLow, frame.getPriority());
/*
* Broadcast SNID exceptions
* Note that last 3 fields are ignored
*/
can.id = CanFrame::FlagEFF | // cppcheck-suppress duplicateExpression
(2 << 0) | (1 << 3) | (0 << 4) | (0 << 10) | (uavcan::TransferTypeMessageBroadcast << 17) | (456 << 19);
ASSERT_TRUE(frame.parse(can)); // Broadcast Src Node ID with single frame broadcast transfer
can.id = CanFrame::FlagEFF |
(2 << 27) | // Priority
(2000 << 16) | // Message Type ID
(0 << 9) | // Source Node ID
(1 << 8); // BroadcastNotUnicast
ASSERT_FALSE(frame.parse(can)); // Invalid priority
can.id = CanFrame::FlagEFF |
(1 << 27) | // Priority
(2000 << 16) | // Message Type ID
(0 << 9) | // Source Node ID
(1 << 8); // BroadcastNotUnicast
ASSERT_TRUE(frame.parse(can));
}
@@ -193,14 +414,14 @@ TEST(Frame, RxFrameParse)
// Valid
can_rx_frame.ts_mono = uavcan::MonotonicTime::fromUSec(1); // Zero is not allowed
can_rx_frame.id =
CanFrame::FlagEFF |
(2 << 0) | // Transfer ID
(1 << 3) | // Last Frame
(29 << 4) | // Frame Index
(42 << 10) | // Source Node ID
(uavcan::TransferTypeMessageBroadcast << 17) |
(456 << 19); // Data Type ID
can_rx_frame.id = CanFrame::FlagEFF |
(2 << 0) |
(1 << 3) |
(0 << 4) |
(1 << 8) |
(42 << 9) |
(456 << 16) |
(1 << 27);
ASSERT_TRUE(rx_frame.parse(can_rx_frame));
ASSERT_EQ(1, rx_frame.getMonotonicTimestamp().toUSec());
+15 -8
View File
@@ -46,19 +46,26 @@ TEST(TransferListener, BasicMFT)
*/
static const std::string DATA[] =
{
"123456789",
// Too long for unicast messages
"Build a man a fire, and he'll be warm for a day. "
"Set a man on fire, and he'll be warm for the rest of his life.",
"The USSR, which they'd begun to renovate and improve at about the time when Tatarsky decided to "
"change his profession, improved so much that it ceased to exist",
"123456789",
"In the beginning there was nothing, which exploded.",
// Too long for message transfers
"The USSR, which they'd begun to renovate and improve at about the time when Tatarsky decided to "
"change his profession, improved so much that it ceased to exist",
"BEWARE JET BLAST"
};
for (unsigned i = 0; i < sizeof(DATA) / sizeof(DATA[0]); i++)
{
std::cout << "Size of test data chunk " << i << ": " << DATA[i].length() << std::endl;
}
TransferListenerEmulator emulator(subscriber, type);
const Transfer transfers[] =
{
@@ -71,15 +78,15 @@ TEST(TransferListener, BasicMFT)
/*
* Sending concurrently
* Expected reception order: 0, 4, 3, 1, 2
* Expected reception order: 1, 4, 2, 0, 3
*/
emulator.send(transfers);
ASSERT_TRUE(subscriber.matchAndPop(transfers[0]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[4]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[3]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[1]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[4]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[2]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[0]));
ASSERT_TRUE(subscriber.matchAndPop(transfers[3]));
ASSERT_TRUE(subscriber.isEmpty());
}
@@ -137,7 +137,7 @@ TEST(TransferReceiver, Basic)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "abcdefgh", 1, false, 1, 1200), bk));
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "45678910", 1, false, 2, 1300), bk)); // Next TID, but FI > 0
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "", 2, true, 1, 1300), bk)); // Wrong iface
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "", 31, true, 1, 1300), bk)); // Unexpected FI
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "", 11, true, 1, 1300), bk)); // Unexpected FI
CHECK_COMPLETE( rcv.addFrame(gen(0, "", 2, true, 1, 1300), bk));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "345678abcdefgh"));