blob: 7f268ddbd5ea26bb41af6eab40bdffcae2a2e034 [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/*
Eric Newberryd656aff2020-04-03 00:30:38 -07003 * Copyright (c) 2014-2020, 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
31namespace nfd {
32namespace tools {
Junxiao Shi331ade72016-08-19 14:07:19 +000033namespace nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000034namespace tests {
35
Junxiao Shi331ade72016-08-19 14:07:19 +000036BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi1f481fa2017-01-26 15:14:43 +000037BOOST_FIXTURE_TEST_SUITE(TestRibModule, StatusFixture<RibModule>)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000038
Junxiao Shi1d62e622017-03-08 22:39:28 +000039class RouteListFixture : public ExecuteCommandFixture
40{
41protected:
42 bool
43 respondRibDataset(const Interest& interest)
44 {
45 if (!Name("/localhost/nfd/rib/list").isPrefixOf(interest.getName())) {
46 return false;
47 }
48
49 RibEntry entry1;
50 entry1.setName("/5BBmTevRJ");
51 entry1.addRoute(Route()
52 .setFaceId(6720)
53 .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)
54 .setCost(2956)
55 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE)
Davide Pesavento14e71f02019-03-28 17:35:25 -040056 .setExpirationPeriod(29950035_ms));
Junxiao Shi1d62e622017-03-08 22:39:28 +000057 entry1.addRoute(Route()
58 .setFaceId(6720)
59 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
60 .setCost(425)
61 .setFlags(ndn::nfd::ROUTE_FLAGS_NONE));
62 entry1.addRoute(Route()
63 .setFaceId(8599)
64 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
65 .setCost(9140)
66 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
67
68 RibEntry entry2;
69 entry2.setName("/aDPTKCio");
70 entry2.addRoute(Route()
71 .setFaceId(31066)
72 .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)
73 .setCost(4617)
74 .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE));
75
76 this->sendDataset(interest.getName(), entry1, entry2);
77 return true;
78 }
79};
80
81BOOST_FIXTURE_TEST_SUITE(ListShowCommand, RouteListFixture)
82
83const std::string NOFILTER_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +000084prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
85prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
86prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
87prefix=/aDPTKCio nexthop=31066 origin=client cost=4617 flags=capture expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +000088)TEXT").substr(1);
89
90BOOST_AUTO_TEST_CASE(ListNoFilter)
91{
92 this->processInterest = [this] (const Interest& interest) {
93 BOOST_CHECK(this->respondRibDataset(interest));
94 };
95
96 this->execute("route");
97 BOOST_CHECK_EQUAL(exitCode, 0);
98 BOOST_CHECK(out.is_equal(NOFILTER_OUTPUT));
99 BOOST_CHECK(err.is_empty());
100}
101
102const std::string NEXTHOP_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000103prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
104prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
105prefix=/aDPTKCio nexthop=31066 origin=client cost=4617 flags=capture expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000106)TEXT").substr(1);
107
108BOOST_AUTO_TEST_CASE(ListByNexthop)
109{
110 this->processInterest = [this] (const Interest& interest) {
111 BOOST_CHECK(this->respondFaceQuery(interest) || this->respondRibDataset(interest));
112 };
113
114 this->execute("route list udp4://225.131.75.231:56363");
115 BOOST_CHECK_EQUAL(exitCode, 0);
116 BOOST_CHECK(out.is_equal(NEXTHOP_OUTPUT));
117 BOOST_CHECK(err.is_empty());
118}
119
120const std::string ORIGIN_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000121prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
122prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000123)TEXT").substr(1);
124
Junxiao Shi8eda6822017-04-12 02:53:14 +0000125BOOST_AUTO_TEST_CASE(ListByOriginNumeric)
Junxiao Shi1d62e622017-03-08 22:39:28 +0000126{
127 this->processInterest = [this] (const Interest& interest) {
128 BOOST_CHECK(this->respondRibDataset(interest));
129 };
130
131 this->execute("route list origin 255");
132 BOOST_CHECK_EQUAL(exitCode, 0);
133 BOOST_CHECK(out.is_equal(ORIGIN_OUTPUT));
134 BOOST_CHECK(err.is_empty());
135}
136
Junxiao Shi8eda6822017-04-12 02:53:14 +0000137BOOST_AUTO_TEST_CASE(ListByOriginString)
138{
139 this->processInterest = [this] (const Interest& interest) {
140 BOOST_CHECK(this->respondRibDataset(interest));
141 };
142
143 this->execute("route list origin static");
144 BOOST_CHECK_EQUAL(exitCode, 0);
145 BOOST_CHECK(out.is_equal(ORIGIN_OUTPUT));
146 BOOST_CHECK(err.is_empty());
147}
148
Junxiao Shi1d62e622017-03-08 22:39:28 +0000149const std::string PREFIX_OUTPUT = std::string(R"TEXT(
Junxiao Shi8eda6822017-04-12 02:53:14 +0000150prefix=/5BBmTevRJ nexthop=6720 origin=client cost=2956 flags=child-inherit|capture expires=29950s
151prefix=/5BBmTevRJ nexthop=6720 origin=static cost=425 flags=none expires=never
152prefix=/5BBmTevRJ nexthop=8599 origin=static cost=9140 flags=child-inherit expires=never
Junxiao Shi1d62e622017-03-08 22:39:28 +0000153)TEXT").substr(1);
154
155BOOST_AUTO_TEST_CASE(ShowByPrefix)
156{
157 this->processInterest = [this] (const Interest& interest) {
158 BOOST_CHECK(this->respondRibDataset(interest));
159 };
160
161 this->execute("route show 5BBmTevRJ");
162 BOOST_CHECK_EQUAL(exitCode, 0);
163 BOOST_CHECK(out.is_equal(PREFIX_OUTPUT));
164 BOOST_CHECK(err.is_empty());
165}
166
167BOOST_AUTO_TEST_CASE(FaceNotExist)
168{
169 this->processInterest = [this] (const Interest& interest) {
170 BOOST_CHECK(this->respondFaceQuery(interest));
171 };
172
173 this->execute("route list 23728");
174 BOOST_CHECK_EQUAL(exitCode, 3);
175 BOOST_CHECK(out.is_empty());
176 BOOST_CHECK(err.is_equal("Face not found\n"));
177}
178
179BOOST_AUTO_TEST_CASE(RouteNotExist)
180{
181 this->processInterest = [this] (const Interest& interest) {
182 BOOST_CHECK(this->respondFaceQuery(interest) || this->respondRibDataset(interest));
183 };
184
185 this->execute("route list 10156");
186 BOOST_CHECK_EQUAL(exitCode, 6);
187 BOOST_CHECK(out.is_empty());
188 BOOST_CHECK(err.is_equal("Route not found\n"));
189}
190
191BOOST_AUTO_TEST_CASE(ErrorDataset)
192{
193 this->processInterest = nullptr; // no response to dataset
194
195 this->execute("route list");
196 BOOST_CHECK_EQUAL(exitCode, 1);
197 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700198 BOOST_CHECK(err.is_equal("Error 10060 when fetching RIB dataset: Timeout exceeded\n"));
Junxiao Shi1d62e622017-03-08 22:39:28 +0000199}
200
201BOOST_AUTO_TEST_SUITE_END() // ListShowCommand
202
Junxiao Shi918e5d42017-02-25 03:58:21 +0000203BOOST_FIXTURE_TEST_SUITE(AddCommand, ExecuteCommandFixture)
204
205BOOST_AUTO_TEST_CASE(NormalByFaceId)
206{
207 this->processInterest = [this] (const Interest& interest) {
208 if (this->respondFaceQuery(interest)) {
209 return;
210 }
211
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000212 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Junxiao Shi918e5d42017-02-25 03:58:21 +0000213 ndn::nfd::RibRegisterCommand cmd;
214 cmd.validateRequest(req);
215 cmd.applyDefaultsToRequest(req);
216 BOOST_CHECK_EQUAL(req.getName(), "/vxXoEaWeDB");
217 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
218 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
219 BOOST_CHECK_EQUAL(req.getCost(), 0);
220 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAGS_NONE);
221 BOOST_CHECK_EQUAL(req.hasExpirationPeriod(), false);
222
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000223 this->succeedCommand(interest, req);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000224 };
225
226 this->execute("route add /vxXoEaWeDB 10156 no-inherit");
227 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000228 BOOST_CHECK(out.is_equal("route-add-accepted prefix=/vxXoEaWeDB nexthop=10156 origin=static "
Junxiao Shi918e5d42017-02-25 03:58:21 +0000229 "cost=0 flags=none expires=never\n"));
230 BOOST_CHECK(err.is_empty());
231}
232
233BOOST_AUTO_TEST_CASE(NormalByFaceUri)
234{
235 this->processInterest = [this] (const Interest& interest) {
236 if (this->respondFaceQuery(interest)) {
237 return;
238 }
239
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000240 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Junxiao Shi918e5d42017-02-25 03:58:21 +0000241 ndn::nfd::RibRegisterCommand cmd;
242 cmd.validateRequest(req);
243 cmd.applyDefaultsToRequest(req);
244 BOOST_CHECK_EQUAL(req.getName(), "/FLQAsaYnYf");
245 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
246 BOOST_CHECK_EQUAL(req.getOrigin(), 17591);
247 BOOST_CHECK_EQUAL(req.getCost(), 702);
248 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAG_CHILD_INHERIT |
249 ndn::nfd::ROUTE_FLAG_CAPTURE);
250 BOOST_REQUIRE_EQUAL(req.hasExpirationPeriod(), true);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400251 BOOST_REQUIRE_EQUAL(req.getExpirationPeriod(), 727411987_ms);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000252
253 ControlParameters resp = req;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400254 resp.setExpirationPeriod(727411154_ms); // server side may change expiration
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000255 this->succeedCommand(interest, resp);
Junxiao Shi918e5d42017-02-25 03:58:21 +0000256 };
257
258 this->execute("route add /FLQAsaYnYf tcp4://32.121.182.82:6363 "
259 "origin 17591 cost 702 capture expires 727411987");
260 BOOST_CHECK_EQUAL(exitCode, 0);
261 BOOST_CHECK(out.is_equal("route-add-accepted prefix=/FLQAsaYnYf nexthop=2249 origin=17591 "
262 "cost=702 flags=child-inherit|capture expires=727411154ms\n"));
263 BOOST_CHECK(err.is_empty());
264}
265
Eric Newberryd656aff2020-04-03 00:30:38 -0700266BOOST_AUTO_TEST_CASE(FaceNotExistFaceId)
Junxiao Shi918e5d42017-02-25 03:58:21 +0000267{
268 this->processInterest = [this] (const Interest& interest) {
269 BOOST_CHECK(this->respondFaceQuery(interest));
270 };
271
272 this->execute("route add /GJiKDus5i 23728");
273 BOOST_CHECK_EQUAL(exitCode, 3);
274 BOOST_CHECK(out.is_empty());
275 BOOST_CHECK(err.is_equal("Face not found\n"));
276}
277
Eric Newberryd656aff2020-04-03 00:30:38 -0700278BOOST_AUTO_TEST_CASE(FaceNotExistFaceUri)
279{
280 this->processInterest = [this] (const Interest& interest) {
281 if (Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName())) {
282 this->respondFaceQuery(interest);
283 }
284 else if (Name("/localhost/nfd/faces/create").isPrefixOf(interest.getName())) {
285 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
286 ndn::nfd::FaceCreateCommand cmd;
287 cmd.validateRequest(req);
288 cmd.applyDefaultsToRequest(req);
289 BOOST_CHECK_EQUAL(req.getUri(), "udp4://202.83.168.28:6363");
290
291 ControlParameters resp = req;
292 resp.setFaceId(255);
293 resp.setLocalUri("udp4://32.121.182.82:50000");
294 resp.setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
295 resp.setBaseCongestionMarkingInterval(100_ms);
296 resp.setDefaultCongestionThreshold(65536);
297 resp.setMtu(8800);
298 resp.setFlags(0);
299 this->succeedCommand(interest, resp);
300 }
301 else if (Name("/localhost/nfd/rib/register").isPrefixOf(interest.getName())) {
302 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
303 ndn::nfd::RibRegisterCommand cmd;
304 cmd.validateRequest(req);
305 cmd.applyDefaultsToRequest(req);
306 BOOST_CHECK_EQUAL(req.getName(), "/634jfAfdf");
307 BOOST_CHECK_EQUAL(req.getFaceId(), 255);
308 BOOST_CHECK_EQUAL(req.getOrigin(), 17591);
309 BOOST_CHECK_EQUAL(req.getCost(), 702);
310 BOOST_CHECK_EQUAL(req.getFlags(), ndn::nfd::ROUTE_FLAG_CHILD_INHERIT |
311 ndn::nfd::ROUTE_FLAG_CAPTURE);
312 BOOST_REQUIRE_EQUAL(req.hasExpirationPeriod(), true);
313 BOOST_REQUIRE_EQUAL(req.getExpirationPeriod(), 727411987_ms);
314
315 ControlParameters resp = req;
316 resp.setExpirationPeriod(727411154_ms); // server side may change expiration
317 this->succeedCommand(interest, resp);
318 }
319 };
320
321 this->execute("route add /634jfAfdf udp4://202.83.168.28:6363 "
322 "origin 17591 cost 702 capture expires 727411987");
323 BOOST_CHECK(out.is_equal("face-created id=255 local=udp4://32.121.182.82:50000 "
324 "remote=udp4://202.83.168.28:6363 persistency=persistent "
325 "reliability=off congestion-marking=off "
326 "congestion-marking-interval=100ms default-congestion-threshold=65536B "
327 "mtu=8800\n"
328 "route-add-accepted prefix=/634jfAfdf nexthop=255 origin=17591 "
329 "cost=702 flags=child-inherit|capture expires=727411154ms\n"));
330 BOOST_CHECK(err.is_empty());
331 BOOST_CHECK_EQUAL(exitCode, 0);
332}
333
334BOOST_AUTO_TEST_CASE(FaceNotExistNotCanonizable)
335{
336 this->processInterest = [this] (const Interest& interest) {
337 BOOST_CHECK(this->respondFaceQuery(interest));
338 };
339
340 this->execute("route add /634jfAfdf udp6://202.83.168.28:6363 "
341 "origin 17591 cost 702 capture expires 727411987");
342 BOOST_CHECK(out.is_empty());
343 BOOST_CHECK(err.is_equal("Error during canonization of 'udp6://202.83.168.28:6363': "
344 "IPv4/v6 mismatch\n"));
345 BOOST_CHECK_EQUAL(exitCode, 4);
346}
347
Junxiao Shi918e5d42017-02-25 03:58:21 +0000348BOOST_AUTO_TEST_CASE(Ambiguous)
349{
350 this->processInterest = [this] (const Interest& interest) {
351 BOOST_CHECK(this->respondFaceQuery(interest));
352 };
353
354 this->execute("route add /BQqjjnVsz udp4://225.131.75.231:56363");
355 BOOST_CHECK_EQUAL(exitCode, 5);
356 BOOST_CHECK(out.is_empty());
357 BOOST_CHECK(err.is_equal("Multiple faces match specified remote FaceUri. "
358 "Re-run the command with a FaceId: "
359 "6720 (local=udp4://202.83.168.28:56363), "
360 "31066 (local=udp4://25.90.26.32:56363)\n"));
361}
362
363BOOST_AUTO_TEST_CASE(ErrorCanonization)
364{
365 this->execute("route add /bxJfGsVtDt udp6://32.38.164.64:10445");
366 BOOST_CHECK_EQUAL(exitCode, 4);
367 BOOST_CHECK(out.is_empty());
Eric Newberryd656aff2020-04-03 00:30:38 -0700368 BOOST_CHECK(err.is_equal("Error during canonization of 'udp6://32.38.164.64:10445': "
Eric Newberry7d8695d2017-05-29 15:49:10 -0700369 "IPv4/v6 mismatch\n"));
Junxiao Shi918e5d42017-02-25 03:58:21 +0000370}
371
372BOOST_AUTO_TEST_CASE(ErrorDataset)
373{
374 this->processInterest = nullptr; // no response to dataset or command
375
376 this->execute("route add /q1Qf7go7 udp://159.242.33.78");
377 BOOST_CHECK_EQUAL(exitCode, 1);
378 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700379 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout exceeded\n"));
Junxiao Shi918e5d42017-02-25 03:58:21 +0000380}
381
382BOOST_AUTO_TEST_CASE(ErrorCommand)
383{
384 this->processInterest = [this] (const Interest& interest) {
385 if (this->respondFaceQuery(interest)) {
386 return;
387 }
388
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000389 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/register");
Junxiao Shi918e5d42017-02-25 03:58:21 +0000390 // no response to command
391 };
392
393 this->execute("route add /bYiMbEuE 10156");
394 BOOST_CHECK_EQUAL(exitCode, 1);
395 BOOST_CHECK(out.is_empty());
396 BOOST_CHECK(err.is_equal("Error 10060 when adding route: request timed out\n"));
397}
398
399BOOST_AUTO_TEST_SUITE_END() // AddCommand
400
Junxiao Shi084b7952017-02-26 22:00:53 +0000401BOOST_FIXTURE_TEST_SUITE(RemoveCommand, ExecuteCommandFixture)
402
403BOOST_AUTO_TEST_CASE(NormalByFaceId)
404{
405 this->processInterest = [this] (const Interest& interest) {
406 if (this->respondFaceQuery(interest)) {
407 return;
408 }
409
410 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
411 ndn::nfd::RibUnregisterCommand cmd;
412 cmd.validateRequest(req);
413 cmd.applyDefaultsToRequest(req);
414 BOOST_CHECK_EQUAL(req.getName(), "/2B5NUGjpt");
415 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
416 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
417
418 this->succeedCommand(interest, req);
419 };
420
421 this->execute("route remove /2B5NUGjpt 10156");
422 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000423 BOOST_CHECK(out.is_equal("route-removed prefix=/2B5NUGjpt nexthop=10156 origin=static\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000424 BOOST_CHECK(err.is_empty());
425}
426
427BOOST_AUTO_TEST_CASE(NormalByFaceUri)
428{
429 this->processInterest = [this] (const Interest& interest) {
430 if (this->respondFaceQuery(interest)) {
431 return;
432 }
433
434 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
435 ndn::nfd::RibUnregisterCommand cmd;
436 cmd.validateRequest(req);
437 cmd.applyDefaultsToRequest(req);
438 BOOST_CHECK_EQUAL(req.getName(), "/wHdNn0BtUF");
439 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
440 BOOST_CHECK_EQUAL(req.getOrigin(), 15246);
441
442 this->succeedCommand(interest, req);
443 };
444
445 this->execute("route remove /wHdNn0BtUF tcp4://32.121.182.82:6363 origin 15246");
446 BOOST_CHECK_EQUAL(exitCode, 0);
447 BOOST_CHECK(out.is_equal("route-removed prefix=/wHdNn0BtUF nexthop=2249 origin=15246\n"));
448 BOOST_CHECK(err.is_empty());
449}
450
451BOOST_AUTO_TEST_CASE(MultipleFaces)
452{
453 std::set<uint64_t> faceIds{6720, 31066};
454 this->processInterest = [this, &faceIds] (const Interest& interest) {
455 if (this->respondFaceQuery(interest)) {
456 return;
457 }
458
459 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
460 ndn::nfd::RibUnregisterCommand cmd;
461 cmd.validateRequest(req);
462 cmd.applyDefaultsToRequest(req);
463 BOOST_CHECK_EQUAL(req.getName(), "/nm5y8X8b2");
Alexander Afanasyev0c63c632017-12-05 11:17:09 -0500464 BOOST_CHECK_MESSAGE(faceIds.erase(req.getFaceId()), "expected face " + to_string(req.getFaceId()));
Junxiao Shi084b7952017-02-26 22:00:53 +0000465 BOOST_CHECK_EQUAL(req.getOrigin(), ndn::nfd::ROUTE_ORIGIN_STATIC);
466
467 this->succeedCommand(interest, req);
468 };
469
470 this->execute("route remove /nm5y8X8b2 udp4://225.131.75.231:56363");
471 BOOST_CHECK(faceIds.empty());
472 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi8eda6822017-04-12 02:53:14 +0000473 BOOST_CHECK(out.is_equal("route-removed prefix=/nm5y8X8b2 nexthop=6720 origin=static\n"
474 "route-removed prefix=/nm5y8X8b2 nexthop=31066 origin=static\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000475 BOOST_CHECK(err.is_empty());
476}
477
478BOOST_AUTO_TEST_CASE(FaceNotExist)
479{
480 this->processInterest = [this] (const Interest& interest) {
481 BOOST_CHECK(this->respondFaceQuery(interest));
482 };
483
484 this->execute("route remove /HeGRjzwFM 23728");
485 BOOST_CHECK_EQUAL(exitCode, 3);
486 BOOST_CHECK(out.is_empty());
487 BOOST_CHECK(err.is_equal("Face not found\n"));
488}
489
490BOOST_AUTO_TEST_CASE(ErrorDataset)
491{
492 this->processInterest = nullptr; // no response to dataset or command
493
494 this->execute("route remove /YX4xQQN3v5 udp://26.97.248.3");
495 BOOST_CHECK_EQUAL(exitCode, 1);
496 BOOST_CHECK(out.is_empty());
Eric Newberry359135c2018-06-26 21:02:12 -0700497 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout exceeded\n"));
Junxiao Shi084b7952017-02-26 22:00:53 +0000498}
499
500BOOST_AUTO_TEST_CASE(ErrorCommand)
501{
502 this->processInterest = [this] (const Interest& interest) {
503 if (this->respondFaceQuery(interest)) {
504 return;
505 }
506
507 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/rib/unregister");
508 // no response to command
509 };
510
511 this->execute("route remove /mvGRoxD2 10156");
512 BOOST_CHECK_EQUAL(exitCode, 1);
513 BOOST_CHECK(out.is_empty());
514 BOOST_CHECK(err.is_equal("Error 10060 when removing route: request timed out\n"));
515}
516
517BOOST_AUTO_TEST_SUITE_END() // RemoveCommand
518
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000519const std::string STATUS_XML = stripXmlSpaces(R"XML(
520 <rib>
521 <ribEntry>
522 <prefix>/</prefix>
523 <routes>
524 <route>
525 <faceId>262</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000526 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000527 <cost>9</cost>
528 <flags>
529 <ribCapture/>
530 </flags>
531 </route>
532 <route>
533 <faceId>272</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000534 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000535 <cost>50</cost>
536 <flags/>
537 </route>
538 <route>
539 <faceId>274</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000540 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000541 <cost>78</cost>
542 <flags>
543 <childInherit/>
544 <ribCapture/>
545 </flags>
546 </route>
547 <route>
548 <faceId>276</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000549 <origin>static</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000550 <cost>79</cost>
551 <flags>
552 <childInherit/>
553 </flags>
554 <expirationPeriod>PT47S</expirationPeriod>
555 </route>
556 </routes>
557 </ribEntry>
558 <ribEntry>
559 <prefix>/localhost/nfd</prefix>
560 <routes>
561 <route>
562 <faceId>258</faceId>
Junxiao Shi8eda6822017-04-12 02:53:14 +0000563 <origin>app</origin>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000564 <cost>0</cost>
565 <flags>
566 <childInherit/>
567 </flags>
568 </route>
569 </routes>
570 </ribEntry>
571 </rib>
572)XML");
573
574const std::string STATUS_TEXT =
575 "RIB:\n"
Junxiao Shi8eda6822017-04-12 02:53:14 +0000576 " / routes={nexthop=262 origin=static cost=9 flags=capture expires=never, "
577 "nexthop=272 origin=static cost=50 flags=none expires=never, "
578 "nexthop=274 origin=static cost=78 flags=child-inherit|capture expires=never, "
579 "nexthop=276 origin=static cost=79 flags=child-inherit expires=47s}\n"
580 " /localhost/nfd routes={nexthop=258 origin=app cost=0 flags=child-inherit expires=never}\n";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000581
582BOOST_AUTO_TEST_CASE(Status)
583{
584 this->fetchStatus();
585 RibEntry payload1;
586 payload1.setName("/")
587 .addRoute(Route().setFaceId(262)
588 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
589 .setCost(9)
590 .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE))
591 .addRoute(Route().setFaceId(272)
592 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
593 .setCost(50)
594 .setFlags(ndn::nfd::ROUTE_FLAGS_NONE))
595 .addRoute(Route().setFaceId(274)
596 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
597 .setCost(78)
598 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE))
599 .addRoute(Route().setFaceId(276)
600 .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
601 .setCost(79)
602 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
Davide Pesavento14e71f02019-03-28 17:35:25 -0400603 .setExpirationPeriod(47292_ms));
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000604 RibEntry payload2;
605 payload2.setName("/localhost/nfd")
606 .addRoute(Route().setFaceId(258)
607 .setOrigin(ndn::nfd::ROUTE_ORIGIN_APP)
608 .setCost(0)
609 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
610 this->sendDataset("/localhost/nfd/rib/list", payload1, payload2);
611 this->prepareStatusOutput();
612
613 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
614 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
615}
616
617BOOST_AUTO_TEST_SUITE_END() // TestRibModule
Junxiao Shi331ade72016-08-19 14:07:19 +0000618BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000619
620} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000621} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000622} // namespace tools
623} // namespace nfd