blob: b9577cbbb36399b5de3af3df22c60c93e3d81b74 [file] [log] [blame]
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shic542f632017-07-18 14:20:32 +00002/*
Alexander Afanasyev70244f42017-01-04 12:47:12 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07004 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07006 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07007 * 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.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070010 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -070011 * 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.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070014 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -070015 * 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.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070020 */
21
22#include "mgmt/dispatcher.hpp"
Junxiao Shi7357ef22016-09-07 02:39:37 +000023#include "mgmt/nfd/control-parameters.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070024#include "util/dummy-client-face.hpp"
25
26#include "boost-test.hpp"
Junxiao Shi2bea5c42017-08-14 20:10:32 +000027#include "make-interest-data.hpp"
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070028#include "../identity-management-time-fixture.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070029
30namespace ndn {
31namespace mgmt {
32namespace tests {
33
34using namespace ndn::tests;
35
Alexander Afanasyev80782e02017-01-04 13:16:54 -080036class DispatcherFixture : public IdentityManagementTimeFixture
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070037{
38public:
39 DispatcherFixture()
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070040 : face(io, m_keyChain, {true, true})
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080041 , dispatcher(face, m_keyChain, security::SigningInfo())
Yanbiao Li4b4f7542016-03-11 02:04:43 +080042 , storage(dispatcher.m_storage)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070043 {
44 }
45
46public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080047 util::DummyClientFace face;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070048 mgmt::Dispatcher dispatcher;
Junxiao Shic542f632017-07-18 14:20:32 +000049 InMemoryStorageFifo& storage;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070050};
51
52class VoidParameters : public mgmt::ControlParameters
53{
54public:
55 explicit
56 VoidParameters(const Block& wire)
57 {
58 wireDecode(wire);
59 }
60
Junxiao Shid97c9532017-04-27 16:17:04 +000061 Block
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020062 wireEncode() const final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070063 {
64 return Block(128);
65 }
66
Junxiao Shid97c9532017-04-27 16:17:04 +000067 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020068 wireDecode(const Block& wire) final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070069 {
70 if (wire.type() != 128)
Junxiao Shid97c9532017-04-27 16:17:04 +000071 BOOST_THROW_EXCEPTION(tlv::Error("Expecting TLV type 128"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070072 }
73};
74
75static Authorization
76makeTestAuthorization()
77{
78 return [] (const Name& prefix,
79 const Interest& interest,
80 const ControlParameters* params,
81 AcceptContinuation accept,
82 RejectContinuation reject) {
83 if (interest.getName()[-1] == name::Component("valid")) {
84 accept("");
85 }
86 else {
87 if (interest.getName()[-1] == name::Component("silent")) {
88 reject(RejectReply::SILENT);
89 }
90 else {
91 reject(RejectReply::STATUS403);
92 }
93 }
94 };
95}
96
Junxiao Shid97c9532017-04-27 16:17:04 +000097BOOST_AUTO_TEST_SUITE(Mgmt)
98BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
99
100BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700101{
102 BOOST_CHECK_NO_THROW(dispatcher
103 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
104 bind([] { return true; }),
105 bind([]{})));
106 BOOST_CHECK_NO_THROW(dispatcher
107 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
108 bind([] { return true; }),
109 bind([]{})));
110
111 BOOST_CHECK_THROW(dispatcher
112 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
113 bind([] { return true; }),
114 bind([]{})),
115 std::out_of_range);
116
117 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
118 makeAcceptAllAuthorization(), bind([]{})));
119 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
120 makeAcceptAllAuthorization(), bind([]{})));
121 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
122 makeAcceptAllAuthorization(), bind([]{})),
123 std::out_of_range);
124
125 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
126 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
127 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
128
129
130 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
131 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
132 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
133
134 BOOST_CHECK_THROW(dispatcher
135 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
136 bind([] { return true; }),
137 bind([]{})),
138 std::domain_error);
139
140 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
141 makeAcceptAllAuthorization(), bind([]{})),
142 std::domain_error);
143
144 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
145}
146
Junxiao Shid97c9532017-04-27 16:17:04 +0000147BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700148{
149 std::map<std::string, size_t> nCallbackCalled;
150 dispatcher
151 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
152 bind([] { return true; }),
153 bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
154
155 dispatcher
156 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
157 bind([] { return true; }),
158 bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
159
Junxiao Shi85d90832016-08-04 03:19:46 +0000160 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700161 advanceClocks(time::milliseconds(1));
162 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
163 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
164
165 dispatcher.addTopPrefix("/root/1");
166 advanceClocks(time::milliseconds(1));
167
Junxiao Shi85d90832016-08-04 03:19:46 +0000168 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700169 advanceClocks(time::milliseconds(1));
170 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
171 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
172
Junxiao Shi85d90832016-08-04 03:19:46 +0000173 face.receive(*makeInterest("/root/1/test/2/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700174 advanceClocks(time::milliseconds(1));
175 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
176 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
177
Junxiao Shi85d90832016-08-04 03:19:46 +0000178 face.receive(*makeInterest("/root/2/test/1/%80%00"));
179 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700180 advanceClocks(time::milliseconds(1));
181 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
182 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
183
184 dispatcher.addTopPrefix("/root/2");
185 advanceClocks(time::milliseconds(1));
186
Junxiao Shi85d90832016-08-04 03:19:46 +0000187 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700188 advanceClocks(time::milliseconds(1));
189 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
190
Junxiao Shi85d90832016-08-04 03:19:46 +0000191 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700192 advanceClocks(time::milliseconds(1));
193 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
194
195 dispatcher.removeTopPrefix("/root/1");
196 advanceClocks(time::milliseconds(1));
197
Junxiao Shi85d90832016-08-04 03:19:46 +0000198 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700199 advanceClocks(time::milliseconds(1));
200 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
201
Junxiao Shi85d90832016-08-04 03:19:46 +0000202 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700203 advanceClocks(time::milliseconds(1));
204 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
205}
206
Junxiao Shid97c9532017-04-27 16:17:04 +0000207BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700208{
209 size_t nCallbackCalled = 0;
210 dispatcher
211 .addControlCommand<VoidParameters>("test",
212 makeTestAuthorization(),
213 bind([] { return true; }),
214 bind([&nCallbackCalled] { ++nCallbackCalled; }));
215
216 dispatcher.addTopPrefix("/root");
217 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800218 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700219
Junxiao Shi85d90832016-08-04 03:19:46 +0000220 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
221 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
222 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
223 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
224 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700225 advanceClocks(time::milliseconds(1), 20);
226 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800227 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700228
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800229 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Blob);
230 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
231 BOOST_CHECK(face.sentData[1].getContentType() == tlv::ContentType_Blob);
232 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700233
Junxiao Shi85d90832016-08-04 03:19:46 +0000234 face.receive(*makeInterest("/root/test/%80%00/valid"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700235 advanceClocks(time::milliseconds(1), 10);
236 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
237}
238
Junxiao Shid97c9532017-04-27 16:17:04 +0000239class StatefulParameters : public mgmt::ControlParameters
240{
241public:
242 explicit
243 StatefulParameters(const Block& wire)
244 {
245 wireDecode(wire);
246 }
247
248 Block
249 wireEncode() const final
250 {
251 return Block();
252 }
253
254 void
255 wireDecode(const Block& wire) final
256 {
257 m_state = EXPECTED_STATE;
258 }
259
260 bool
261 check() const
262 {
263 return m_state == EXPECTED_STATE;
264 }
265
266private:
267 static constexpr int EXPECTED_STATE = 12602;
268 int m_state = 0;
269};
270
271BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
272{
273 AcceptContinuation authorizationAccept;
274 auto authorization =
275 [&authorizationAccept] (const Name& prefix, const Interest& interest, const ControlParameters* params,
276 AcceptContinuation accept, RejectContinuation reject) {
277 authorizationAccept = accept;
278 };
279
280 auto validateParameters =
281 [] (const ControlParameters& params) {
282 return dynamic_cast<const StatefulParameters&>(params).check();
283 };
284
285 size_t nCallbackCalled = 0;
286 dispatcher
287 .addControlCommand<StatefulParameters>("test",
288 authorization,
289 validateParameters,
290 bind([&nCallbackCalled] { ++nCallbackCalled; }));
291
292 dispatcher.addTopPrefix("/root");
293 advanceClocks(time::milliseconds(1));
294
295 face.receive(*makeInterest("/root/test/%80%00"));
296 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
297 BOOST_REQUIRE(authorizationAccept != nullptr);
298
299 advanceClocks(time::milliseconds(1));
300 authorizationAccept("");
301 advanceClocks(time::milliseconds(1));
302 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
303}
304
305BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700306{
307 static Block smallBlock("\x81\x01\0x01", 3);
308 static Block largeBlock = [] () -> Block {
309 EncodingBuffer encoder;
310 for (size_t i = 0; i < 2500; ++i) {
311 encoder.prependByte(1);
312 }
313 encoder.prependVarNumber(2500);
314 encoder.prependVarNumber(129);
315 return encoder.block();
316 }();
317
318 dispatcher.addStatusDataset("test/small",
319 makeTestAuthorization(),
320 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700321 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700322 context.append(smallBlock);
323 context.append(smallBlock);
324 context.append(smallBlock);
325 context.end();
326 });
327
328 dispatcher.addStatusDataset("test/large",
329 makeTestAuthorization(),
330 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700331 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700332 context.append(largeBlock);
333 context.append(largeBlock);
334 context.append(largeBlock);
335 context.end();
336 });
337
338 dispatcher.addStatusDataset("test/reject",
339 makeTestAuthorization(),
340 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700341 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700342 context.reject();
343 });
344
345 dispatcher.addTopPrefix("/root");
346 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800347 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700348
Junxiao Shi85d90832016-08-04 03:19:46 +0000349 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
350 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
351 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700352 advanceClocks(time::milliseconds(1), 20);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800353 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700354
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800355 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Blob);
356 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
357 BOOST_CHECK(face.sentData[1].getContentType() == tlv::ContentType_Blob);
358 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700359
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800360 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800361
Junxiao Shi85d90832016-08-04 03:19:46 +0000362 auto interestSmall = *makeInterest("/root/test/small/valid");
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800363 face.receive(interestSmall);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700364 advanceClocks(time::milliseconds(1), 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800365
366 // one data packet is generated and sent to both places
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800367 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800368 BOOST_CHECK_EQUAL(storage.size(), 1);
369
370 auto fetchedData = storage.find(interestSmall);
371 BOOST_REQUIRE(fetchedData != nullptr);
372 BOOST_CHECK(face.sentData[0].wireEncode() == fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700373
Junxiao Shi85d90832016-08-04 03:19:46 +0000374 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
375 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700376 advanceClocks(time::milliseconds(1), 10);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800377 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800378 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700379
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800380 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700381 BOOST_CHECK_NO_THROW(content.parse());
382
383 BOOST_CHECK_EQUAL(content.elements().size(), 3);
384 BOOST_CHECK(content.elements()[0] == smallBlock);
385 BOOST_CHECK(content.elements()[1] == smallBlock);
386 BOOST_CHECK(content.elements()[2] == smallBlock);
387
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800388 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800389 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000390 face.receive(*makeInterest("/root/test/large/valid"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700391 advanceClocks(time::milliseconds(1), 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700392
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800393 // two data packets are generated, the first one will be sent to both places
394 // while the second one will only be inserted into the in-memory storage
395 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
396 BOOST_CHECK_EQUAL(storage.size(), 2);
397
398 // segment0 should be sent through the face
399 const auto& component = face.sentData[0].getName().at(-1);
400 BOOST_CHECK(component.isSegment());
401 BOOST_CHECK_EQUAL(component.toSegment(), 0);
402
403 std::vector<Data> dataInStorage;
404 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
405
406 // the Data sent through the face should be the same as the first Data in the storage
407 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
408 BOOST_CHECK(face.sentData[0].getContent() == dataInStorage[0].getContent());
409
410 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700411 EncodingBuffer encoder;
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800412 size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(),
413 dataInStorage[1].getContent().value_size());
414 valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(),
415 dataInStorage[0].getContent().value_size());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700416 encoder.prependVarNumber(valueLength);
417 encoder.prependVarNumber(tlv::Content);
418 return encoder.block();
419 }();
420
421 BOOST_CHECK_NO_THROW(content.parse());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700422 BOOST_CHECK_EQUAL(content.elements().size(), 3);
423 BOOST_CHECK(content.elements()[0] == largeBlock);
424 BOOST_CHECK(content.elements()[1] == largeBlock);
425 BOOST_CHECK(content.elements()[2] == largeBlock);
426
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800427 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800428 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000429 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700430 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800431 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
432 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Nack);
433 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800434 BOOST_CHECK_EQUAL(storage.size(), 0); // the nack packet will not be inserted into the in-memory storage
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700435}
436
Junxiao Shid97c9532017-04-27 16:17:04 +0000437BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700438{
439 static Block block("\x82\x01\x02", 3);
440
441 auto post = dispatcher.addNotificationStream("test");
442
443 post(block);
444 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800445 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700446
447 dispatcher.addTopPrefix("/root");
448 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800449 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700450
451 post(block);
452 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800453 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800454 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700455
456 post(block);
457 post(block);
458 post(block);
459 advanceClocks(time::milliseconds(1), 10);
460
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800461 BOOST_CHECK_EQUAL(face.sentData.size(), 4);
462 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/%FE%00");
463 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/%FE%01");
464 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/%FE%02");
465 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/%FE%03");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700466
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800467 BOOST_CHECK(face.sentData[0].getContent().blockFromValue() == block);
468 BOOST_CHECK(face.sentData[1].getContent().blockFromValue() == block);
469 BOOST_CHECK(face.sentData[2].getContent().blockFromValue() == block);
470 BOOST_CHECK(face.sentData[3].getContent().blockFromValue() == block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800471
472 // each version of notification will be sent to both places
473 std::vector<Data> dataInStorage;
474 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
475 BOOST_CHECK_EQUAL(dataInStorage.size(), 4);
476 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/%FE%00");
477 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/%FE%01");
478 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/%FE%02");
479 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/%FE%03");
480
481 BOOST_CHECK(dataInStorage[0].getContent().blockFromValue() == block);
482 BOOST_CHECK(dataInStorage[1].getContent().blockFromValue() == block);
483 BOOST_CHECK(dataInStorage[2].getContent().blockFromValue() == block);
484 BOOST_CHECK(dataInStorage[3].getContent().blockFromValue() == block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700485}
486
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800487BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
488BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700489
490} // namespace tests
491} // namespace mgmt
492} // namespace ndn