blob: 16fb88f0159b9fc37d4a0b0daaeb21d96ce28cdc [file] [log] [blame]
Eric Newberry185ab292017-03-28 06:45:39 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry7b0071e2017-07-03 17:33:31 +00002/*
Eric Newberry185ab292017-03-28 06:45:39 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "face/lp-reliability.hpp"
27#include "face/face.hpp"
Eric Newberry185ab292017-03-28 06:45:39 +000028#include "face/generic-link-service.hpp"
29
30#include "tests/test-common.hpp"
31#include "dummy-face.hpp"
32#include "dummy-transport.hpp"
33
Eric Newberry7b0071e2017-07-03 17:33:31 +000034#include <cstring>
35
Eric Newberry185ab292017-03-28 06:45:39 +000036namespace nfd {
37namespace face {
38namespace tests {
39
40using namespace nfd::tests;
41
42BOOST_AUTO_TEST_SUITE(Face)
43
44class DummyLpReliabilityLinkService : public GenericLinkService
45{
46public:
47 LpReliability*
48 getLpReliability()
49 {
50 return &m_reliability;
51 }
52
53 void
54 sendLpPackets(std::vector<lp::Packet> frags)
55 {
56 if (frags.front().has<lp::FragmentField>()) {
Eric Newberry7b0071e2017-07-03 17:33:31 +000057 m_reliability.handleOutgoing(frags);
Eric Newberry185ab292017-03-28 06:45:39 +000058 }
59
Eric Newberry7b0071e2017-07-03 17:33:31 +000060 for (lp::Packet frag : frags) {
Eric Newberry185ab292017-03-28 06:45:39 +000061 this->sendLpPacket(std::move(frag));
62 }
63 }
64
65private:
66 void
67 doSendInterest(const Interest& interest) override
68 {
69 BOOST_ASSERT(false);
70 }
71
72 void
73 doSendData(const Data& data) override
74 {
75 BOOST_ASSERT(false);
76 }
77
78 void
79 doSendNack(const lp::Nack& nack) override
80 {
81 BOOST_ASSERT(false);
82 }
83
84 void
85 doReceivePacket(Transport::Packet&& packet) override
86 {
87 BOOST_ASSERT(false);
88 }
89};
90
91class LpReliabilityFixture : public UnitTestTimeFixture
92{
93public:
94 LpReliabilityFixture()
95 : linkService(make_unique<DummyLpReliabilityLinkService>())
96 , transport(make_unique<DummyTransport>())
97 , face(make_unique<DummyFace>())
98 {
99 linkService->setFaceAndTransport(*face, *transport);
100 transport->setFaceAndLinkService(*face, *linkService);
101
102 GenericLinkService::Options options;
103 options.reliabilityOptions.isEnabled = true;
104 linkService->setOptions(options);
105
106 reliability = linkService->getLpReliability();
Eric Newberry7b0071e2017-07-03 17:33:31 +0000107 reliability->m_lastTxSeqNo = 1;
108 }
109
110 static bool
111 netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
112 {
113 return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
114 [txSeq] (const LpReliability::UnackedFrags::iterator& frag) {
115 return frag->first == txSeq;
116 });
117 }
118
119 LpReliability::UnackedFrags::iterator
120 getIteratorFromTxSeq(lp::Sequence txSeq)
121 {
122 return reliability->m_unackedFrags.find(txSeq);
123 }
124
125 /** \brief make an LpPacket with fragment of specified size
126 * \param pktNo packet identifier, which can be extracted with \p getPktNo
127 * \param payloadSize total payload size; if this is less than 4, 4 will be used
128 */
129 static lp::Packet
130 makeFrag(uint32_t pktNo, size_t payloadSize = 4)
131 {
132 payloadSize = std::max(payloadSize, static_cast<size_t>(4));
133 BOOST_ASSERT(payloadSize <= 255);
134
135 lp::Packet pkt;
136 ndn::Buffer buf(payloadSize);
Davide Pesavento6d1c1c32017-10-08 21:44:05 -0400137 std::memcpy(buf.data(), &pktNo, sizeof(pktNo));
Eric Newberry7b0071e2017-07-03 17:33:31 +0000138 pkt.set<lp::FragmentField>(make_pair(buf.cbegin(), buf.cend()));
139 return pkt;
140 }
141
142 /** \brief extract packet identifier from LpPacket made with \p makeFrag
143 * \retval 0 packet identifier cannot be extracted
144 */
145 static uint32_t
146 getPktNo(const lp::Packet& pkt)
147 {
148 BOOST_ASSERT(pkt.has<lp::FragmentField>());
149
150 ndn::Buffer::const_iterator begin, end;
151 std::tie(begin, end) = pkt.get<lp::FragmentField>();
152 if (std::distance(begin, end) < 4) {
153 return 0;
154 }
155
156 uint32_t value = 0;
157 std::memcpy(&value, &*begin, sizeof(value));
158 return value;
Eric Newberry185ab292017-03-28 06:45:39 +0000159 }
160
161public:
162 unique_ptr<DummyLpReliabilityLinkService> linkService;
163 unique_ptr<DummyTransport> transport;
164 unique_ptr<DummyFace> face;
165 LpReliability* reliability;
166};
167
168BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
169
Eric Newberry7b0071e2017-07-03 17:33:31 +0000170BOOST_AUTO_TEST_SUITE(Sender)
171
Eric Newberry185ab292017-03-28 06:45:39 +0000172BOOST_AUTO_TEST_CASE(SendNoFragmentField)
173{
174 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000175
176 linkService->sendLpPackets({pkt});
177 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000178 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
179}
180
Eric Newberry7b0071e2017-07-03 17:33:31 +0000181BOOST_AUTO_TEST_CASE(SendUnfragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000182{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000183 lp::Packet pkt1 = makeFrag(1024, 50);
184 lp::Packet pkt2 = makeFrag(3000, 30);
Eric Newberry185ab292017-03-28 06:45:39 +0000185
186 linkService->sendLpPackets({pkt1});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000187 lp::Packet cached1(transport->sentPackets.front().packet);
188 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
189 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
190 BOOST_CHECK(!cached1.has<lp::SequenceField>());
191 lp::Sequence firstTxSeq = cached1.get<lp::TxSequenceField>();
192 BOOST_CHECK_EQUAL(getPktNo(cached1), 1024);
193
Eric Newberry185ab292017-03-28 06:45:39 +0000194 // T+500ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000195 // 1024 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000196 advanceClocks(time::milliseconds(1), 500);
197 linkService->sendLpPackets({pkt2});
Eric Newberry7b0071e2017-07-03 17:33:31 +0000198 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
Eric Newberry185ab292017-03-28 06:45:39 +0000199
Eric Newberry7b0071e2017-07-03 17:33:31 +0000200 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 2);
201 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 1);
202 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
203 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq).netPkt);
204 BOOST_CHECK(reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
205 BOOST_CHECK_NE(reliability->m_unackedFrags.at(firstTxSeq).netPkt,
206 reliability->m_unackedFrags.at(firstTxSeq + 1).netPkt);
207 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq).retxCount, 0);
208 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
209 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq);
210 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000211
212 // T+1250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000213 // 1024 rto: 1000ms, txSeq: 4, started T+1000ms, retx 1
214 // 3000 rto: 1000ms, txSeq: 3, started T+500ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000215 advanceClocks(time::milliseconds(1), 750);
216
Eric Newberry7b0071e2017-07-03 17:33:31 +0000217 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 2);
218 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq), 0);
219 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 1);
220 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 2).retxCount, 1);
221 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 1);
222 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 1).retxCount, 0);
223 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 1);
224 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000225
226 // T+2250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000227 // 1024 rto: 1000ms, txSeq: 6, started T+2000ms, retx 2
228 // 3000 rto: 1000ms, txSeq: 5, started T+1500ms, retx 1
Eric Newberry185ab292017-03-28 06:45:39 +0000229 advanceClocks(time::milliseconds(1), 1000);
230
Eric Newberry7b0071e2017-07-03 17:33:31 +0000231 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 2);
232 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 1), 0);
233 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 2), 0);
234 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 1);
235 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 4).retxCount, 2);
236 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 1);
237 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 3).retxCount, 1);
238 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 3);
239 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry185ab292017-03-28 06:45:39 +0000240
241 // T+3250ms
Eric Newberry7b0071e2017-07-03 17:33:31 +0000242 // 1024 rto: 1000ms, txSeq: 8, started T+3000ms, retx 3
243 // 3000 rto: 1000ms, txSeq: 7, started T+2500ms, retx 2
Eric Newberry185ab292017-03-28 06:45:39 +0000244 advanceClocks(time::milliseconds(1), 1000);
245
Eric Newberry7b0071e2017-07-03 17:33:31 +0000246 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 2);
247 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 3), 0);
248 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 4), 0);
249 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 1);
250 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 6).retxCount, 3);
251 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 1);
252 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 5).retxCount, 2);
253 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 5);
254 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 7);
Eric Newberry185ab292017-03-28 06:45:39 +0000255
256 // T+4250ms
257 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000258 // 3000 rto: 1000ms, txSeq: 9, started T+3500ms, retx 3
Eric Newberry185ab292017-03-28 06:45:39 +0000259 advanceClocks(time::milliseconds(1), 1000);
260
Eric Newberry7b0071e2017-07-03 17:33:31 +0000261 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.size(), 1);
262 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 5), 0);
263 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 6), 0);
264 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(firstTxSeq + 7), 1);
265 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(firstTxSeq + 7).retxCount, 3);
266 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, firstTxSeq + 7);
267 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000268
269 // T+4750ms
270 // 1024 rto: expired, removed
Eric Newberry7b0071e2017-07-03 17:33:31 +0000271 // 3000 rto: expired, removed
Eric Newberry185ab292017-03-28 06:45:39 +0000272 advanceClocks(time::milliseconds(1), 1000);
273
274 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000275 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
276 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 8);
Eric Newberry185ab292017-03-28 06:45:39 +0000277}
278
Eric Newberry7b0071e2017-07-03 17:33:31 +0000279BOOST_AUTO_TEST_CASE(SendFragmentedRetx)
Eric Newberry185ab292017-03-28 06:45:39 +0000280{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000281 lp::Packet pkt1 = makeFrag(2048, 30);
282 lp::Packet pkt2 = makeFrag(2049, 30);
283 lp::Packet pkt3 = makeFrag(2050, 10);
Eric Newberry185ab292017-03-28 06:45:39 +0000284
Eric Newberry7b0071e2017-07-03 17:33:31 +0000285 linkService->sendLpPackets({pkt1, pkt2, pkt3});
286 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000287
Eric Newberry7b0071e2017-07-03 17:33:31 +0000288 lp::Packet cached1(transport->sentPackets.at(0).packet);
289 BOOST_REQUIRE(cached1.has<lp::TxSequenceField>());
290 BOOST_CHECK_EQUAL(cached1.get<lp::TxSequenceField>(), 2);
291 BOOST_CHECK_EQUAL(getPktNo(cached1), 2048);
292 lp::Packet cached2(transport->sentPackets.at(1).packet);
293 BOOST_REQUIRE(cached2.has<lp::TxSequenceField>());
294 BOOST_CHECK_EQUAL(cached2.get<lp::TxSequenceField>(), 3);
295 BOOST_CHECK_EQUAL(getPktNo(cached2), 2049);
296 lp::Packet cached3(transport->sentPackets.at(2).packet);
297 BOOST_REQUIRE(cached3.has<lp::TxSequenceField>());
298 BOOST_CHECK_EQUAL(cached3.get<lp::TxSequenceField>(), 4);
299 BOOST_CHECK_EQUAL(getPktNo(cached3), 2050);
Eric Newberry185ab292017-03-28 06:45:39 +0000300
Eric Newberry7b0071e2017-07-03 17:33:31 +0000301 // T+0ms
302 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
303 // 2049 rto: 1000ms, txSeq: 3, started T+0ms, retx 0
304 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
Eric Newberry185ab292017-03-28 06:45:39 +0000305
Eric Newberry7b0071e2017-07-03 17:33:31 +0000306 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
307 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(3), 1);
308 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(4), 1);
309 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
310 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(3).pkt), 2049);
311 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
312 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
313 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
314 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
315 BOOST_REQUIRE(reliability->m_unackedFrags.at(3).netPkt);
316 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
317 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
318 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(3).netPkt);
319 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
320 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
321 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
322 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
323 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
324 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
325 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
326 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000327
Eric Newberry7b0071e2017-07-03 17:33:31 +0000328 // T+250ms
329 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
330 // 2049 rto: 1000ms, txSeq: 5, started T+250ms, retx 1
331 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
332 advanceClocks(time::milliseconds(1), 250);
333 reliability->onLpPacketLost(getIteratorFromTxSeq(3));
Eric Newberry185ab292017-03-28 06:45:39 +0000334
Eric Newberry7b0071e2017-07-03 17:33:31 +0000335 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
336 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 0);
337 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(5), 1);
338 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(4), 1);
339 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
340 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(5).pkt), 2049);
341 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
342 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
343 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
344 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(5).retxCount, 1);
345 BOOST_REQUIRE(reliability->m_unackedFrags.at(5).netPkt);
346 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
347 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
348 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(5).netPkt);
349 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
350 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
351 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
352 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 3));
353 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
354 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
355 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
356 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 4);
357
358 // T+500ms
359 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
360 // 2049 rto: 1000ms, txSeq: 6, started T+500ms, retx 2
361 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
362 advanceClocks(time::milliseconds(1), 250);
363 reliability->onLpPacketLost(getIteratorFromTxSeq(5));
364
365 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
366 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(5), 0);
367 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(6), 1);
368 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(4), 1);
369 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
370 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(6).pkt), 2049);
371 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
372 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
373 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
374 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(6).retxCount, 2);
375 BOOST_REQUIRE(reliability->m_unackedFrags.at(6).netPkt);
376 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
377 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
378 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(6).netPkt);
379 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
380 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
381 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
382 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 5));
383 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
384 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
385 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
386 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
387
388 // T+750ms
389 // 2048 rto: 1000ms, txSeq: 2, started T+0ms, retx 0
390 // 2049 rto: 1000ms, txSeq: 7, started T+750ms, retx 3
391 // 2050 rto: 1000ms, txSeq: 4, started T+0ms, retx 0
392 advanceClocks(time::milliseconds(1), 250);
393 reliability->onLpPacketLost(getIteratorFromTxSeq(6));
394
395 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1);
396 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(6), 0);
397 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(7), 1);
398 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(4), 1);
399 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(2).pkt), 2048);
400 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(7).pkt), 2049);
401 BOOST_CHECK_EQUAL(getPktNo(reliability->m_unackedFrags.at(4).pkt), 2050);
402 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
403 BOOST_REQUIRE(reliability->m_unackedFrags.at(2).netPkt);
404 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(7).retxCount, 3);
405 BOOST_REQUIRE(reliability->m_unackedFrags.at(7).netPkt);
406 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 0);
407 BOOST_REQUIRE(reliability->m_unackedFrags.at(4).netPkt);
408 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(7).netPkt);
409 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt, reliability->m_unackedFrags.at(4).netPkt);
410 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).netPkt->unackedFrags.size(), 3);
411 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 2));
412 BOOST_CHECK(!netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 6));
413 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 7));
414 BOOST_CHECK(netPktHasUnackedFrag(reliability->m_unackedFrags.at(2).netPkt, 4));
415 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 2);
416 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
417
418 // T+850ms
419 // 2048 rto: expired, removed
420 // 2049 rto: expired, removed
421 // 2050 rto: expired, removed
422 advanceClocks(time::milliseconds(1), 100);
423 reliability->onLpPacketLost(getIteratorFromTxSeq(7));
424
425 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 0);
426 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
427}
428
429BOOST_AUTO_TEST_CASE(LossByGreaterAcks) // detect loss by 3x greater Acks, also tests wraparound
430{
431 reliability->m_lastTxSeqNo = 0xFFFFFFFFFFFFFFFE;
432
433 // Passed to sendLpPackets individually since they are from separate, non-fragmented network packets
434 linkService->sendLpPackets({makeFrag(1, 50)});
435 linkService->sendLpPackets({makeFrag(2, 50)});
436 linkService->sendLpPackets({makeFrag(3, 50)});
437 linkService->sendLpPackets({makeFrag(4, 50)});
438 linkService->sendLpPackets({makeFrag(5, 50)});
Eric Newberry185ab292017-03-28 06:45:39 +0000439
440 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 5);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000441 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
442 BOOST_CHECK(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).netPkt);
443 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 1); // pkt2
444 BOOST_CHECK(reliability->m_unackedFrags.at(0).netPkt);
445 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
446 BOOST_CHECK(reliability->m_unackedFrags.at(1).netPkt);
447 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
448 BOOST_CHECK(reliability->m_unackedFrags.at(2).netPkt);
449 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
450 BOOST_CHECK(reliability->m_unackedFrags.at(3).netPkt);
Eric Newberry185ab292017-03-28 06:45:39 +0000451 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
452
453 lp::Packet ackPkt1;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000454 ackPkt1.add<lp::AckField>(0);
Eric Newberry185ab292017-03-28 06:45:39 +0000455
456 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
457
458 reliability->processIncomingPacket(ackPkt1);
459
460 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 4);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000461 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000462 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
463 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000464 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
465 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
466 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
467 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 0);
468 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 1); // pkt4
469 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).retxCount, 0);
470 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(2).nGreaterSeqAcks, 0);
471 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
472 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
473 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000474 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000475 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry185ab292017-03-28 06:45:39 +0000476
477 lp::Packet ackPkt2;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000478 ackPkt2.add<lp::AckField>(2);
479 ackPkt1.add<lp::AckField>(101010); // Unknown TxSequence number - ignored
Eric Newberry185ab292017-03-28 06:45:39 +0000480
481 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
482
483 reliability->processIncomingPacket(ackPkt2);
484
485 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 3);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000486 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 1); // pkt1
Eric Newberry185ab292017-03-28 06:45:39 +0000487 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).retxCount, 0);
488 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(0xFFFFFFFFFFFFFFFF).nGreaterSeqAcks, 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000489 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
490 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(1), 1); // pkt3
491 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).retxCount, 0);
492 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(1).nGreaterSeqAcks, 1);
493 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
494 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
495 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
496 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
497 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(101010), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000498 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 0xFFFFFFFFFFFFFFFF);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000499 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
Eric Newberry185ab292017-03-28 06:45:39 +0000500
501 lp::Packet ackPkt3;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000502 ackPkt3.add<lp::AckField>(1);
Eric Newberry185ab292017-03-28 06:45:39 +0000503
504 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
505
506 reliability->processIncomingPacket(ackPkt3);
507
508 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 2);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000509 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
510 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
511 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
512 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
513 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
514 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
515 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 0);
516 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(4), 1); // pkt1 new TxSeq
517 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).retxCount, 1);
518 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(4).nGreaterSeqAcks, 0);
519 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000520 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry185ab292017-03-28 06:45:39 +0000521 lp::Packet sentRetxPkt(transport->sentPackets.back().packet);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000522 BOOST_REQUIRE(sentRetxPkt.has<lp::TxSequenceField>());
523 BOOST_CHECK_EQUAL(sentRetxPkt.get<lp::TxSequenceField>(), 4);
524 BOOST_REQUIRE(sentRetxPkt.has<lp::FragmentField>());
525 BOOST_CHECK_EQUAL(getPktNo(sentRetxPkt), 1);
Eric Newberry185ab292017-03-28 06:45:39 +0000526
527 lp::Packet ackPkt4;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000528 ackPkt4.add<lp::AckField>(4);
Eric Newberry185ab292017-03-28 06:45:39 +0000529
530 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
531
532 reliability->processIncomingPacket(ackPkt4);
533
534 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000535 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0xFFFFFFFFFFFFFFFF), 0); // pkt1 old TxSeq
536 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(0), 0); // pkt2
537 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(1), 0); // pkt3
538 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(2), 0); // pkt4
539 BOOST_REQUIRE_EQUAL(reliability->m_unackedFrags.count(3), 1); // pkt5
540 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).retxCount, 0);
541 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.at(3).nGreaterSeqAcks, 1);
542 BOOST_CHECK_EQUAL(reliability->m_unackedFrags.count(4), 0); // pkt1 new TxSeq
543 BOOST_CHECK_EQUAL(reliability->m_firstUnackedFrag->first, 3);
Eric Newberry185ab292017-03-28 06:45:39 +0000544 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 6);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000545}
546
547BOOST_AUTO_TEST_SUITE_END() // Sender
548
549BOOST_AUTO_TEST_SUITE(Receiver)
550
551BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
552{
553 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
554 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
555
556 lp::Packet pkt1 = makeFrag(100, 40);
557 pkt1.add<lp::TxSequenceField>(765432);
558
559 reliability->processIncomingPacket(pkt1);
560
561 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
562 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
563 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
564
565 lp::Packet pkt2 = makeFrag(276, 40);
566 pkt2.add<lp::TxSequenceField>(234567);
567
568 reliability->processIncomingPacket(pkt2);
569
570 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
571 BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
572 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
573 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
574
575 // T+5ms
576 advanceClocks(time::milliseconds(1), 5);
577 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000578}
579
580BOOST_AUTO_TEST_CASE(PiggybackAcks)
581{
582 reliability->m_ackQueue.push(256);
583 reliability->m_ackQueue.push(257);
584 reliability->m_ackQueue.push(10);
585
586 lp::Packet pkt;
Eric Newberry185ab292017-03-28 06:45:39 +0000587 linkService->sendLpPackets({pkt});
588
589 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
590 lp::Packet sentPkt(transport->sentPackets.front().packet);
591
592 BOOST_REQUIRE_EQUAL(sentPkt.count<lp::AckField>(), 3);
593 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(0), 256);
594 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(1), 257);
595 BOOST_CHECK_EQUAL(sentPkt.get<lp::AckField>(2), 10);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000596 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000597
598 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
599}
600
601BOOST_AUTO_TEST_CASE(PiggybackAcksMtu)
602{
603 // This test case tests for piggybacking Acks when there is an MTU on the link.
604
Eric Newberry7b0071e2017-07-03 17:33:31 +0000605 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000606
Eric Newberry7b0071e2017-07-03 17:33:31 +0000607 for (lp::Sequence i = 1000; i < 2000; i++) {
608 reliability->m_ackQueue.push(i);
609 }
Eric Newberry185ab292017-03-28 06:45:39 +0000610
Eric Newberry7b0071e2017-07-03 17:33:31 +0000611 BOOST_CHECK(!reliability->m_ackQueue.empty());
Eric Newberry185ab292017-03-28 06:45:39 +0000612
Eric Newberry7b0071e2017-07-03 17:33:31 +0000613 for (int i = 0; i < 5; i++) {
614 lp::Packet pkt = makeFrag(i, 60);
615 linkService->sendLpPackets({pkt});
Eric Newberry185ab292017-03-28 06:45:39 +0000616
Eric Newberry7b0071e2017-07-03 17:33:31 +0000617 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), i + 1);
618 lp::Packet sentPkt(transport->sentPackets.back().packet);
619 BOOST_CHECK_EQUAL(getPktNo(sentPkt), i);
620 BOOST_CHECK(sentPkt.has<lp::AckField>());
621 }
Eric Newberry185ab292017-03-28 06:45:39 +0000622
Eric Newberry7b0071e2017-07-03 17:33:31 +0000623 BOOST_CHECK(reliability->m_ackQueue.empty());
624}
Eric Newberry185ab292017-03-28 06:45:39 +0000625
Eric Newberry7b0071e2017-07-03 17:33:31 +0000626BOOST_AUTO_TEST_CASE(PiggybackAcksMtuNoSpace)
627{
628 // This test case tests for piggybacking Acks when there is an MTU on the link, resulting in no
629 // space for Acks (and negative remainingSpace in the piggyback function).
630
631 transport->setMtu(250);
632
633 for (lp::Sequence i = 1000; i < 1100; i++) {
634 reliability->m_ackQueue.push(i);
635 }
636
637 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
638
639 lp::Packet pkt = makeFrag(1, 240);
640 linkService->sendLpPackets({pkt});
641
642 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 100);
Eric Newberry185ab292017-03-28 06:45:39 +0000643
644 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000645 lp::Packet sentPkt(transport->sentPackets.back().packet);
646 BOOST_CHECK_EQUAL(getPktNo(sentPkt), 1);
647 BOOST_CHECK(!sentPkt.has<lp::AckField>());
648}
Eric Newberry185ab292017-03-28 06:45:39 +0000649
Eric Newberry7b0071e2017-07-03 17:33:31 +0000650BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
651{
652 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000653
Eric Newberry7b0071e2017-07-03 17:33:31 +0000654 lp::Packet pkt1 = makeFrag(1, 100);
655 pkt1.add<lp::TxSequenceField>(12);
656 reliability->processIncomingPacket({pkt1});
657 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000658
Eric Newberry7b0071e2017-07-03 17:33:31 +0000659 // T+1ms
660 advanceClocks(time::milliseconds(1), 1);
661 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000662
Eric Newberry7b0071e2017-07-03 17:33:31 +0000663 lp::Packet pkt2 = makeFrag(2, 100);
664 pkt2.add<lp::TxSequenceField>(13);
665 reliability->processIncomingPacket({pkt2});
666 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000667
Eric Newberry7b0071e2017-07-03 17:33:31 +0000668 // T+5ms
669 advanceClocks(time::milliseconds(1), 4);
670 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000671
Eric Newberry7b0071e2017-07-03 17:33:31 +0000672 lp::Packet pkt3 = makeFrag(3, 100);
673 pkt3.add<lp::TxSequenceField>(15);
674 reliability->processIncomingPacket({pkt3});
675 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000676
Eric Newberry7b0071e2017-07-03 17:33:31 +0000677 // T+9ms
678 advanceClocks(time::milliseconds(1), 4);
679 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000680
Eric Newberry7b0071e2017-07-03 17:33:31 +0000681 // T+10ms
682 advanceClocks(time::milliseconds(1), 1);
683 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000684}
685
686BOOST_AUTO_TEST_CASE(IdleAckTimer)
687{
688 // T+1ms
689 advanceClocks(time::milliseconds(1), 1);
690
Eric Newberry7b0071e2017-07-03 17:33:31 +0000691 for (lp::Sequence i = 1000; i < 2000; i++) {
692 reliability->m_ackQueue.push(i);
693 }
694
695 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000696 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
697 reliability->startIdleAckTimer();
698 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
699
700 // T+5ms
701 advanceClocks(time::milliseconds(1), 4);
702 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000703 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
704 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
705 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1999);
Eric Newberry185ab292017-03-28 06:45:39 +0000706 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
707
708 // T+6ms
709 advanceClocks(time::milliseconds(1), 1);
710
711 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000712 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000713 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
714 lp::Packet sentPkt1(transport->sentPackets.back().packet);
715
Eric Newberry7b0071e2017-07-03 17:33:31 +0000716 BOOST_CHECK(!sentPkt1.has<lp::TxSequenceField>());
717 BOOST_CHECK_EQUAL(sentPkt1.count<lp::AckField>(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000718
Eric Newberry7b0071e2017-07-03 17:33:31 +0000719 for (lp::Sequence i = 10000; i < 11000; i++) {
720 reliability->m_ackQueue.push(i);
721 }
722
Eric Newberry185ab292017-03-28 06:45:39 +0000723 reliability->startIdleAckTimer();
724 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000725 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
726 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 10000);
727 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 10999);
Eric Newberry185ab292017-03-28 06:45:39 +0000728
729 // T+10ms
730 advanceClocks(time::milliseconds(1), 4);
731 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
732 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000733 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000734
735 // T+11ms
736 advanceClocks(time::milliseconds(1), 1);
737
738 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000739 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry185ab292017-03-28 06:45:39 +0000740 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
741 lp::Packet sentPkt2(transport->sentPackets.back().packet);
742
Eric Newberry7b0071e2017-07-03 17:33:31 +0000743 BOOST_REQUIRE_EQUAL(sentPkt2.count<lp::AckField>(), 1000);
744 BOOST_CHECK(!sentPkt2.has<lp::TxSequenceField>());
Eric Newberry185ab292017-03-28 06:45:39 +0000745
746 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000747 reliability->startIdleAckTimer();
Eric Newberry185ab292017-03-28 06:45:39 +0000748
749 // T+16ms
750 advanceClocks(time::milliseconds(1), 5);
751
752 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
753 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 2);
754 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
755}
756
757BOOST_AUTO_TEST_CASE(IdleAckTimerMtu)
758{
Eric Newberry7b0071e2017-07-03 17:33:31 +0000759 transport->setMtu(1500);
Eric Newberry185ab292017-03-28 06:45:39 +0000760
761 // T+1ms
762 advanceClocks(time::milliseconds(1), 1);
763
Eric Newberry7b0071e2017-07-03 17:33:31 +0000764 for (lp::Sequence i = 1000; i < 2000; i++) {
765 reliability->m_ackQueue.push(i);
766 }
767
768 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000769 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
770 reliability->startIdleAckTimer();
771 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
772
773 // T+5ms
774 advanceClocks(time::milliseconds(1), 4);
775 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000776 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000777 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
778
779 // T+6ms
780 advanceClocks(time::milliseconds(1), 1);
781
782 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
783
Eric Newberry7b0071e2017-07-03 17:33:31 +0000784 for (lp::Sequence i = 5000; i < 6000; i++) {
785 reliability->m_ackQueue.push(i);
786 }
787
Eric Newberry185ab292017-03-28 06:45:39 +0000788 reliability->startIdleAckTimer();
789 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
790
Eric Newberry7b0071e2017-07-03 17:33:31 +0000791 // given Ack of size 6 and MTU of 1500, 249 Acks/IDLE packet
792 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
793 for (int i = 0; i < 4; i++) {
794 lp::Packet sentPkt(transport->sentPackets[i].packet);
795 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
796 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), 249);
797 }
798 lp::Packet sentPkt(transport->sentPackets[4].packet);
799 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
800 BOOST_CHECK_LE(sentPkt.count<lp::AckField>(), 249);
Eric Newberry185ab292017-03-28 06:45:39 +0000801
Eric Newberry7b0071e2017-07-03 17:33:31 +0000802 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
803 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 5000);
804 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 5999);
Eric Newberry185ab292017-03-28 06:45:39 +0000805
806 // T+10ms
807 advanceClocks(time::milliseconds(1), 4);
808 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000809 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 5);
810 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000811
812 // T+11ms
813 advanceClocks(time::milliseconds(1), 1);
814
815 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
816
Eric Newberry7b0071e2017-07-03 17:33:31 +0000817 for (lp::Sequence i = 100000; i < 101000; i++) {
818 reliability->m_ackQueue.push(i);
819 }
820
Eric Newberry185ab292017-03-28 06:45:39 +0000821 reliability->startIdleAckTimer();
Eric Newberry185ab292017-03-28 06:45:39 +0000822 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry185ab292017-03-28 06:45:39 +0000823
Eric Newberry7b0071e2017-07-03 17:33:31 +0000824 // given Ack of size 6 and MTU of 1500, 249 Acks/IDLE packet
825 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 10);
826 for (int i = 5; i < 9; i++) {
827 lp::Packet sentPkt(transport->sentPackets[i].packet);
828 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
829 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), 249);
830 }
831 sentPkt.wireDecode(transport->sentPackets[9].packet);
832 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
833 BOOST_CHECK_LE(sentPkt.count<lp::AckField>(), 249);
834
835 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
836 BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 100000);
837 BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 100999);
Eric Newberry185ab292017-03-28 06:45:39 +0000838 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
839
840 // T+15ms
841 advanceClocks(time::milliseconds(1), 4);
842 BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000843 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 10);
844 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 1000);
Eric Newberry185ab292017-03-28 06:45:39 +0000845
846 // T+16ms
847 advanceClocks(time::milliseconds(1), 1);
848
Eric Newberry7b0071e2017-07-03 17:33:31 +0000849 // given Ack of size 8 and MTU of 1500, approx 187 Acks/IDLE packet
Eric Newberry185ab292017-03-28 06:45:39 +0000850 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000851 BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 16);
852 for (int i = 10; i < 15; i++) {
853 lp::Packet sentPkt(transport->sentPackets[i].packet);
854 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
855 BOOST_CHECK_EQUAL(sentPkt.count<lp::AckField>(), 187);
856 }
857 sentPkt.wireDecode(transport->sentPackets[15].packet);
858 BOOST_CHECK(!sentPkt.has<lp::TxSequenceField>());
859 BOOST_CHECK_LE(sentPkt.count<lp::AckField>(), 187);
Eric Newberry185ab292017-03-28 06:45:39 +0000860
861 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000862 reliability->startIdleAckTimer();
Eric Newberry185ab292017-03-28 06:45:39 +0000863
864 // T+21ms
865 advanceClocks(time::milliseconds(1), 5);
866
867 BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
Eric Newberry7b0071e2017-07-03 17:33:31 +0000868 BOOST_CHECK_EQUAL(transport->sentPackets.size(), 16);
Eric Newberry185ab292017-03-28 06:45:39 +0000869 BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
870}
871
Eric Newberry7b0071e2017-07-03 17:33:31 +0000872BOOST_AUTO_TEST_SUITE_END() // Receiver
Eric Newberry185ab292017-03-28 06:45:39 +0000873
Eric Newberry7b0071e2017-07-03 17:33:31 +0000874BOOST_AUTO_TEST_SUITE_END() // TestLpReliability
Eric Newberry185ab292017-03-28 06:45:39 +0000875BOOST_AUTO_TEST_SUITE_END() // Face
876
877} // namespace tests
878} // namespace face
879} // namespace nfd