blob: 9b01628daf514dee6a15f3e0ebbb621b5cc59879 [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 Pesavento152ef442023-04-22 02:02:29 -04003 * Copyright (c) 2013-2023 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(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400100 std::bind([] { return true; }),
101 std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700102 BOOST_CHECK_NO_THROW(dispatcher
103 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400104 std::bind([] { return true; }),
105 std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700106
107 BOOST_CHECK_THROW(dispatcher
108 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400109 std::bind([] { return true; }),
110 std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700111 std::out_of_range);
112
113 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
Davide Pesavento152ef442023-04-22 02:02:29 -0400114 makeAcceptAllAuthorization(), std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700115 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
Davide Pesavento152ef442023-04-22 02:02:29 -0400116 makeAcceptAllAuthorization(), std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700117 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
Davide Pesavento152ef442023-04-22 02:02:29 -0400118 makeAcceptAllAuthorization(), std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700119 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(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400132 std::bind([] { return true; }),
133 std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700134 std::domain_error);
135
136 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
Davide Pesavento152ef442023-04-22 02:02:29 -0400137 makeAcceptAllAuthorization(), std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700138 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(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400148 std::bind([] { return true; }),
149 std::bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700150
151 dispatcher
152 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400153 std::bind([] { return true; }),
154 std::bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700155
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(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400209 std::bind([] { return true; }),
210 std::bind([&nCallbackCalled] { ++nCallbackCalled; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700211
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 {
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500247 return {};
Junxiao Shid97c9532017-04-27 16:17:04 +0000248 }
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,
Davide Pesavento152ef442023-04-22 02:02:29 -0400283 std::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 Pesaventofbea4fc2022-02-08 07:26:04 -0500300 const Block smallBlock({0x81, 0x01, 0x01});
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400301 const Block largeBlock = [] {
302 Block b(129, std::make_shared<const Buffer>(3000));
303 b.encode();
304 return b;
305 }();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700306
307 dispatcher.addStatusDataset("test/small",
308 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400309 [&smallBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400310 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700311 context.append(smallBlock);
312 context.append(smallBlock);
313 context.append(smallBlock);
314 context.end();
315 });
316
317 dispatcher.addStatusDataset("test/large",
318 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400319 [&largeBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400320 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700321 context.append(largeBlock);
322 context.append(largeBlock);
323 context.append(largeBlock);
324 context.end();
325 });
326
327 dispatcher.addStatusDataset("test/reject",
328 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400329 [] (const Name&, const Interest&, StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700330 context.reject();
331 });
332
333 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500334 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800335 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700336
Junxiao Shi85d90832016-08-04 03:19:46 +0000337 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
338 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
339 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500340 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700341
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400342 BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000343 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800344 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000345 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800346 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700347
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800348 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800349
Junxiao Shib55e5d32018-07-18 13:32:00 -0600350 auto interestSmall = *makeInterest("/root/test/small/valid", true);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800351 face.receive(interestSmall);
Davide Pesavento0f830802018-01-16 23:58:58 -0500352 advanceClocks(1_ms, 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800353
354 // one data packet is generated and sent to both places
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400355 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800356 BOOST_CHECK_EQUAL(storage.size(), 1);
357
358 auto fetchedData = storage.find(interestSmall);
359 BOOST_REQUIRE(fetchedData != nullptr);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000360 BOOST_CHECK_EQUAL(face.sentData[0].wireEncode(), fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700361
Junxiao Shi85d90832016-08-04 03:19:46 +0000362 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
363 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500364 advanceClocks(1_ms, 10);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400365 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800366 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700367
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800368 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700369 BOOST_CHECK_NO_THROW(content.parse());
370
Junxiao Shi72c0c642018-04-20 15:41:09 +0000371 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
372 BOOST_CHECK_EQUAL(content.elements()[0], smallBlock);
373 BOOST_CHECK_EQUAL(content.elements()[1], smallBlock);
374 BOOST_CHECK_EQUAL(content.elements()[2], smallBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700375
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800376 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800377 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000378 face.receive(*makeInterest("/root/test/large/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500379 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700380
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800381 // two data packets are generated, the first one will be sent to both places
382 // while the second one will only be inserted into the in-memory storage
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400383 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
384 BOOST_REQUIRE_EQUAL(storage.size(), 2);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800385
386 // segment0 should be sent through the face
387 const auto& component = face.sentData[0].getName().at(-1);
388 BOOST_CHECK(component.isSegment());
389 BOOST_CHECK_EQUAL(component.toSegment(), 0);
390
391 std::vector<Data> dataInStorage;
392 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
393
394 // the Data sent through the face should be the same as the first Data in the storage
395 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000396 BOOST_CHECK_EQUAL(face.sentData[0].getContent(), dataInStorage[0].getContent());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800397
398 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700399 EncodingBuffer encoder;
Davide Pesavento258d51a2022-02-27 21:26:28 -0500400 size_t valueLength = encoder.prependBytes(dataInStorage[1].getContent().value_bytes());
401 valueLength += encoder.prependBytes(dataInStorage[0].getContent().value_bytes());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700402 encoder.prependVarNumber(valueLength);
403 encoder.prependVarNumber(tlv::Content);
404 return encoder.block();
405 }();
406
407 BOOST_CHECK_NO_THROW(content.parse());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000408 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
409 BOOST_CHECK_EQUAL(content.elements()[0], largeBlock);
410 BOOST_CHECK_EQUAL(content.elements()[1], largeBlock);
411 BOOST_CHECK_EQUAL(content.elements()[2], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700412
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800413 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800414 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000415 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Davide Pesavento0f830802018-01-16 23:58:58 -0500416 advanceClocks(1_ms);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400417
418 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000419 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Nack);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800420 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800421 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 -0700422}
423
Junxiao Shid97c9532017-04-27 16:17:04 +0000424BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700425{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500426 const Block block({0x82, 0x01, 0x02});
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700427 auto post = dispatcher.addNotificationStream("test");
428
429 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500430 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800431 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700432
433 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500434 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800435 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700436
437 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500438 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800439 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800440 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700441
442 post(block);
443 post(block);
444 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500445 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700446
Junxiao Shi72c0c642018-04-20 15:41:09 +0000447 BOOST_REQUIRE_EQUAL(face.sentData.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800448 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/seq=0");
449 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/seq=1");
450 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/seq=2");
451 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/seq=3");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700452
Junxiao Shi72c0c642018-04-20 15:41:09 +0000453 BOOST_CHECK_EQUAL(face.sentData[0].getContent().blockFromValue(), block);
454 BOOST_CHECK_EQUAL(face.sentData[1].getContent().blockFromValue(), block);
455 BOOST_CHECK_EQUAL(face.sentData[2].getContent().blockFromValue(), block);
456 BOOST_CHECK_EQUAL(face.sentData[3].getContent().blockFromValue(), block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800457
458 // each version of notification will be sent to both places
459 std::vector<Data> dataInStorage;
460 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000461 BOOST_REQUIRE_EQUAL(dataInStorage.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800462 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/seq=0");
463 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/seq=1");
464 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/seq=2");
465 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/seq=3");
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800466
Junxiao Shi72c0c642018-04-20 15:41:09 +0000467 BOOST_CHECK_EQUAL(dataInStorage[0].getContent().blockFromValue(), block);
468 BOOST_CHECK_EQUAL(dataInStorage[1].getContent().blockFromValue(), block);
469 BOOST_CHECK_EQUAL(dataInStorage[2].getContent().blockFromValue(), block);
470 BOOST_CHECK_EQUAL(dataInStorage[3].getContent().blockFromValue(), block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700471}
472
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800473BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
474BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700475
476} // namespace tests
477} // namespace mgmt
478} // namespace ndn