blob: f219729dab841bd6641efa3916d52ffd218d225a [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 Pesavento47ce2ee2023-05-09 01:33:33 -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/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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040026namespace ndn::tests {
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070027
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040028using namespace ndn::mgmt;
Junxiao Shi85d90832016-08-04 03:19:46 +000029
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070030class StatusDatasetContextFixture
31{
Davide Pesaventoeee3e822016-11-26 19:19:34 +010032private:
Yanbiao Li4b4f7542016-03-11 02:04:43 +080033 struct SendDataArgs
34 {
35 Name dataName;
36 Block content;
Yanbiao Li4b4f7542016-03-11 02:04:43 +080037 bool isFinalBlock;
38 };
39
Davide Pesaventoeee3e822016-11-26 19:19:34 +010040protected:
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070041 StatusDatasetContextFixture()
Junxiao Shi85d90832016-08-04 03:19:46 +000042 : interest(makeInterest("/test/context/interest"))
Yanbiao Li4b4f7542016-03-11 02:04:43 +080043 , context(*interest,
Davide Pesavento3c34ec12021-03-28 21:50:06 -040044 [this] (auto&&... args) {
45 sendDataHistory.push_back({std::forward<decltype(args)>(args)...});
Yanbiao Li4b4f7542016-03-11 02:04:43 +080046 },
Davide Pesavento3c34ec12021-03-28 21:50:06 -040047 [this] (const auto& resp) {
Yanbiao Li4b4f7542016-03-11 02:04:43 +080048 sendNackHistory.push_back(resp);
49 })
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070050 {
51 }
52
Yanbiao Li4b4f7542016-03-11 02:04:43 +080053 Name
Davide Pesaventoeee3e822016-11-26 19:19:34 +010054 makeSegmentName(size_t segmentNo) const
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070055 {
Yanbiao Li4b4f7542016-03-11 02:04:43 +080056 auto name = context.getPrefix();
57 return name.appendSegment(segmentNo);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070058 }
59
Davide Pesavento258d51a2022-02-27 21:26:28 -050060 ConstBufferPtr
Davide Pesaventoeee3e822016-11-26 19:19:34 +010061 concatenateDataContent() const
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070062 {
Davide Pesavento258d51a2022-02-27 21:26:28 -050063 auto buf = std::make_shared<Buffer>();
Davide Pesaventoeee3e822016-11-26 19:19:34 +010064 for (const auto& args : sendDataHistory) {
Davide Pesavento258d51a2022-02-27 21:26:28 -050065 buf->insert(buf->end(), args.content.value_begin(), args.content.value_end());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070066 }
Davide Pesavento258d51a2022-02-27 21:26:28 -050067 return buf;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070068 }
69
Davide Pesaventoeee3e822016-11-26 19:19:34 +010070protected:
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070071 shared_ptr<Interest> interest;
Davide Pesavento3c34ec12021-03-28 21:50:06 -040072 StatusDatasetContext context;
73 std::vector<SendDataArgs> sendDataHistory;
74 std::vector<ControlResponse> sendNackHistory;
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070075};
76
Yanbiao Li4b4f7542016-03-11 02:04:43 +080077BOOST_AUTO_TEST_SUITE(Mgmt)
78BOOST_FIXTURE_TEST_SUITE(TestStatusDatasetContext, StatusDatasetContextFixture)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070079
Davide Pesaventoeee3e822016-11-26 19:19:34 +010080BOOST_AUTO_TEST_SUITE(Prefix)
81
82BOOST_AUTO_TEST_CASE(Get)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070083{
84 Name dataName = context.getPrefix();
85 BOOST_CHECK(dataName[-1].isVersion());
Junxiao Shi72c0c642018-04-20 15:41:09 +000086 BOOST_CHECK_EQUAL(dataName.getPrefix(-1), interest->getName());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070087}
88
Davide Pesaventoeee3e822016-11-26 19:19:34 +010089BOOST_AUTO_TEST_CASE(SetValid)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070090{
91 Name validPrefix = Name(interest->getName()).append("/valid");
92 BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
Junxiao Shi72c0c642018-04-20 15:41:09 +000093 BOOST_CHECK_EQUAL(context.getPrefix().getPrefix(-1), validPrefix);
Davide Pesavento3c34ec12021-03-28 21:50:06 -040094 BOOST_CHECK(context.getPrefix()[-1].isVersion());
95
96 // trailing version component is preserved
97 validPrefix.appendVersion(42);
98 BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
99 BOOST_CHECK_EQUAL(context.getPrefix(), validPrefix);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700100}
101
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100102BOOST_AUTO_TEST_CASE(SetInvalid)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700103{
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400104 // Interest name is not a prefix of invalidPrefix
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700105 Name invalidPrefix = Name(interest->getName()).getPrefix(-1).append("/invalid");
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400106 BOOST_CHECK_EXCEPTION(context.setPrefix(invalidPrefix), std::invalid_argument, [] (const auto& e) {
107 return e.what() == "prefix must start with the Interest's name"s;
108 });
109
110 // invalidPrefix contains a segment component
111 invalidPrefix = Name(interest->getName()).appendSegment(1);
112 BOOST_CHECK_EXCEPTION(context.setPrefix(invalidPrefix), std::invalid_argument, [] (const auto& e) {
113 return e.what() == "prefix must not contain a segment component"s;
114 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700115}
116
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400117BOOST_AUTO_TEST_CASE(SetValidAfterAppend)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700118{
119 Name validPrefix = Name(interest->getName()).append("/valid");
Davide Pesavento258d51a2022-02-27 21:26:28 -0500120 context.append({0x12, 0x34});
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400121 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
122 return e.what() == "cannot call setPrefix() after append/end/reject"s;
123 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700124}
125
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400126BOOST_AUTO_TEST_CASE(SetValidAfterEnd)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700127{
128 Name validPrefix = Name(interest->getName()).append("/valid");
129 context.end();
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400130 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
131 return e.what() == "cannot call setPrefix() after append/end/reject"s;
132 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700133}
134
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400135BOOST_AUTO_TEST_CASE(SetValidAfterReject)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700136{
137 Name validPrefix = Name(interest->getName()).append("/valid");
138 context.reject();
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400139 BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
140 return e.what() == "cannot call setPrefix() after append/end/reject"s;
141 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700142}
143
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100144BOOST_AUTO_TEST_SUITE_END() // Prefix
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700145
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100146BOOST_AUTO_TEST_SUITE(Respond)
147
148BOOST_AUTO_TEST_CASE(Basic)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700149{
Davide Pesavento258d51a2022-02-27 21:26:28 -0500150 const auto testBlock = makeStringBlock(tlv::Content, "TEST");
151 context.append(testBlock);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400152 BOOST_CHECK(sendDataHistory.empty()); // end() not called yet
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700153
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400154 context.end();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800155 BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 1);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800156
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400157 const auto& args = sendDataHistory[0];
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800158 BOOST_CHECK_EQUAL(args.dataName, makeSegmentName(0));
Davide Pesavento258d51a2022-02-27 21:26:28 -0500159 BOOST_CHECK_EQUAL(args.content.blockFromValue(), testBlock);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800160 BOOST_CHECK_EQUAL(args.isFinalBlock, true);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700161}
162
Davide Pesavento258d51a2022-02-27 21:26:28 -0500163BOOST_AUTO_TEST_CASE(Empty)
164{
165 context.append({});
166 BOOST_TEST(sendDataHistory.empty()); // end() not called yet
167
168 context.end();
169 BOOST_TEST_REQUIRE(sendDataHistory.size() == 1);
170
171 const auto& args = sendDataHistory[0];
172 BOOST_TEST(args.dataName == makeSegmentName(0));
173 BOOST_TEST(args.content.value_size() == 0);
174 BOOST_TEST(args.isFinalBlock);
175}
176
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100177BOOST_AUTO_TEST_CASE(Large)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700178{
Davide Pesavento258d51a2022-02-27 21:26:28 -0500179 const std::vector<uint8_t> big(10000, 'A');
180 context.append(big);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400181 BOOST_CHECK_EQUAL(sendDataHistory.size(), 1);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700182
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400183 context.end();
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800184 BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 2);
185
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400186 // check segment 0
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800187 BOOST_CHECK_EQUAL(sendDataHistory[0].dataName, makeSegmentName(0));
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800188 BOOST_CHECK_EQUAL(sendDataHistory[0].isFinalBlock, false);
189
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400190 // check segment 1
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800191 BOOST_CHECK_EQUAL(sendDataHistory[1].dataName, makeSegmentName(1));
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800192 BOOST_CHECK_EQUAL(sendDataHistory[1].isFinalBlock, true);
193
194 // check data content
Davide Pesavento258d51a2022-02-27 21:26:28 -0500195 BOOST_TEST(*concatenateDataContent() == big, boost::test_tools::per_element());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700196}
197
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100198BOOST_AUTO_TEST_CASE(MultipleSmall)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700199{
Davide Pesavento258d51a2022-02-27 21:26:28 -0500200 const size_t nBlocks = 1000;
201 const auto contentBlock = makeStringBlock(0xFFFF, "Test Data Content");
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
Davide Pesavento258d51a2022-02-27 21:26:28 -0500207 BOOST_TEST_REQUIRE(sendDataHistory.size() == 3);
208 BOOST_TEST(sendDataHistory[0].dataName == makeSegmentName(0));
209 BOOST_TEST(!sendDataHistory[0].isFinalBlock);
210 BOOST_TEST(sendDataHistory[1].dataName == makeSegmentName(1));
211 BOOST_TEST(!sendDataHistory[1].isFinalBlock);
212 BOOST_TEST(sendDataHistory[2].dataName == makeSegmentName(2));
213 BOOST_TEST(sendDataHistory[2].isFinalBlock);
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800214
Davide Pesavento258d51a2022-02-27 21:26:28 -0500215 Block contentMultiBlocks(tlv::Content, concatenateDataContent());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400216 contentMultiBlocks.parse();
Davide Pesavento258d51a2022-02-27 21:26:28 -0500217 BOOST_TEST(contentMultiBlocks.elements().size() == nBlocks);
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400218 for (const auto& element : contentMultiBlocks.elements()) {
Davide Pesavento258d51a2022-02-27 21:26:28 -0500219 BOOST_TEST(element == contentBlock, boost::test_tools::per_element());
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700220 }
221}
222
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100223BOOST_AUTO_TEST_SUITE_END() // Respond
224
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400225BOOST_AUTO_TEST_CASE(Reject)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700226{
227 BOOST_CHECK_NO_THROW(context.reject());
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800228 BOOST_REQUIRE_EQUAL(sendNackHistory.size(), 1);
229 BOOST_CHECK_EQUAL(sendNackHistory[0].getCode(), 400);
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700230}
231
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800232class AbnormalStateTestFixture
233{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100234protected:
Davide Pesavento2e481fc2021-07-02 18:20:03 -0400235 StatusDatasetContext context{Interest("/abnormal-state"), [] (auto&&...) {}, [] (auto&&...) {}};
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800236};
237
238BOOST_FIXTURE_TEST_SUITE(AbnormalState, AbnormalStateTestFixture)
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700239
240BOOST_AUTO_TEST_CASE(AppendReject)
241{
Davide Pesavento258d51a2022-02-27 21:26:28 -0500242 BOOST_CHECK_NO_THROW(context.append({0x82, 0x01, 0x02}));
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400243 BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
244 return e.what() == "cannot call reject() after append/end"s;
245 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700246}
247
248BOOST_AUTO_TEST_CASE(AppendEndReject)
249{
Davide Pesavento258d51a2022-02-27 21:26:28 -0500250 BOOST_CHECK_NO_THROW(context.append({0x82, 0x01, 0x02}));
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700251 BOOST_CHECK_NO_THROW(context.end());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400252 BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
253 return e.what() == "cannot call reject() after append/end"s;
254 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700255}
256
257BOOST_AUTO_TEST_CASE(EndAppend)
258{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700259 BOOST_CHECK_NO_THROW(context.end());
Davide Pesavento258d51a2022-02-27 21:26:28 -0500260 BOOST_CHECK_EXCEPTION(context.append({0x82, 0x01, 0x02}), std::logic_error, [] (const auto& e) {
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400261 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 Pesavento258d51a2022-02-27 21:26:28 -0500284 BOOST_CHECK_EXCEPTION(context.append({0x82, 0x01, 0x02}), std::logic_error, [] (const auto& e) {
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400285 return e.what() == "cannot call append() on a finalized context"s;
286 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700287}
288
289BOOST_AUTO_TEST_CASE(RejectEnd)
290{
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700291 BOOST_CHECK_NO_THROW(context.reject());
Davide Pesavento3c34ec12021-03-28 21:50:06 -0400292 BOOST_CHECK_EXCEPTION(context.end(), std::logic_error, [] (const auto& e) {
293 return e.what() == "cannot call end() on a finalized context"s;
294 });
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700295}
296
297BOOST_AUTO_TEST_SUITE_END() // AbnormalState
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100298
Yanbiao Li4b4f7542016-03-11 02:04:43 +0800299BOOST_AUTO_TEST_SUITE_END() // TestStatusDatasetContext
300BOOST_AUTO_TEST_SUITE_END() // Mgmt
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700301
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400302} // namespace ndn::tests