blob: 94f5a28d14957d9162a3c7c986c63da26af88f44 [file] [log] [blame]
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07003 * Copyright (c) 2013-2015 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
22#include "mgmt/status-dataset-context.hpp"
23#include "boost-test.hpp"
24#include "unit-tests/make-interest-data.hpp"
25
26namespace ndn {
27namespace mgmt {
28namespace tests {
29
30class StatusDatasetContextFixture
31{
32public:
33 StatusDatasetContextFixture()
34 : interest(util::makeInterest("/test/context/interest"))
35 , contentBlock(makeStringBlock(tlv::Content, "/test/data/content"))
36 , context(*interest, bind(&StatusDatasetContextFixture::sendData, this, _1, _2, _3))
37 {
38 }
39
40 void
41 sendData(const Name& dataName, const Block& content, const MetaInfo& info)
42 {
43 sentData.push_back(Data(dataName).setContent(content).setMetaInfo(info));
44 }
45
46 Block
47 concatenate()
48 {
49 EncodingBuffer encoder;
50 size_t valueLength = 0;
51 for (auto data : sentData) {
52 valueLength += encoder.appendByteArray(data.getContent().value(),
53 data.getContent().value_size());
54 }
55 encoder.prependVarNumber(valueLength);
56 encoder.prependVarNumber(tlv::Content);
57 return encoder.block();
58 }
59
60public:
61 std::vector<Data> sentData;
62 shared_ptr<Interest> interest;
63 Block contentBlock;
64 mgmt::StatusDatasetContext context;
65};
66
67BOOST_FIXTURE_TEST_SUITE(MgmtStatusDatasetContext, StatusDatasetContextFixture)
68
69BOOST_AUTO_TEST_CASE(GetPrefix)
70{
71 Name dataName = context.getPrefix();
72 BOOST_CHECK(dataName[-1].isVersion());
73 BOOST_CHECK(dataName.getPrefix(-1) == interest->getName());
74}
75
76BOOST_AUTO_TEST_SUITE(SetPrefix)
77
78BOOST_AUTO_TEST_CASE(Valid)
79{
80 Name validPrefix = Name(interest->getName()).append("/valid");
81 BOOST_CHECK_NO_THROW(context.setPrefix(validPrefix));
82 BOOST_CHECK(context.getPrefix()[-1].isVersion());
83 BOOST_CHECK(context.getPrefix().getPrefix(-1) == validPrefix);
84}
85
86BOOST_AUTO_TEST_CASE(Invalid)
87{
88 Name invalidPrefix = Name(interest->getName()).getPrefix(-1).append("/invalid");
89 BOOST_CHECK_THROW(context.setPrefix(invalidPrefix), std::invalid_argument);
90}
91
92BOOST_AUTO_TEST_CASE(ValidWithAppendCalled)
93{
94 Name validPrefix = Name(interest->getName()).append("/valid");
95 context.append(contentBlock);
96 BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
97}
98
99BOOST_AUTO_TEST_CASE(ValidWithEndCalled)
100{
101 Name validPrefix = Name(interest->getName()).append("/valid");
102 context.end();
103 BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
104}
105
106BOOST_AUTO_TEST_CASE(ValidWithRejectCalled)
107{
108 Name validPrefix = Name(interest->getName()).append("/valid");
109 context.reject();
110 BOOST_CHECK_THROW(context.setPrefix(validPrefix), std::domain_error);
111}
112
113BOOST_AUTO_TEST_SUITE_END() // SetPrefix
114
115BOOST_AUTO_TEST_CASE(Expiry)
116{
117 // getExpiry & setExpiry
118 auto period = time::milliseconds(9527);
119 BOOST_CHECK_EQUAL(context.getExpiry(), time::milliseconds(1000));
120 BOOST_CHECK_EQUAL(context.setExpiry(period).getExpiry(), period);
121}
122
123BOOST_AUTO_TEST_CASE(Respond)
124{
125 BOOST_CHECK_NO_THROW(context.append(contentBlock));
126 BOOST_CHECK(sentData.empty()); // does not call end yet
127
128 BOOST_CHECK_NO_THROW(context.end());
129 BOOST_CHECK_EQUAL(sentData.size(), 1);
130 BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
131 BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
132 BOOST_CHECK_EQUAL(sentData[0].getFinalBlockId().toSegment(), 0);
133 BOOST_CHECK(sentData[0].getContent().blockFromValue() == contentBlock);
134}
135
136BOOST_AUTO_TEST_CASE(RespondLarge)
137{
138 static Block largeBlock = [] () -> Block {
139 EncodingBuffer encoder;
140 size_t maxBlockSize = MAX_NDN_PACKET_SIZE >> 1;
141 for (size_t i = 0; i < maxBlockSize; ++i) {
142 encoder.prependByte(1);
143 }
144 encoder.prependVarNumber(maxBlockSize);
145 encoder.prependVarNumber(tlv::Content);
146 return encoder.block();
147 }();
148
149 BOOST_CHECK_NO_THROW(context.append(largeBlock));
150 BOOST_CHECK_NO_THROW(context.end());
151 BOOST_CHECK_EQUAL(sentData.size(), 2);
152 BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
153 BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
154 BOOST_CHECK_EQUAL(sentData[1].getName()[-1].toSegment(), 1);
155 BOOST_CHECK_EQUAL(sentData[1].getName().getPrefix(-1), context.getPrefix());
156 BOOST_CHECK_EQUAL(sentData[1].getFinalBlockId().toSegment(), 1);
157
158 auto contentLargeBlock = concatenate();
159 BOOST_CHECK_NO_THROW(contentLargeBlock.parse());
160 BOOST_CHECK_EQUAL(contentLargeBlock.elements().size(), 1);
161 BOOST_CHECK(contentLargeBlock.elements()[0] == largeBlock);
162}
163
164BOOST_AUTO_TEST_CASE(ResponseMultipleSmall)
165{
166 size_t nBlocks = 100;
167 for (size_t i = 0 ; i < nBlocks ; i ++) {
168 BOOST_CHECK_NO_THROW(context.append(contentBlock));
169 }
170 BOOST_CHECK_NO_THROW(context.end());
171 BOOST_CHECK_EQUAL(sentData.size(), 1);
172 BOOST_CHECK_EQUAL(sentData[0].getName()[-1].toSegment(), 0);
173 BOOST_CHECK_EQUAL(sentData[0].getName().getPrefix(-1), context.getPrefix());
174 BOOST_CHECK_EQUAL(sentData[0].getFinalBlockId().toSegment(), 0);
175
176 auto contentMultiBlocks = concatenate();
177 BOOST_CHECK_NO_THROW(contentMultiBlocks.parse());
178 BOOST_CHECK_EQUAL(contentMultiBlocks.elements().size(), nBlocks);
179 for (auto&& element : contentMultiBlocks.elements()) {
180 BOOST_CHECK(element == contentBlock);
181 }
182}
183
184BOOST_AUTO_TEST_CASE(Reject)
185{
186 BOOST_CHECK_NO_THROW(context.reject());
187 BOOST_CHECK_EQUAL(sentData.size(), 1);
188 BOOST_CHECK(sentData[0].getContentType() == tlv::ContentType_Nack);
189 BOOST_CHECK_EQUAL(ControlResponse(sentData[0].getContent().blockFromValue()).getCode(), 400);
190}
191
192BOOST_AUTO_TEST_SUITE(AbnormalState)
193
194BOOST_AUTO_TEST_CASE(AppendReject)
195{
196 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
197 BOOST_CHECK_NO_THROW(context.append(Block("\x82\x01\x02", 3)));
198 BOOST_CHECK_THROW(context.reject(), std::domain_error);
199}
200
201BOOST_AUTO_TEST_CASE(AppendEndReject)
202{
203 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
204 BOOST_CHECK_NO_THROW(context.append(Block("\x82\x01\x02", 3)));
205 BOOST_CHECK_NO_THROW(context.end());
206 BOOST_CHECK_THROW(context.reject(), std::domain_error);
207}
208
209BOOST_AUTO_TEST_CASE(EndAppend)
210{
211 mgmt::StatusDatasetContext context (Interest("/abnormal-state"), bind([]{}));
212 BOOST_CHECK_NO_THROW(context.end());
213 // end, append -> error
214 BOOST_CHECK_THROW(context.append(Block("\x82\x01\x02", 3)), std::domain_error);
215}
216
217BOOST_AUTO_TEST_CASE(EndEnd)
218{
219 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
220 BOOST_CHECK_NO_THROW(context.end());
221 BOOST_CHECK_THROW(context.end(), std::domain_error);
222}
223
224BOOST_AUTO_TEST_CASE(EndReject)
225{
226 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
227 BOOST_CHECK_NO_THROW(context.end());
228 BOOST_CHECK_THROW(context.reject(), std::domain_error);
229}
230
231BOOST_AUTO_TEST_CASE(RejectAppend)
232{
233 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
234 BOOST_CHECK_NO_THROW(context.reject());
235 BOOST_CHECK_THROW(context.append(Block("\x82\x01\x02", 3)), std::domain_error);
236}
237
238BOOST_AUTO_TEST_CASE(RejectEnd)
239{
240 mgmt::StatusDatasetContext context(Interest("/abnormal-state"), bind([]{}));
241 BOOST_CHECK_NO_THROW(context.reject());
242 BOOST_CHECK_THROW(context.end(), std::domain_error);
243}
244
245BOOST_AUTO_TEST_SUITE_END() // AbnormalState
246
247
248BOOST_AUTO_TEST_SUITE_END()
249
250} // namespace tests
251} // namespace mgmt
252} // namespace ndn