blob: ec6f90f81cf1911cccc41f8e3705503cc3fbfe91 [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 Pesavento0c526032024-01-31 21:14:01 -05003 * Copyright (c) 2013-2024 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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040029namespace ndn::tests {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070030
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040031using namespace ndn::mgmt;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070032
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050033class DispatcherFixture : public IoKeyChainFixture
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070034{
Davide Pesavento54dfc4a2024-12-26 17:30:41 -050035protected:
36 DummyClientFace face{m_io, m_keyChain, {true, true}};
37 Dispatcher dispatcher{face, m_keyChain};
38 InMemoryStorageFifo& storage{dispatcher.m_storage};
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070039};
40
41class VoidParameters : public mgmt::ControlParameters
42{
43public:
44 explicit
45 VoidParameters(const Block& wire)
46 {
47 wireDecode(wire);
48 }
49
Junxiao Shid97c9532017-04-27 16:17:04 +000050 Block
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020051 wireEncode() const final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070052 {
53 return Block(128);
54 }
55
Junxiao Shid97c9532017-04-27 16:17:04 +000056 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020057 wireDecode(const Block& wire) final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070058 {
59 if (wire.type() != 128)
Davide Pesavento923ba442019-02-12 22:00:38 -050060 NDN_THROW(tlv::Error("Expecting TLV type 128"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070061 }
62};
63
64static Authorization
65makeTestAuthorization()
66{
Davide Pesavento3c34ec12021-03-28 21:50:06 -040067 return [] (const Name&, const Interest& interest, const ControlParameters*,
68 AcceptContinuation accept, RejectContinuation reject) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070069 if (interest.getName()[-1] == name::Component("valid")) {
70 accept("");
71 }
72 else {
73 if (interest.getName()[-1] == name::Component("silent")) {
74 reject(RejectReply::SILENT);
75 }
76 else {
77 reject(RejectReply::STATUS403);
78 }
79 }
80 };
81}
82
Junxiao Shid97c9532017-04-27 16:17:04 +000083BOOST_AUTO_TEST_SUITE(Mgmt)
84BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
85
86BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070087{
88 BOOST_CHECK_NO_THROW(dispatcher
89 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -040090 std::bind([] { return true; }),
91 std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070092 BOOST_CHECK_NO_THROW(dispatcher
93 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -040094 std::bind([] { return true; }),
95 std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070096
97 BOOST_CHECK_THROW(dispatcher
98 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -040099 std::bind([] { return true; }),
100 std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700101 std::out_of_range);
102
103 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
Davide Pesavento152ef442023-04-22 02:02:29 -0400104 makeAcceptAllAuthorization(), std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700105 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
Davide Pesavento152ef442023-04-22 02:02:29 -0400106 makeAcceptAllAuthorization(), std::bind([]{})));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700107 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
Davide Pesavento152ef442023-04-22 02:02:29 -0400108 makeAcceptAllAuthorization(), std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700109 std::out_of_range);
110
111 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
112 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
113 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
114
115
116 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
117 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
118 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
119
120 BOOST_CHECK_THROW(dispatcher
121 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400122 std::bind([] { return true; }),
123 std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700124 std::domain_error);
125
126 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
Davide Pesavento152ef442023-04-22 02:02:29 -0400127 makeAcceptAllAuthorization(), std::bind([]{})),
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700128 std::domain_error);
129
130 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
131}
132
Junxiao Shid97c9532017-04-27 16:17:04 +0000133BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700134{
135 std::map<std::string, size_t> nCallbackCalled;
136 dispatcher
137 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400138 std::bind([] { return true; }),
139 std::bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700140
141 dispatcher
142 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400143 std::bind([] { return true; }),
144 std::bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700145
Junxiao Shi85d90832016-08-04 03:19:46 +0000146 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500147 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700148 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
149 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
150
151 dispatcher.addTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500152 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700153
Junxiao Shi85d90832016-08-04 03:19:46 +0000154 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500155 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700156 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
157 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
158
Junxiao Shi85d90832016-08-04 03:19:46 +0000159 face.receive(*makeInterest("/root/1/test/2/%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"], 1);
162 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
163
Junxiao Shi85d90832016-08-04 03:19:46 +0000164 face.receive(*makeInterest("/root/2/test/1/%80%00"));
165 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500166 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700167 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
168 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
169
170 dispatcher.addTopPrefix("/root/2");
Davide Pesavento0f830802018-01-16 23:58:58 -0500171 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700172
Junxiao Shi85d90832016-08-04 03:19:46 +0000173 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500174 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700175 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 2);
176
Junxiao Shi85d90832016-08-04 03:19:46 +0000177 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500178 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700179 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
180
181 dispatcher.removeTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500182 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700183
Junxiao Shi85d90832016-08-04 03:19:46 +0000184 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500185 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700186 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
187
Junxiao Shi85d90832016-08-04 03:19:46 +0000188 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500189 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700190 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
191}
192
Junxiao Shid97c9532017-04-27 16:17:04 +0000193BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700194{
195 size_t nCallbackCalled = 0;
196 dispatcher
197 .addControlCommand<VoidParameters>("test",
198 makeTestAuthorization(),
Davide Pesavento152ef442023-04-22 02:02:29 -0400199 std::bind([] { return true; }),
200 std::bind([&nCallbackCalled] { ++nCallbackCalled; }));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700201
202 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500203 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800204 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700205
Junxiao Shi85d90832016-08-04 03:19:46 +0000206 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
207 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
208 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
209 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
210 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Davide Pesavento0f830802018-01-16 23:58:58 -0500211 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700212 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800213 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700214
Junxiao Shi72c0c642018-04-20 15:41:09 +0000215 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800216 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000217 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800218 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700219
Junxiao Shi85d90832016-08-04 03:19:46 +0000220 face.receive(*makeInterest("/root/test/%80%00/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500221 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700222 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
223}
224
Junxiao Shid97c9532017-04-27 16:17:04 +0000225class StatefulParameters : public mgmt::ControlParameters
226{
227public:
228 explicit
229 StatefulParameters(const Block& wire)
230 {
231 wireDecode(wire);
232 }
233
234 Block
235 wireEncode() const final
236 {
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500237 return {};
Junxiao Shid97c9532017-04-27 16:17:04 +0000238 }
239
240 void
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400241 wireDecode(const Block&) final
Junxiao Shid97c9532017-04-27 16:17:04 +0000242 {
243 m_state = EXPECTED_STATE;
244 }
245
246 bool
247 check() const
248 {
249 return m_state == EXPECTED_STATE;
250 }
251
252private:
253 static constexpr int EXPECTED_STATE = 12602;
254 int m_state = 0;
255};
256
Davide Pesavento0c526032024-01-31 21:14:01 -0500257BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization,
258 * ut::description("test for bug #4059"))
Junxiao Shid97c9532017-04-27 16:17:04 +0000259{
260 AcceptContinuation authorizationAccept;
Davide Pesavento54dfc4a2024-12-26 17:30:41 -0500261 auto authorization = [&authorizationAccept] (const Name&, const Interest&, const ControlParameters*,
262 AcceptContinuation accept, RejectContinuation) {
263 authorizationAccept = std::move(accept);
264 };
Junxiao Shid97c9532017-04-27 16:17:04 +0000265
Davide Pesavento54dfc4a2024-12-26 17:30:41 -0500266 auto validateParameters = [] (const ControlParameters& params) {
267 return dynamic_cast<const StatefulParameters&>(params).check();
268 };
Junxiao Shid97c9532017-04-27 16:17:04 +0000269
270 size_t nCallbackCalled = 0;
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400271 dispatcher.addControlCommand<StatefulParameters>("test", authorization, validateParameters,
Davide Pesavento152ef442023-04-22 02:02:29 -0400272 std::bind([&nCallbackCalled] { ++nCallbackCalled; }));
Junxiao Shid97c9532017-04-27 16:17:04 +0000273
274 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500275 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000276
277 face.receive(*makeInterest("/root/test/%80%00"));
278 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
279 BOOST_REQUIRE(authorizationAccept != nullptr);
280
Davide Pesavento0f830802018-01-16 23:58:58 -0500281 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000282 authorizationAccept("");
Davide Pesavento0f830802018-01-16 23:58:58 -0500283 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000284 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
285}
286
287BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700288{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500289 const Block smallBlock({0x81, 0x01, 0x01});
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400290 const Block largeBlock = [] {
291 Block b(129, std::make_shared<const Buffer>(3000));
292 b.encode();
293 return b;
294 }();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700295
296 dispatcher.addStatusDataset("test/small",
297 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400298 [&smallBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400299 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700300 context.append(smallBlock);
301 context.append(smallBlock);
302 context.append(smallBlock);
303 context.end();
304 });
305
306 dispatcher.addStatusDataset("test/large",
307 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400308 [&largeBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400309 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700310 context.append(largeBlock);
311 context.append(largeBlock);
312 context.append(largeBlock);
313 context.end();
314 });
315
316 dispatcher.addStatusDataset("test/reject",
317 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400318 [] (const Name&, const Interest&, StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700319 context.reject();
320 });
321
322 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500323 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800324 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700325
Junxiao Shi85d90832016-08-04 03:19:46 +0000326 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
327 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
328 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500329 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700330
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400331 BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000332 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800333 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000334 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800335 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700336
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800337 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800338
Junxiao Shib55e5d32018-07-18 13:32:00 -0600339 auto interestSmall = *makeInterest("/root/test/small/valid", true);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800340 face.receive(interestSmall);
Davide Pesavento0f830802018-01-16 23:58:58 -0500341 advanceClocks(1_ms, 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800342
343 // one data packet is generated and sent to both places
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400344 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800345 BOOST_CHECK_EQUAL(storage.size(), 1);
346
347 auto fetchedData = storage.find(interestSmall);
348 BOOST_REQUIRE(fetchedData != nullptr);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000349 BOOST_CHECK_EQUAL(face.sentData[0].wireEncode(), fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700350
Junxiao Shi85d90832016-08-04 03:19:46 +0000351 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
352 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500353 advanceClocks(1_ms, 10);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400354 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800355 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700356
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800357 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700358 BOOST_CHECK_NO_THROW(content.parse());
359
Junxiao Shi72c0c642018-04-20 15:41:09 +0000360 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
361 BOOST_CHECK_EQUAL(content.elements()[0], smallBlock);
362 BOOST_CHECK_EQUAL(content.elements()[1], smallBlock);
363 BOOST_CHECK_EQUAL(content.elements()[2], smallBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700364
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800365 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800366 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000367 face.receive(*makeInterest("/root/test/large/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500368 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700369
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800370 // two data packets are generated, the first one will be sent to both places
371 // while the second one will only be inserted into the in-memory storage
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400372 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
373 BOOST_REQUIRE_EQUAL(storage.size(), 2);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800374
375 // segment0 should be sent through the face
376 const auto& component = face.sentData[0].getName().at(-1);
377 BOOST_CHECK(component.isSegment());
378 BOOST_CHECK_EQUAL(component.toSegment(), 0);
379
380 std::vector<Data> dataInStorage;
381 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
382
383 // the Data sent through the face should be the same as the first Data in the storage
384 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000385 BOOST_CHECK_EQUAL(face.sentData[0].getContent(), dataInStorage[0].getContent());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800386
387 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700388 EncodingBuffer encoder;
Davide Pesavento258d51a2022-02-27 21:26:28 -0500389 size_t valueLength = encoder.prependBytes(dataInStorage[1].getContent().value_bytes());
390 valueLength += encoder.prependBytes(dataInStorage[0].getContent().value_bytes());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700391 encoder.prependVarNumber(valueLength);
392 encoder.prependVarNumber(tlv::Content);
393 return encoder.block();
394 }();
395
396 BOOST_CHECK_NO_THROW(content.parse());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000397 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
398 BOOST_CHECK_EQUAL(content.elements()[0], largeBlock);
399 BOOST_CHECK_EQUAL(content.elements()[1], largeBlock);
400 BOOST_CHECK_EQUAL(content.elements()[2], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700401
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800402 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800403 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000404 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Davide Pesavento0f830802018-01-16 23:58:58 -0500405 advanceClocks(1_ms);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400406
407 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000408 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Nack);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800409 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800410 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 -0700411}
412
Junxiao Shid97c9532017-04-27 16:17:04 +0000413BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700414{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500415 const Block block({0x82, 0x01, 0x02});
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700416 auto post = dispatcher.addNotificationStream("test");
417
418 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500419 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800420 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700421
422 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500423 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800424 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700425
426 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500427 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800428 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800429 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700430
431 post(block);
432 post(block);
433 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500434 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700435
Junxiao Shi72c0c642018-04-20 15:41:09 +0000436 BOOST_REQUIRE_EQUAL(face.sentData.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800437 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/seq=0");
438 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/seq=1");
439 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/seq=2");
440 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/seq=3");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700441
Junxiao Shi72c0c642018-04-20 15:41:09 +0000442 BOOST_CHECK_EQUAL(face.sentData[0].getContent().blockFromValue(), block);
443 BOOST_CHECK_EQUAL(face.sentData[1].getContent().blockFromValue(), block);
444 BOOST_CHECK_EQUAL(face.sentData[2].getContent().blockFromValue(), block);
445 BOOST_CHECK_EQUAL(face.sentData[3].getContent().blockFromValue(), block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800446
447 // each version of notification will be sent to both places
448 std::vector<Data> dataInStorage;
449 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000450 BOOST_REQUIRE_EQUAL(dataInStorage.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800451 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/seq=0");
452 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/seq=1");
453 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/seq=2");
454 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/seq=3");
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800455
Junxiao Shi72c0c642018-04-20 15:41:09 +0000456 BOOST_CHECK_EQUAL(dataInStorage[0].getContent().blockFromValue(), block);
457 BOOST_CHECK_EQUAL(dataInStorage[1].getContent().blockFromValue(), block);
458 BOOST_CHECK_EQUAL(dataInStorage[2].getContent().blockFromValue(), block);
459 BOOST_CHECK_EQUAL(dataInStorage[3].getContent().blockFromValue(), block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700460}
461
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800462BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
463BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700464
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400465} // namespace ndn::tests