blob: cc0101838bc3a6d85d560a0ffcccf43427dbf1d7 [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev0c63c632017-12-05 11:17:09 -05002/*
Davide Pesavento45c1f6a2025-01-01 19:30:30 -05003 * Copyright (c) 2014-2025, Regents of the University of California,
Junxiao Shi38f4ce92016-08-04 10:01:52 +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
Junxiao Shi331ade72016-08-19 14:07:19 +000026#include "nfdc/rib-module.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000027
Junxiao Shi918e5d42017-02-25 03:58:21 +000028#include "execute-command-fixture.hpp"
Junxiao Shi1f481fa2017-01-26 15:14:43 +000029#include "status-fixture.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000030
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::tools::nfdc::tests {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000032
Junxiao Shi331ade72016-08-19 14:07:19 +000033BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi1f481fa2017-01-26 15:14:43 +000034BOOST_FIXTURE_TEST_SUITE(TestRibModule, StatusFixture<RibModule>)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000035
Junxiao Shi1d62e622017-03-08 22:39:28 +000036class RouteListFixture : public ExecuteCommandFixture
37{
38protected:
39 bool
40 respondRibDataset(const Interest& interest)
41 {
42 if (!Name("/localhost/nfd/rib/list").isPrefixOf(interest.getName())) {
43 return false;
44 }
45
46 RibEntry entry1;
47 entry1.setName("/5BBmTevRJ");
48 entry1.addRoute(Route()
49 .setFaceId(6720)
50 .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)
51 .setCost(2956)
52 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE)
Davide Pesavento14e71f02019-03-28 17:35:25 -040053 .setExpirationPeriod(29950035_ms));
Junxiao Shi1d62e622017-03-08 22:39:28 +000054 entry1.addRoute(Route()
55 .setFaceId(6720)
56 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
57 .setCost(425)
58 .setFlags(ndn::nfd::ROUTE_FLAGS_NONE));
59 entry1.addRoute(Route()
60 .setFaceId(8599)
61 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
62 .setCost(9140)
63 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
64
65 RibEntry entry2;
66 entry2.setName("/aDPTKCio");
67 entry2.addRoute(Route()
68 .setFaceId(31066)
69 .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)
70 .setCost(4617)
71 .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE));
72
73 this->sendDataset(interest.getName(), entry1, entry2);
74 return true;
75 }
76};
77
78BOOST_FIXTURE_TEST_SUITE(ListShowCommand, RouteListFixture)
79
80const std::string NOFILTER_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +000081prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
82prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
83prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
84prefix=/aDPTKCio nexthop=31066 origin=client cost=4617 flags=capture expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +000085)TEXT").substr(1);
86
87BOOST_AUTO_TEST_CASE(ListNoFilter)
88{
89 this->processInterest = [this] (const Interest& interest) {
90 BOOST_CHECK(this->respondRibDataset(interest));
91 };
92
93 this->execute("route");
94 BOOST_CHECK_EQUAL(exitCode, 0);
95 BOOST_CHECK(out.is_equal(NOFILTER_OUTPUT));
96 BOOST_CHECK(err.is_empty());
97}
98
99const std::string NEXTHOP_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000100prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
101prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
102prefix=/aDPTKCio nexthop=31066 origin=client cost=4617 flags=capture expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000103)TEXT").substr(1);
104
105BOOST_AUTO_TEST_CASE(ListByNexthop)
106{
107 this->processInterest = [this] (const Interest& interest) {
108 BOOST_CHECK(this->respondFaceQuery(interest) || this->respondRibDataset(interest));
109 };
110
111 this->execute("route list udp4://225.131.75.231:56363");
112 BOOST_CHECK_EQUAL(exitCode, 0);
113 BOOST_CHECK(out.is_equal(NEXTHOP_OUTPUT));
114 BOOST_CHECK(err.is_empty());
115}
116
117const std::string ORIGIN_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000118prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
119prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000120)TEXT").substr(1);
121
Junxiao Shi8eda6822017-04-12 02:53:14 +0000122BOOST_AUTO_TEST_CASE(ListByOriginNumeric)
Junxiao Shi1d62e622017-03-08 22:39:28 +0000123{
124 this->processInterest = [this] (const Interest& interest) {
125 BOOST_CHECK(this->respondRibDataset(interest));
126 };
127
128 this->execute("route list origin 255");
129 BOOST_CHECK_EQUAL(exitCode, 0);
130 BOOST_CHECK(out.is_equal(ORIGIN_OUTPUT));
131 BOOST_CHECK(err.is_empty());
132}
133
Junxiao Shi8eda6822017-04-12 02:53:14 +0000134BOOST_AUTO_TEST_CASE(ListByOriginString)
135{
136 this->processInterest = [this] (const Interest& interest) {
137 BOOST_CHECK(this->respondRibDataset(interest));
138 };
139
140 this->execute("route list origin static");
141 BOOST_CHECK_EQUAL(exitCode, 0);
142 BOOST_CHECK(out.is_equal(ORIGIN_OUTPUT));
143 BOOST_CHECK(err.is_empty());
144}
145
Junxiao Shi1d62e622017-03-08 22:39:28 +0000146const std::string PREFIX_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000147prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
148prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
149prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000150)TEXT").substr(1);
151
152BOOST_AUTO_TEST_CASE(ShowByPrefix)
153{
154 this->processInterest = [this] (const Interest& interest) {
155 BOOST_CHECK(this->respondRibDataset(interest));
156 };
157
158 this->execute("route show 5BBmTevRJ");
159 BOOST_CHECK_EQUAL(exitCode, 0);
160 BOOST_CHECK(out.is_equal(PREFIX_OUTPUT));
161 BOOST_CHECK(err.is_empty());
162}
163
164BOOST_AUTO_TEST_CASE(FaceNotExist)
165{
166 this->processInterest = [this] (const Interest& interest) {
167 BOOST_CHECK(this->respondFaceQuery(interest));
168 };
169
170 this->execute("route list 23728");
171 BOOST_CHECK_EQUAL(exitCode, 3);
172 BOOST_CHECK(out.is_empty());
173 BOOST_CHECK(err.is_equal("Face not found\n"));
174}
175
176BOOST_AUTO_TEST_CASE(RouteNotExist)
177{
178 this->processInterest = [this] (const Interest& interest) {
179 BOOST_CHECK(this->respondFaceQuery(interest) || this->respondRibDataset(interest));
180 };
181
182 this->execute("route list 10156");
183 BOOST_CHECK_EQUAL(exitCode, 6);
184 BOOST_CHECK(out.is_empty());
185 BOOST_CHECK(err.is_equal("Route not found\n"));
186}
187
188BOOST_AUTO_TEST_CASE(ErrorDataset)
189{
190 this->processInterest = nullptr; // no response to dataset
191
192 this->execute("route list");
193 BOOST_CHECK_EQUAL(exitCode, 1);
194 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700195 BOOST_CHECK(err.is_equal("Error 10060 when fetching RIB dataset: Timeout exceeded\n"));
Junxiao Shi1d62e622017-03-08 22:39:28 +0000196}
197
198BOOST_AUTO_TEST_SUITE_END() // ListShowCommand
199
Junxiao Shi918e5d42017-02-25 03:58:21 +0000200BOOST_FIXTURE_TEST_SUITE(AddCommand, ExecuteCommandFixture)
201
202BOOST_AUTO_TEST_CASE(NormalByFaceId)
203{
204 this->processInterest = [this] (const Interest& interest) {
205 if (this->respondFaceQuery(interest)) {
206 return;
207 }
208
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000209 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500210 ndn::nfd::RibRegisterCommand::validateRequest(req);
211 ndn::nfd::RibRegisterCommand::applyDefaultsToRequest(req);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000212 BOOST_CHECK_EQUAL(req.getName(), "/vxXoEaWeDB");
213 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
214 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
215 BOOST_CHECK_EQUAL(req.getCost(), 0);
216 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAGS_NONE);
217 BOOST_CHECK_EQUAL(req.hasExpirationPeriod(), false);
218
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000219 this->succeedCommand(interest, req);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000220 };
221
222 this->execute("route add /vxXoEaWeDB 10156 no-inherit");
223 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000224 BOOST_CHECK(out.is_equal("route-add-accepted prefix=/vxXoEaWeDB nexthop=10156 origin=static "
Junxiao Shi918e5d42017-02-25 03:58:21 +0000225 "cost=0 flags=none expires=never\n"));
226 BOOST_CHECK(err.is_empty());
227}
228
229BOOST_AUTO_TEST_CASE(NormalByFaceUri)
230{
231 this->processInterest = [this] (const Interest& interest) {
232 if (this->respondFaceQuery(interest)) {
233 return;
234 }
235
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000236 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500237 ndn::nfd::RibRegisterCommand::validateRequest(req);
238 ndn::nfd::RibRegisterCommand::applyDefaultsToRequest(req);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000239 BOOST_CHECK_EQUAL(req.getName(), "/FLQAsaYnYf");
240 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
241 BOOST_CHECK_EQUAL(req.getOrigin(), 17591);
242 BOOST_CHECK_EQUAL(req.getCost(), 702);
243 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAG_CHILD_INHERIT |
244 ndn::nfd::ROUTE_FLAG_CAPTURE);
245 BOOST_REQUIRE_EQUAL(req.hasExpirationPeriod(), true);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400246 BOOST_REQUIRE_EQUAL(req.getExpirationPeriod(), 727411987_ms);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000247
248 ControlParameters resp = req;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400249 resp.setExpirationPeriod(727411154_ms); // server side may change expiration
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000250 this->succeedCommand(interest, resp);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000251 };
252
253 this->execute("route add /FLQAsaYnYf tcp4://32.121.182.82:6363 "
254 "origin 17591 cost 702 capture expires 727411987");
255 BOOST_CHECK_EQUAL(exitCode, 0);
256 BOOST_CHECK(out.is_equal("route-add-accepted prefix=/FLQAsaYnYf nexthop=2249 origin=17591 "
257 "cost=702 flags=child-inherit|capture expires=727411154ms\n"));
258 BOOST_CHECK(err.is_empty());
259}
260
Eric Newberryd656aff2020-04-03 00:30:38 -0700261BOOST_AUTO_TEST_CASE(FaceNotExistFaceId)
Junxiao Shi918e5d42017-02-25 03:58:21 +0000262{
263 this->processInterest = [this] (const Interest& interest) {
264 BOOST_CHECK(this->respondFaceQuery(interest));
265 };
266
267 this->execute("route add /GJiKDus5i 23728");
268 BOOST_CHECK_EQUAL(exitCode, 3);
269 BOOST_CHECK(out.is_empty());
270 BOOST_CHECK(err.is_equal("Face not found\n"));
271}
272
Eric Newberryd656aff2020-04-03 00:30:38 -0700273BOOST_AUTO_TEST_CASE(FaceNotExistFaceUri)
274{
275 this->processInterest = [this] (const Interest& interest) {
276 if (Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName())) {
277 this->respondFaceQuery(interest);
278 }
279 else if (Name("/localhost/nfd/faces/create").isPrefixOf(interest.getName())) {
280 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500281 ndn::nfd::FaceCreateCommand::validateRequest(req);
282 ndn::nfd::FaceCreateCommand::applyDefaultsToRequest(req);
Eric Newberryd656aff2020-04-03 00:30:38 -0700283 BOOST_CHECK_EQUAL(req.getUri(), "udp4://202.83.168.28:6363");
284
285 ControlParameters resp = req;
286 resp.setFaceId(255);
287 resp.setLocalUri("udp4://32.121.182.82:50000");
288 resp.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
289 resp.setBaseCongestionMarkingInterval(100_ms);
290 resp.setDefaultCongestionThreshold(65536);
291 resp.setMtu(8800);
292 resp.setFlags(0);
293 this->succeedCommand(interest, resp);
294 }
295 else if (Name("/localhost/nfd/rib/register").isPrefixOf(interest.getName())) {
296 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500297 ndn::nfd::RibRegisterCommand::validateRequest(req);
298 ndn::nfd::RibRegisterCommand::applyDefaultsToRequest(req);
Eric Newberryd656aff2020-04-03 00:30:38 -0700299 BOOST_CHECK_EQUAL(req.getName(), "/634jfAfdf");
300 BOOST_CHECK_EQUAL(req.getFaceId(), 255);
301 BOOST_CHECK_EQUAL(req.getOrigin(), 17591);
302 BOOST_CHECK_EQUAL(req.getCost(), 702);
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500303 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE);
Eric Newberryd656aff2020-04-03 00:30:38 -0700304 BOOST_REQUIRE_EQUAL(req.hasExpirationPeriod(), true);
305 BOOST_REQUIRE_EQUAL(req.getExpirationPeriod(), 727411987_ms);
306
307 ControlParameters resp = req;
308 resp.setExpirationPeriod(727411154_ms); // server side may change expiration
309 this->succeedCommand(interest, resp);
310 }
311 };
312
313 this->execute("route add /634jfAfdf udp4://202.83.168.28:6363 "
314 "origin 17591 cost 702 capture expires 727411987");
315 BOOST_CHECK(out.is_equal("face-created id=255 local=udp4://32.121.182.82:50000 "
316 "remote=udp4://202.83.168.28:6363 persistency=persistent "
317 "reliability=off congestion-marking=off "
318 "congestion-marking-interval=100ms default-congestion-threshold=65536B "
319 "mtu=8800\n"
320 "route-add-accepted prefix=/634jfAfdf nexthop=255 origin=17591 "
321 "cost=702 flags=child-inherit|capture expires=727411154ms\n"));
322 BOOST_CHECK(err.is_empty());
323 BOOST_CHECK_EQUAL(exitCode, 0);
324}
325
326BOOST_AUTO_TEST_CASE(FaceNotExistNotCanonizable)
327{
328 this->processInterest = [this] (const Interest& interest) {
329 BOOST_CHECK(this->respondFaceQuery(interest));
330 };
331
332 this->execute("route add /634jfAfdf udp6://202.83.168.28:6363 "
333 "origin 17591 cost 702 capture expires 727411987");
334 BOOST_CHECK(out.is_empty());
335 BOOST_CHECK(err.is_equal("Error during canonization of 'udp6://202.83.168.28:6363': "
336 "IPv4/v6 mismatch\n"));
337 BOOST_CHECK_EQUAL(exitCode, 4);
338}
339
Junxiao Shi918e5d42017-02-25 03:58:21 +0000340BOOST_AUTO_TEST_CASE(Ambiguous)
341{
342 this->processInterest = [this] (const Interest& interest) {
343 BOOST_CHECK(this->respondFaceQuery(interest));
344 };
345
346 this->execute("route add /BQqjjnVsz udp4://225.131.75.231:56363");
347 BOOST_CHECK_EQUAL(exitCode, 5);
348 BOOST_CHECK(out.is_empty());
349 BOOST_CHECK(err.is_equal("Multiple faces match specified remote FaceUri. "
350 "Re-run the command with a FaceId: "
351 "6720 (local=udp4://202.83.168.28:56363), "
352 "31066 (local=udp4://25.90.26.32:56363)\n"));
353}
354
355BOOST_AUTO_TEST_CASE(ErrorCanonization)
356{
357 this->execute("route add /bxJfGsVtDt udp6://32.38.164.64:10445");
358 BOOST_CHECK_EQUAL(exitCode, 4);
359 BOOST_CHECK(out.is_empty());
Eric Newberryd656aff2020-04-03 00:30:38 -0700360 BOOST_CHECK(err.is_equal("Error during canonization of 'udp6://32.38.164.64:10445': "
Eric Newberry7d8695d2017-05-29 15:49:10 -0700361 "IPv4/v6 mismatch\n"));
Junxiao Shi918e5d42017-02-25 03:58:21 +0000362}
363
364BOOST_AUTO_TEST_CASE(ErrorDataset)
365{
366 this->processInterest = nullptr; // no response to dataset or command
367
368 this->execute("route add /q1Qf7go7 udp://159.242.33.78");
369 BOOST_CHECK_EQUAL(exitCode, 1);
370 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700371 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout exceeded\n"));
Junxiao Shi918e5d42017-02-25 03:58:21 +0000372}
373
374BOOST_AUTO_TEST_CASE(ErrorCommand)
375{
376 this->processInterest = [this] (const Interest& interest) {
377 if (this->respondFaceQuery(interest)) {
378 return;
379 }
380
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000381 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Junxiao Shi918e5d42017-02-25 03:58:21 +0000382 // no response to command
383 };
384
385 this->execute("route add /bYiMbEuE 10156");
386 BOOST_CHECK_EQUAL(exitCode, 1);
387 BOOST_CHECK(out.is_empty());
388 BOOST_CHECK(err.is_equal("Error 10060 when adding route: request timed out\n"));
389}
390
391BOOST_AUTO_TEST_SUITE_END() // AddCommand
392
Junxiao Shi084b7952017-02-26 22:00:53 +0000393BOOST_FIXTURE_TEST_SUITE(RemoveCommand, ExecuteCommandFixture)
394
395BOOST_AUTO_TEST_CASE(NormalByFaceId)
396{
397 this->processInterest = [this] (const Interest& interest) {
398 if (this->respondFaceQuery(interest)) {
399 return;
400 }
401
402 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500403 ndn::nfd::RibUnregisterCommand::validateRequest(req);
404 ndn::nfd::RibUnregisterCommand::applyDefaultsToRequest(req);
Junxiao Shi084b7952017-02-26 22:00:53 +0000405 BOOST_CHECK_EQUAL(req.getName(), "/2B5NUGjpt");
406 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
407 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
408
409 this->succeedCommand(interest, req);
410 };
411
412 this->execute("route remove /2B5NUGjpt 10156");
413 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000414 BOOST_CHECK(out.is_equal("route-removed prefix=/2B5NUGjpt nexthop=10156 origin=static\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000415 BOOST_CHECK(err.is_empty());
416}
417
418BOOST_AUTO_TEST_CASE(NormalByFaceUri)
419{
420 this->processInterest = [this] (const Interest& interest) {
421 if (this->respondFaceQuery(interest)) {
422 return;
423 }
424
425 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500426 ndn::nfd::RibUnregisterCommand::validateRequest(req);
427 ndn::nfd::RibUnregisterCommand::applyDefaultsToRequest(req);
Junxiao Shi084b7952017-02-26 22:00:53 +0000428 BOOST_CHECK_EQUAL(req.getName(), "/wHdNn0BtUF");
429 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
430 BOOST_CHECK_EQUAL(req.getOrigin(), 15246);
431
432 this->succeedCommand(interest, req);
433 };
434
435 this->execute("route remove /wHdNn0BtUF tcp4://32.121.182.82:6363 origin 15246");
436 BOOST_CHECK_EQUAL(exitCode, 0);
437 BOOST_CHECK(out.is_equal("route-removed prefix=/wHdNn0BtUF nexthop=2249 origin=15246\n"));
438 BOOST_CHECK(err.is_empty());
439}
440
441BOOST_AUTO_TEST_CASE(MultipleFaces)
442{
443 std::set<uint64_t> faceIds{6720, 31066};
444 this->processInterest = [this, &faceIds] (const Interest& interest) {
445 if (this->respondFaceQuery(interest)) {
446 return;
447 }
448
449 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
Davide Pesavento45c1f6a2025-01-01 19:30:30 -0500450 ndn::nfd::RibUnregisterCommand::validateRequest(req);
451 ndn::nfd::RibUnregisterCommand::applyDefaultsToRequest(req);
Davide Pesaventod7083a52023-10-19 17:51:16 -0400452 BOOST_TEST_INFO_SCOPE("FaceId=" << req.getFaceId());
Junxiao Shi084b7952017-02-26 22:00:53 +0000453 BOOST_CHECK_EQUAL(req.getName(), "/nm5y8X8b2");
Davide Pesaventod7083a52023-10-19 17:51:16 -0400454 BOOST_CHECK(faceIds.erase(req.getFaceId()));
Junxiao Shi084b7952017-02-26 22:00:53 +0000455 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
456
457 this->succeedCommand(interest, req);
458 };
459
460 this->execute("route remove /nm5y8X8b2 udp4://225.131.75.231:56363");
461 BOOST_CHECK(faceIds.empty());
462 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000463 BOOST_CHECK(out.is_equal("route-removed prefix=/nm5y8X8b2 nexthop=6720 origin=static\n"
464 "route-removed prefix=/nm5y8X8b2 nexthop=31066 origin=static\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000465 BOOST_CHECK(err.is_empty());
466}
467
468BOOST_AUTO_TEST_CASE(FaceNotExist)
469{
470 this->processInterest = [this] (const Interest& interest) {
471 BOOST_CHECK(this->respondFaceQuery(interest));
472 };
473
474 this->execute("route remove /HeGRjzwFM 23728");
475 BOOST_CHECK_EQUAL(exitCode, 3);
476 BOOST_CHECK(out.is_empty());
477 BOOST_CHECK(err.is_equal("Face not found\n"));
478}
479
480BOOST_AUTO_TEST_CASE(ErrorDataset)
481{
482 this->processInterest = nullptr; // no response to dataset or command
483
484 this->execute("route remove /YX4xQQN3v5 udp://26.97.248.3");
485 BOOST_CHECK_EQUAL(exitCode, 1);
486 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700487 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout exceeded\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000488}
489
490BOOST_AUTO_TEST_CASE(ErrorCommand)
491{
492 this->processInterest = [this] (const Interest& interest) {
493 if (this->respondFaceQuery(interest)) {
494 return;
495 }
496
497 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
498 // no response to command
499 };
500
501 this->execute("route remove /mvGRoxD2 10156");
502 BOOST_CHECK_EQUAL(exitCode, 1);
503 BOOST_CHECK(out.is_empty());
504 BOOST_CHECK(err.is_equal("Error 10060 when removing route: request timed out\n"));
505}
506
507BOOST_AUTO_TEST_SUITE_END() // RemoveCommand
508
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000509const std::string STATUS_XML = stripXmlSpaces(R"XML(
510 <rib>
511 <ribEntry>
512 <prefix>/</prefix>
513 <routes>
514 <route>
515 <faceId>262</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000516 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000517 <cost>9</cost>
518 <flags>
519 <ribCapture/>
520 </flags>
521 </route>
522 <route>
523 <faceId>272</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000524 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000525 <cost>50</cost>
526 <flags/>
527 </route>
528 <route>
529 <faceId>274</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000530 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000531 <cost>78</cost>
532 <flags>
533 <childInherit/>
534 <ribCapture/>
535 </flags>
536 </route>
537 <route>
538 <faceId>276</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000539 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000540 <cost>79</cost>
541 <flags>
542 <childInherit/>
543 </flags>
544 <expirationPeriod>PT47S</expirationPeriod>
545 </route>
546 </routes>
547 </ribEntry>
548 <ribEntry>
549 <prefix>/localhost/nfd</prefix>
550 <routes>
551 <route>
552 <faceId>258</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000553 <origin>app</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000554 <cost>0</cost>
555 <flags>
556 <childInherit/>
557 </flags>
558 </route>
559 </routes>
560 </ribEntry>
561 </rib>
562)XML");
563
564const std::string STATUS_TEXT =
565 "RIB:\n"
Junxiao Shi8eda6822017-04-12 02:53:14 +0000566 " / routes={nexthop=262 origin=static cost=9 flags=capture expires=never, "
567 "nexthop=272 origin=static cost=50 flags=none expires=never, "
568 "nexthop=274 origin=static cost=78 flags=child-inherit|capture expires=never, "
569 "nexthop=276 origin=static cost=79 flags=child-inherit expires=47s}\n"
570 " /localhost/nfd routes={nexthop=258 origin=app cost=0 flags=child-inherit expires=never}\n";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000571
572BOOST_AUTO_TEST_CASE(Status)
573{
574 this->fetchStatus();
575 RibEntry payload1;
576 payload1.setName("/")
577 .addRoute(Route().setFaceId(262)
578 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
579 .setCost(9)
580 .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE))
581 .addRoute(Route().setFaceId(272)
582 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
583 .setCost(50)
584 .setFlags(ndn::nfd::ROUTE_FLAGS_NONE))
585 .addRoute(Route().setFaceId(274)
586 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
587 .setCost(78)
588 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE))
589 .addRoute(Route().setFaceId(276)
590 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
591 .setCost(79)
592 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
Davide Pesavento14e71f02019-03-28 17:35:25 -0400593 .setExpirationPeriod(47292_ms));
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000594 RibEntry payload2;
595 payload2.setName("/localhost/nfd")
596 .addRoute(Route().setFaceId(258)
597 .setOrigin(ndn::nfd::ROUTE_ORIGIN_APP)
598 .setCost(0)
599 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
600 this->sendDataset("/localhost/nfd/rib/list", payload1, payload2);
601 this->prepareStatusOutput();
602
603 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
604 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
605}
606
607BOOST_AUTO_TEST_SUITE_END() // TestRibModule
Junxiao Shi331ade72016-08-19 14:07:19 +0000608BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000609
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400610} // namespace nfd::tools::nfdc::tests