blob: 78275167330d9bbc0de1009c6bda2cb39a87433b [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;
Davide Pesavento2e481fc2021-07-02 18:20:03 -040034using std::bind;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070035
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050036class DispatcherFixture : public IoKeyChainFixture
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070037{
38public:
39 DispatcherFixture()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050040 : face(m_io, m_keyChain, {true, true})
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080041 , dispatcher(face, m_keyChain, security::SigningInfo())
Yanbiao Li4b4f7542016-03-11 02:04:43 +080042 , storage(dispatcher.m_storage)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070043 {
44 }
45
46public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080047 util::DummyClientFace face;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070048 mgmt::Dispatcher dispatcher;
Junxiao Shic542f632017-07-18 14:20:32 +000049 InMemoryStorageFifo& storage;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070050};
51
52class VoidParameters : public mgmt::ControlParameters
53{
54public:
55 explicit
56 VoidParameters(const Block& wire)
57 {
58 wireDecode(wire);
59 }
60
Junxiao Shid97c9532017-04-27 16:17:04 +000061 Block
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020062 wireEncode() const final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070063 {
64 return Block(128);
65 }
66
Junxiao Shid97c9532017-04-27 16:17:04 +000067 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +020068 wireDecode(const Block& wire) final
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070069 {
70 if (wire.type() != 128)
Davide Pesavento923ba442019-02-12 22:00:38 -050071 NDN_THROW(tlv::Error("Expecting TLV type 128"));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070072 }
73};
74
75static Authorization
76makeTestAuthorization()
77{
Davide Pesavento3c34ec12021-03-28 21:50:06 -040078 return [] (const Name&, const Interest& interest, const ControlParameters*,
79 AcceptContinuation accept, RejectContinuation reject) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070080 if (interest.getName()[-1] == name::Component("valid")) {
81 accept("");
82 }
83 else {
84 if (interest.getName()[-1] == name::Component("silent")) {
85 reject(RejectReply::SILENT);
86 }
87 else {
88 reject(RejectReply::STATUS403);
89 }
90 }
91 };
92}
93
Junxiao Shid97c9532017-04-27 16:17:04 +000094BOOST_AUTO_TEST_SUITE(Mgmt)
95BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
96
97BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070098{
99 BOOST_CHECK_NO_THROW(dispatcher
100 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
101 bind([] { return true; }),
102 bind([]{})));
103 BOOST_CHECK_NO_THROW(dispatcher
104 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
105 bind([] { return true; }),
106 bind([]{})));
107
108 BOOST_CHECK_THROW(dispatcher
109 .addControlCommand<VoidParameters>("test", makeAcceptAllAuthorization(),
110 bind([] { return true; }),
111 bind([]{})),
112 std::out_of_range);
113
114 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/1",
115 makeAcceptAllAuthorization(), bind([]{})));
116 BOOST_CHECK_NO_THROW(dispatcher.addStatusDataset("status/2",
117 makeAcceptAllAuthorization(), bind([]{})));
118 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status",
119 makeAcceptAllAuthorization(), bind([]{})),
120 std::out_of_range);
121
122 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/1"));
123 BOOST_CHECK_NO_THROW(dispatcher.addNotificationStream("stream/2"));
124 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream"), std::out_of_range);
125
126
127 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/1"));
128 BOOST_CHECK_NO_THROW(dispatcher.addTopPrefix("/root/2"));
129 BOOST_CHECK_THROW(dispatcher.addTopPrefix("/root"), std::out_of_range);
130
131 BOOST_CHECK_THROW(dispatcher
132 .addControlCommand<VoidParameters>("test/3", makeAcceptAllAuthorization(),
133 bind([] { return true; }),
134 bind([]{})),
135 std::domain_error);
136
137 BOOST_CHECK_THROW(dispatcher.addStatusDataset("status/3",
138 makeAcceptAllAuthorization(), bind([]{})),
139 std::domain_error);
140
141 BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
142}
143
Junxiao Shid97c9532017-04-27 16:17:04 +0000144BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700145{
146 std::map<std::string, size_t> nCallbackCalled;
147 dispatcher
148 .addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
149 bind([] { return true; }),
150 bind([&nCallbackCalled] { ++nCallbackCalled["test/1"]; }));
151
152 dispatcher
153 .addControlCommand<VoidParameters>("test/2", makeAcceptAllAuthorization(),
154 bind([] { return true; }),
155 bind([&nCallbackCalled] { ++nCallbackCalled["test/2"]; }));
156
Junxiao Shi85d90832016-08-04 03:19:46 +0000157 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500158 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700159 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 0);
160 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 0);
161
162 dispatcher.addTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500163 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700164
Junxiao Shi85d90832016-08-04 03:19:46 +0000165 face.receive(*makeInterest("/root/1/test/1/%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"], 0);
169
Junxiao Shi85d90832016-08-04 03:19:46 +0000170 face.receive(*makeInterest("/root/1/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500171 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700172 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
173 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
174
Junxiao Shi85d90832016-08-04 03:19:46 +0000175 face.receive(*makeInterest("/root/2/test/1/%80%00"));
176 face.receive(*makeInterest("/root/2/test/2/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500177 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700178 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 1);
179 BOOST_CHECK_EQUAL(nCallbackCalled["test/2"], 1);
180
181 dispatcher.addTopPrefix("/root/2");
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"], 2);
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"], 3);
191
192 dispatcher.removeTopPrefix("/root/1");
Davide Pesavento0f830802018-01-16 23:58:58 -0500193 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700194
Junxiao Shi85d90832016-08-04 03:19:46 +0000195 face.receive(*makeInterest("/root/1/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500196 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700197 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 3);
198
Junxiao Shi85d90832016-08-04 03:19:46 +0000199 face.receive(*makeInterest("/root/2/test/1/%80%00"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500200 advanceClocks(1_ms);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700201 BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
202}
203
Junxiao Shid97c9532017-04-27 16:17:04 +0000204BOOST_AUTO_TEST_CASE(ControlCommand)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700205{
206 size_t nCallbackCalled = 0;
207 dispatcher
208 .addControlCommand<VoidParameters>("test",
209 makeTestAuthorization(),
210 bind([] { return true; }),
211 bind([&nCallbackCalled] { ++nCallbackCalled; }));
212
213 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500214 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800215 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700216
Junxiao Shi85d90832016-08-04 03:19:46 +0000217 face.receive(*makeInterest("/root/test/%80%00")); // returns 403
218 face.receive(*makeInterest("/root/test/%80%00/invalid")); // returns 403
219 face.receive(*makeInterest("/root/test/%80%00/silent")); // silently ignored
220 face.receive(*makeInterest("/root/test/.../invalid")); // silently ignored (wrong format)
221 face.receive(*makeInterest("/root/test/.../valid")); // silently ignored (wrong format)
Davide Pesavento0f830802018-01-16 23:58:58 -0500222 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700223 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800224 BOOST_CHECK_EQUAL(face.sentData.size(), 2);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700225
Junxiao Shi72c0c642018-04-20 15:41:09 +0000226 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800227 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000228 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800229 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700230
Junxiao Shi85d90832016-08-04 03:19:46 +0000231 face.receive(*makeInterest("/root/test/%80%00/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500232 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700233 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
234}
235
Junxiao Shid97c9532017-04-27 16:17:04 +0000236class StatefulParameters : public mgmt::ControlParameters
237{
238public:
239 explicit
240 StatefulParameters(const Block& wire)
241 {
242 wireDecode(wire);
243 }
244
245 Block
246 wireEncode() const final
247 {
248 return Block();
249 }
250
251 void
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400252 wireDecode(const Block&) final
Junxiao Shid97c9532017-04-27 16:17:04 +0000253 {
254 m_state = EXPECTED_STATE;
255 }
256
257 bool
258 check() const
259 {
260 return m_state == EXPECTED_STATE;
261 }
262
263private:
264 static constexpr int EXPECTED_STATE = 12602;
265 int m_state = 0;
266};
267
268BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
269{
270 AcceptContinuation authorizationAccept;
271 auto authorization =
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400272 [&authorizationAccept] (const Name&, const Interest&, const ControlParameters*,
273 AcceptContinuation accept, RejectContinuation) {
274 authorizationAccept = std::move(accept);
Junxiao Shid97c9532017-04-27 16:17:04 +0000275 };
276
277 auto validateParameters =
278 [] (const ControlParameters& params) {
279 return dynamic_cast<const StatefulParameters&>(params).check();
280 };
281
282 size_t nCallbackCalled = 0;
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400283 dispatcher.addControlCommand<StatefulParameters>("test", authorization, validateParameters,
284 bind([&nCallbackCalled] { ++nCallbackCalled; }));
Junxiao Shid97c9532017-04-27 16:17:04 +0000285
286 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500287 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000288
289 face.receive(*makeInterest("/root/test/%80%00"));
290 BOOST_CHECK_EQUAL(nCallbackCalled, 0);
291 BOOST_REQUIRE(authorizationAccept != nullptr);
292
Davide Pesavento0f830802018-01-16 23:58:58 -0500293 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000294 authorizationAccept("");
Davide Pesavento0f830802018-01-16 23:58:58 -0500295 advanceClocks(1_ms);
Junxiao Shid97c9532017-04-27 16:17:04 +0000296 BOOST_CHECK_EQUAL(nCallbackCalled, 1);
297}
298
299BOOST_AUTO_TEST_CASE(StatusDataset)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700300{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400301 const uint8_t smallBuf[] = {0x81, 0x01, 0x01};
302 const Block smallBlock(smallBuf, sizeof(smallBuf));
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400303 const Block largeBlock = [] {
304 Block b(129, std::make_shared<const Buffer>(3000));
305 b.encode();
306 return b;
307 }();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700308
309 dispatcher.addStatusDataset("test/small",
310 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400311 [&smallBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400312 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700313 context.append(smallBlock);
314 context.append(smallBlock);
315 context.append(smallBlock);
316 context.end();
317 });
318
319 dispatcher.addStatusDataset("test/large",
320 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400321 [&largeBlock] (const Name&, const Interest&,
Davide Pesaventob10024c2017-09-22 01:36:44 -0400322 StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700323 context.append(largeBlock);
324 context.append(largeBlock);
325 context.append(largeBlock);
326 context.end();
327 });
328
329 dispatcher.addStatusDataset("test/reject",
330 makeTestAuthorization(),
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400331 [] (const Name&, const Interest&, StatusDatasetContext& context) {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700332 context.reject();
333 });
334
335 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500336 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800337 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700338
Junxiao Shi85d90832016-08-04 03:19:46 +0000339 face.receive(*makeInterest("/root/test/small/%80%00")); // returns 403
340 face.receive(*makeInterest("/root/test/small/%80%00/invalid")); // returns 403
341 face.receive(*makeInterest("/root/test/small/%80%00/silent")); // silently ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500342 advanceClocks(1_ms, 20);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700343
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400344 BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000345 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800346 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000347 BOOST_CHECK_EQUAL(face.sentData[1].getContentType(), tlv::ContentType_Blob);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800348 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700349
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800350 face.sentData.clear();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800351
Junxiao Shib55e5d32018-07-18 13:32:00 -0600352 auto interestSmall = *makeInterest("/root/test/small/valid", true);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800353 face.receive(interestSmall);
Davide Pesavento0f830802018-01-16 23:58:58 -0500354 advanceClocks(1_ms, 10);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800355
356 // one data packet is generated and sent to both places
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400357 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800358 BOOST_CHECK_EQUAL(storage.size(), 1);
359
360 auto fetchedData = storage.find(interestSmall);
361 BOOST_REQUIRE(fetchedData != nullptr);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000362 BOOST_CHECK_EQUAL(face.sentData[0].wireEncode(), fetchedData->wireEncode());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700363
Junxiao Shi85d90832016-08-04 03:19:46 +0000364 face.receive(*makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored
365 face.receive(*makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored
Davide Pesavento0f830802018-01-16 23:58:58 -0500366 advanceClocks(1_ms, 10);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400367 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800368 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700369
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800370 Block content = face.sentData[0].getContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700371 BOOST_CHECK_NO_THROW(content.parse());
372
Junxiao Shi72c0c642018-04-20 15:41:09 +0000373 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
374 BOOST_CHECK_EQUAL(content.elements()[0], smallBlock);
375 BOOST_CHECK_EQUAL(content.elements()[1], smallBlock);
376 BOOST_CHECK_EQUAL(content.elements()[2], smallBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700377
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800378 storage.erase("/", true); // clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800379 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000380 face.receive(*makeInterest("/root/test/large/valid"));
Davide Pesavento0f830802018-01-16 23:58:58 -0500381 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700382
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800383 // two data packets are generated, the first one will be sent to both places
384 // while the second one will only be inserted into the in-memory storage
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400385 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
386 BOOST_REQUIRE_EQUAL(storage.size(), 2);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800387
388 // segment0 should be sent through the face
389 const auto& component = face.sentData[0].getName().at(-1);
390 BOOST_CHECK(component.isSegment());
391 BOOST_CHECK_EQUAL(component.toSegment(), 0);
392
393 std::vector<Data> dataInStorage;
394 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
395
396 // the Data sent through the face should be the same as the first Data in the storage
397 BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000398 BOOST_CHECK_EQUAL(face.sentData[0].getContent(), dataInStorage[0].getContent());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800399
400 content = [&dataInStorage] () -> Block {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700401 EncodingBuffer encoder;
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800402 size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(),
403 dataInStorage[1].getContent().value_size());
404 valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(),
405 dataInStorage[0].getContent().value_size());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700406 encoder.prependVarNumber(valueLength);
407 encoder.prependVarNumber(tlv::Content);
408 return encoder.block();
409 }();
410
411 BOOST_CHECK_NO_THROW(content.parse());
Junxiao Shi72c0c642018-04-20 15:41:09 +0000412 BOOST_REQUIRE_EQUAL(content.elements().size(), 3);
413 BOOST_CHECK_EQUAL(content.elements()[0], largeBlock);
414 BOOST_CHECK_EQUAL(content.elements()[1], largeBlock);
415 BOOST_CHECK_EQUAL(content.elements()[2], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700416
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800417 storage.erase("/", true);// clear the storage
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800418 face.sentData.clear();
Junxiao Shi85d90832016-08-04 03:19:46 +0000419 face.receive(*makeInterest("/root/test/reject/%80%00/valid")); // returns nack
Davide Pesavento0f830802018-01-16 23:58:58 -0500420 advanceClocks(1_ms);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400421
422 BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000423 BOOST_CHECK_EQUAL(face.sentData[0].getContentType(), tlv::ContentType_Nack);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800424 BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800425 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 -0700426}
427
Junxiao Shid97c9532017-04-27 16:17:04 +0000428BOOST_AUTO_TEST_CASE(NotificationStream)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700429{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400430 const uint8_t buf[] = {0x82, 0x01, 0x02};
431 const Block block(buf, sizeof(buf));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700432 auto post = dispatcher.addNotificationStream("test");
433
434 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500435 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800436 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700437
438 dispatcher.addTopPrefix("/root");
Davide Pesavento0f830802018-01-16 23:58:58 -0500439 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800440 face.sentData.clear();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700441
442 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500443 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800444 BOOST_CHECK_EQUAL(face.sentData.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800445 BOOST_CHECK_EQUAL(storage.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700446
447 post(block);
448 post(block);
449 post(block);
Davide Pesavento0f830802018-01-16 23:58:58 -0500450 advanceClocks(1_ms, 10);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700451
Junxiao Shi72c0c642018-04-20 15:41:09 +0000452 BOOST_REQUIRE_EQUAL(face.sentData.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800453 BOOST_CHECK_EQUAL(face.sentData[0].getName(), "/root/test/seq=0");
454 BOOST_CHECK_EQUAL(face.sentData[1].getName(), "/root/test/seq=1");
455 BOOST_CHECK_EQUAL(face.sentData[2].getName(), "/root/test/seq=2");
456 BOOST_CHECK_EQUAL(face.sentData[3].getName(), "/root/test/seq=3");
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700457
Junxiao Shi72c0c642018-04-20 15:41:09 +0000458 BOOST_CHECK_EQUAL(face.sentData[0].getContent().blockFromValue(), block);
459 BOOST_CHECK_EQUAL(face.sentData[1].getContent().blockFromValue(), block);
460 BOOST_CHECK_EQUAL(face.sentData[2].getContent().blockFromValue(), block);
461 BOOST_CHECK_EQUAL(face.sentData[3].getContent().blockFromValue(), block);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800462
463 // each version of notification will be sent to both places
464 std::vector<Data> dataInStorage;
465 std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000466 BOOST_REQUIRE_EQUAL(dataInStorage.size(), 4);
Eric Newberryc25e4632021-02-11 10:48:11 -0800467 BOOST_CHECK_EQUAL(dataInStorage[0].getName(), "/root/test/seq=0");
468 BOOST_CHECK_EQUAL(dataInStorage[1].getName(), "/root/test/seq=1");
469 BOOST_CHECK_EQUAL(dataInStorage[2].getName(), "/root/test/seq=2");
470 BOOST_CHECK_EQUAL(dataInStorage[3].getName(), "/root/test/seq=3");
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800471
Junxiao Shi72c0c642018-04-20 15:41:09 +0000472 BOOST_CHECK_EQUAL(dataInStorage[0].getContent().blockFromValue(), block);
473 BOOST_CHECK_EQUAL(dataInStorage[1].getContent().blockFromValue(), block);
474 BOOST_CHECK_EQUAL(dataInStorage[2].getContent().blockFromValue(), block);
475 BOOST_CHECK_EQUAL(dataInStorage[3].getContent().blockFromValue(), block);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700476}
477
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800478BOOST_AUTO_TEST_SUITE_END() // TestDispatcher
479BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700480
481} // namespace tests
482} // namespace mgmt
483} // namespace ndn