blob: 0b4e0d0261419a3dcfa25d0332228c399e5a5c90 [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 Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, 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 Pesavento2c9d2ca2024-01-27 16:36:51 -050031#include <ndn-cxx/net/face-uri.hpp>
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040032#include <boost/lexical_cast.hpp>
33
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::tools::nfdc::tests {
Junxiao Shi64567bb2016-09-04 16:00:27 +000035
Junxiao Shi64567bb2016-09-04 16:00:27 +000036BOOST_AUTO_TEST_SUITE(Nfdc)
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040037BOOST_AUTO_TEST_SUITE(TestCommandDefinition)
Junxiao Shi64567bb2016-09-04 16:00:27 +000038
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -050039using ndn::FaceUri;
40
Junxiao Shi64567bb2016-09-04 16:00:27 +000041BOOST_AUTO_TEST_SUITE(Arguments)
42
43BOOST_AUTO_TEST_CASE(NoArg)
44{
45 CommandDefinition cs("noun", "verb");
46
47 CommandArguments ca;
48
49 ca = cs.parse(std::vector<std::string>{});
50 BOOST_CHECK_EQUAL(ca.size(), 0);
51
52 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x"}), CommandDefinition::Error);
53 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x", "y"}), CommandDefinition::Error);
54}
55
56BOOST_AUTO_TEST_CASE(NamedArgs)
57{
58 CommandDefinition cs("noun", "verb");
59 cs.addArg("a", ArgValueType::UNSIGNED, Required::NO, Positional::NO, "int")
60 .addArg("b", ArgValueType::NAME, Required::NO, Positional::NO, "name");
61
62 CommandArguments ca;
63
64 ca = cs.parse(std::vector<std::string>{});
65 BOOST_CHECK_EQUAL(ca.size(), 0);
66
67 ca = cs.parse(std::vector<std::string>{"a", "1"});
68 BOOST_CHECK_EQUAL(ca.size(), 1);
69 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
70
71 ca = cs.parse(std::vector<std::string>{"a", "1", "b", "/n"});
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 ca = cs.parse(std::vector<std::string>{"b", "/n", "a", "1"});
77 BOOST_CHECK_EQUAL(ca.size(), 2);
78 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
79 BOOST_CHECK_EQUAL(ca.get<Name>("b"), "/n");
80
81 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"1"}), CommandDefinition::Error);
82 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"c", "1"}), CommandDefinition::Error);
83}
84
85BOOST_AUTO_TEST_CASE(PositionalArgs)
86{
87 CommandDefinition cs("face", "create");
88 cs.addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
89 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES);
90
91 CommandArguments ca;
92
93 ca = cs.parse(std::vector<std::string>{"udp4://router.example.com", "persistent"});
94 BOOST_CHECK_EQUAL(ca.size(), 2);
95 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
96 FaceUri("udp4://router.example.com"));
97 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
98 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
99
100 ca = cs.parse(std::vector<std::string>{"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>{"remote", "udp4://router.example.com"});
106 BOOST_CHECK_EQUAL(ca.size(), 1);
107 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
108 FaceUri("udp4://router.example.com"));
109
110 ca = cs.parse(std::vector<std::string>{
111 "udp4://router.example.com", "persistency", "persistent"});
112 BOOST_CHECK_EQUAL(ca.size(), 2);
113 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
114 FaceUri("udp4://router.example.com"));
115 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
116 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
117
118 ca = cs.parse(std::vector<std::string>{
119 "remote", "udp4://router.example.com", "persistency", "persistent"});
120 BOOST_CHECK_EQUAL(ca.size(), 2);
121 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
122 FaceUri("udp4://router.example.com"));
123 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
124 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
125
126 ca = cs.parse(std::vector<std::string>{
127 "persistency", "persistent", "remote", "udp4://router.example.com"});
128 BOOST_CHECK_EQUAL(ca.size(), 2);
129 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
130 FaceUri("udp4://router.example.com"));
131 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
132 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
133
134 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
135 "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
136 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
137 "persistency", "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
138 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
139 "remote", "udp4://router.example.com", "persistent"}), CommandDefinition::Error);
140}
141
142BOOST_AUTO_TEST_SUITE_END() // Arguments
143
144BOOST_AUTO_TEST_SUITE(ParseValue)
145
146BOOST_AUTO_TEST_CASE(NoneType)
147{
Davide Pesaventod2147442018-02-19 23:58:17 -0500148 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NONE), "none");
149
Junxiao Shi64567bb2016-09-04 16:00:27 +0000150 CommandDefinition cs("noun", "verb");
151 cs.addArg("a", ArgValueType::NONE, Required::YES, Positional::NO);
152
153 CommandArguments ca;
154
155 ca = cs.parse(std::vector<std::string>{"a"});
156 BOOST_CHECK_EQUAL(ca.size(), 1);
157 BOOST_CHECK(ca.at("a").type() == typeid(bool));
158 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
159
160 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "value"}), CommandDefinition::Error);
161}
162
163BOOST_AUTO_TEST_CASE(AnyType)
164{
Davide Pesaventod2147442018-02-19 23:58:17 -0500165 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ANY), "any");
166
Junxiao Shi64567bb2016-09-04 16:00:27 +0000167 CommandDefinition cs("noun", "verb");
168 cs.addArg("a", ArgValueType::ANY, Required::NO, Positional::YES);
169
170 CommandArguments ca;
171
172 ca = cs.parse(std::vector<std::string>{});
173 BOOST_CHECK_EQUAL(ca.size(), 0);
174
175 ca = cs.parse(std::vector<std::string>{"a"});
176 BOOST_CHECK_EQUAL(ca.size(), 1);
177 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
178 std::vector<std::string> values = ca.get<std::vector<std::string>>("a");
179 BOOST_CHECK_EQUAL(values.size(), 1);
180 BOOST_CHECK_EQUAL(values.at(0), "a");
181
182 ca = cs.parse(std::vector<std::string>{"b", "c"});
183 BOOST_CHECK_EQUAL(ca.size(), 1);
184 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
185 values = ca.get<std::vector<std::string>>("a");
186 BOOST_CHECK_EQUAL(values.size(), 2);
187 BOOST_CHECK_EQUAL(values.at(0), "b");
188 BOOST_CHECK_EQUAL(values.at(1), "c");
189}
190
Davide Pesaventod2147442018-02-19 23:58:17 -0500191BOOST_AUTO_TEST_CASE(BooleanType)
192{
193 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::BOOLEAN), "boolean");
194
195 CommandDefinition cs("noun", "verb");
196 cs.addArg("a", ArgValueType::BOOLEAN, Required::YES);
197
198 CommandArguments ca;
199
200 ca = cs.parse({"a", "on"});
201 BOOST_CHECK_EQUAL(ca.size(), 1);
202 BOOST_CHECK(ca.at("a").type() == typeid(bool));
203 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
204
205 ca = cs.parse({"a", "off"});
206 BOOST_CHECK_EQUAL(ca.size(), 1);
207 BOOST_CHECK(ca.at("a").type() == typeid(bool));
208 BOOST_CHECK_EQUAL(ca.get<bool>("a"), false);
209
210 BOOST_CHECK_EQUAL(cs.parse({"a", "true"}).get<bool>("a"), true);
211 BOOST_CHECK_EQUAL(cs.parse({"a", "enabled"}).get<bool>("a"), true);
212 BOOST_CHECK_EQUAL(cs.parse({"a", "yes"}).get<bool>("a"), true);
213 BOOST_CHECK_EQUAL(cs.parse({"a", "1"}).get<bool>("a"), true);
214 BOOST_CHECK_EQUAL(cs.parse({"a", "false"}).get<bool>("a"), false);
215 BOOST_CHECK_EQUAL(cs.parse({"a", "disabled"}).get<bool>("a"), false);
216 BOOST_CHECK_EQUAL(cs.parse({"a", "no"}).get<bool>("a"), false);
217 BOOST_CHECK_EQUAL(cs.parse({"a", "0"}).get<bool>("a"), false);
218
219 BOOST_CHECK_THROW(cs.parse({"a", "42"}), CommandDefinition::Error);
220 BOOST_CHECK_THROW(cs.parse({"a", "not-bool"}), CommandDefinition::Error);
221}
222
Junxiao Shi64567bb2016-09-04 16:00:27 +0000223BOOST_AUTO_TEST_CASE(UnsignedType)
224{
Davide Pesaventod2147442018-02-19 23:58:17 -0500225 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::UNSIGNED), "non-negative integer");
226
Junxiao Shi64567bb2016-09-04 16:00:27 +0000227 CommandDefinition cs("noun", "verb");
228 cs.addArg("a", ArgValueType::UNSIGNED, Required::YES);
229
230 CommandArguments ca;
231
232 ca = cs.parse(std::vector<std::string>{"a", "0"});
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"), 0);
236
237 ca = cs.parse(std::vector<std::string>{"a", "12923"});
238 BOOST_CHECK_EQUAL(ca.size(), 1);
239 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
240 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 12923);
241
242 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "-25705"}), CommandDefinition::Error);
243 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-uint"}), CommandDefinition::Error);
244}
245
246BOOST_AUTO_TEST_CASE(StringType)
247{
Davide Pesaventod2147442018-02-19 23:58:17 -0500248 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::STRING), "string");
249
Junxiao Shi64567bb2016-09-04 16:00:27 +0000250 CommandDefinition cs("noun", "verb");
251 cs.addArg("a", ArgValueType::STRING, Required::YES);
252
253 CommandArguments ca;
254
255 ca = cs.parse(std::vector<std::string>{"a", "hello"});
256 BOOST_CHECK_EQUAL(ca.size(), 1);
257 BOOST_CHECK(ca.at("a").type() == typeid(std::string));
258 BOOST_CHECK_EQUAL(ca.get<std::string>("a"), "hello");
259}
260
261BOOST_AUTO_TEST_CASE(ReportFormatType)
262{
Davide Pesaventod2147442018-02-19 23:58:17 -0500263 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::REPORT_FORMAT), "ReportFormat");
264
Junxiao Shi64567bb2016-09-04 16:00:27 +0000265 CommandDefinition cs("noun", "verb");
266 cs.addArg("a", ArgValueType::REPORT_FORMAT, Required::YES);
267
268 CommandArguments ca;
269
270 ca = cs.parse(std::vector<std::string>{"a", "xml"});
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::XML);
274
275 ca = cs.parse(std::vector<std::string>{"a", "text"});
276 BOOST_CHECK_EQUAL(ca.size(), 1);
277 BOOST_CHECK(ca.at("a").type() == typeid(ReportFormat));
278 BOOST_CHECK_EQUAL(ca.get<ReportFormat>("a"), ReportFormat::TEXT);
279
280 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-fmt"}), CommandDefinition::Error);
281}
282
283BOOST_AUTO_TEST_CASE(NameType)
284{
Davide Pesaventod2147442018-02-19 23:58:17 -0500285 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NAME), "Name");
286
Junxiao Shi64567bb2016-09-04 16:00:27 +0000287 CommandDefinition cs("noun", "verb");
288 cs.addArg("a", ArgValueType::NAME, Required::YES);
289
290 CommandArguments ca;
291
292 ca = cs.parse(std::vector<std::string>{"a", "/n"});
293 BOOST_CHECK_EQUAL(ca.size(), 1);
294 BOOST_CHECK(ca.at("a").type() == typeid(Name));
295 BOOST_CHECK_EQUAL(ca.get<Name>("a"), "/n");
296}
297
298BOOST_AUTO_TEST_CASE(FaceUriType)
299{
Davide Pesaventod2147442018-02-19 23:58:17 -0500300 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_URI), "FaceUri");
301
Junxiao Shi64567bb2016-09-04 16:00:27 +0000302 CommandDefinition cs("noun", "verb");
303 cs.addArg("a", ArgValueType::FACE_URI, Required::YES);
304
305 CommandArguments ca;
306
307 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
308 BOOST_CHECK_EQUAL(ca.size(), 1);
309 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
310 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
311
312 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "208"}), CommandDefinition::Error);
313 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
314}
315
316BOOST_AUTO_TEST_CASE(FaceIdOrUriType)
317{
Davide Pesaventod2147442018-02-19 23:58:17 -0500318 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_ID_OR_URI), "FaceId or FaceUri");
319
Junxiao Shi64567bb2016-09-04 16:00:27 +0000320 CommandDefinition cs("noun", "verb");
321 cs.addArg("a", ArgValueType::FACE_ID_OR_URI, Required::YES);
322
323 CommandArguments ca;
324
325 ca = cs.parse(std::vector<std::string>{"a", "208"});
326 BOOST_CHECK_EQUAL(ca.size(), 1);
327 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
328 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 208);
329
330 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
331 BOOST_CHECK_EQUAL(ca.size(), 1);
332 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
333 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
334
335 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
336}
337
338BOOST_AUTO_TEST_CASE(FacePersistencyType)
339{
Davide Pesaventod2147442018-02-19 23:58:17 -0500340 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_PERSISTENCY), "FacePersistency");
341
Junxiao Shi64567bb2016-09-04 16:00:27 +0000342 CommandDefinition cs("noun", "verb");
343 cs.addArg("a", ArgValueType::FACE_PERSISTENCY, Required::YES);
344
345 CommandArguments ca;
346
347 ca = cs.parse(std::vector<std::string>{"a", "persistent"});
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_PERSISTENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000351
352 ca = cs.parse(std::vector<std::string>{"a", "permanent"});
353 BOOST_CHECK_EQUAL(ca.size(), 1);
354 BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency));
Davide Pesaventod2147442018-02-19 23:58:17 -0500355 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("a"), FacePersistency::FACE_PERSISTENCY_PERMANENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000356
357 // nfdc does not accept "on-demand"
358 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "on-demand"}), CommandDefinition::Error);
359}
360
Junxiao Shi8eda6822017-04-12 02:53:14 +0000361BOOST_AUTO_TEST_CASE(RouteOriginType)
362{
Davide Pesaventod2147442018-02-19 23:58:17 -0500363 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ROUTE_ORIGIN), "RouteOrigin");
364
Junxiao Shi8eda6822017-04-12 02:53:14 +0000365 CommandDefinition cs("noun", "verb");
366 cs.addArg("a", ArgValueType::ROUTE_ORIGIN, Required::YES);
367
368 CommandArguments ca;
369
370 ca = cs.parse(std::vector<std::string>{"a", "Nlsr"});
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"), RouteOrigin::ROUTE_ORIGIN_NLSR);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000374
375 ca = cs.parse(std::vector<std::string>{"a", "27"});
376 BOOST_CHECK_EQUAL(ca.size(), 1);
377 BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin));
Davide Pesaventod2147442018-02-19 23:58:17 -0500378 BOOST_CHECK_EQUAL(ca.get<RouteOrigin>("a"), static_cast<RouteOrigin>(27));
Junxiao Shi8eda6822017-04-12 02:53:14 +0000379
380 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-RouteOrigin"}), CommandDefinition::Error);
381}
382
Junxiao Shi64567bb2016-09-04 16:00:27 +0000383BOOST_AUTO_TEST_SUITE_END() // ParseValue
384
385BOOST_AUTO_TEST_SUITE_END() // TestCommandDefinition
386BOOST_AUTO_TEST_SUITE_END() // Nfdc
387
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400388} // namespace nfd::tools::nfdc::tests