blob: 8aa7f50529c822c45df36421dc2c7155bdf4fec8 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi22f85682018-01-22 19:23:22 +00002/*
Davide Pesaventoaebf5d72024-12-26 16:04:12 -05003 * Copyright (c) 2013-2025 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Junxiao Shi5ec80222014-03-25 20:08:05 -070020 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/mgmt/nfd/control-command.hpp"
Junxiao Shi5ec80222014-03-25 20:08:05 -070023
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "tests/boost-test.hpp"
jaczhi82d8ed02025-01-07 15:51:02 -080025#include "tests/key-chain-fixture.hpp"
Junxiao Shi5ec80222014-03-25 20:08:05 -070026
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040027namespace ndn::tests {
28
29using namespace ndn::nfd;
Junxiao Shi5ec80222014-03-25 20:08:05 -070030
Junxiao Shi7357ef22016-09-07 02:39:37 +000031BOOST_AUTO_TEST_SUITE(Mgmt)
32BOOST_AUTO_TEST_SUITE(Nfd)
33BOOST_AUTO_TEST_SUITE(TestControlCommand)
Junxiao Shi5ec80222014-03-25 20:08:05 -070034
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000035BOOST_AUTO_TEST_CASE(FaceCreateRequest)
Junxiao Shi5ec80222014-03-25 20:08:05 -070036{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050037 using Command = FaceCreateCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -070038
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000039 // good with required fields only
Junxiao Shi5ec80222014-03-25 20:08:05 -070040 ControlParameters p1;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000041 p1.setUri("tcp4://192.0.2.1:6363");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050042 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
43 Name n1 = Command::createRequest("/PREFIX", p1).getName();
44 BOOST_CHECK(Name("/PREFIX/faces/create").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -070045
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000046 // good with optional fields
47 ControlParameters p2(p1);
48 p2.setLocalUri("tcp4://192.0.2.2:32114")
49 .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
Eric Newberry07d05c92018-01-22 16:08:01 -070050 .setBaseCongestionMarkingInterval(100_ms)
51 .setDefaultCongestionThreshold(10000)
Eric Newberry3c9bc042018-06-02 17:58:10 -070052 .setMtu(8192)
Eric Newberryda916d62016-08-11 23:04:34 -070053 .setFlags(0x3)
54 .setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050055 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
Yukai Tud93c5fc2015-08-25 11:37:16 +080056
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000057 // Uri is required
58 ControlParameters p3;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050059 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000060
61 // Name is forbidden
62 ControlParameters p4(p1);
63 p4.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050064 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000065
66 // Flags and Mask must be specified together
67 ControlParameters p5(p1);
68 p5.setFlags(0x3);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050069 BOOST_CHECK_THROW(Command::validateRequest(p5), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000070
Eric Newberryce9c1952020-02-15 15:10:59 -080071 // Flags and Mask must be specified together
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000072 ControlParameters p6(p1);
73 p6.setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050074 BOOST_CHECK_THROW(Command::validateRequest(p6), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000075}
76
77BOOST_AUTO_TEST_CASE(FaceCreateResponse)
78{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050079 using Command = FaceCreateCommand;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000080
81 // good
82 ControlParameters p1;
83 p1.setFaceId(3208)
Junxiao Shi144c7e32017-04-20 01:04:06 +000084 .setUri("tcp4://192.0.2.1:6363")
85 .setLocalUri("tcp4://192.0.2.2:32114")
86 .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
Eric Newberry07d05c92018-01-22 16:08:01 -070087 .setBaseCongestionMarkingInterval(500_ns)
88 .setDefaultCongestionThreshold(12345)
Eric Newberry3c9bc042018-06-02 17:58:10 -070089 .setMtu(2048)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000090 .setFlags(0x3);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050091 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
Eric Newberryda916d62016-08-11 23:04:34 -070092
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000093 // Name is forbidden
94 ControlParameters p2(p1);
95 p2.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050096 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Yukai Tud93c5fc2015-08-25 11:37:16 +080097
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000098 // Mask is forbidden
99 ControlParameters p3(p1);
100 p3.setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500101 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Eric Newberryda916d62016-08-11 23:04:34 -0700102
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000103 // FaceId must be valid
104 ControlParameters p4(p1);
105 p4.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500106 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Eric Newberryda916d62016-08-11 23:04:34 -0700107
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000108 // LocalUri is required
109 ControlParameters p5(p1);
110 p5.unsetLocalUri();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500111 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700112}
113
Yanbiao Licbdacb22016-08-02 16:02:35 +0800114BOOST_AUTO_TEST_CASE(FaceUpdate)
115{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500116 using Command = FaceUpdateCommand;
Yanbiao Licbdacb22016-08-02 16:02:35 +0800117
Eric Newberryce9c1952020-02-15 15:10:59 -0800118 // FaceId must be valid
Yanbiao Licbdacb22016-08-02 16:02:35 +0800119 ControlParameters p1;
120 p1.setFaceId(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500121 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500122 p1.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500123 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800124
Eric Newberryce9c1952020-02-15 15:10:59 -0800125 // Persistency and Flags are required in response
Yanbiao Licbdacb22016-08-02 16:02:35 +0800126 p1.setFaceId(1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500127 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
128 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
129 Command::applyDefaultsToRequest(p1);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700130 BOOST_CHECK_EQUAL(p1.getFaceId(), 1);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800131
Eric Newberryce9c1952020-02-15 15:10:59 -0800132 // Good request, bad response (Mask is forbidden but present)
Yanbiao Licbdacb22016-08-02 16:02:35 +0800133 ControlParameters p2;
134 p2.setFaceId(1)
Eric Newberry138ef2c2016-08-15 20:29:03 -0700135 .setFacePersistency(FACE_PERSISTENCY_PERSISTENT)
Eric Newberry07d05c92018-01-22 16:08:01 -0700136 .setBaseCongestionMarkingInterval(765_ns)
137 .setDefaultCongestionThreshold(54321)
Eric Newberryce9c1952020-02-15 15:10:59 -0800138 .setMtu(8192)
Eric Newberry138ef2c2016-08-15 20:29:03 -0700139 .setFlagBit(BIT_LOCAL_FIELDS_ENABLED, false);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500140 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
141 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800142
Eric Newberryce9c1952020-02-15 15:10:59 -0800143 // Flags without Mask (good response, bad request)
Eric Newberryda916d62016-08-11 23:04:34 -0700144 p2.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500145 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
146 BOOST_CHECK_NO_THROW(Command::validateResponse(p2));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700147
Eric Newberryce9c1952020-02-15 15:10:59 -0800148 // FaceId is optional in request
Eric Newberry138ef2c2016-08-15 20:29:03 -0700149 p2.setFlagBit(BIT_LOCAL_FIELDS_ENABLED, false);
150 p2.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500151 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Eric Newberryda916d62016-08-11 23:04:34 -0700152
Eric Newberryce9c1952020-02-15 15:10:59 -0800153 // Name is forbidden
Yanbiao Licbdacb22016-08-02 16:02:35 +0800154 ControlParameters p3;
Eric Newberryda916d62016-08-11 23:04:34 -0700155 p3.setFaceId(1)
156 .setName("/ndn/name");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500157 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
158 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800159
Eric Newberryce9c1952020-02-15 15:10:59 -0800160 // Uri is forbidden
Yanbiao Licbdacb22016-08-02 16:02:35 +0800161 ControlParameters p4;
162 p4.setFaceId(1)
Eric Newberryda916d62016-08-11 23:04:34 -0700163 .setUri("tcp4://192.0.2.1");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500164 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
165 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800166
Eric Newberryce9c1952020-02-15 15:10:59 -0800167 // Empty request is valid, empty response is invalid
Yanbiao Licbdacb22016-08-02 16:02:35 +0800168 ControlParameters p5;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500169 BOOST_CHECK_NO_THROW(Command::validateRequest(p5));
170 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700171 BOOST_CHECK(!p5.hasFaceId());
Eric Newberryce9c1952020-02-15 15:10:59 -0800172
173 // Default request, not valid response due to missing FacePersistency and Flags
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500174 Command::applyDefaultsToRequest(p5);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700175 BOOST_REQUIRE(p5.hasFaceId());
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500176 BOOST_CHECK_NO_THROW(Command::validateRequest(p5));
177 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700178 BOOST_CHECK_EQUAL(p5.getFaceId(), 0);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800179}
180
Junxiao Shi5ec80222014-03-25 20:08:05 -0700181BOOST_AUTO_TEST_CASE(FaceDestroy)
182{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500183 using Command = FaceDestroyCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700184
Eric Newberryce9c1952020-02-15 15:10:59 -0800185 // Uri is forbidden
Junxiao Shi5ec80222014-03-25 20:08:05 -0700186 ControlParameters p1;
187 p1.setUri("tcp4://192.0.2.1")
188 .setFaceId(4);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500189 BOOST_CHECK_THROW(Command::validateRequest(p1), ArgumentError);
190 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700191
Eric Newberryce9c1952020-02-15 15:10:59 -0800192 // FaceId must be valid
Junxiao Shi5ec80222014-03-25 20:08:05 -0700193 ControlParameters p2;
Davide Pesaventof8503d22017-02-17 01:19:10 -0500194 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500195 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
196 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700197
Eric Newberryce9c1952020-02-15 15:10:59 -0800198 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700199 ControlParameters p3;
200 p3.setFaceId(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500201 BOOST_CHECK_NO_THROW(Command::validateRequest(p3));
202 BOOST_CHECK_NO_THROW(Command::validateResponse(p3));
203 Name n3 = Command::createRequest("/PREFIX", p3).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700204 BOOST_CHECK(Name("ndn:/PREFIX/faces/destroy").isPrefixOf(n3));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700205}
206
Junxiao Shi5ec80222014-03-25 20:08:05 -0700207BOOST_AUTO_TEST_CASE(FibAddNextHop)
208{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500209 using Command = FibAddNextHopCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700210
Eric Newberryce9c1952020-02-15 15:10:59 -0800211 // Cost required in response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700212 ControlParameters p1;
213 p1.setName("ndn:/")
214 .setFaceId(22);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500215 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
216 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
217 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700218 BOOST_CHECK(Name("ndn:/PREFIX/fib/add-nexthop").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700219
Eric Newberryce9c1952020-02-15 15:10:59 -0800220 // Good request, bad response (FaceId must be valid)
Junxiao Shi5ec80222014-03-25 20:08:05 -0700221 ControlParameters p2;
222 p2.setName("ndn:/example")
223 .setFaceId(0)
224 .setCost(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500225 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500226 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500227 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700228
Eric Newberryce9c1952020-02-15 15:10:59 -0800229 // Default request
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500230 Command::applyDefaultsToRequest(p1);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700231 BOOST_REQUIRE(p1.hasCost());
232 BOOST_CHECK_EQUAL(p1.getCost(), 0);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700233
Eric Newberryce9c1952020-02-15 15:10:59 -0800234 // FaceId optional in request
Junxiao Shicaac54e2014-05-20 15:27:01 -0700235 p1.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500236 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
237 Command::applyDefaultsToRequest(p1);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700238 BOOST_REQUIRE(p1.hasFaceId());
239 BOOST_CHECK_EQUAL(p1.getFaceId(), 0);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700240}
241
242BOOST_AUTO_TEST_CASE(FibRemoveNextHop)
243{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500244 using Command = FibRemoveNextHopCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700245
Eric Newberryce9c1952020-02-15 15:10:59 -0800246 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700247 ControlParameters p1;
248 p1.setName("ndn:/")
249 .setFaceId(22);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500250 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
251 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
252 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700253 BOOST_CHECK(Name("ndn:/PREFIX/fib/remove-nexthop").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700254
Eric Newberryce9c1952020-02-15 15:10:59 -0800255 // Good request, bad response (FaceId must be valid)
Junxiao Shi5ec80222014-03-25 20:08:05 -0700256 ControlParameters p2;
257 p2.setName("ndn:/example")
258 .setFaceId(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500259 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500260 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500261 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700262
Eric Newberryce9c1952020-02-15 15:10:59 -0800263 // FaceId is optional in request
Junxiao Shicaac54e2014-05-20 15:27:01 -0700264 p1.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500265 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
266 Command::applyDefaultsToRequest(p1);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700267 BOOST_REQUIRE(p1.hasFaceId());
268 BOOST_CHECK_EQUAL(p1.getFaceId(), 0);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700269}
270
Junxiao Shi22f85682018-01-22 19:23:22 +0000271BOOST_AUTO_TEST_CASE(CsConfigRequest)
272{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500273 using Command = CsConfigCommand;
Junxiao Shi22f85682018-01-22 19:23:22 +0000274
275 // good empty request
276 ControlParameters p1;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500277 Command::validateRequest(p1);
278 Name n1 = Command::createRequest("/PREFIX", p1).getName();
279 BOOST_CHECK(Name("/PREFIX/cs/config").isPrefixOf(n1));
Junxiao Shi22f85682018-01-22 19:23:22 +0000280
281 // good full request
282 ControlParameters p2;
283 p2.setCapacity(1574);
284 p2.setFlagBit(BIT_CS_ENABLE_ADMIT, true);
285 p2.setFlagBit(BIT_CS_ENABLE_SERVE, true);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500286 Command::validateRequest(p2);
Junxiao Shi22f85682018-01-22 19:23:22 +0000287
288 // bad request: Flags but no Mask
289 ControlParameters p3(p2);
290 p3.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500291 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000292
293 // bad request: Mask but no Flags
294 ControlParameters p4(p2);
295 p4.unsetFlags();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500296 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000297
298 // bad request: forbidden field
299 ControlParameters p5(p2);
300 p5.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500301 BOOST_CHECK_THROW(Command::validateRequest(p5), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000302}
303
304BOOST_AUTO_TEST_CASE(CsConfigResponse)
305{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500306 using Command = CsConfigCommand;
Junxiao Shi22f85682018-01-22 19:23:22 +0000307
308 // bad empty response
309 ControlParameters p1;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500310 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000311
312 // bad response: Mask not allowed
313 ControlParameters p2;
314 p2.setCapacity(1574);
315 p2.setFlagBit(BIT_CS_ENABLE_ADMIT, true);
316 p2.setFlagBit(BIT_CS_ENABLE_SERVE, true);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500317 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000318
319 // good response
320 ControlParameters p3(p2);
321 p3.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500322 Command::validateResponse(p3);
Junxiao Shi22f85682018-01-22 19:23:22 +0000323}
324
Junxiao Shidf505382018-03-04 13:40:44 +0000325BOOST_AUTO_TEST_CASE(CsEraseRequest)
326{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500327 using Command = CsEraseCommand;
Junxiao Shidf505382018-03-04 13:40:44 +0000328
329 // good no-limit request
330 ControlParameters p1;
331 p1.setName("/u4LYPNU8Q");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500332 Command::validateRequest(p1);
333 Name n1 = Command::createRequest("/PREFIX", p1).getName();
334 BOOST_CHECK(Name("/PREFIX/cs/erase").isPrefixOf(n1));
Junxiao Shidf505382018-03-04 13:40:44 +0000335
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500336 // good limited request
Junxiao Shidf505382018-03-04 13:40:44 +0000337 ControlParameters p2;
338 p2.setName("/IMw1RaLF");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500339 p2.setCount(177);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500340 Command::validateRequest(p2);
Junxiao Shidf505382018-03-04 13:40:44 +0000341
342 // bad request: zero entry
343 ControlParameters p3;
344 p3.setName("/ahMID1jcib");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500345 p3.setCount(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500346 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000347
348 // bad request: forbidden field
349 ControlParameters p4(p2);
350 p4.setCapacity(278);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500351 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000352}
353
354BOOST_AUTO_TEST_CASE(CsEraseResponse)
355{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500356 using Command = CsEraseCommand;
Junxiao Shidf505382018-03-04 13:40:44 +0000357
358 // good normal response
359 ControlParameters p1;
360 p1.setName("/TwiIwCdR");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500361 p1.setCount(1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500362 Command::validateResponse(p1);
Junxiao Shidf505382018-03-04 13:40:44 +0000363
364 // good limit exceeded request
365 ControlParameters p2;
366 p2.setName("/NMsiy44pr");
367 p2.setCapacity(360);
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500368 p2.setCount(360);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500369 Command::validateResponse(p2);
Junxiao Shidf505382018-03-04 13:40:44 +0000370
371 // good zero-entry response
372 ControlParameters p3;
373 p3.setName("/5f1LRPh1L");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500374 p3.setCount(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500375 Command::validateResponse(p3);
Junxiao Shidf505382018-03-04 13:40:44 +0000376
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500377 // bad request: missing Count
Junxiao Shidf505382018-03-04 13:40:44 +0000378 ControlParameters p4(p1);
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500379 p4.unsetCount();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500380 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000381
382 // bad request: zero capacity
383 ControlParameters p5(p1);
384 p5.setCapacity(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500385 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000386}
387
Junxiao Shi5ec80222014-03-25 20:08:05 -0700388BOOST_AUTO_TEST_CASE(StrategyChoiceSet)
389{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500390 using Command = StrategyChoiceSetCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700391
Eric Newberryce9c1952020-02-15 15:10:59 -0800392 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700393 ControlParameters p1;
394 p1.setName("ndn:/")
395 .setStrategy("ndn:/strategy/P");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500396 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
397 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
398 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700399 BOOST_CHECK(Name("ndn:/PREFIX/strategy-choice/set").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700400
Eric Newberryce9c1952020-02-15 15:10:59 -0800401 // Strategy is required in both requests and responses
Junxiao Shi5ec80222014-03-25 20:08:05 -0700402 ControlParameters p2;
403 p2.setName("ndn:/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500404 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
405 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700406}
407
408BOOST_AUTO_TEST_CASE(StrategyChoiceUnset)
409{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500410 using Command = StrategyChoiceUnsetCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700411
Eric Newberryce9c1952020-02-15 15:10:59 -0800412 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700413 ControlParameters p1;
414 p1.setName("ndn:/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500415 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
416 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
417 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700418 BOOST_CHECK(Name("ndn:/PREFIX/strategy-choice/unset").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700419
Eric Newberryce9c1952020-02-15 15:10:59 -0800420 // Strategy is forbidden
Junxiao Shi5ec80222014-03-25 20:08:05 -0700421 ControlParameters p2;
422 p2.setName("ndn:/example")
423 .setStrategy("ndn:/strategy/P");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500424 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
425 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700426
Eric Newberryce9c1952020-02-15 15:10:59 -0800427 // Name must have at least one component
Junxiao Shi5ec80222014-03-25 20:08:05 -0700428 ControlParameters p3;
429 p3.setName("ndn:/");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500430 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
431 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700432}
433
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700434BOOST_AUTO_TEST_CASE(RibRegister)
435{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500436 using Command = RibRegisterCommand;
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700437
Eric Newberryce9c1952020-02-15 15:10:59 -0800438 // Good request, response missing many fields
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700439 ControlParameters p1;
440 p1.setName("ndn:/");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500441 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
442 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
443 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700444 BOOST_CHECK(Name("ndn:/PREFIX/rib/register").isPrefixOf(n1));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700445
Eric Newberryce9c1952020-02-15 15:10:59 -0800446 // Default request
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500447 Command::applyDefaultsToRequest(p1);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700448 BOOST_REQUIRE(p1.hasOrigin());
Davide Pesaventoe8e48c22017-04-13 00:35:33 -0400449 BOOST_CHECK_EQUAL(p1.getOrigin(), ROUTE_ORIGIN_APP);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700450 BOOST_REQUIRE(p1.hasCost());
451 BOOST_CHECK_EQUAL(p1.getCost(), 0);
452 BOOST_REQUIRE(p1.hasFlags());
453 BOOST_CHECK_EQUAL(p1.getFlags(), static_cast<uint64_t>(ROUTE_FLAG_CHILD_INHERIT));
Alexander Afanasyev21f13b02014-07-17 16:17:34 -0700454 BOOST_CHECK_EQUAL(p1.hasExpirationPeriod(), false);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700455
Eric Newberryce9c1952020-02-15 15:10:59 -0800456 // Good request, good response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700457 ControlParameters p2;
458 p2.setName("ndn:/example")
459 .setFaceId(2)
460 .setCost(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500461 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
462 Command::applyDefaultsToRequest(p2);
Alexander Afanasyev21f13b02014-07-17 16:17:34 -0700463 BOOST_CHECK_EQUAL(p2.hasExpirationPeriod(), false);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500464 BOOST_CHECK_NO_THROW(Command::validateResponse(p2));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700465}
466
467BOOST_AUTO_TEST_CASE(RibUnregister)
468{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500469 using Command = RibUnregisterCommand;
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700470
Eric Newberryce9c1952020-02-15 15:10:59 -0800471 // Good request, good response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700472 ControlParameters p1;
473 p1.setName("ndn:/")
474 .setFaceId(22)
475 .setOrigin(ROUTE_ORIGIN_STATIC);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500476 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
477 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
478 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700479 BOOST_CHECK(Name("ndn:/PREFIX/rib/unregister").isPrefixOf(n1));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700480
Eric Newberryce9c1952020-02-15 15:10:59 -0800481 // Good request, bad response (FaceId must be valid)
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700482 ControlParameters p2;
483 p2.setName("ndn:/example")
484 .setFaceId(0)
485 .setOrigin(ROUTE_ORIGIN_APP);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500486 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500487 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500488 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700489
Eric Newberryce9c1952020-02-15 15:10:59 -0800490 // FaceId is optional in request, required in response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700491 p2.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500492 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
493 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700494}
495
jaczhi82d8ed02025-01-07 15:51:02 -0800496BOOST_FIXTURE_TEST_CASE(RibAnnounce, KeyChainFixture)
497{
498 using Command = RibAnnounceCommand;
499
500 // Good request
501 PrefixAnnouncement pa1;
502 pa1.setAnnouncedName("ndn:/");
503 pa1.setExpiration(1_min);
504 pa1.toData(m_keyChain);
505 RibAnnounceParameters p1;
506 p1.setPrefixAnnouncement(pa1);
507 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
508 Name n1 = Command::createRequest("/PREFIX", p1).getName();
509 BOOST_CHECK(Name("ndn:/PREFIX/rib/announce").isPrefixOf(n1));
510
511 // Good response
512 ControlParameters p2;
513 p2.setName("ndn:/")
514 .setFaceId(22)
515 .setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN)
516 .setCost(2048)
517 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
518 .setExpirationPeriod(1_min);
519 BOOST_CHECK_NO_THROW(Command::validateResponse(p2));
520
521 // Bad request (PrefixAnnouncement must be signed)
522 PrefixAnnouncement pa2;
523 pa2.setAnnouncedName("ndn:/");
524 pa2.setExpiration(1_min);
525 RibAnnounceParameters p3;
526 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
527 p3.setPrefixAnnouncement(pa2);
528 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
529
530 // Bad response (FaceId must be valid)
531 ControlParameters p4;
532 p4.setName("ndn:/")
533 .setFaceId(0)
534 .setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN)
535 .setCost(2048)
536 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
537 .setExpirationPeriod(1_min);
538 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
539}
540
Junxiao Shi7357ef22016-09-07 02:39:37 +0000541BOOST_AUTO_TEST_SUITE_END() // TestControlCommand
542BOOST_AUTO_TEST_SUITE_END() // Nfd
543BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi5ec80222014-03-25 20:08:05 -0700544
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400545} // namespace ndn::tests