blob: 6127ea0befe4671d0b45efcb19a1a215a0530bee [file] [log] [blame]
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
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"
27#include "identity-management-fixture.hpp"
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070028#include "../identity-management-time-fixture.hpp"
29#include "../make-interest-data.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070030
31namespace ndn {
32namespace mgmt {
33namespace tests {
34
35using namespace ndn::tests;
36
Alexander Afanasyev80782e02017-01-04 13:16:54 -080037class DispatcherFixture : public IdentityManagementTimeFixture
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070038{
39public:
40 DispatcherFixture()
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070041 : face(io, m_keyChain, {true, true})
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080042 , dispatcher(face, m_keyChain, security::SigningInfo())
Yanbiao Li4b4f7542016-03-11 02:04:43 +080043 , storage(dispatcher.m_storage)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070044 {
45 }
46
47public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080048 util::DummyClientFace face;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070049 mgmt::Dispatcher dispatcher;
Yanbiao Li4b4f7542016-03-11 02:04:43 +080050 util::InMemoryStorageFifo& storage;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070051};
52
53class VoidParameters : public mgmt::ControlParameters
54{
55public:
56 explicit
57 VoidParameters(const Block& wire)
58 {
59 wireDecode(wire);
60 }
61
Junxiao Shid97c9532017-04-27 16:17:04 +000062 Block
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020063 wireEncode() const final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070064 {
65 return Block(128);
66 }
67
Junxiao Shid97c9532017-04-27 16:17:04 +000068 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020069 wireDecode(const Block& wire) final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070070 {
71 if (wire.type() != 128)
Junxiao Shid97c9532017-04-27 16:17:04 +000072 BOOST_THROW_EXCEPTION(tlv::Error("Expecting TLV type 128"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070073 }
74};
75
76static Authorization
77makeTestAuthorization()
78{
79 return [] (const Name& prefix,
80 const Interest& interest,
81 const ControlParameters* params,
82 AcceptContinuation accept,
83 RejectContinuation reject) {
84 if (interest.getName()[-1] == name::Component("valid")) {
85 accept("");
86 }
87 else {
88 if (interest.getName()[-1] == name::Component("silent")) {
89 reject(RejectReply::SILENT);
90 }
91 else {
92 reject(RejectReply::STATUS403);
93 }
94 }
95 };
96}
97
Junxiao Shid97c9532017-04-27 16:17:04 +000098BOOST_AUTO_TEST_SUITE(Mgmt)
99BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
100
101BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700102{
103 BOOST_CHECK_NO_THROW(dispatcher
104 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
105 bind([] { return true; }),
106 bind([]{})));
107 BOOST_CHECK_NO_THROW(dispatcher
108 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
109 bind([] { return true; }),
110 bind([]{})));
111
112 BOOST_CHECK_THROW(dispatcher
113 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
114 bind([] { return true; }),
115 bind([]{})),
116 std::out_of_range);
117
118 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
119 makeAcceptAllAuthorization(), bind([]{})));
120 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
121 makeAcceptAllAuthorization(), bind([]{})));
122 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
123 makeAcceptAllAuthorization(), bind([]{})),
124 std::out_of_range);
125
126 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
127 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
128 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
129
130
131 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
132 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
133 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
134
135 BOOST_CHECK_THROW(dispatcher
136 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
137 bind([] { return true; }),
138 bind([]{})),
139 std::domain_error);
140
141 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
142 makeAcceptAllAuthorization(), bind([]{})),
143 std::domain_error);
144
145 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
146}
147
Junxiao Shid97c9532017-04-27 16:17:04 +0000148BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700149{
150 std::map<std::string, size_t> nCallbackCalled;
151 dispatcher
152 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
153 bind([] { return true; }),
154 bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
155
156 dispatcher
157 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
158 bind([] { return true; }),
159 bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
160
Junxiao Shi85d90832016-08-04 03:19:46 +0000161 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700162 advanceClocks(time::milliseconds(1));
163 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
164 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
165
166 dispatcher.addTopPrefix("/root/1");
167 advanceClocks(time::milliseconds(1));
168
Junxiao Shi85d90832016-08-04 03:19:46 +0000169 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700170 advanceClocks(time::milliseconds(1));
171 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
172 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
173
Junxiao Shi85d90832016-08-04 03:19:46 +0000174 face.receive(*makeInterest("/root/1/test/2/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700175 advanceClocks(time::milliseconds(1));
176 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
177 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
178
Junxiao Shi85d90832016-08-04 03:19:46 +0000179 face.receive(*makeInterest("/root/2/test/1/%80%00"));
180 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700181 advanceClocks(time::milliseconds(1));
182 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
183 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
184
185 dispatcher.addTopPrefix("/root/2");
186 advanceClocks(time::milliseconds(1));
187
Junxiao Shi85d90832016-08-04 03:19:46 +0000188 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700189 advanceClocks(time::milliseconds(1));
190 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
191
Junxiao Shi85d90832016-08-04 03:19:46 +0000192 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700193 advanceClocks(time::milliseconds(1));
194 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
195
196 dispatcher.removeTopPrefix("/root/1");
197 advanceClocks(time::milliseconds(1));
198
Junxiao Shi85d90832016-08-04 03:19:46 +0000199 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700200 advanceClocks(time::milliseconds(1));
201 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
202
Junxiao Shi85d90832016-08-04 03:19:46 +0000203 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700204 advanceClocks(time::milliseconds(1));
205 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
206}
207
Junxiao Shid97c9532017-04-27 16:17:04 +0000208BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700209{
210 size_t nCallbackCalled = 0;
211 dispatcher
212 .addControlCommand<VoidParameters>("test",
213 makeTestAuthorization(),
214 bind([] { return true; }),
215 bind([&nCallbackCalled] { ++nCallbackCalled; }));
216
217 dispatcher.addTopPrefix("/root");
218 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800219 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700220
Junxiao Shi85d90832016-08-04 03:19:46 +0000221 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
222 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
223 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
224 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
225 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700226 advanceClocks(time::milliseconds(1), 20);
227 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800228 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700229
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800230 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Blob);
231 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
232 BOOST_CHECK(face.sentData[1].getContentType() == tlv::ContentType_Blob);
233 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700234
Junxiao Shi85d90832016-08-04 03:19:46 +0000235 face.receive(*makeInterest("/root/test/%80%00/valid"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700236 advanceClocks(time::milliseconds(1), 10);
237 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
238}
239
Junxiao Shid97c9532017-04-27 16:17:04 +0000240class StatefulParameters : public mgmt::ControlParameters
241{
242public:
243 explicit
244 StatefulParameters(const Block& wire)
245 {
246 wireDecode(wire);
247 }
248
249 Block
250 wireEncode() const final
251 {
252 return Block();
253 }
254
255 void
256 wireDecode(const Block& wire) final
257 {
258 m_state = EXPECTED_STATE;
259 }
260
261 bool
262 check() const
263 {
264 return m_state == EXPECTED_STATE;
265 }
266
267private:
268 static constexpr int EXPECTED_STATE = 12602;
269 int m_state = 0;
270};
271
272BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
273{
274 AcceptContinuation authorizationAccept;
275 auto authorization =
276 [&authorizationAccept] (const Name& prefix, const Interest& interest, const ControlParameters* params,
277 AcceptContinuation accept, RejectContinuation reject) {
278 authorizationAccept = accept;
279 };
280
281 auto validateParameters =
282 [] (const ControlParameters& params) {
283 return dynamic_cast<const StatefulParameters&>(params).check();
284 };
285
286 size_t nCallbackCalled = 0;
287 dispatcher
288 .addControlCommand<StatefulParameters>("test",
289 authorization,
290 validateParameters,
291 bind([&nCallbackCalled] { ++nCallbackCalled; }));
292
293 dispatcher.addTopPrefix("/root");
294 advanceClocks(time::milliseconds(1));
295
296 face.receive(*makeInterest("/root/test/%80%00"));
297 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
298 BOOST_REQUIRE(authorizationAccept != nullptr);
299
300 advanceClocks(time::milliseconds(1));
301 authorizationAccept("");
302 advanceClocks(time::milliseconds(1));
303 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
304}
305
306BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700307{
308 static Block smallBlock("\x81\x01\0x01", 3);
309 static Block largeBlock = [] () -> Block {
310 EncodingBuffer encoder;
311 for (size_t i = 0; i < 2500; ++i) {
312 encoder.prependByte(1);
313 }
314 encoder.prependVarNumber(2500);
315 encoder.prependVarNumber(129);
316 return encoder.block();
317 }();
318
319 dispatcher.addStatusDataset("test/small",
320 makeTestAuthorization(),
321 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700322 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700323 context.append(smallBlock);
324 context.append(smallBlock);
325 context.append(smallBlock);
326 context.end();
327 });
328
329 dispatcher.addStatusDataset("test/large",
330 makeTestAuthorization(),
331 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700332 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700333 context.append(largeBlock);
334 context.append(largeBlock);
335 context.append(largeBlock);
336 context.end();
337 });
338
339 dispatcher.addStatusDataset("test/reject",
340 makeTestAuthorization(),
341 [] (const Name& prefix, const Interest& interest,
Junxiao Shif65a3362015-09-06 20:54:54 -0700342 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700343 context.reject();
344 });
345
346 dispatcher.addTopPrefix("/root");
347 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800348 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700349
Junxiao Shi85d90832016-08-04 03:19:46 +0000350 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
351 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
352 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700353 advanceClocks(time::milliseconds(1), 20);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800354 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700355
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800356 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Blob);
357 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
358 BOOST_CHECK(face.sentData[1].getContentType() == tlv::ContentType_Blob);
359 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700360
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800361 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800362
Junxiao Shi85d90832016-08-04 03:19:46 +0000363 auto interestSmall = *makeInterest("/root/test/small/valid");
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800364 face.receive(interestSmall);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700365 advanceClocks(time::milliseconds(1), 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800366
367 // one data packet is generated and sent to both places
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800368 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800369 BOOST_CHECK_EQUAL(storage.size(), 1);
370
371 auto fetchedData = storage.find(interestSmall);
372 BOOST_REQUIRE(fetchedData != nullptr);
373 BOOST_CHECK(face.sentData[0].wireEncode() == fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700374
Junxiao Shi85d90832016-08-04 03:19:46 +0000375 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
376 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700377 advanceClocks(time::milliseconds(1), 10);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800378 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800379 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700380
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800381 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700382 BOOST_CHECK_NO_THROW(content.parse());
383
384 BOOST_CHECK_EQUAL(content.elements().size(), 3);
385 BOOST_CHECK(content.elements()[0] == smallBlock);
386 BOOST_CHECK(content.elements()[1] == smallBlock);
387 BOOST_CHECK(content.elements()[2] == smallBlock);
388
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800389 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800390 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000391 face.receive(*makeInterest("/root/test/large/valid"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700392 advanceClocks(time::milliseconds(1), 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700393
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800394 // two data packets are generated, the first one will be sent to both places
395 // while the second one will only be inserted into the in-memory storage
396 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
397 BOOST_CHECK_EQUAL(storage.size(), 2);
398
399 // segment0 should be sent through the face
400 const auto& component = face.sentData[0].getName().at(-1);
401 BOOST_CHECK(component.isSegment());
402 BOOST_CHECK_EQUAL(component.toSegment(), 0);
403
404 std::vector<Data> dataInStorage;
405 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
406
407 // the Data sent through the face should be the same as the first Data in the storage
408 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
409 BOOST_CHECK(face.sentData[0].getContent() == dataInStorage[0].getContent());
410
411 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700412 EncodingBuffer encoder;
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800413 size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(),
414 dataInStorage[1].getContent().value_size());
415 valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(),
416 dataInStorage[0].getContent().value_size());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700417 encoder.prependVarNumber(valueLength);
418 encoder.prependVarNumber(tlv::Content);
419 return encoder.block();
420 }();
421
422 BOOST_CHECK_NO_THROW(content.parse());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700423 BOOST_CHECK_EQUAL(content.elements().size(), 3);
424 BOOST_CHECK(content.elements()[0] == largeBlock);
425 BOOST_CHECK(content.elements()[1] == largeBlock);
426 BOOST_CHECK(content.elements()[2] == largeBlock);
427
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800428 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800429 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000430 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700431 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800432 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
433 BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Nack);
434 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800435 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 -0700436}
437
Junxiao Shid97c9532017-04-27 16:17:04 +0000438BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700439{
440 static Block block("\x82\x01\x02", 3);
441
442 auto post = dispatcher.addNotificationStream("test");
443
444 post(block);
445 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800446 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700447
448 dispatcher.addTopPrefix("/root");
449 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800450 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700451
452 post(block);
453 advanceClocks(time::milliseconds(1));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800454 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800455 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700456
457 post(block);
458 post(block);
459 post(block);
460 advanceClocks(time::milliseconds(1), 10);
461
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800462 BOOST_CHECK_EQUAL(face.sentData.size(), 4);
463 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/%FE%00");
464 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/%FE%01");
465 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/%FE%02");
466 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/%FE%03");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700467
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800468 BOOST_CHECK(face.sentData[0].getContent().blockFromValue() == block);
469 BOOST_CHECK(face.sentData[1].getContent().blockFromValue() == block);
470 BOOST_CHECK(face.sentData[2].getContent().blockFromValue() == block);
471 BOOST_CHECK(face.sentData[3].getContent().blockFromValue() == block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800472
473 // each version of notification will be sent to both places
474 std::vector<Data> dataInStorage;
475 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
476 BOOST_CHECK_EQUAL(dataInStorage.size(), 4);
477 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/%FE%00");
478 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/%FE%01");
479 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/%FE%02");
480 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/%FE%03");
481
482 BOOST_CHECK(dataInStorage[0].getContent().blockFromValue() == block);
483 BOOST_CHECK(dataInStorage[1].getContent().blockFromValue() == block);
484 BOOST_CHECK(dataInStorage[2].getContent().blockFromValue() == block);
485 BOOST_CHECK(dataInStorage[3].getContent().blockFromValue() == block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700486}
487
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800488BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
489BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700490
491} // namespace tests
492} // namespace mgmt
493} // namespace ndn