blob: f5322144cfe8c9bc1ca3cfbd2daaaee1bc17a8f7 [file] [log] [blame]
Eric Newberry261dbc22015-07-22 23:18:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2015 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "lp/packet.hpp"
23
24#include "boost-test.hpp"
25
26namespace ndn {
27namespace lp {
28namespace tests {
29
30BOOST_AUTO_TEST_SUITE(LpPacket)
31
32BOOST_AUTO_TEST_CASE(FieldAccess)
33{
34 Packet packet;
35
36 BOOST_CHECK(!packet.has<FragIndexField>());
37 BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
38 BOOST_CHECK_NO_THROW(packet.set<FragIndexField>(1234));
39 BOOST_CHECK(packet.has<FragIndexField>());
40 BOOST_CHECK_THROW(packet.add<FragIndexField>(5678), std::length_error);
41 BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
42 BOOST_CHECK_EQUAL(1234, packet.get<FragIndexField>(0));
43 BOOST_CHECK_THROW(packet.get<FragIndexField>(1), std::out_of_range);
44 BOOST_CHECK_THROW(packet.remove<FragIndexField>(1), std::out_of_range);
45 BOOST_CHECK_NO_THROW(packet.remove<FragIndexField>(0));
46 BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
47 BOOST_CHECK_NO_THROW(packet.add<FragIndexField>(832));
48 std::vector<uint64_t> fragIndexes;
49 BOOST_REQUIRE_NO_THROW(fragIndexes = packet.list<FragIndexField>());
50 BOOST_CHECK_EQUAL(1, fragIndexes.size());
51 BOOST_CHECK_EQUAL(832, fragIndexes.at(0));
52 BOOST_CHECK_NO_THROW(packet.clear<FragIndexField>());
53 BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
54}
55
56/// \todo test field access methods with a REPEATABLE field
57
58BOOST_AUTO_TEST_CASE(EncodeFragment)
59{
60 static const uint8_t expectedBlock[] = {
61 0x64, 0x04, // LpPacket
62 0x50, 0x02, // Fragment
63 0x03, 0xe8,
64 };
65
66 Buffer buf(2);
67 buf[0] = 0x03;
68 buf[1] = 0xe8;
69
70 Packet packet;
71 BOOST_CHECK_NO_THROW(packet.add<FragmentField>(std::make_pair(buf.begin(), buf.end())));
72 Block wire;
73 BOOST_REQUIRE_NO_THROW(wire = packet.wireEncode());
74 BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
75 wire.begin(), wire.end());
76}
77
78BOOST_AUTO_TEST_CASE(EncodeSubTlv)
79{
80 static const uint8_t expectedBlock[] = {
81 0x64, 0x09, // LpPacket
82 0xfd, 0x03, 0x20, 0x05, // Nack
83 0xfd, 0x03, 0x21, 0x01, // NackReason
84 0x64,
85 };
86
87 NackHeader nack;
88 nack.setReason(NackReason::DUPLICATE);
89
90 Packet packet;
91 BOOST_CHECK_NO_THROW(packet.add<NackField>(nack));
92 Block wire;
93 BOOST_REQUIRE_NO_THROW(wire = packet.wireEncode());
94 BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
95 wire.begin(), wire.end());
96}
97
98BOOST_AUTO_TEST_CASE(EncodeSortOrder)
99{
100 static const uint8_t expectedBlock[] = {
101 0x64, 0x0a, // LpPacket
102 0x52, 0x01, // FragIndex
103 0x00,
104 0x53, 0x01, // FragCount
105 0x01,
106 0x50, 0x02, // Fragment
107 0x03, 0xe8,
108 };
109
110 Buffer frag(2);
111 frag[0] = 0x03;
112 frag[1] = 0xe8;
113
114 Packet packet;
115 BOOST_CHECK_NO_THROW(packet.add<FragmentField>(std::make_pair(frag.begin(), frag.end())));
116 BOOST_CHECK_NO_THROW(packet.add<FragIndexField>(0));
117 BOOST_CHECK_NO_THROW(packet.add<FragCountField>(1));
118 Block wire;
119 BOOST_REQUIRE_NO_THROW(wire = packet.wireEncode());
120 BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
121 wire.begin(), wire.end());
122}
123
124BOOST_AUTO_TEST_CASE(DecodeNormal)
125{
126 static const uint8_t inputBlock[] = {
127 0x64, 0x0a, // LpPacket
128 0x52, 0x01, // FragIndex
129 0x00,
130 0x53, 0x01, // FragCount
131 0x01,
132 0x50, 0x02, // Fragment
133 0x03, 0xe8,
134 };
135
136 Packet packet;
137 Block wire(inputBlock, sizeof(inputBlock));
138 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
139 BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
140 BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
141 BOOST_CHECK_EQUAL(1, packet.count<FragCountField>());
142 Buffer::const_iterator first, last;
143 BOOST_REQUIRE_NO_THROW(std::tie(first, last) = packet.get<FragmentField>(0));
144 BOOST_CHECK_EQUAL(2, last - first);
145 BOOST_CHECK_EQUAL(0x03, *first);
146 BOOST_CHECK_EQUAL(0xe8, *(last - 1));
147 BOOST_CHECK_EQUAL(0, packet.get<FragIndexField>(0));
148 BOOST_CHECK_EQUAL(1, packet.get<FragCountField>(0));
149}
150
151BOOST_AUTO_TEST_CASE(DecodeIdle)
152{
153 static const uint8_t inputBlock[] = {
154 0x64, 0x06, // LpPacket
155 0x52, 0x01, // FragIndex
156 0x00,
157 0x53, 0x01, // FragCount
158 0x01,
159 };
160
161 Packet packet;
162 Block wire(inputBlock, sizeof(inputBlock));
163 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
164 BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
165 BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
166 BOOST_CHECK_EQUAL(1, packet.count<FragCountField>());
167 BOOST_CHECK_EQUAL(0, packet.get<FragIndexField>(0));
168 BOOST_CHECK_EQUAL(1, packet.get<FragCountField>(0));
169}
170
171BOOST_AUTO_TEST_CASE(DecodeFragment)
172{
173 static const uint8_t inputBlock[] = {
174 0x64, 0x04, // LpPacket
175 0x50, 0x02, // Fragment
176 0x03, 0xe8,
177 };
178
179 Packet packet;
180 Block wire(inputBlock, sizeof(inputBlock));
181 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
182 BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
183 BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
184 Buffer::const_iterator first, last;
185 BOOST_REQUIRE_NO_THROW(std::tie(first, last) = packet.get<FragmentField>(0));
186 BOOST_CHECK_EQUAL(2, last - first);
187 BOOST_CHECK_EQUAL(0x03, *first);
188 BOOST_CHECK_EQUAL(0xe8, *(last - 1));
189}
190
191BOOST_AUTO_TEST_CASE(DecodeEmpty)
192{
193 static const uint8_t inputBlock[] = {
194 0x64, 0x00, // LpPacket
195 };
196
197 Packet packet;
198 Block wire(inputBlock, sizeof(inputBlock));
199 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
200 BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
201 BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
202}
203
204BOOST_AUTO_TEST_CASE(DecodeRepeatedNonRepeatableHeader)
205{
206 static const uint8_t inputBlock[] = {
207 0x64, 0x06, // LpPacket
208 0x52, 0x01, // FragIndex
209 0x00,
210 0x52, 0x01, // FragIndex
211 0x01,
212 };
213
214 Packet packet;
215 Block wire(inputBlock, sizeof(inputBlock));
216 BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
217}
218
219BOOST_AUTO_TEST_CASE(DecodeRepeatedFragment)
220{
221 static const uint8_t inputBlock[] = {
222 0x64, 0x08, // LpPacket
223 0x50, 0x02, // Fragment
224 0x03, 0xe8,
225 0x50, 0x02, // Fragment
226 0x03, 0xe9,
227 };
228
229 Packet packet;
230 Block wire(inputBlock, sizeof(inputBlock));
231 BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
232}
233
234BOOST_AUTO_TEST_CASE(DecodeWrongOrderAmongHeaders)
235{
236 static const uint8_t inputBlock[] = {
237 0x64, 0x0a, // LpPacket
238 0x53, 0x01, // FragCount
239 0x01,
240 0x52, 0x01, // FragIndex
241 0x00,
242 0x50, 0x02, // Fragment
243 0x03, 0xe8,
244 };
245
246 Packet packet;
247 Block wire(inputBlock, sizeof(inputBlock));
248 BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
249}
250
251BOOST_AUTO_TEST_CASE(DecodeWrongOrderFragment)
252{
253 static const uint8_t inputBlock[] = {
254 0x64, 0x0a, // LpPacket
255 0x52, 0x01, // FragIndex
256 0x00,
257 0x50, 0x02, // Fragment
258 0x03, 0xe8,
259 0x53, 0x01, // FragCount
260 0x01,
261 };
262
263 Packet packet;
264 Block wire(inputBlock, sizeof(inputBlock));
265 BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
266}
267
268BOOST_AUTO_TEST_CASE(DecodeIgnoredHeader)
269{
270 static const uint8_t inputBlock[] = {
271 0x64, 0x0c, // LpPacket
272 0x52, 0x01, // FragIndex
273 0x00,
274 0xfd, 0x03, 0x23, 0x01, // unknown TLV-TYPE 803 (ignored)
275 0x02,
276 0x50, 0x02, // Fragment
277 0x03, 0xe8,
278 };
279
280 Packet packet;
281 Block wire(inputBlock, sizeof(inputBlock));
282 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
283 BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
284 BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
285}
286
287BOOST_AUTO_TEST_CASE(DecodeUnrecognizedHeader)
288{
289 static const uint8_t inputBlock[] = {
290 0x64, 0x0c, // LpPacket
291 0x52, 0x01, // FragIndex
292 0x00,
293 0xfd, 0x03, 0x22, 0x01, // unknown TLV-TYPE 802 (cannot ignore)
294 0x02,
295 0x50, 0x02, // Fragment
296 0x03, 0xe8,
297 };
298
299 Packet packet;
300 Block wire(inputBlock, sizeof(inputBlock));
301 BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
302}
303
304BOOST_AUTO_TEST_CASE(DecodeBareNetworkLayerPacket)
305{
306 static const uint8_t inputBlock[] = {
307 0x05, 0x0a, // Interest
308 0x07, 0x02, // Name
309 0x03, 0xe8,
310 0x0a, 0x04, // Nonce
311 0x01, 0x02, 0x03, 0x04,
312 };
313
314 Packet packet;
315 Block wire(inputBlock, sizeof(inputBlock));
316 BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
317 BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
318
319 static const uint8_t expectedBlock[] = {
320 0x64, 0x0e, // LpPacket
321 0x50, 0x0c, // Fragment
322 0x05, 0x0a, // Interest
323 0x07, 0x02, // Name
324 0x03, 0xe8,
325 0x0a, 0x04, // Nonce
326 0x01, 0x02, 0x03, 0x04,
327 };
328
329 Block encoded;
330 BOOST_CHECK_NO_THROW(encoded = packet.wireEncode());
331 BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
332 encoded.begin(), encoded.end());
333}
334
335BOOST_AUTO_TEST_SUITE_END()
336
337} // namespace tests
338} // namespace lp
339} // namespace ndn