blob: 6d1e0b9418ce09a8a84eb568f41b5dae9d97f11f [file] [log] [blame]
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi2bea5c42017-08-14 20:10: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/status-dataset-context.hpp"
Davide Pesaventoeee3e822016-11-26 19:19:34 +010023
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050024#include "tests/test-common.hpp"
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070025
26namespace ndn {
27namespace mgmt {
28namespace tests {
29
Junxiao Shi85d90832016-08-04 03:19:46 +000030using namespace ndn::tests;
31
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070032class StatusDatasetContextFixture
33{
Davide Pesaventoeee3e822016-11-26 19:19:34 +010034private:
Yanbiao Li4b4f7542016-03-11 02:04:43 +080035 struct SendDataArgs
36 {
37 Name dataName;
38 Block content;
Yanbiao Li4b4f7542016-03-11 02:04:43 +080039 bool isFinalBlock;
40 };
41
Davide Pesaventoeee3e822016-11-26 19:19:34 +010042protected:
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070043 StatusDatasetContextFixture()
Junxiao Shi85d90832016-08-04 03:19:46 +000044 : interest(makeInterest("/test/context/interest"))
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070045 , contentBlock(makeStringBlock(tlv::Content, "/test/data/content"))
Yanbiao Li4b4f7542016-03-11 02:04:43 +080046 , context(*interest,
Davide Pesavento3c34ec12021-03-28 21:50:06 -040047 [this] (auto&&... args) {
48 sendDataHistory.push_back({std::forward<decltype(args)>(args)...});
Yanbiao Li4b4f7542016-03-11 02:04:43 +080049 },
Davide Pesavento3c34ec12021-03-28 21:50:06 -040050 [this] (const auto& resp) {
Yanbiao Li4b4f7542016-03-11 02:04:43 +080051 sendNackHistory.push_back(resp);
52 })
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070053 {
54 }
55
Yanbiao Li4b4f7542016-03-11 02:04:43 +080056 Name
Davide Pesaventoeee3e822016-11-26 19:19:34 +010057 makeSegmentName(size_t segmentNo) const
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070058 {
Yanbiao Li4b4f7542016-03-11 02:04:43 +080059 auto name = context.getPrefix();
60 return name.appendSegment(segmentNo);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070061 }
62
63 Block
Davide Pesaventoeee3e822016-11-26 19:19:34 +010064 concatenateDataContent() const
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070065 {
66 EncodingBuffer encoder;
67 size_t valueLength = 0;
Davide Pesaventoeee3e822016-11-26 19:19:34 +010068 for (const auto& args : sendDataHistory) {
Yanbiao Li4b4f7542016-03-11 02:04:43 +080069 const auto& content = args.content;
70 valueLength += encoder.appendByteArray(content.value(), content.value_size());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070071 }
72 encoder.prependVarNumber(valueLength);
73 encoder.prependVarNumber(tlv::Content);
74 return encoder.block();
75 }
76
Davide Pesaventoeee3e822016-11-26 19:19:34 +010077protected:
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070078 shared_ptr<Interest> interest;
79 Block contentBlock;
Davide Pesavento3c34ec12021-03-28 21:50:06 -040080 StatusDatasetContext context;
81 std::vector<SendDataArgs> sendDataHistory;
82 std::vector<ControlResponse> sendNackHistory;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070083};
84
Yanbiao Li4b4f7542016-03-11 02:04:43 +080085BOOST_AUTO_TEST_SUITE(Mgmt)
86BOOST_FIXTURE_TEST_SUITE(TestStatusDatasetContext, StatusDatasetContextFixture)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070087
Davide Pesaventoeee3e822016-11-26 19:19:34 +010088BOOST_AUTO_TEST_SUITE(Prefix)
89
90BOOST_AUTO_TEST_CASE(Get)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070091{
92 Name dataName = context.getPrefix();
93 BOOST_CHECK(dataName[-1].isVersion());
Junxiao Shi72c0c642018-04-20 15:41:09 +000094 BOOST_CHECK_EQUAL(dataName.getPrefix(-1), interest->getName());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070095}
96
Davide Pesaventoeee3e822016-11-26 19:19:34 +010097BOOST_AUTO_TEST_CASE(SetValid)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070098{
99 Name validPrefix = Name(interest->getName()).append("/valid");
100 BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000101 BOOST_CHECK_EQUAL(context.getPrefix().getPrefix(-1), validPrefix);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400102 BOOST_CHECK(context.getPrefix()[-1].isVersion());
103
104 // trailing version component is preserved
105 validPrefix.appendVersion(42);
106 BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
107 BOOST_CHECK_EQUAL(context.getPrefix(), validPrefix);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700108}
109
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100110BOOST_AUTO_TEST_CASE(SetInvalid)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700111{
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400112 // Interest name is not a prefix of invalidPrefix
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700113 Name invalidPrefix = Name(interest->getName()).getPrefix(-1).append("/invalid");
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400114 BOOST_CHECK_EXCEPTION(context.setPrefix(invalidPrefix), std::invalid_argument, [] (const auto& e) {
115 return e.what() == "prefix must start with the Interest's name"s;
116 });
117
118 // invalidPrefix contains a segment component
119 invalidPrefix = Name(interest->getName()).appendSegment(1);
120 BOOST_CHECK_EXCEPTION(context.setPrefix(invalidPrefix), std::invalid_argument, [] (const auto& e) {
121 return e.what() == "prefix must not contain a segment component"s;
122 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700123}
124
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400125BOOST_AUTO_TEST_CASE(SetValidAfterAppend)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700126{
127 Name validPrefix = Name(interest->getName()).append("/valid");
128 context.append(contentBlock);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400129 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
130 return e.what() == "cannot call setPrefix() after append/end/reject"s;
131 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700132}
133
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400134BOOST_AUTO_TEST_CASE(SetValidAfterEnd)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700135{
136 Name validPrefix = Name(interest->getName()).append("/valid");
137 context.end();
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400138 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
139 return e.what() == "cannot call setPrefix() after append/end/reject"s;
140 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700141}
142
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400143BOOST_AUTO_TEST_CASE(SetValidAfterReject)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700144{
145 Name validPrefix = Name(interest->getName()).append("/valid");
146 context.reject();
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400147 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
148 return e.what() == "cannot call setPrefix() after append/end/reject"s;
149 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700150}
151
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100152BOOST_AUTO_TEST_SUITE_END() // Prefix
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700153
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100154BOOST_AUTO_TEST_SUITE(Respond)
155
156BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700157{
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400158 context.append(contentBlock);
159 BOOST_CHECK(sendDataHistory.empty()); // end() not called yet
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700160
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400161 context.end();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800162 BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800163
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400164 const auto& args = sendDataHistory[0];
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800165 BOOST_CHECK_EQUAL(args.dataName, makeSegmentName(0));
Junxiao Shi72c0c642018-04-20 15:41:09 +0000166 BOOST_CHECK_EQUAL(args.content.blockFromValue(), contentBlock);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800167 BOOST_CHECK_EQUAL(args.isFinalBlock, true);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700168}
169
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100170BOOST_AUTO_TEST_CASE(Large)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700171{
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400172 const Block largeBlock = [] {
173 Block b(tlv::Content, std::make_shared<const Buffer>(10000));
174 b.encode();
175 return b;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700176 }();
177
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400178 context.append(largeBlock);
179 BOOST_CHECK_EQUAL(sendDataHistory.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700180
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400181 context.end();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800182 BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 2);
183
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400184 // check segment 0
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800185 BOOST_CHECK_EQUAL(sendDataHistory[0].dataName, makeSegmentName(0));
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800186 BOOST_CHECK_EQUAL(sendDataHistory[0].isFinalBlock, false);
187
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400188 // check segment 1
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800189 BOOST_CHECK_EQUAL(sendDataHistory[1].dataName, makeSegmentName(1));
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800190 BOOST_CHECK_EQUAL(sendDataHistory[1].isFinalBlock, true);
191
192 // check data content
193 auto contentLargeBlock = concatenateDataContent();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700194 BOOST_CHECK_NO_THROW(contentLargeBlock.parse());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800195 BOOST_REQUIRE_EQUAL(contentLargeBlock.elements().size(), 1);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000196 BOOST_CHECK_EQUAL(contentLargeBlock.elements()[0], largeBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700197}
198
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100199BOOST_AUTO_TEST_CASE(MultipleSmall)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700200{
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400201 const size_t nBlocks = 100;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700202 for (size_t i = 0 ; i < nBlocks ; i ++) {
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400203 context.append(contentBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700204 }
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400205 context.end();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700206
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800207 // check data to in-memory storage
208 BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 1);
209 BOOST_CHECK_EQUAL(sendDataHistory[0].dataName, makeSegmentName(0));
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800210 BOOST_CHECK_EQUAL(sendDataHistory[0].isFinalBlock, true);
211
212 auto contentMultiBlocks = concatenateDataContent();
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400213 contentMultiBlocks.parse();
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700214 BOOST_CHECK_EQUAL(contentMultiBlocks.elements().size(), nBlocks);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400215 for (const auto& element : contentMultiBlocks.elements()) {
Junxiao Shi72c0c642018-04-20 15:41:09 +0000216 BOOST_CHECK_EQUAL(element, contentBlock);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700217 }
218}
219
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100220BOOST_AUTO_TEST_SUITE_END() // Respond
221
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400222BOOST_AUTO_TEST_CASE(Reject)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700223{
224 BOOST_CHECK_NO_THROW(context.reject());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800225 BOOST_REQUIRE_EQUAL(sendNackHistory.size(), 1);
226 BOOST_CHECK_EQUAL(sendNackHistory[0].getCode(), 400);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700227}
228
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800229class AbnormalStateTestFixture
230{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100231protected:
Davide Pesavento2e481fc2021-07-02 18:20:03 -0400232 StatusDatasetContext context{Interest("/abnormal-state"), [] (auto&&...) {}, [] (auto&&...) {}};
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800233};
234
235BOOST_FIXTURE_TEST_SUITE(AbnormalState, AbnormalStateTestFixture)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700236
237BOOST_AUTO_TEST_CASE(AppendReject)
238{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400239 const uint8_t buf[] = {0x82, 0x01, 0x02};
240 BOOST_CHECK_NO_THROW(context.append(Block(buf, sizeof(buf))));
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400241 BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
242 return e.what() == "cannot call reject() after append/end"s;
243 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700244}
245
246BOOST_AUTO_TEST_CASE(AppendEndReject)
247{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400248 const uint8_t buf[] = {0x82, 0x01, 0x02};
249 BOOST_CHECK_NO_THROW(context.append(Block(buf, sizeof(buf))));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700250 BOOST_CHECK_NO_THROW(context.end());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400251 BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
252 return e.what() == "cannot call reject() after append/end"s;
253 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700254}
255
256BOOST_AUTO_TEST_CASE(EndAppend)
257{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700258 BOOST_CHECK_NO_THROW(context.end());
Davide Pesaventob10024c2017-09-22 01:36:44 -0400259 const uint8_t buf[] = {0x82, 0x01, 0x02};
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400260 BOOST_CHECK_EXCEPTION(context.append(Block(buf, sizeof(buf))), std::logic_error, [] (const auto& e) {
261 return e.what() == "cannot call append() on a finalized context"s;
262 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700263}
264
265BOOST_AUTO_TEST_CASE(EndEnd)
266{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700267 BOOST_CHECK_NO_THROW(context.end());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400268 BOOST_CHECK_EXCEPTION(context.end(), std::logic_error, [] (const auto& e) {
269 return e.what() == "cannot call end() on a finalized context"s;
270 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700271}
272
273BOOST_AUTO_TEST_CASE(EndReject)
274{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700275 BOOST_CHECK_NO_THROW(context.end());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400276 BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
277 return e.what() == "cannot call reject() after append/end"s;
278 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700279}
280
281BOOST_AUTO_TEST_CASE(RejectAppend)
282{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700283 BOOST_CHECK_NO_THROW(context.reject());
Davide Pesaventob10024c2017-09-22 01:36:44 -0400284 const uint8_t buf[] = {0x82, 0x01, 0x02};
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400285 BOOST_CHECK_EXCEPTION(context.append(Block(buf, sizeof(buf))), std::logic_error, [] (const auto& e) {
286 return e.what() == "cannot call append() on a finalized context"s;
287 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700288}
289
290BOOST_AUTO_TEST_CASE(RejectEnd)
291{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700292 BOOST_CHECK_NO_THROW(context.reject());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400293 BOOST_CHECK_EXCEPTION(context.end(), std::logic_error, [] (const auto& e) {
294 return e.what() == "cannot call end() on a finalized context"s;
295 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700296}
297
298BOOST_AUTO_TEST_SUITE_END() // AbnormalState
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100299
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800300BOOST_AUTO_TEST_SUITE_END() // TestStatusDatasetContext
301BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700302
303} // namespace tests
304} // namespace mgmt
305} // namespace ndn