blob: 7681e86a6bec44fd02982393fc8849de49e3a813 [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
31namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070032namespace tests {
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070033
Junxiao Shid9ee45c2014-02-27 15:38:11 -070034BOOST_FIXTURE_TEST_SUITE(FaceNdnlp, BaseFixture)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070035
36BOOST_AUTO_TEST_CASE(SequenceBlock)
37{
38 ndnlp::SequenceBlock sb(0x8000, 2);
39 BOOST_CHECK_EQUAL(sb.count(), 2);
40 BOOST_CHECK_EQUAL(sb[0], 0x8000);
41 BOOST_CHECK_EQUAL(sb[1], 0x8001);
42 BOOST_CHECK_THROW(sb[2], std::out_of_range);
43}
44
45// sequence number can safely wrap around
46BOOST_AUTO_TEST_CASE(SequenceBlockWrap)
47{
48 ndnlp::SequenceBlock sb(std::numeric_limits<uint64_t>::max(), 2);
49 BOOST_CHECK_EQUAL(sb[0], std::numeric_limits<uint64_t>::max());
50 BOOST_CHECK_EQUAL(sb[1], std::numeric_limits<uint64_t>::min());
51 BOOST_CHECK_EQUAL(sb[1] - sb[0], 1);
52}
53
54BOOST_AUTO_TEST_CASE(SequenceGenerator)
55{
56 ndnlp::SequenceGenerator seqgen;
Junxiao Shidf3b4382014-02-23 11:28:21 -070057
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070058 ndnlp::SequenceBlock sb1 = seqgen.nextBlock(2);
59 BOOST_CHECK_EQUAL(sb1.count(), 2);
60
61 ndnlp::SequenceBlock sb2 = seqgen.nextBlock(1);
62 BOOST_CHECK_NE(sb1[0], sb2[0]);
63 BOOST_CHECK_NE(sb1[1], sb2[0]);
64}
65
66// slice a Block to one NDNLP packet
67BOOST_AUTO_TEST_CASE(Slice1)
68{
69 uint8_t blockValue[60];
70 memset(blockValue, 0xcc, sizeof(blockValue));
71 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -070072
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070073 ndnlp::Slicer slicer(9000);
74 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -070075
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070076 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -070077
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070078 const Block& pkt = pa->at(0);
79 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
80 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -070081
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070082 const Block::element_container& elements = pkt.elements();
83 BOOST_REQUIRE_EQUAL(elements.size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -070084
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070085 const Block& sequenceElement = elements[0];
86 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
87 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
Junxiao Shidf3b4382014-02-23 11:28:21 -070088
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070089 const Block& payloadElement = elements[1];
90 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
91 size_t payloadSize = payloadElement.value_size();
92 BOOST_CHECK_EQUAL(payloadSize, block.size());
Junxiao Shidf3b4382014-02-23 11:28:21 -070093
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070094 BOOST_CHECK_EQUAL_COLLECTIONS(payloadElement.value_begin(), payloadElement.value_end(),
95 block.begin(), block.end());
96}
97
98// slice a Block to four NDNLP packets
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070099BOOST_AUTO_TEST_CASE(Slice4)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700100{
101 uint8_t blockValue[5050];
102 memset(blockValue, 0xcc, sizeof(blockValue));
103 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700104
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700105 ndnlp::Slicer slicer(1500);
106 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700107
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700108 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700109
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700110 uint64_t seq0 = 0xdddd;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700111
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700112 size_t totalPayloadSize = 0;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700113
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700114 for (size_t i = 0; i < 4; ++i) {
115 const Block& pkt = pa->at(i);
116 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
117 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -0700118
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700119 const Block::element_container& elements = pkt.elements();
120 BOOST_REQUIRE_EQUAL(elements.size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700121
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700122 const Block& sequenceElement = elements[0];
123 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
124 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
125 uint64_t seq = be64toh(*reinterpret_cast<const uint64_t*>(
126 &*sequenceElement.value_begin()));
127 if (i == 0) {
128 seq0 = seq;
129 }
130 BOOST_CHECK_EQUAL(seq, seq0 + i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700131
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700132 const Block& fragIndexElement = elements[1];
133 BOOST_CHECK_EQUAL(fragIndexElement.type(), static_cast<uint32_t>(tlv::NdnlpFragIndex));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700134 uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700135 BOOST_CHECK_EQUAL(fragIndex, i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700136
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700137 const Block& fragCountElement = elements[2];
138 BOOST_CHECK_EQUAL(fragCountElement.type(), static_cast<uint32_t>(tlv::NdnlpFragCount));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700139 uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700140 BOOST_CHECK_EQUAL(fragCount, 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700141
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700142 const Block& payloadElement = elements[3];
143 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
144 size_t payloadSize = payloadElement.value_size();
145 totalPayloadSize += payloadSize;
146 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700147
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700148 BOOST_CHECK_EQUAL(totalPayloadSize, block.size());
149}
150
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700151class ReassembleFixture : protected BaseFixture
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700152{
153protected:
154 ReassembleFixture()
Junxiao Shi98e29f42014-03-31 10:27:26 -0700155 : m_slicer(1500)
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700156 {
157 m_partialMessageStore.onReceive += bind(&std::vector<Block>::push_back,
158 &m_received, _1);
159 }
160
161 Block
162 makeBlock(size_t valueLength)
163 {
164 uint8_t blockValue[valueLength];
165 memset(blockValue, 0xcc, sizeof(blockValue));
166 return ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
167 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700168
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700169protected:
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700170 ndnlp::Slicer m_slicer;
171 ndnlp::PartialMessageStore m_partialMessageStore;
172
173 // received network layer packets
174 std::vector<Block> m_received;
175};
176
177// reassemble one NDNLP packets into one Block
178BOOST_FIXTURE_TEST_CASE(Reassemble1, ReassembleFixture)
179{
180 Block block = makeBlock(60);
181 ndnlp::PacketArray pa = m_slicer.slice(block);
182 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700183
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700184 BOOST_CHECK_EQUAL(m_received.size(), 0);
185 m_partialMessageStore.receiveNdnlpData(pa->at(0));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700186
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700187 BOOST_REQUIRE_EQUAL(m_received.size(), 1);
188 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
189 block.begin(), block.end());
190}
191
192// reassemble four and two NDNLP packets into two Blocks
193BOOST_FIXTURE_TEST_CASE(Reassemble4and2, ReassembleFixture)
194{
195 Block block = makeBlock(5050);
196 ndnlp::PacketArray pa = m_slicer.slice(block);
197 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700198
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700199 Block block2 = makeBlock(2000);
200 ndnlp::PacketArray pa2 = m_slicer.slice(block2);
201 BOOST_REQUIRE_EQUAL(pa2->size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700202
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700203 BOOST_CHECK_EQUAL(m_received.size(), 0);
204 m_partialMessageStore.receiveNdnlpData(pa->at(0));
205 BOOST_CHECK_EQUAL(m_received.size(), 0);
206 m_partialMessageStore.receiveNdnlpData(pa->at(1));
207 BOOST_CHECK_EQUAL(m_received.size(), 0);
208 m_partialMessageStore.receiveNdnlpData(pa2->at(1));
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(0));
213 BOOST_CHECK_EQUAL(m_received.size(), 1);
214 m_partialMessageStore.receiveNdnlpData(pa->at(3));
215 BOOST_CHECK_EQUAL(m_received.size(), 1);
216 m_partialMessageStore.receiveNdnlpData(pa->at(2));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700217
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700218 BOOST_REQUIRE_EQUAL(m_received.size(), 2);
219 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(1).begin(), m_received.at(1).end(),
220 block.begin(), block.end());
221 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
222 block2.begin(), block2.end());
223}
224
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700225BOOST_AUTO_TEST_SUITE_END()
226
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700227} // namespace tests
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700228} // namespace nfd