blob: 7dbbbf6666ec206486c9bfa33aa5891171347b5a [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
31namespace nfd {
32namespace tools {
33namespace nfdc {
34namespace tests {
35
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
39BOOST_AUTO_TEST_SUITE(Arguments)
40
41BOOST_AUTO_TEST_CASE(NoArg)
42{
43 CommandDefinition cs("noun", "verb");
44
45 CommandArguments ca;
46
47 ca = cs.parse(std::vector<std::string>{});
48 BOOST_CHECK_EQUAL(ca.size(), 0);
49
50 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x"}), CommandDefinition::Error);
51 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"x", "y"}), CommandDefinition::Error);
52}
53
54BOOST_AUTO_TEST_CASE(NamedArgs)
55{
56 CommandDefinition cs("noun", "verb");
57 cs.addArg("a", ArgValueType::UNSIGNED, Required::NO, Positional::NO, "int")
58 .addArg("b", ArgValueType::NAME, Required::NO, Positional::NO, "name");
59
60 CommandArguments ca;
61
62 ca = cs.parse(std::vector<std::string>{});
63 BOOST_CHECK_EQUAL(ca.size(), 0);
64
65 ca = cs.parse(std::vector<std::string>{"a", "1"});
66 BOOST_CHECK_EQUAL(ca.size(), 1);
67 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
68
69 ca = cs.parse(std::vector<std::string>{"a", "1", "b", "/n"});
70 BOOST_CHECK_EQUAL(ca.size(), 2);
71 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
72 BOOST_CHECK_EQUAL(ca.get<Name>("b"), "/n");
73
74 ca = cs.parse(std::vector<std::string>{"b", "/n", "a", "1"});
75 BOOST_CHECK_EQUAL(ca.size(), 2);
76 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 1);
77 BOOST_CHECK_EQUAL(ca.get<Name>("b"), "/n");
78
79 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"1"}), CommandDefinition::Error);
80 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"c", "1"}), CommandDefinition::Error);
81}
82
83BOOST_AUTO_TEST_CASE(PositionalArgs)
84{
85 CommandDefinition cs("face", "create");
86 cs.addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
87 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES);
88
89 CommandArguments ca;
90
91 ca = cs.parse(std::vector<std::string>{"udp4://router.example.com", "persistent"});
92 BOOST_CHECK_EQUAL(ca.size(), 2);
93 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
94 FaceUri("udp4://router.example.com"));
95 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
96 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
97
98 ca = cs.parse(std::vector<std::string>{"udp4://router.example.com"});
99 BOOST_CHECK_EQUAL(ca.size(), 1);
100 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
101 FaceUri("udp4://router.example.com"));
102
103 ca = cs.parse(std::vector<std::string>{"remote", "udp4://router.example.com"});
104 BOOST_CHECK_EQUAL(ca.size(), 1);
105 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
106 FaceUri("udp4://router.example.com"));
107
108 ca = cs.parse(std::vector<std::string>{
109 "udp4://router.example.com", "persistency", "persistent"});
110 BOOST_CHECK_EQUAL(ca.size(), 2);
111 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
112 FaceUri("udp4://router.example.com"));
113 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
114 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
115
116 ca = cs.parse(std::vector<std::string>{
117 "remote", "udp4://router.example.com", "persistency", "persistent"});
118 BOOST_CHECK_EQUAL(ca.size(), 2);
119 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
120 FaceUri("udp4://router.example.com"));
121 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
122 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
123
124 ca = cs.parse(std::vector<std::string>{
125 "persistency", "persistent", "remote", "udp4://router.example.com"});
126 BOOST_CHECK_EQUAL(ca.size(), 2);
127 BOOST_CHECK_EQUAL(ca.get<FaceUri>("remote"),
128 FaceUri("udp4://router.example.com"));
129 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("persistency"),
130 FacePersistency::FACE_PERSISTENCY_PERSISTENT);
131
132 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
133 "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
134 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
135 "persistency", "persistent", "udp4://router.example.com"}), CommandDefinition::Error);
136 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{
137 "remote", "udp4://router.example.com", "persistent"}), CommandDefinition::Error);
138}
139
140BOOST_AUTO_TEST_SUITE_END() // Arguments
141
142BOOST_AUTO_TEST_SUITE(ParseValue)
143
144BOOST_AUTO_TEST_CASE(NoneType)
145{
Davide Pesaventod2147442018-02-19 23:58:17 -0500146 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NONE), "none");
147
Junxiao Shi64567bb2016-09-04 16:00:27 +0000148 CommandDefinition cs("noun", "verb");
149 cs.addArg("a", ArgValueType::NONE, Required::YES, Positional::NO);
150
151 CommandArguments ca;
152
153 ca = cs.parse(std::vector<std::string>{"a"});
154 BOOST_CHECK_EQUAL(ca.size(), 1);
155 BOOST_CHECK(ca.at("a").type() == typeid(bool));
156 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
157
158 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "value"}), CommandDefinition::Error);
159}
160
161BOOST_AUTO_TEST_CASE(AnyType)
162{
Davide Pesaventod2147442018-02-19 23:58:17 -0500163 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ANY), "any");
164
Junxiao Shi64567bb2016-09-04 16:00:27 +0000165 CommandDefinition cs("noun", "verb");
166 cs.addArg("a", ArgValueType::ANY, Required::NO, Positional::YES);
167
168 CommandArguments ca;
169
170 ca = cs.parse(std::vector<std::string>{});
171 BOOST_CHECK_EQUAL(ca.size(), 0);
172
173 ca = cs.parse(std::vector<std::string>{"a"});
174 BOOST_CHECK_EQUAL(ca.size(), 1);
175 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
176 std::vector<std::string> values = ca.get<std::vector<std::string>>("a");
177 BOOST_CHECK_EQUAL(values.size(), 1);
178 BOOST_CHECK_EQUAL(values.at(0), "a");
179
180 ca = cs.parse(std::vector<std::string>{"b", "c"});
181 BOOST_CHECK_EQUAL(ca.size(), 1);
182 BOOST_CHECK(ca.at("a").type() == typeid(std::vector<std::string>));
183 values = ca.get<std::vector<std::string>>("a");
184 BOOST_CHECK_EQUAL(values.size(), 2);
185 BOOST_CHECK_EQUAL(values.at(0), "b");
186 BOOST_CHECK_EQUAL(values.at(1), "c");
187}
188
Davide Pesaventod2147442018-02-19 23:58:17 -0500189BOOST_AUTO_TEST_CASE(BooleanType)
190{
191 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::BOOLEAN), "boolean");
192
193 CommandDefinition cs("noun", "verb");
194 cs.addArg("a", ArgValueType::BOOLEAN, Required::YES);
195
196 CommandArguments ca;
197
198 ca = cs.parse({"a", "on"});
199 BOOST_CHECK_EQUAL(ca.size(), 1);
200 BOOST_CHECK(ca.at("a").type() == typeid(bool));
201 BOOST_CHECK_EQUAL(ca.get<bool>("a"), true);
202
203 ca = cs.parse({"a", "off"});
204 BOOST_CHECK_EQUAL(ca.size(), 1);
205 BOOST_CHECK(ca.at("a").type() == typeid(bool));
206 BOOST_CHECK_EQUAL(ca.get<bool>("a"), false);
207
208 BOOST_CHECK_EQUAL(cs.parse({"a", "true"}).get<bool>("a"), true);
209 BOOST_CHECK_EQUAL(cs.parse({"a", "enabled"}).get<bool>("a"), true);
210 BOOST_CHECK_EQUAL(cs.parse({"a", "yes"}).get<bool>("a"), true);
211 BOOST_CHECK_EQUAL(cs.parse({"a", "1"}).get<bool>("a"), true);
212 BOOST_CHECK_EQUAL(cs.parse({"a", "false"}).get<bool>("a"), false);
213 BOOST_CHECK_EQUAL(cs.parse({"a", "disabled"}).get<bool>("a"), false);
214 BOOST_CHECK_EQUAL(cs.parse({"a", "no"}).get<bool>("a"), false);
215 BOOST_CHECK_EQUAL(cs.parse({"a", "0"}).get<bool>("a"), false);
216
217 BOOST_CHECK_THROW(cs.parse({"a", "42"}), CommandDefinition::Error);
218 BOOST_CHECK_THROW(cs.parse({"a", "not-bool"}), CommandDefinition::Error);
219}
220
Junxiao Shi64567bb2016-09-04 16:00:27 +0000221BOOST_AUTO_TEST_CASE(UnsignedType)
222{
Davide Pesaventod2147442018-02-19 23:58:17 -0500223 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::UNSIGNED), "non-negative integer");
224
Junxiao Shi64567bb2016-09-04 16:00:27 +0000225 CommandDefinition cs("noun", "verb");
226 cs.addArg("a", ArgValueType::UNSIGNED, Required::YES);
227
228 CommandArguments ca;
229
230 ca = cs.parse(std::vector<std::string>{"a", "0"});
231 BOOST_CHECK_EQUAL(ca.size(), 1);
232 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
233 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 0);
234
235 ca = cs.parse(std::vector<std::string>{"a", "12923"});
236 BOOST_CHECK_EQUAL(ca.size(), 1);
237 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
238 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 12923);
239
240 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "-25705"}), CommandDefinition::Error);
241 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-uint"}), CommandDefinition::Error);
242}
243
244BOOST_AUTO_TEST_CASE(StringType)
245{
Davide Pesaventod2147442018-02-19 23:58:17 -0500246 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::STRING), "string");
247
Junxiao Shi64567bb2016-09-04 16:00:27 +0000248 CommandDefinition cs("noun", "verb");
249 cs.addArg("a", ArgValueType::STRING, Required::YES);
250
251 CommandArguments ca;
252
253 ca = cs.parse(std::vector<std::string>{"a", "hello"});
254 BOOST_CHECK_EQUAL(ca.size(), 1);
255 BOOST_CHECK(ca.at("a").type() == typeid(std::string));
256 BOOST_CHECK_EQUAL(ca.get<std::string>("a"), "hello");
257}
258
259BOOST_AUTO_TEST_CASE(ReportFormatType)
260{
Davide Pesaventod2147442018-02-19 23:58:17 -0500261 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::REPORT_FORMAT), "ReportFormat");
262
Junxiao Shi64567bb2016-09-04 16:00:27 +0000263 CommandDefinition cs("noun", "verb");
264 cs.addArg("a", ArgValueType::REPORT_FORMAT, Required::YES);
265
266 CommandArguments ca;
267
268 ca = cs.parse(std::vector<std::string>{"a", "xml"});
269 BOOST_CHECK_EQUAL(ca.size(), 1);
270 BOOST_CHECK(ca.at("a").type() == typeid(ReportFormat));
271 BOOST_CHECK_EQUAL(ca.get<ReportFormat>("a"), ReportFormat::XML);
272
273 ca = cs.parse(std::vector<std::string>{"a", "text"});
274 BOOST_CHECK_EQUAL(ca.size(), 1);
275 BOOST_CHECK(ca.at("a").type() == typeid(ReportFormat));
276 BOOST_CHECK_EQUAL(ca.get<ReportFormat>("a"), ReportFormat::TEXT);
277
278 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-fmt"}), CommandDefinition::Error);
279}
280
281BOOST_AUTO_TEST_CASE(NameType)
282{
Davide Pesaventod2147442018-02-19 23:58:17 -0500283 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::NAME), "Name");
284
Junxiao Shi64567bb2016-09-04 16:00:27 +0000285 CommandDefinition cs("noun", "verb");
286 cs.addArg("a", ArgValueType::NAME, Required::YES);
287
288 CommandArguments ca;
289
290 ca = cs.parse(std::vector<std::string>{"a", "/n"});
291 BOOST_CHECK_EQUAL(ca.size(), 1);
292 BOOST_CHECK(ca.at("a").type() == typeid(Name));
293 BOOST_CHECK_EQUAL(ca.get<Name>("a"), "/n");
294}
295
296BOOST_AUTO_TEST_CASE(FaceUriType)
297{
Davide Pesaventod2147442018-02-19 23:58:17 -0500298 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_URI), "FaceUri");
299
Junxiao Shi64567bb2016-09-04 16:00:27 +0000300 CommandDefinition cs("noun", "verb");
301 cs.addArg("a", ArgValueType::FACE_URI, Required::YES);
302
303 CommandArguments ca;
304
305 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
306 BOOST_CHECK_EQUAL(ca.size(), 1);
307 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
308 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
309
310 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "208"}), CommandDefinition::Error);
311 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
312}
313
314BOOST_AUTO_TEST_CASE(FaceIdOrUriType)
315{
Davide Pesaventod2147442018-02-19 23:58:17 -0500316 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_ID_OR_URI), "FaceId or FaceUri");
317
Junxiao Shi64567bb2016-09-04 16:00:27 +0000318 CommandDefinition cs("noun", "verb");
319 cs.addArg("a", ArgValueType::FACE_ID_OR_URI, Required::YES);
320
321 CommandArguments ca;
322
323 ca = cs.parse(std::vector<std::string>{"a", "208"});
324 BOOST_CHECK_EQUAL(ca.size(), 1);
325 BOOST_CHECK(ca.at("a").type() == typeid(uint64_t));
326 BOOST_CHECK_EQUAL(ca.get<uint64_t>("a"), 208);
327
328 ca = cs.parse(std::vector<std::string>{"a", "udp4://192.0.2.1:6363"});
329 BOOST_CHECK_EQUAL(ca.size(), 1);
330 BOOST_CHECK(ca.at("a").type() == typeid(FaceUri));
331 BOOST_CHECK_EQUAL(ca.get<FaceUri>("a"), FaceUri("udp4://192.0.2.1:6363"));
332
333 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-FaceUri"}), CommandDefinition::Error);
334}
335
336BOOST_AUTO_TEST_CASE(FacePersistencyType)
337{
Davide Pesaventod2147442018-02-19 23:58:17 -0500338 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::FACE_PERSISTENCY), "FacePersistency");
339
Junxiao Shi64567bb2016-09-04 16:00:27 +0000340 CommandDefinition cs("noun", "verb");
341 cs.addArg("a", ArgValueType::FACE_PERSISTENCY, Required::YES);
342
343 CommandArguments ca;
344
345 ca = cs.parse(std::vector<std::string>{"a", "persistent"});
346 BOOST_CHECK_EQUAL(ca.size(), 1);
347 BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency));
Davide Pesaventod2147442018-02-19 23:58:17 -0500348 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("a"), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000349
350 ca = cs.parse(std::vector<std::string>{"a", "permanent"});
351 BOOST_CHECK_EQUAL(ca.size(), 1);
352 BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency));
Davide Pesaventod2147442018-02-19 23:58:17 -0500353 BOOST_CHECK_EQUAL(ca.get<FacePersistency>("a"), FacePersistency::FACE_PERSISTENCY_PERMANENT);
Junxiao Shi64567bb2016-09-04 16:00:27 +0000354
355 // nfdc does not accept "on-demand"
356 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "on-demand"}), CommandDefinition::Error);
357}
358
Junxiao Shi8eda6822017-04-12 02:53:14 +0000359BOOST_AUTO_TEST_CASE(RouteOriginType)
360{
Davide Pesaventod2147442018-02-19 23:58:17 -0500361 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ArgValueType::ROUTE_ORIGIN), "RouteOrigin");
362
Junxiao Shi8eda6822017-04-12 02:53:14 +0000363 CommandDefinition cs("noun", "verb");
364 cs.addArg("a", ArgValueType::ROUTE_ORIGIN, Required::YES);
365
366 CommandArguments ca;
367
368 ca = cs.parse(std::vector<std::string>{"a", "Nlsr"});
369 BOOST_CHECK_EQUAL(ca.size(), 1);
370 BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin));
Davide Pesaventod2147442018-02-19 23:58:17 -0500371 BOOST_CHECK_EQUAL(ca.get<RouteOrigin>("a"), RouteOrigin::ROUTE_ORIGIN_NLSR);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000372
373 ca = cs.parse(std::vector<std::string>{"a", "27"});
374 BOOST_CHECK_EQUAL(ca.size(), 1);
375 BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin));
Davide Pesaventod2147442018-02-19 23:58:17 -0500376 BOOST_CHECK_EQUAL(ca.get<RouteOrigin>("a"), static_cast<RouteOrigin>(27));
Junxiao Shi8eda6822017-04-12 02:53:14 +0000377
378 BOOST_CHECK_THROW(cs.parse(std::vector<std::string>{"a", "not-RouteOrigin"}), CommandDefinition::Error);
379}
380
Junxiao Shi64567bb2016-09-04 16:00:27 +0000381BOOST_AUTO_TEST_SUITE_END() // ParseValue
382
383BOOST_AUTO_TEST_SUITE_END() // TestCommandDefinition
384BOOST_AUTO_TEST_SUITE_END() // Nfdc
385
386} // namespace tests
387} // namespace nfdc
388} // namespace tools
389} // namespace nfd