blob: 52091d3af114422447f0c4d7779e08a59046c76b [file] [log] [blame]
Junxiao Shi9b0d3e92014-02-15 12:27:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shic099ddb2014-12-25 20:53:20 -070024 */
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070025
26#include "face/ndnlp-sequence-generator.hpp"
27#include "face/ndnlp-slicer.hpp"
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070028#include "face/ndnlp-partial-message-store.hpp"
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070029
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030#include "tests/test-common.hpp"
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070031
Davide Pesavento1bdef282014-04-08 20:59:50 +020032#include <boost/scoped_array.hpp>
33
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070034namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070035namespace tests {
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070036
Junxiao Shid9ee45c2014-02-27 15:38:11 -070037BOOST_FIXTURE_TEST_SUITE(FaceNdnlp, BaseFixture)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070038
39BOOST_AUTO_TEST_CASE(SequenceBlock)
40{
41 ndnlp::SequenceBlock sb(0x8000, 2);
42 BOOST_CHECK_EQUAL(sb.count(), 2);
43 BOOST_CHECK_EQUAL(sb[0], 0x8000);
44 BOOST_CHECK_EQUAL(sb[1], 0x8001);
45 BOOST_CHECK_THROW(sb[2], std::out_of_range);
46}
47
48// sequence number can safely wrap around
49BOOST_AUTO_TEST_CASE(SequenceBlockWrap)
50{
51 ndnlp::SequenceBlock sb(std::numeric_limits<uint64_t>::max(), 2);
52 BOOST_CHECK_EQUAL(sb[0], std::numeric_limits<uint64_t>::max());
53 BOOST_CHECK_EQUAL(sb[1], std::numeric_limits<uint64_t>::min());
54 BOOST_CHECK_EQUAL(sb[1] - sb[0], 1);
55}
56
57BOOST_AUTO_TEST_CASE(SequenceGenerator)
58{
59 ndnlp::SequenceGenerator seqgen;
Junxiao Shidf3b4382014-02-23 11:28:21 -070060
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070061 ndnlp::SequenceBlock sb1 = seqgen.nextBlock(2);
62 BOOST_CHECK_EQUAL(sb1.count(), 2);
63
64 ndnlp::SequenceBlock sb2 = seqgen.nextBlock(1);
65 BOOST_CHECK_NE(sb1[0], sb2[0]);
66 BOOST_CHECK_NE(sb1[1], sb2[0]);
67}
68
Junxiao Shia37405d2015-01-26 10:50:58 -070069// slice a Block to one fragment
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070070BOOST_AUTO_TEST_CASE(Slice1)
71{
72 uint8_t blockValue[60];
73 memset(blockValue, 0xcc, sizeof(blockValue));
74 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -070075
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070076 ndnlp::Slicer slicer(9000);
77 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -070078
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070079 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -070080
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070081 const Block& pkt = pa->at(0);
82 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
83 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -070084
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070085 const Block::element_container& elements = pkt.elements();
86 BOOST_REQUIRE_EQUAL(elements.size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -070087
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070088 const Block& sequenceElement = elements[0];
89 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
90 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
Junxiao Shidf3b4382014-02-23 11:28:21 -070091
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070092 const Block& payloadElement = elements[1];
93 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
94 size_t payloadSize = payloadElement.value_size();
95 BOOST_CHECK_EQUAL(payloadSize, block.size());
Junxiao Shidf3b4382014-02-23 11:28:21 -070096
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070097 BOOST_CHECK_EQUAL_COLLECTIONS(payloadElement.value_begin(), payloadElement.value_end(),
98 block.begin(), block.end());
99}
100
Junxiao Shia37405d2015-01-26 10:50:58 -0700101// slice a Block to four fragments
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700102BOOST_AUTO_TEST_CASE(Slice4)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700103{
104 uint8_t blockValue[5050];
105 memset(blockValue, 0xcc, sizeof(blockValue));
106 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700107
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700108 ndnlp::Slicer slicer(1500);
109 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700110
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700111 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700112
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700113 uint64_t seq0 = 0xdddd;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700114
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700115 size_t totalPayloadSize = 0;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700116
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700117 for (size_t i = 0; i < 4; ++i) {
118 const Block& pkt = pa->at(i);
119 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
120 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -0700121
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700122 const Block::element_container& elements = pkt.elements();
123 BOOST_REQUIRE_EQUAL(elements.size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700124
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700125 const Block& sequenceElement = elements[0];
126 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
127 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
128 uint64_t seq = be64toh(*reinterpret_cast<const uint64_t*>(
129 &*sequenceElement.value_begin()));
130 if (i == 0) {
131 seq0 = seq;
132 }
133 BOOST_CHECK_EQUAL(seq, seq0 + i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700134
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700135 const Block& fragIndexElement = elements[1];
136 BOOST_CHECK_EQUAL(fragIndexElement.type(), static_cast<uint32_t>(tlv::NdnlpFragIndex));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700137 uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700138 BOOST_CHECK_EQUAL(fragIndex, i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700139
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700140 const Block& fragCountElement = elements[2];
141 BOOST_CHECK_EQUAL(fragCountElement.type(), static_cast<uint32_t>(tlv::NdnlpFragCount));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700142 uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700143 BOOST_CHECK_EQUAL(fragCount, 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700144
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700145 const Block& payloadElement = elements[3];
146 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
147 size_t payloadSize = payloadElement.value_size();
148 totalPayloadSize += payloadSize;
149 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700150
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700151 BOOST_CHECK_EQUAL(totalPayloadSize, block.size());
152}
153
Junxiao Shia37405d2015-01-26 10:50:58 -0700154class ReassembleFixture : protected UnitTestTimeFixture
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700155{
156protected:
157 ReassembleFixture()
Junxiao Shia37405d2015-01-26 10:50:58 -0700158 : slicer(1500)
159 , pms(time::milliseconds(100))
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700160 {
Junxiao Shia37405d2015-01-26 10:50:58 -0700161 pms.onReceive.connect([this] (const Block& block) {
162 received.push_back(block);
Junxiao Shic099ddb2014-12-25 20:53:20 -0700163 });
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700164 }
165
166 Block
167 makeBlock(size_t valueLength)
168 {
Davide Pesavento1bdef282014-04-08 20:59:50 +0200169 boost::scoped_array<uint8_t> blockValue(new uint8_t[valueLength]);
170 memset(blockValue.get(), 0xcc, valueLength);
171 return ndn::dataBlock(0x01, blockValue.get(), valueLength);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700172 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700173
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700174protected:
Junxiao Shia37405d2015-01-26 10:50:58 -0700175 ndnlp::Slicer slicer;
176 ndnlp::PartialMessageStore pms;
177
178 static const time::nanoseconds IDLE_DURATION;
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700179
180 // received network layer packets
Junxiao Shia37405d2015-01-26 10:50:58 -0700181 std::vector<Block> received;
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700182};
183
Junxiao Shia37405d2015-01-26 10:50:58 -0700184// reassemble one fragment into one Block
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700185BOOST_FIXTURE_TEST_CASE(Reassemble1, ReassembleFixture)
186{
187 Block block = makeBlock(60);
Junxiao Shia37405d2015-01-26 10:50:58 -0700188 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700189 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700190
Junxiao Shia37405d2015-01-26 10:50:58 -0700191 BOOST_CHECK_EQUAL(received.size(), 0);
192 pms.receiveNdnlpData(pa->at(0));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700193
Junxiao Shia37405d2015-01-26 10:50:58 -0700194 BOOST_REQUIRE_EQUAL(received.size(), 1);
195 BOOST_CHECK_EQUAL_COLLECTIONS(received.at(0).begin(), received.at(0).end(),
196 block.begin(), block.end());
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700197}
198
Junxiao Shia37405d2015-01-26 10:50:58 -0700199// reassemble four and two fragments into two Blocks
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700200BOOST_FIXTURE_TEST_CASE(Reassemble4and2, ReassembleFixture)
201{
202 Block block = makeBlock(5050);
Junxiao Shia37405d2015-01-26 10:50:58 -0700203 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700204 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700205
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700206 Block block2 = makeBlock(2000);
Junxiao Shia37405d2015-01-26 10:50:58 -0700207 ndnlp::PacketArray pa2 = slicer.slice(block2);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700208 BOOST_REQUIRE_EQUAL(pa2->size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700209
Junxiao Shia37405d2015-01-26 10:50:58 -0700210 BOOST_CHECK_EQUAL(received.size(), 0);
211 pms.receiveNdnlpData(pa->at(0));
212 BOOST_CHECK_EQUAL(received.size(), 0);
213 this->advanceClocks(time::milliseconds(40));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700214
Junxiao Shia37405d2015-01-26 10:50:58 -0700215 pms.receiveNdnlpData(pa->at(1));
216 BOOST_CHECK_EQUAL(received.size(), 0);
217 this->advanceClocks(time::milliseconds(40));
218
219 pms.receiveNdnlpData(pa2->at(1));
220 BOOST_CHECK_EQUAL(received.size(), 0);
221 this->advanceClocks(time::milliseconds(40));
222
223 pms.receiveNdnlpData(pa->at(1));
224 BOOST_CHECK_EQUAL(received.size(), 0);
225 this->advanceClocks(time::milliseconds(40));
226
227 pms.receiveNdnlpData(pa2->at(0));
228 BOOST_CHECK_EQUAL(received.size(), 1);
229 this->advanceClocks(time::milliseconds(40));
230
231 pms.receiveNdnlpData(pa->at(3));
232 BOOST_CHECK_EQUAL(received.size(), 1);
233 this->advanceClocks(time::milliseconds(40));
234
235 pms.receiveNdnlpData(pa->at(2));
236
237 BOOST_REQUIRE_EQUAL(received.size(), 2);
238 BOOST_CHECK_EQUAL_COLLECTIONS(received.at(1).begin(), received.at(1).end(),
239 block.begin(), block.end());
240 BOOST_CHECK_EQUAL_COLLECTIONS(received.at(0).begin(), received.at(0).end(),
241 block2.begin(), block2.end());
242}
243
244// reassemble four fragments into one Block, but another two fragments are expired
245BOOST_FIXTURE_TEST_CASE(ReassembleTimeout, ReassembleFixture)
246{
247 Block block = makeBlock(5050);
248 ndnlp::PacketArray pa = slicer.slice(block);
249 BOOST_REQUIRE_EQUAL(pa->size(), 4);
250
251 Block block2 = makeBlock(2000);
252 ndnlp::PacketArray pa2 = slicer.slice(block2);
253 BOOST_REQUIRE_EQUAL(pa2->size(), 2);
254
255 BOOST_CHECK_EQUAL(received.size(), 0);
256 pms.receiveNdnlpData(pa->at(0));
257 BOOST_CHECK_EQUAL(received.size(), 0);
258 this->advanceClocks(time::milliseconds(40));
259
260 pms.receiveNdnlpData(pa->at(1));
261 BOOST_CHECK_EQUAL(received.size(), 0);
262 this->advanceClocks(time::milliseconds(40));
263
264 pms.receiveNdnlpData(pa2->at(1));
265 BOOST_CHECK_EQUAL(received.size(), 0);
266 this->advanceClocks(time::milliseconds(40));
267
268 pms.receiveNdnlpData(pa->at(1));
269 BOOST_CHECK_EQUAL(received.size(), 0);
270 this->advanceClocks(time::milliseconds(40));
271
272 pms.receiveNdnlpData(pa->at(3));
273 BOOST_CHECK_EQUAL(received.size(), 0);
274 this->advanceClocks(time::milliseconds(40));
275
276 pms.receiveNdnlpData(pa->at(2));
277 BOOST_CHECK_EQUAL(received.size(), 1);
278 this->advanceClocks(time::milliseconds(40));
279
280 pms.receiveNdnlpData(pa2->at(0)); // last fragment was received 160ms ago, expired
281 BOOST_CHECK_EQUAL(received.size(), 1);
282 this->advanceClocks(time::milliseconds(40));
283
284 BOOST_REQUIRE_EQUAL(received.size(), 1);
285 BOOST_CHECK_EQUAL_COLLECTIONS(received.at(0).begin(), received.at(0).end(),
286 block.begin(), block.end());
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700287}
288
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700289BOOST_AUTO_TEST_SUITE_END()
290
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700291} // namespace tests
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700292} // namespace nfd