blob: f5ba8e11412f95f378db9af0b118cedfd6616980 [file] [log] [blame]
Junxiao Shi9b0d3e92014-02-15 12:27:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070024
25#include "face/ndnlp-sequence-generator.hpp"
26#include "face/ndnlp-slicer.hpp"
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070027#include "face/ndnlp-partial-message-store.hpp"
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070028
Junxiao Shid9ee45c2014-02-27 15:38:11 -070029#include "tests/test-common.hpp"
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070030
Davide Pesavento1bdef282014-04-08 20:59:50 +020031#include <boost/scoped_array.hpp>
32
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070033namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070034namespace tests {
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070035
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036BOOST_FIXTURE_TEST_SUITE(FaceNdnlp, BaseFixture)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070037
38BOOST_AUTO_TEST_CASE(SequenceBlock)
39{
40 ndnlp::SequenceBlock sb(0x8000, 2);
41 BOOST_CHECK_EQUAL(sb.count(), 2);
42 BOOST_CHECK_EQUAL(sb[0], 0x8000);
43 BOOST_CHECK_EQUAL(sb[1], 0x8001);
44 BOOST_CHECK_THROW(sb[2], std::out_of_range);
45}
46
47// sequence number can safely wrap around
48BOOST_AUTO_TEST_CASE(SequenceBlockWrap)
49{
50 ndnlp::SequenceBlock sb(std::numeric_limits<uint64_t>::max(), 2);
51 BOOST_CHECK_EQUAL(sb[0], std::numeric_limits<uint64_t>::max());
52 BOOST_CHECK_EQUAL(sb[1], std::numeric_limits<uint64_t>::min());
53 BOOST_CHECK_EQUAL(sb[1] - sb[0], 1);
54}
55
56BOOST_AUTO_TEST_CASE(SequenceGenerator)
57{
58 ndnlp::SequenceGenerator seqgen;
Junxiao Shidf3b4382014-02-23 11:28:21 -070059
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070060 ndnlp::SequenceBlock sb1 = seqgen.nextBlock(2);
61 BOOST_CHECK_EQUAL(sb1.count(), 2);
62
63 ndnlp::SequenceBlock sb2 = seqgen.nextBlock(1);
64 BOOST_CHECK_NE(sb1[0], sb2[0]);
65 BOOST_CHECK_NE(sb1[1], sb2[0]);
66}
67
68// slice a Block to one NDNLP packet
69BOOST_AUTO_TEST_CASE(Slice1)
70{
71 uint8_t blockValue[60];
72 memset(blockValue, 0xcc, sizeof(blockValue));
73 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -070074
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070075 ndnlp::Slicer slicer(9000);
76 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -070077
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070078 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -070079
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070080 const Block& pkt = pa->at(0);
81 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
82 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -070083
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070084 const Block::element_container& elements = pkt.elements();
85 BOOST_REQUIRE_EQUAL(elements.size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -070086
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070087 const Block& sequenceElement = elements[0];
88 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
89 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
Junxiao Shidf3b4382014-02-23 11:28:21 -070090
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070091 const Block& payloadElement = elements[1];
92 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
93 size_t payloadSize = payloadElement.value_size();
94 BOOST_CHECK_EQUAL(payloadSize, block.size());
Junxiao Shidf3b4382014-02-23 11:28:21 -070095
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070096 BOOST_CHECK_EQUAL_COLLECTIONS(payloadElement.value_begin(), payloadElement.value_end(),
97 block.begin(), block.end());
98}
99
100// slice a Block to four NDNLP packets
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700101BOOST_AUTO_TEST_CASE(Slice4)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700102{
103 uint8_t blockValue[5050];
104 memset(blockValue, 0xcc, sizeof(blockValue));
105 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700106
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700107 ndnlp::Slicer slicer(1500);
108 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700109
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700110 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700111
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700112 uint64_t seq0 = 0xdddd;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700113
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700114 size_t totalPayloadSize = 0;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700115
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700116 for (size_t i = 0; i < 4; ++i) {
117 const Block& pkt = pa->at(i);
118 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
119 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -0700120
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700121 const Block::element_container& elements = pkt.elements();
122 BOOST_REQUIRE_EQUAL(elements.size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700123
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700124 const Block& sequenceElement = elements[0];
125 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
126 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
127 uint64_t seq = be64toh(*reinterpret_cast<const uint64_t*>(
128 &*sequenceElement.value_begin()));
129 if (i == 0) {
130 seq0 = seq;
131 }
132 BOOST_CHECK_EQUAL(seq, seq0 + i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700133
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700134 const Block& fragIndexElement = elements[1];
135 BOOST_CHECK_EQUAL(fragIndexElement.type(), static_cast<uint32_t>(tlv::NdnlpFragIndex));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700136 uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700137 BOOST_CHECK_EQUAL(fragIndex, i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700138
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700139 const Block& fragCountElement = elements[2];
140 BOOST_CHECK_EQUAL(fragCountElement.type(), static_cast<uint32_t>(tlv::NdnlpFragCount));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700141 uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700142 BOOST_CHECK_EQUAL(fragCount, 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700143
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700144 const Block& payloadElement = elements[3];
145 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
146 size_t payloadSize = payloadElement.value_size();
147 totalPayloadSize += payloadSize;
148 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700149
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700150 BOOST_CHECK_EQUAL(totalPayloadSize, block.size());
151}
152
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700153class ReassembleFixture : protected BaseFixture
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700154{
155protected:
156 ReassembleFixture()
Junxiao Shi98e29f42014-03-31 10:27:26 -0700157 : m_slicer(1500)
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700158 {
Davide Pesavento52a18f92014-04-10 00:55:01 +0200159 m_partialMessageStore.onReceive +=
160 // push_back in C++11 has 2 overloads, and specific version needs to be selected
161 bind(static_cast<void (std::vector<Block>::*)(const Block&)>(&std::vector<Block>::push_back),
162 &m_received, _1);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700163 }
164
165 Block
166 makeBlock(size_t valueLength)
167 {
Davide Pesavento1bdef282014-04-08 20:59:50 +0200168 boost::scoped_array<uint8_t> blockValue(new uint8_t[valueLength]);
169 memset(blockValue.get(), 0xcc, valueLength);
170 return ndn::dataBlock(0x01, blockValue.get(), valueLength);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700171 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700172
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700173protected:
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700174 ndnlp::Slicer m_slicer;
175 ndnlp::PartialMessageStore m_partialMessageStore;
176
177 // received network layer packets
178 std::vector<Block> m_received;
179};
180
181// reassemble one NDNLP packets into one Block
182BOOST_FIXTURE_TEST_CASE(Reassemble1, ReassembleFixture)
183{
184 Block block = makeBlock(60);
185 ndnlp::PacketArray pa = m_slicer.slice(block);
186 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700187
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700188 BOOST_CHECK_EQUAL(m_received.size(), 0);
189 m_partialMessageStore.receiveNdnlpData(pa->at(0));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700190
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700191 BOOST_REQUIRE_EQUAL(m_received.size(), 1);
192 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
193 block.begin(), block.end());
194}
195
196// reassemble four and two NDNLP packets into two Blocks
197BOOST_FIXTURE_TEST_CASE(Reassemble4and2, ReassembleFixture)
198{
199 Block block = makeBlock(5050);
200 ndnlp::PacketArray pa = m_slicer.slice(block);
201 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700202
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700203 Block block2 = makeBlock(2000);
204 ndnlp::PacketArray pa2 = m_slicer.slice(block2);
205 BOOST_REQUIRE_EQUAL(pa2->size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700206
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700207 BOOST_CHECK_EQUAL(m_received.size(), 0);
208 m_partialMessageStore.receiveNdnlpData(pa->at(0));
209 BOOST_CHECK_EQUAL(m_received.size(), 0);
210 m_partialMessageStore.receiveNdnlpData(pa->at(1));
211 BOOST_CHECK_EQUAL(m_received.size(), 0);
212 m_partialMessageStore.receiveNdnlpData(pa2->at(1));
213 BOOST_CHECK_EQUAL(m_received.size(), 0);
214 m_partialMessageStore.receiveNdnlpData(pa->at(1));
215 BOOST_CHECK_EQUAL(m_received.size(), 0);
216 m_partialMessageStore.receiveNdnlpData(pa2->at(0));
217 BOOST_CHECK_EQUAL(m_received.size(), 1);
218 m_partialMessageStore.receiveNdnlpData(pa->at(3));
219 BOOST_CHECK_EQUAL(m_received.size(), 1);
220 m_partialMessageStore.receiveNdnlpData(pa->at(2));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700221
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700222 BOOST_REQUIRE_EQUAL(m_received.size(), 2);
223 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(1).begin(), m_received.at(1).end(),
224 block.begin(), block.end());
225 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
226 block2.begin(), block2.end());
227}
228
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700229BOOST_AUTO_TEST_SUITE_END()
230
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700231} // namespace tests
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700232} // namespace nfd