blob: 77e99e29195727f62fe9e47335d020f562dc7c82 [file] [log] [blame]
Junxiao Shi9b0d3e92014-02-15 12:27:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "face/ndnlp-sequence-generator.hpp"
8#include "face/ndnlp-slicer.hpp"
Junxiao Shid6dcd2c2014-02-16 14:49:54 -07009#include "face/ndnlp-partial-message-store.hpp"
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070010
11#include <boost/test/unit_test.hpp>
12
13namespace nfd {
14
15BOOST_AUTO_TEST_SUITE(FaceNdnlp)
16
17BOOST_AUTO_TEST_CASE(SequenceBlock)
18{
19 ndnlp::SequenceBlock sb(0x8000, 2);
20 BOOST_CHECK_EQUAL(sb.count(), 2);
21 BOOST_CHECK_EQUAL(sb[0], 0x8000);
22 BOOST_CHECK_EQUAL(sb[1], 0x8001);
23 BOOST_CHECK_THROW(sb[2], std::out_of_range);
24}
25
26// sequence number can safely wrap around
27BOOST_AUTO_TEST_CASE(SequenceBlockWrap)
28{
29 ndnlp::SequenceBlock sb(std::numeric_limits<uint64_t>::max(), 2);
30 BOOST_CHECK_EQUAL(sb[0], std::numeric_limits<uint64_t>::max());
31 BOOST_CHECK_EQUAL(sb[1], std::numeric_limits<uint64_t>::min());
32 BOOST_CHECK_EQUAL(sb[1] - sb[0], 1);
33}
34
35BOOST_AUTO_TEST_CASE(SequenceGenerator)
36{
37 ndnlp::SequenceGenerator seqgen;
Junxiao Shidf3b4382014-02-23 11:28:21 -070038
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070039 ndnlp::SequenceBlock sb1 = seqgen.nextBlock(2);
40 BOOST_CHECK_EQUAL(sb1.count(), 2);
41
42 ndnlp::SequenceBlock sb2 = seqgen.nextBlock(1);
43 BOOST_CHECK_NE(sb1[0], sb2[0]);
44 BOOST_CHECK_NE(sb1[1], sb2[0]);
45}
46
47// slice a Block to one NDNLP packet
48BOOST_AUTO_TEST_CASE(Slice1)
49{
50 uint8_t blockValue[60];
51 memset(blockValue, 0xcc, sizeof(blockValue));
52 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -070053
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070054 ndnlp::Slicer slicer(9000);
55 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -070056
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070057 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -070058
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070059 const Block& pkt = pa->at(0);
60 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
61 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -070062
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070063 const Block::element_container& elements = pkt.elements();
64 BOOST_REQUIRE_EQUAL(elements.size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -070065
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070066 const Block& sequenceElement = elements[0];
67 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
68 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
Junxiao Shidf3b4382014-02-23 11:28:21 -070069
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070070 const Block& payloadElement = elements[1];
71 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
72 size_t payloadSize = payloadElement.value_size();
73 BOOST_CHECK_EQUAL(payloadSize, block.size());
Junxiao Shidf3b4382014-02-23 11:28:21 -070074
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070075 BOOST_CHECK_EQUAL_COLLECTIONS(payloadElement.value_begin(), payloadElement.value_end(),
76 block.begin(), block.end());
77}
78
79// slice a Block to four NDNLP packets
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070080BOOST_AUTO_TEST_CASE(Slice4)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070081{
82 uint8_t blockValue[5050];
83 memset(blockValue, 0xcc, sizeof(blockValue));
84 Block block = ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
Junxiao Shidf3b4382014-02-23 11:28:21 -070085
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070086 ndnlp::Slicer slicer(1500);
87 ndnlp::PacketArray pa = slicer.slice(block);
Junxiao Shidf3b4382014-02-23 11:28:21 -070088
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070089 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -070090
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070091 uint64_t seq0 = 0xdddd;
Junxiao Shidf3b4382014-02-23 11:28:21 -070092
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070093 size_t totalPayloadSize = 0;
Junxiao Shidf3b4382014-02-23 11:28:21 -070094
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070095 for (size_t i = 0; i < 4; ++i) {
96 const Block& pkt = pa->at(i);
97 BOOST_CHECK_EQUAL(pkt.type(), static_cast<uint32_t>(tlv::NdnlpData));
98 pkt.parse();
Junxiao Shidf3b4382014-02-23 11:28:21 -070099
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700100 const Block::element_container& elements = pkt.elements();
101 BOOST_REQUIRE_EQUAL(elements.size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700102
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700103 const Block& sequenceElement = elements[0];
104 BOOST_CHECK_EQUAL(sequenceElement.type(), static_cast<uint32_t>(tlv::NdnlpSequence));
105 BOOST_REQUIRE_EQUAL(sequenceElement.value_size(), sizeof(uint64_t));
106 uint64_t seq = be64toh(*reinterpret_cast<const uint64_t*>(
107 &*sequenceElement.value_begin()));
108 if (i == 0) {
109 seq0 = seq;
110 }
111 BOOST_CHECK_EQUAL(seq, seq0 + i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700112
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700113 const Block& fragIndexElement = elements[1];
114 BOOST_CHECK_EQUAL(fragIndexElement.type(), static_cast<uint32_t>(tlv::NdnlpFragIndex));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700115 uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700116 BOOST_CHECK_EQUAL(fragIndex, i);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700117
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700118 const Block& fragCountElement = elements[2];
119 BOOST_CHECK_EQUAL(fragCountElement.type(), static_cast<uint32_t>(tlv::NdnlpFragCount));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700120 uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700121 BOOST_CHECK_EQUAL(fragCount, 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700122
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700123 const Block& payloadElement = elements[3];
124 BOOST_CHECK_EQUAL(payloadElement.type(), static_cast<uint32_t>(tlv::NdnlpPayload));
125 size_t payloadSize = payloadElement.value_size();
126 totalPayloadSize += payloadSize;
127 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700128
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700129 BOOST_CHECK_EQUAL(totalPayloadSize, block.size());
130}
131
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700132class ReassembleFixture
133{
134protected:
135 ReassembleFixture()
Junxiao Shic0d05912014-02-17 19:06:21 -0700136 : m_scheduler(m_io)
137 , m_slicer(1500)
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700138 , m_partialMessageStore(m_scheduler)
139 {
140 m_partialMessageStore.onReceive += bind(&std::vector<Block>::push_back,
141 &m_received, _1);
142 }
143
144 Block
145 makeBlock(size_t valueLength)
146 {
147 uint8_t blockValue[valueLength];
148 memset(blockValue, 0xcc, sizeof(blockValue));
149 return ndn::dataBlock(0x01, blockValue, sizeof(blockValue));
150 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700151
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700152protected:
153 boost::asio::io_service m_io;
154 Scheduler m_scheduler;
Junxiao Shidf3b4382014-02-23 11:28:21 -0700155
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700156 ndnlp::Slicer m_slicer;
157 ndnlp::PartialMessageStore m_partialMessageStore;
158
159 // received network layer packets
160 std::vector<Block> m_received;
161};
162
163// reassemble one NDNLP packets into one Block
164BOOST_FIXTURE_TEST_CASE(Reassemble1, ReassembleFixture)
165{
166 Block block = makeBlock(60);
167 ndnlp::PacketArray pa = m_slicer.slice(block);
168 BOOST_REQUIRE_EQUAL(pa->size(), 1);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700169
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700170 BOOST_CHECK_EQUAL(m_received.size(), 0);
171 m_partialMessageStore.receiveNdnlpData(pa->at(0));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700172
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700173 BOOST_REQUIRE_EQUAL(m_received.size(), 1);
174 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
175 block.begin(), block.end());
176}
177
178// reassemble four and two NDNLP packets into two Blocks
179BOOST_FIXTURE_TEST_CASE(Reassemble4and2, ReassembleFixture)
180{
181 Block block = makeBlock(5050);
182 ndnlp::PacketArray pa = m_slicer.slice(block);
183 BOOST_REQUIRE_EQUAL(pa->size(), 4);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700184
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700185 Block block2 = makeBlock(2000);
186 ndnlp::PacketArray pa2 = m_slicer.slice(block2);
187 BOOST_REQUIRE_EQUAL(pa2->size(), 2);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700188
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700189 BOOST_CHECK_EQUAL(m_received.size(), 0);
190 m_partialMessageStore.receiveNdnlpData(pa->at(0));
191 BOOST_CHECK_EQUAL(m_received.size(), 0);
192 m_partialMessageStore.receiveNdnlpData(pa->at(1));
193 BOOST_CHECK_EQUAL(m_received.size(), 0);
194 m_partialMessageStore.receiveNdnlpData(pa2->at(1));
195 BOOST_CHECK_EQUAL(m_received.size(), 0);
196 m_partialMessageStore.receiveNdnlpData(pa->at(1));
197 BOOST_CHECK_EQUAL(m_received.size(), 0);
198 m_partialMessageStore.receiveNdnlpData(pa2->at(0));
199 BOOST_CHECK_EQUAL(m_received.size(), 1);
200 m_partialMessageStore.receiveNdnlpData(pa->at(3));
201 BOOST_CHECK_EQUAL(m_received.size(), 1);
202 m_partialMessageStore.receiveNdnlpData(pa->at(2));
Junxiao Shidf3b4382014-02-23 11:28:21 -0700203
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700204 BOOST_REQUIRE_EQUAL(m_received.size(), 2);
205 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(1).begin(), m_received.at(1).end(),
206 block.begin(), block.end());
207 BOOST_CHECK_EQUAL_COLLECTIONS(m_received.at(0).begin(), m_received.at(0).end(),
208 block2.begin(), block2.end());
209}
210
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700211BOOST_AUTO_TEST_SUITE_END()
212
213} // namespace nfd