blob: d89da1b1c9023e39a7380444606629bd3da613f1 [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 Pesavento3c34ec12021-03-28 21:50:06 -04003 * Copyright (c) 2013-2021 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{
Davide Pesavento3c34ec12021-03-28 21:50:06 -040077 return [] (const Name&, const Interest& interest, const ControlParameters*,
78 AcceptContinuation accept, RejectContinuation reject) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070079 if (interest.getName()[-1] == name::Component("valid")) {
80 accept("");
81 }
82 else {
83 if (interest.getName()[-1] == name::Component("silent")) {
84 reject(RejectReply::SILENT);
85 }
86 else {
87 reject(RejectReply::STATUS403);
88 }
89 }
90 };
91}
92
Junxiao Shid97c9532017-04-27 16:17:04 +000093BOOST_AUTO_TEST_SUITE(Mgmt)
94BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
95
96BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070097{
98 BOOST_CHECK_NO_THROW(dispatcher
99 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
100 bind([] { return true; }),
101 bind([]{})));
102 BOOST_CHECK_NO_THROW(dispatcher
103 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
104 bind([] { return true; }),
105 bind([]{})));
106
107 BOOST_CHECK_THROW(dispatcher
108 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
109 bind([] { return true; }),
110 bind([]{})),
111 std::out_of_range);
112
113 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
114 makeAcceptAllAuthorization(), bind([]{})));
115 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
116 makeAcceptAllAuthorization(), bind([]{})));
117 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
118 makeAcceptAllAuthorization(), bind([]{})),
119 std::out_of_range);
120
121 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
122 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
123 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
124
125
126 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
127 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
128 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
129
130 BOOST_CHECK_THROW(dispatcher
131 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
132 bind([] { return true; }),
133 bind([]{})),
134 std::domain_error);
135
136 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
137 makeAcceptAllAuthorization(), bind([]{})),
138 std::domain_error);
139
140 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
141}
142
Junxiao Shid97c9532017-04-27 16:17:04 +0000143BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700144{
145 std::map<std::string, size_t> nCallbackCalled;
146 dispatcher
147 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
148 bind([] { return true; }),
149 bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
150
151 dispatcher
152 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
153 bind([] { return true; }),
154 bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
155
Junxiao Shi85d90832016-08-04 03:19:46 +0000156 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500157 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700158 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
159 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
160
161 dispatcher.addTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500162 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700163
Junxiao Shi85d90832016-08-04 03:19:46 +0000164 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500165 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700166 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
167 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
168
Junxiao Shi85d90832016-08-04 03:19:46 +0000169 face.receive(*makeInterest("/root/1/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500170 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700171 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
172 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
173
Junxiao Shi85d90832016-08-04 03:19:46 +0000174 face.receive(*makeInterest("/root/2/test/1/%80%00"));
175 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500176 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700177 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
178 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
179
180 dispatcher.addTopPrefix("/root/2");
Davide Pesavento0f830802018-01-16 23:58:58 -0500181 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700182
Junxiao Shi85d90832016-08-04 03:19:46 +0000183 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500184 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700185 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
186
Junxiao Shi85d90832016-08-04 03:19:46 +0000187 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500188 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700189 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
190
191 dispatcher.removeTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500192 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700193
Junxiao Shi85d90832016-08-04 03:19:46 +0000194 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500195 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700196 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
197
Junxiao Shi85d90832016-08-04 03:19:46 +0000198 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500199 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700200 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
201}
202
Junxiao Shid97c9532017-04-27 16:17:04 +0000203BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700204{
205 size_t nCallbackCalled = 0;
206 dispatcher
207 .addControlCommand<VoidParameters>("test",
208 makeTestAuthorization(),
209 bind([] { return true; }),
210 bind([&nCallbackCalled] { ++nCallbackCalled; }));
211
212 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500213 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800214 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700215
Junxiao Shi85d90832016-08-04 03:19:46 +0000216 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
217 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
218 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
219 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
220 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Davide Pesavento0f830802018-01-16 23:58:58 -0500221 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700222 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800223 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700224
Junxiao Shi72c0c642018-04-20 15:41:09 +0000225 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800226 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000227 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800228 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700229
Junxiao Shi85d90832016-08-04 03:19:46 +0000230 face.receive(*makeInterest("/root/test/%80%00/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500231 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700232 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
233}
234
Junxiao Shid97c9532017-04-27 16:17:04 +0000235class StatefulParameters : public mgmt::ControlParameters
236{
237public:
238 explicit
239 StatefulParameters(const Block& wire)
240 {
241 wireDecode(wire);
242 }
243
244 Block
245 wireEncode() const final
246 {
247 return Block();
248 }
249
250 void
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400251 wireDecode(const Block&) final
Junxiao Shid97c9532017-04-27 16:17:04 +0000252 {
253 m_state = EXPECTED_STATE;
254 }
255
256 bool
257 check() const
258 {
259 return m_state == EXPECTED_STATE;
260 }
261
262private:
263 static constexpr int EXPECTED_STATE = 12602;
264 int m_state = 0;
265};
266
267BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
268{
269 AcceptContinuation authorizationAccept;
270 auto authorization =
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400271 [&authorizationAccept] (const Name&, const Interest&, const ControlParameters*,
272 AcceptContinuation accept, RejectContinuation) {
273 authorizationAccept = std::move(accept);
Junxiao Shid97c9532017-04-27 16:17:04 +0000274 };
275
276 auto validateParameters =
277 [] (const ControlParameters& params) {
278 return dynamic_cast<const StatefulParameters&>(params).check();
279 };
280
281 size_t nCallbackCalled = 0;
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400282 dispatcher.addControlCommand<StatefulParameters>("test", authorization, validateParameters,
283 bind([&nCallbackCalled] { ++nCallbackCalled; }));
Junxiao Shid97c9532017-04-27 16:17:04 +0000284
285 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500286 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000287
288 face.receive(*makeInterest("/root/test/%80%00"));
289 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
290 BOOST_REQUIRE(authorizationAccept != nullptr);
291
Davide Pesavento0f830802018-01-16 23:58:58 -0500292 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000293 authorizationAccept("");
Davide Pesavento0f830802018-01-16 23:58:58 -0500294 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000295 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
296}
297
298BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700299{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400300 const uint8_t smallBuf[] = {0x81, 0x01, 0x01};
301 const Block smallBlock(smallBuf, sizeof(smallBuf));
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400302 const Block largeBlock = [] {
303 Block b(129, std::make_shared<const Buffer>(3000));
304 b.encode();
305 return b;
306 }();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700307
308 dispatcher.addStatusDataset("test/small",
309 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400310 [&smallBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400311 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700312 context.append(smallBlock);
313 context.append(smallBlock);
314 context.append(smallBlock);
315 context.end();
316 });
317
318 dispatcher.addStatusDataset("test/large",
319 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400320 [&largeBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400321 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700322 context.append(largeBlock);
323 context.append(largeBlock);
324 context.append(largeBlock);
325 context.end();
326 });
327
328 dispatcher.addStatusDataset("test/reject",
329 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400330 [] (const Name&, const Interest&, StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700331 context.reject();
332 });
333
334 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500335 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800336 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700337
Junxiao Shi85d90832016-08-04 03:19:46 +0000338 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
339 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
340 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500341 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700342
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400343 BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000344 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800345 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000346 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800347 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700348
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800349 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800350
Junxiao Shib55e5d32018-07-18 13:32:00 -0600351 auto interestSmall = *makeInterest("/root/test/small/valid", true);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800352 face.receive(interestSmall);
Davide Pesavento0f830802018-01-16 23:58:58 -0500353 advanceClocks(1_ms, 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800354
355 // one data packet is generated and sent to both places
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400356 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800357 BOOST_CHECK_EQUAL(storage.size(), 1);
358
359 auto fetchedData = storage.find(interestSmall);
360 BOOST_REQUIRE(fetchedData != nullptr);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000361 BOOST_CHECK_EQUAL(face.sentData[0].wireEncode(), fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700362
Junxiao Shi85d90832016-08-04 03:19:46 +0000363 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
364 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500365 advanceClocks(1_ms, 10);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400366 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800367 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700368
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800369 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700370 BOOST_CHECK_NO_THROW(content.parse());
371
Junxiao Shi72c0c642018-04-20 15:41:09 +0000372 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
373 BOOST_CHECK_EQUAL(content.elements()[0], smallBlock);
374 BOOST_CHECK_EQUAL(content.elements()[1], smallBlock);
375 BOOST_CHECK_EQUAL(content.elements()[2], smallBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700376
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800377 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800378 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000379 face.receive(*makeInterest("/root/test/large/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500380 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700381
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800382 // two data packets are generated, the first one will be sent to both places
383 // while the second one will only be inserted into the in-memory storage
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400384 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
385 BOOST_REQUIRE_EQUAL(storage.size(), 2);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800386
387 // segment0 should be sent through the face
388 const auto& component = face.sentData[0].getName().at(-1);
389 BOOST_CHECK(component.isSegment());
390 BOOST_CHECK_EQUAL(component.toSegment(), 0);
391
392 std::vector<Data> dataInStorage;
393 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
394
395 // the Data sent through the face should be the same as the first Data in the storage
396 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000397 BOOST_CHECK_EQUAL(face.sentData[0].getContent(), dataInStorage[0].getContent());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800398
399 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700400 EncodingBuffer encoder;
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800401 size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(),
402 dataInStorage[1].getContent().value_size());
403 valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(),
404 dataInStorage[0].getContent().value_size());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700405 encoder.prependVarNumber(valueLength);
406 encoder.prependVarNumber(tlv::Content);
407 return encoder.block();
408 }();
409
410 BOOST_CHECK_NO_THROW(content.parse());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000411 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
412 BOOST_CHECK_EQUAL(content.elements()[0], largeBlock);
413 BOOST_CHECK_EQUAL(content.elements()[1], largeBlock);
414 BOOST_CHECK_EQUAL(content.elements()[2], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700415
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800416 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800417 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000418 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Davide Pesavento0f830802018-01-16 23:58:58 -0500419 advanceClocks(1_ms);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400420
421 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000422 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Nack);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800423 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800424 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 -0700425}
426
Junxiao Shid97c9532017-04-27 16:17:04 +0000427BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700428{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400429 const uint8_t buf[] = {0x82, 0x01, 0x02};
430 const Block block(buf, sizeof(buf));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700431 auto post = dispatcher.addNotificationStream("test");
432
433 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500434 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800435 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700436
437 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500438 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800439 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700440
441 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500442 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800443 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800444 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700445
446 post(block);
447 post(block);
448 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500449 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700450
Junxiao Shi72c0c642018-04-20 15:41:09 +0000451 BOOST_REQUIRE_EQUAL(face.sentData.size(), 4);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800452 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/%FE%00");
453 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/%FE%01");
454 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/%FE%02");
455 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/%FE%03");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700456
Junxiao Shi72c0c642018-04-20 15:41:09 +0000457 BOOST_CHECK_EQUAL(face.sentData[0].getContent().blockFromValue(), block);
458 BOOST_CHECK_EQUAL(face.sentData[1].getContent().blockFromValue(), block);
459 BOOST_CHECK_EQUAL(face.sentData[2].getContent().blockFromValue(), block);
460 BOOST_CHECK_EQUAL(face.sentData[3].getContent().blockFromValue(), block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800461
462 // each version of notification will be sent to both places
463 std::vector<Data> dataInStorage;
464 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000465 BOOST_REQUIRE_EQUAL(dataInStorage.size(), 4);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800466 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/%FE%00");
467 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/%FE%01");
468 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/%FE%02");
469 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/%FE%03");
470
Junxiao Shi72c0c642018-04-20 15:41:09 +0000471 BOOST_CHECK_EQUAL(dataInStorage[0].getContent().blockFromValue(), block);
472 BOOST_CHECK_EQUAL(dataInStorage[1].getContent().blockFromValue(), block);
473 BOOST_CHECK_EQUAL(dataInStorage[2].getContent().blockFromValue(), block);
474 BOOST_CHECK_EQUAL(dataInStorage[3].getContent().blockFromValue(), block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700475}
476
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800477BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
478BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700479
480} // namespace tests
481} // namespace mgmt
482} // namespace ndn