blob: 79d3dd30e854142b1b4ca6d1911b911113048bb0 [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/*
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -05003 * Copyright (c) 2013-2020 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
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/mgmt/dispatcher.hpp"
23#include "ndn-cxx/mgmt/nfd/control-parameters.hpp"
24#include "ndn-cxx/util/dummy-client-face.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070025
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050026#include "tests/test-common.hpp"
27#include "tests/unit/io-key-chain-fixture.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070028
29namespace ndn {
30namespace mgmt {
31namespace tests {
32
33using namespace ndn::tests;
34
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050035class DispatcherFixture : public IoKeyChainFixture
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070036{
37public:
38 DispatcherFixture()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050039 : face(m_io, m_keyChain, {true, true})
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080040 , dispatcher(face, m_keyChain, security::SigningInfo())
Yanbiao Li4b4f7542016-03-11 02:04:43 +080041 , storage(dispatcher.m_storage)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070042 {
43 }
44
45public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080046 util::DummyClientFace face;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070047 mgmt::Dispatcher dispatcher;
Junxiao Shic542f632017-07-18 14:20:32 +000048 InMemoryStorageFifo& storage;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070049};
50
51class VoidParameters : public mgmt::ControlParameters
52{
53public:
54 explicit
55 VoidParameters(const Block& wire)
56 {
57 wireDecode(wire);
58 }
59
Junxiao Shid97c9532017-04-27 16:17:04 +000060 Block
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020061 wireEncode() const final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070062 {
63 return Block(128);
64 }
65
Junxiao Shid97c9532017-04-27 16:17:04 +000066 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020067 wireDecode(const Block& wire) final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070068 {
69 if (wire.type() != 128)
Davide Pesavento923ba442019-02-12 22:00:38 -050070 NDN_THROW(tlv::Error("Expecting TLV type 128"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070071 }
72};
73
74static Authorization
75makeTestAuthorization()
76{
77 return [] (const Name& prefix,
78 const Interest& interest,
79 const ControlParameters* params,
80 AcceptContinuation accept,
81 RejectContinuation reject) {
82 if (interest.getName()[-1] == name::Component("valid")) {
83 accept("");
84 }
85 else {
86 if (interest.getName()[-1] == name::Component("silent")) {
87 reject(RejectReply::SILENT);
88 }
89 else {
90 reject(RejectReply::STATUS403);
91 }
92 }
93 };
94}
95
Junxiao Shid97c9532017-04-27 16:17:04 +000096BOOST_AUTO_TEST_SUITE(Mgmt)
97BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
98
99BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700100{
101 BOOST_CHECK_NO_THROW(dispatcher
102 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
103 bind([] { return true; }),
104 bind([]{})));
105 BOOST_CHECK_NO_THROW(dispatcher
106 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
107 bind([] { return true; }),
108 bind([]{})));
109
110 BOOST_CHECK_THROW(dispatcher
111 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
112 bind([] { return true; }),
113 bind([]{})),
114 std::out_of_range);
115
116 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
117 makeAcceptAllAuthorization(), bind([]{})));
118 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
119 makeAcceptAllAuthorization(), bind([]{})));
120 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
121 makeAcceptAllAuthorization(), bind([]{})),
122 std::out_of_range);
123
124 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
125 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
126 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
127
128
129 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
130 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
131 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
132
133 BOOST_CHECK_THROW(dispatcher
134 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
135 bind([] { return true; }),
136 bind([]{})),
137 std::domain_error);
138
139 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
140 makeAcceptAllAuthorization(), bind([]{})),
141 std::domain_error);
142
143 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
144}
145
Junxiao Shid97c9532017-04-27 16:17:04 +0000146BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700147{
148 std::map<std::string, size_t> nCallbackCalled;
149 dispatcher
150 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
151 bind([] { return true; }),
152 bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
153
154 dispatcher
155 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
156 bind([] { return true; }),
157 bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
158
Junxiao Shi85d90832016-08-04 03:19:46 +0000159 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500160 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700161 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
162 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
163
164 dispatcher.addTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500165 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700166
Junxiao Shi85d90832016-08-04 03:19:46 +0000167 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500168 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700169 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
170 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
171
Junxiao Shi85d90832016-08-04 03:19:46 +0000172 face.receive(*makeInterest("/root/1/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500173 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700174 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
175 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
176
Junxiao Shi85d90832016-08-04 03:19:46 +0000177 face.receive(*makeInterest("/root/2/test/1/%80%00"));
178 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500179 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700180 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
181 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
182
183 dispatcher.addTopPrefix("/root/2");
Davide Pesavento0f830802018-01-16 23:58:58 -0500184 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700185
Junxiao Shi85d90832016-08-04 03:19:46 +0000186 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500187 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700188 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
189
Junxiao Shi85d90832016-08-04 03:19:46 +0000190 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500191 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700192 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
193
194 dispatcher.removeTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500195 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700196
Junxiao Shi85d90832016-08-04 03:19:46 +0000197 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500198 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700199 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
200
Junxiao Shi85d90832016-08-04 03:19:46 +0000201 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500202 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700203 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
204}
205
Junxiao Shid97c9532017-04-27 16:17:04 +0000206BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700207{
208 size_t nCallbackCalled = 0;
209 dispatcher
210 .addControlCommand<VoidParameters>("test",
211 makeTestAuthorization(),
212 bind([] { return true; }),
213 bind([&nCallbackCalled] { ++nCallbackCalled; }));
214
215 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500216 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800217 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700218
Junxiao Shi85d90832016-08-04 03:19:46 +0000219 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
220 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
221 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
222 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
223 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Davide Pesavento0f830802018-01-16 23:58:58 -0500224 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700225 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800226 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700227
Junxiao Shi72c0c642018-04-20 15:41:09 +0000228 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800229 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000230 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800231 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700232
Junxiao Shi85d90832016-08-04 03:19:46 +0000233 face.receive(*makeInterest("/root/test/%80%00/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500234 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700235 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
236}
237
Junxiao Shid97c9532017-04-27 16:17:04 +0000238class StatefulParameters : public mgmt::ControlParameters
239{
240public:
241 explicit
242 StatefulParameters(const Block& wire)
243 {
244 wireDecode(wire);
245 }
246
247 Block
248 wireEncode() const final
249 {
250 return Block();
251 }
252
253 void
254 wireDecode(const Block& wire) final
255 {
256 m_state = EXPECTED_STATE;
257 }
258
259 bool
260 check() const
261 {
262 return m_state == EXPECTED_STATE;
263 }
264
265private:
266 static constexpr int EXPECTED_STATE = 12602;
267 int m_state = 0;
268};
269
270BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
271{
272 AcceptContinuation authorizationAccept;
273 auto authorization =
274 [&authorizationAccept] (const Name& prefix, const Interest& interest, const ControlParameters* params,
275 AcceptContinuation accept, RejectContinuation reject) {
276 authorizationAccept = accept;
277 };
278
279 auto validateParameters =
280 [] (const ControlParameters& params) {
281 return dynamic_cast<const StatefulParameters&>(params).check();
282 };
283
284 size_t nCallbackCalled = 0;
285 dispatcher
286 .addControlCommand<StatefulParameters>("test",
287 authorization,
288 validateParameters,
289 bind([&nCallbackCalled] { ++nCallbackCalled; }));
290
291 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500292 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000293
294 face.receive(*makeInterest("/root/test/%80%00"));
295 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
296 BOOST_REQUIRE(authorizationAccept != nullptr);
297
Davide Pesavento0f830802018-01-16 23:58:58 -0500298 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000299 authorizationAccept("");
Davide Pesavento0f830802018-01-16 23:58:58 -0500300 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000301 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
302}
303
304BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700305{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400306 const uint8_t smallBuf[] = {0x81, 0x01, 0x01};
307 const Block smallBlock(smallBuf, sizeof(smallBuf));
308 Block largeBlock;
309 {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700310 EncodingBuffer encoder;
311 for (size_t i = 0; i < 2500; ++i) {
312 encoder.prependByte(1);
313 }
314 encoder.prependVarNumber(2500);
315 encoder.prependVarNumber(129);
Davide Pesaventob10024c2017-09-22 01:36:44 -0400316 largeBlock = encoder.block();
317 }
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700318
319 dispatcher.addStatusDataset("test/small",
320 makeTestAuthorization(),
Davide Pesaventob10024c2017-09-22 01:36:44 -0400321 [&smallBlock] (const Name& prefix, const Interest& interest,
322 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(),
Davide Pesaventob10024c2017-09-22 01:36:44 -0400331 [&largeBlock] (const Name& prefix, const Interest& interest,
332 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");
Davide Pesavento0f830802018-01-16 23:58:58 -0500347 advanceClocks(1_ms);
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
Davide Pesavento0f830802018-01-16 23:58:58 -0500353 advanceClocks(1_ms, 20);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800354 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700355
Junxiao Shi72c0c642018-04-20 15:41:09 +0000356 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800357 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000358 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800359 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 Shib55e5d32018-07-18 13:32:00 -0600363 auto interestSmall = *makeInterest("/root/test/small/valid", true);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800364 face.receive(interestSmall);
Davide Pesavento0f830802018-01-16 23:58:58 -0500365 advanceClocks(1_ms, 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);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000373 BOOST_CHECK_EQUAL(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
Davide Pesavento0f830802018-01-16 23:58:58 -0500377 advanceClocks(1_ms, 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
Junxiao Shi72c0c642018-04-20 15:41:09 +0000384 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
385 BOOST_CHECK_EQUAL(content.elements()[0], smallBlock);
386 BOOST_CHECK_EQUAL(content.elements()[1], smallBlock);
387 BOOST_CHECK_EQUAL(content.elements()[2], smallBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700388
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"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500392 advanceClocks(1_ms, 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());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000409 BOOST_CHECK_EQUAL(face.sentData[0].getContent(), dataInStorage[0].getContent());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800410
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());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000423 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
424 BOOST_CHECK_EQUAL(content.elements()[0], largeBlock);
425 BOOST_CHECK_EQUAL(content.elements()[1], largeBlock);
426 BOOST_CHECK_EQUAL(content.elements()[2], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700427
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
Davide Pesavento0f830802018-01-16 23:58:58 -0500431 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800432 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000433 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Nack);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800434 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{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400440 const uint8_t buf[] = {0x82, 0x01, 0x02};
441 const Block block(buf, sizeof(buf));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700442 auto post = dispatcher.addNotificationStream("test");
443
444 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500445 advanceClocks(1_ms);
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");
Davide Pesavento0f830802018-01-16 23:58:58 -0500449 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800450 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700451
452 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500453 advanceClocks(1_ms);
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);
Davide Pesavento0f830802018-01-16 23:58:58 -0500460 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700461
Junxiao Shi72c0c642018-04-20 15:41:09 +0000462 BOOST_REQUIRE_EQUAL(face.sentData.size(), 4);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800463 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
Junxiao Shi72c0c642018-04-20 15:41:09 +0000468 BOOST_CHECK_EQUAL(face.sentData[0].getContent().blockFromValue(), block);
469 BOOST_CHECK_EQUAL(face.sentData[1].getContent().blockFromValue(), block);
470 BOOST_CHECK_EQUAL(face.sentData[2].getContent().blockFromValue(), block);
471 BOOST_CHECK_EQUAL(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));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000476 BOOST_REQUIRE_EQUAL(dataInStorage.size(), 4);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800477 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
Junxiao Shi72c0c642018-04-20 15:41:09 +0000482 BOOST_CHECK_EQUAL(dataInStorage[0].getContent().blockFromValue(), block);
483 BOOST_CHECK_EQUAL(dataInStorage[1].getContent().blockFromValue(), block);
484 BOOST_CHECK_EQUAL(dataInStorage[2].getContent().blockFromValue(), block);
485 BOOST_CHECK_EQUAL(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