blob: 6314e2e59a108aff6ce6e400554bb60423af26e4 [file] [log] [blame]
Junxiao Shi64567bb2016-09-04 16:00:27 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventod2147442018-02-19 23:58:17 -05002/*
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shi64567bb2016-09-04 16:00:27 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "nfdc/command-definition.hpp"
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040027#include "nfdc/status-report.hpp"
Junxiao Shi64567bb2016-09-04 16:00:27 +000028
29#include "tests/test-common.hpp"
30
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::tools::nfdc::tests {
Junxiao Shi64567bb2016-09-04 16:00:27 +000032
Junxiao Shi64567bb2016-09-04 16:00:27 +000033BOOST_AUTO_TEST_SUITE(Nfdc)
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040034BOOST_AUTO_TEST_SUITE(TestCommandDefinition)
Junxiao Shi64567bb2016-09-04 16:00:27 +000035
36BOOST_AUTO_TEST_SUITE(Arguments)
37
38BOOST_AUTO_TEST_CASE(NoArg)
39{
40 CommandDefinition cs("noun", "verb");
41
42 CommandArguments ca;
43
44 ca = cs.parse(std::vector<std::string>{});
45 BOOST_CHECK_EQUAL(ca.size(), 0);
46
47 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x"}), CommandDefinition::Error);
48 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x", "y"}), CommandDefinition::Error);
49}
50
51BOOST_AUTO_TEST_CASE(NamedArgs)
52{
53 CommandDefinition cs("noun", "verb");
54 cs.addArg("a", ArgValueType::UNSIGNED, Required::NO, Positional::NO, "int")
55 .addArg("b", ArgValueType::NAME, Required::NO, Positional::NO, "name");
56
57 CommandArguments ca;
58
59 ca = cs.parse(std::vector<std::string>{});
60 BOOST_CHECK_EQUAL(ca.size(), 0);
61
62 ca = cs.parse(std::vector<std::string>{"a", "1"});
63 BOOST_CHECK_EQUAL(ca.size(), 1);
64 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
65
66 ca = cs.parse(std::vector<std::string>{"a", "1", "b", "/n"});
67 BOOST_CHECK_EQUAL(ca.size(), 2);
68 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
69 BOOST_CHECK_EQUAL(ca.get<Name>("b"), "/n");
70
71 ca = cs.parse(std::vector<std::string>{"b", "/n", "a", "1"});
72 BOOST_CHECK_EQUAL(ca.size(), 2);
73 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
74 BOOST_CHECK_EQUAL(ca.get<Name>("b"), "/n");
75
76 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"1"}), CommandDefinition::Error);
77 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"c", "1"}), CommandDefinition::Error);
78}
79
80BOOST_AUTO_TEST_CASE(PositionalArgs)
81{
82 CommandDefinition cs("face", "create");
83 cs.addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
84 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES);
85
86 CommandArguments ca;
87
88 ca = cs.parse(std::vector<std::string>{"udp4://router.example.com", "persistent"});
89 BOOST_CHECK_EQUAL(ca.size(), 2);
90 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
91 FaceUri("udp4://router.example.com"));
92 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
93 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
94
95 ca = cs.parse(std::vector<std::string>{"udp4://router.example.com"});
96 BOOST_CHECK_EQUAL(ca.size(), 1);
97 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
98 FaceUri("udp4://router.example.com"));
99
100 ca = cs.parse(std::vector<std::string>{"remote", "udp4://router.example.com"});
101 BOOST_CHECK_EQUAL(ca.size(), 1);
102 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
103 FaceUri("udp4://router.example.com"));
104
105 ca = cs.parse(std::vector<std::string>{
106 "udp4://router.example.com", "persistency", "persistent"});
107 BOOST_CHECK_EQUAL(ca.size(), 2);
108 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
109 FaceUri("udp4://router.example.com"));
110 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
111 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
112
113 ca = cs.parse(std::vector<std::string>{
114 "remote", "udp4://router.example.com", "persistency", "persistent"});
115 BOOST_CHECK_EQUAL(ca.size(), 2);
116 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
117 FaceUri("udp4://router.example.com"));
118 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
119 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
120
121 ca = cs.parse(std::vector<std::string>{
122 "persistency", "persistent", "remote", "udp4://router.example.com"});
123 BOOST_CHECK_EQUAL(ca.size(), 2);
124 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
125 FaceUri("udp4://router.example.com"));
126 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
127 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
128
129 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
130 "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
131 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
132 "persistency", "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
133 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
134 "remote", "udp4://router.example.com", "persistent"}), CommandDefinition::Error);
135}
136
137BOOST_AUTO_TEST_SUITE_END() // Arguments
138
139BOOST_AUTO_TEST_SUITE(ParseValue)
140
141BOOST_AUTO_TEST_CASE(NoneType)
142{
Davide Pesaventod2147442018-02-19 23:58:17 -0500143 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NONE), "none");
144
Junxiao Shi64567bb2016-09-04 16:00:27 +0000145 CommandDefinition cs("noun", "verb");
146 cs.addArg("a", ArgValueType::NONE, Required::YES, Positional::NO);
147
148 CommandArguments ca;
149
150 ca = cs.parse(std::vector<std::string>{"a"});
151 BOOST_CHECK_EQUAL(ca.size(), 1);
152 BOOST_CHECK(ca.at("a").type() == typeid(bool));
153 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
154
155 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "value"}), CommandDefinition::Error);
156}
157
158BOOST_AUTO_TEST_CASE(AnyType)
159{
Davide Pesaventod2147442018-02-19 23:58:17 -0500160 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ANY), "any");
161
Junxiao Shi64567bb2016-09-04 16:00:27 +0000162 CommandDefinition cs("noun", "verb");
163 cs.addArg("a", ArgValueType::ANY, Required::NO, Positional::YES);
164
165 CommandArguments ca;
166
167 ca = cs.parse(std::vector<std::string>{});
168 BOOST_CHECK_EQUAL(ca.size(), 0);
169
170 ca = cs.parse(std::vector<std::string>{"a"});
171 BOOST_CHECK_EQUAL(ca.size(), 1);
172 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
173 std::vector<std::string> values = ca.get<std::vector<std::string>>("a");
174 BOOST_CHECK_EQUAL(values.size(), 1);
175 BOOST_CHECK_EQUAL(values.at(0), "a");
176
177 ca = cs.parse(std::vector<std::string>{"b", "c"});
178 BOOST_CHECK_EQUAL(ca.size(), 1);
179 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
180 values = ca.get<std::vector<std::string>>("a");
181 BOOST_CHECK_EQUAL(values.size(), 2);
182 BOOST_CHECK_EQUAL(values.at(0), "b");
183 BOOST_CHECK_EQUAL(values.at(1), "c");
184}
185
Davide Pesaventod2147442018-02-19 23:58:17 -0500186BOOST_AUTO_TEST_CASE(BooleanType)
187{
188 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::BOOLEAN), "boolean");
189
190 CommandDefinition cs("noun", "verb");
191 cs.addArg("a", ArgValueType::BOOLEAN, Required::YES);
192
193 CommandArguments ca;
194
195 ca = cs.parse({"a", "on"});
196 BOOST_CHECK_EQUAL(ca.size(), 1);
197 BOOST_CHECK(ca.at("a").type() == typeid(bool));
198 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
199
200 ca = cs.parse({"a", "off"});
201 BOOST_CHECK_EQUAL(ca.size(), 1);
202 BOOST_CHECK(ca.at("a").type() == typeid(bool));
203 BOOST_CHECK_EQUAL(ca.get<bool>("a"), false);
204
205 BOOST_CHECK_EQUAL(cs.parse({"a", "true"}).get<bool>("a"), true);
206 BOOST_CHECK_EQUAL(cs.parse({"a", "enabled"}).get<bool>("a"), true);
207 BOOST_CHECK_EQUAL(cs.parse({"a", "yes"}).get<bool>("a"), true);
208 BOOST_CHECK_EQUAL(cs.parse({"a", "1"}).get<bool>("a"), true);
209 BOOST_CHECK_EQUAL(cs.parse({"a", "false"}).get<bool>("a"), false);
210 BOOST_CHECK_EQUAL(cs.parse({"a", "disabled"}).get<bool>("a"), false);
211 BOOST_CHECK_EQUAL(cs.parse({"a", "no"}).get<bool>("a"), false);
212 BOOST_CHECK_EQUAL(cs.parse({"a", "0"}).get<bool>("a"), false);
213
214 BOOST_CHECK_THROW(cs.parse({"a", "42"}), CommandDefinition::Error);
215 BOOST_CHECK_THROW(cs.parse({"a", "not-bool"}), CommandDefinition::Error);
216}
217
Junxiao Shi64567bb2016-09-04 16:00:27 +0000218BOOST_AUTO_TEST_CASE(UnsignedType)
219{
Davide Pesaventod2147442018-02-19 23:58:17 -0500220 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::UNSIGNED), "non-negative integer");
221
Junxiao Shi64567bb2016-09-04 16:00:27 +0000222 CommandDefinition cs("noun", "verb");
223 cs.addArg("a", ArgValueType::UNSIGNED, Required::YES);
224
225 CommandArguments ca;
226
227 ca = cs.parse(std::vector<std::string>{"a", "0"});
228 BOOST_CHECK_EQUAL(ca.size(), 1);
229 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
230 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 0);
231
232 ca = cs.parse(std::vector<std::string>{"a", "12923"});
233 BOOST_CHECK_EQUAL(ca.size(), 1);
234 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
235 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 12923);
236
237 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "-25705"}), CommandDefinition::Error);
238 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-uint"}), CommandDefinition::Error);
239}
240
241BOOST_AUTO_TEST_CASE(StringType)
242{
Davide Pesaventod2147442018-02-19 23:58:17 -0500243 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::STRING), "string");
244
Junxiao Shi64567bb2016-09-04 16:00:27 +0000245 CommandDefinition cs("noun", "verb");
246 cs.addArg("a", ArgValueType::STRING, Required::YES);
247
248 CommandArguments ca;
249
250 ca = cs.parse(std::vector<std::string>{"a", "hello"});
251 BOOST_CHECK_EQUAL(ca.size(), 1);
252 BOOST_CHECK(ca.at("a").type() == typeid(std::string));
253 BOOST_CHECK_EQUAL(ca.get<std::string>("a"), "hello");
254}
255
256BOOST_AUTO_TEST_CASE(ReportFormatType)
257{
Davide Pesaventod2147442018-02-19 23:58:17 -0500258 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::REPORT_FORMAT), "ReportFormat");
259
Junxiao Shi64567bb2016-09-04 16:00:27 +0000260 CommandDefinition cs("noun", "verb");
261 cs.addArg("a", ArgValueType::REPORT_FORMAT, Required::YES);
262
263 CommandArguments ca;
264
265 ca = cs.parse(std::vector<std::string>{"a", "xml"});
266 BOOST_CHECK_EQUAL(ca.size(), 1);
267 BOOST_CHECK(ca.at("a").type() == typeid(ReportFormat));
268 BOOST_CHECK_EQUAL(ca.get<ReportFormat>("a"), ReportFormat::XML);
269
270 ca = cs.parse(std::vector<std::string>{"a", "text"});
271 BOOST_CHECK_EQUAL(ca.size(), 1);
272 BOOST_CHECK(ca.at("a").type() == typeid(ReportFormat));
273 BOOST_CHECK_EQUAL(ca.get<ReportFormat>("a"), ReportFormat::TEXT);
274
275 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-fmt"}), CommandDefinition::Error);
276}
277
278BOOST_AUTO_TEST_CASE(NameType)
279{
Davide Pesaventod2147442018-02-19 23:58:17 -0500280 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NAME), "Name");
281
Junxiao Shi64567bb2016-09-04 16:00:27 +0000282 CommandDefinition cs("noun", "verb");
283 cs.addArg("a", ArgValueType::NAME, Required::YES);
284
285 CommandArguments ca;
286
287 ca = cs.parse(std::vector<std::string>{"a", "/n"});
288 BOOST_CHECK_EQUAL(ca.size(), 1);
289 BOOST_CHECK(ca.at("a").type() == typeid(Name));
290 BOOST_CHECK_EQUAL(ca.get<Name>("a"), "/n");
291}
292
293BOOST_AUTO_TEST_CASE(FaceUriType)
294{
Davide Pesaventod2147442018-02-19 23:58:17 -0500295 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_URI), "FaceUri");
296
Junxiao Shi64567bb2016-09-04 16:00:27 +0000297 CommandDefinition cs("noun", "verb");
298 cs.addArg("a", ArgValueType::FACE_URI, Required::YES);
299
300 CommandArguments ca;
301
302 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
303 BOOST_CHECK_EQUAL(ca.size(), 1);
304 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
305 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
306
307 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "208"}), CommandDefinition::Error);
308 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
309}
310
311BOOST_AUTO_TEST_CASE(FaceIdOrUriType)
312{
Davide Pesaventod2147442018-02-19 23:58:17 -0500313 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_ID_OR_URI), "FaceId or FaceUri");
314
Junxiao Shi64567bb2016-09-04 16:00:27 +0000315 CommandDefinition cs("noun", "verb");
316 cs.addArg("a", ArgValueType::FACE_ID_OR_URI, Required::YES);
317
318 CommandArguments ca;
319
320 ca = cs.parse(std::vector<std::string>{"a", "208"});
321 BOOST_CHECK_EQUAL(ca.size(), 1);
322 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
323 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 208);
324
325 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
326 BOOST_CHECK_EQUAL(ca.size(), 1);
327 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
328 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
329
330 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
331}
332
333BOOST_AUTO_TEST_CASE(FacePersistencyType)
334{
Davide Pesaventod2147442018-02-19 23:58:17 -0500335 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_PERSISTENCY), "FacePersistency");
336
Junxiao Shi64567bb2016-09-04 16:00:27 +0000337 CommandDefinition cs("noun", "verb");
338 cs.addArg("a", ArgValueType::FACE_PERSISTENCY, Required::YES);
339
340 CommandArguments ca;
341
342 ca = cs.parse(std::vector<std::string>{"a", "persistent"});
343 BOOST_CHECK_EQUAL(ca.size(), 1);
344 BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency));
Davide Pesaventod2147442018-02-19 23:58:17 -0500345 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("a"), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000346
347 ca = cs.parse(std::vector<std::string>{"a", "permanent"});
348 BOOST_CHECK_EQUAL(ca.size(), 1);
349 BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency));
Davide Pesaventod2147442018-02-19 23:58:17 -0500350 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("a"), FacePersistency::FACE_PERSISTENCY_PERMANENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000351
352 // nfdc does not accept "on-demand"
353 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "on-demand"}), CommandDefinition::Error);
354}
355
Junxiao Shi8eda6822017-04-12 02:53:14 +0000356BOOST_AUTO_TEST_CASE(RouteOriginType)
357{
Davide Pesaventod2147442018-02-19 23:58:17 -0500358 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ROUTE_ORIGIN), "RouteOrigin");
359
Junxiao Shi8eda6822017-04-12 02:53:14 +0000360 CommandDefinition cs("noun", "verb");
361 cs.addArg("a", ArgValueType::ROUTE_ORIGIN, Required::YES);
362
363 CommandArguments ca;
364
365 ca = cs.parse(std::vector<std::string>{"a", "Nlsr"});
366 BOOST_CHECK_EQUAL(ca.size(), 1);
367 BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin));
Davide Pesaventod2147442018-02-19 23:58:17 -0500368 BOOST_CHECK_EQUAL(ca.get<RouteOrigin>("a"), RouteOrigin::ROUTE_ORIGIN_NLSR);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000369
370 ca = cs.parse(std::vector<std::string>{"a", "27"});
371 BOOST_CHECK_EQUAL(ca.size(), 1);
372 BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin));
Davide Pesaventod2147442018-02-19 23:58:17 -0500373 BOOST_CHECK_EQUAL(ca.get<RouteOrigin>("a"), static_cast<RouteOrigin>(27));
Junxiao Shi8eda6822017-04-12 02:53:14 +0000374
375 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-RouteOrigin"}), CommandDefinition::Error);
376}
377
Junxiao Shi64567bb2016-09-04 16:00:27 +0000378BOOST_AUTO_TEST_SUITE_END() // ParseValue
379
380BOOST_AUTO_TEST_SUITE_END() // TestCommandDefinition
381BOOST_AUTO_TEST_SUITE_END() // Nfdc
382
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400383} // namespace nfd::tools::nfdc::tests