blob: dc8cff065249cda3009e29313bbcf3715fe6866d [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"
Junxiao Shi5ec80222014-03-25 20:08:05 -070025
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040026namespace ndn::tests {
27
28using namespace ndn::nfd;
Junxiao Shi5ec80222014-03-25 20:08:05 -070029
Junxiao Shi7357ef22016-09-07 02:39:37 +000030BOOST_AUTO_TEST_SUITE(Mgmt)
31BOOST_AUTO_TEST_SUITE(Nfd)
32BOOST_AUTO_TEST_SUITE(TestControlCommand)
Junxiao Shi5ec80222014-03-25 20:08:05 -070033
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000034BOOST_AUTO_TEST_CASE(FaceCreateRequest)
Junxiao Shi5ec80222014-03-25 20:08:05 -070035{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050036 using Command = FaceCreateCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -070037
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000038 // good with required fields only
Junxiao Shi5ec80222014-03-25 20:08:05 -070039 ControlParameters p1;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000040 p1.setUri("tcp4://192.0.2.1:6363");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050041 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
42 Name n1 = Command::createRequest("/PREFIX", p1).getName();
43 BOOST_CHECK(Name("/PREFIX/faces/create").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -070044
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000045 // good with optional fields
46 ControlParameters p2(p1);
47 p2.setLocalUri("tcp4://192.0.2.2:32114")
48 .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
Eric Newberry07d05c92018-01-22 16:08:01 -070049 .setBaseCongestionMarkingInterval(100_ms)
50 .setDefaultCongestionThreshold(10000)
Eric Newberry3c9bc042018-06-02 17:58:10 -070051 .setMtu(8192)
Eric Newberryda916d62016-08-11 23:04:34 -070052 .setFlags(0x3)
53 .setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050054 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
Yukai Tud93c5fc2015-08-25 11:37:16 +080055
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000056 // Uri is required
57 ControlParameters p3;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050058 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000059
60 // Name is forbidden
61 ControlParameters p4(p1);
62 p4.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050063 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000064
65 // Flags and Mask must be specified together
66 ControlParameters p5(p1);
67 p5.setFlags(0x3);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050068 BOOST_CHECK_THROW(Command::validateRequest(p5), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000069
Eric Newberryce9c1952020-02-15 15:10:59 -080070 // Flags and Mask must be specified together
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000071 ControlParameters p6(p1);
72 p6.setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050073 BOOST_CHECK_THROW(Command::validateRequest(p6), ArgumentError);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000074}
75
76BOOST_AUTO_TEST_CASE(FaceCreateResponse)
77{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050078 using Command = FaceCreateCommand;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000079
80 // good
81 ControlParameters p1;
82 p1.setFaceId(3208)
Junxiao Shi144c7e32017-04-20 01:04:06 +000083 .setUri("tcp4://192.0.2.1:6363")
84 .setLocalUri("tcp4://192.0.2.2:32114")
85 .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
Eric Newberry07d05c92018-01-22 16:08:01 -070086 .setBaseCongestionMarkingInterval(500_ns)
87 .setDefaultCongestionThreshold(12345)
Eric Newberry3c9bc042018-06-02 17:58:10 -070088 .setMtu(2048)
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000089 .setFlags(0x3);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050090 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
Eric Newberryda916d62016-08-11 23:04:34 -070091
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000092 // Name is forbidden
93 ControlParameters p2(p1);
94 p2.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -050095 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Yukai Tud93c5fc2015-08-25 11:37:16 +080096
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000097 // Mask is forbidden
98 ControlParameters p3(p1);
99 p3.setMask(0x1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500100 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Eric Newberryda916d62016-08-11 23:04:34 -0700101
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000102 // FaceId must be valid
103 ControlParameters p4(p1);
104 p4.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500105 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Eric Newberryda916d62016-08-11 23:04:34 -0700106
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000107 // LocalUri is required
108 ControlParameters p5(p1);
109 p5.unsetLocalUri();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500110 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700111}
112
Yanbiao Licbdacb22016-08-02 16:02:35 +0800113BOOST_AUTO_TEST_CASE(FaceUpdate)
114{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500115 using Command = FaceUpdateCommand;
Yanbiao Licbdacb22016-08-02 16:02:35 +0800116
Eric Newberryce9c1952020-02-15 15:10:59 -0800117 // FaceId must be valid
Yanbiao Licbdacb22016-08-02 16:02:35 +0800118 ControlParameters p1;
119 p1.setFaceId(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500120 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500121 p1.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500122 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800123
Eric Newberryce9c1952020-02-15 15:10:59 -0800124 // Persistency and Flags are required in response
Yanbiao Licbdacb22016-08-02 16:02:35 +0800125 p1.setFaceId(1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500126 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
127 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
128 Command::applyDefaultsToRequest(p1);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700129 BOOST_CHECK_EQUAL(p1.getFaceId(), 1);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800130
Eric Newberryce9c1952020-02-15 15:10:59 -0800131 // Good request, bad response (Mask is forbidden but present)
Yanbiao Licbdacb22016-08-02 16:02:35 +0800132 ControlParameters p2;
133 p2.setFaceId(1)
Eric Newberry138ef2c2016-08-15 20:29:03 -0700134 .setFacePersistency(FACE_PERSISTENCY_PERSISTENT)
Eric Newberry07d05c92018-01-22 16:08:01 -0700135 .setBaseCongestionMarkingInterval(765_ns)
136 .setDefaultCongestionThreshold(54321)
Eric Newberryce9c1952020-02-15 15:10:59 -0800137 .setMtu(8192)
Eric Newberry138ef2c2016-08-15 20:29:03 -0700138 .setFlagBit(BIT_LOCAL_FIELDS_ENABLED, false);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500139 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
140 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800141
Eric Newberryce9c1952020-02-15 15:10:59 -0800142 // Flags without Mask (good response, bad request)
Eric Newberryda916d62016-08-11 23:04:34 -0700143 p2.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500144 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
145 BOOST_CHECK_NO_THROW(Command::validateResponse(p2));
Eric Newberry138ef2c2016-08-15 20:29:03 -0700146
Eric Newberryce9c1952020-02-15 15:10:59 -0800147 // FaceId is optional in request
Eric Newberry138ef2c2016-08-15 20:29:03 -0700148 p2.setFlagBit(BIT_LOCAL_FIELDS_ENABLED, false);
149 p2.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500150 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Eric Newberryda916d62016-08-11 23:04:34 -0700151
Eric Newberryce9c1952020-02-15 15:10:59 -0800152 // Name is forbidden
Yanbiao Licbdacb22016-08-02 16:02:35 +0800153 ControlParameters p3;
Eric Newberryda916d62016-08-11 23:04:34 -0700154 p3.setFaceId(1)
155 .setName("/ndn/name");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500156 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
157 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800158
Eric Newberryce9c1952020-02-15 15:10:59 -0800159 // Uri is forbidden
Yanbiao Licbdacb22016-08-02 16:02:35 +0800160 ControlParameters p4;
161 p4.setFaceId(1)
Eric Newberryda916d62016-08-11 23:04:34 -0700162 .setUri("tcp4://192.0.2.1");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500163 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
164 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800165
Eric Newberryce9c1952020-02-15 15:10:59 -0800166 // Empty request is valid, empty response is invalid
Yanbiao Licbdacb22016-08-02 16:02:35 +0800167 ControlParameters p5;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500168 BOOST_CHECK_NO_THROW(Command::validateRequest(p5));
169 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700170 BOOST_CHECK(!p5.hasFaceId());
Eric Newberryce9c1952020-02-15 15:10:59 -0800171
172 // Default request, not valid response due to missing FacePersistency and Flags
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500173 Command::applyDefaultsToRequest(p5);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700174 BOOST_REQUIRE(p5.hasFaceId());
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500175 BOOST_CHECK_NO_THROW(Command::validateRequest(p5));
176 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Eric Newberry138ef2c2016-08-15 20:29:03 -0700177 BOOST_CHECK_EQUAL(p5.getFaceId(), 0);
Yanbiao Licbdacb22016-08-02 16:02:35 +0800178}
179
Junxiao Shi5ec80222014-03-25 20:08:05 -0700180BOOST_AUTO_TEST_CASE(FaceDestroy)
181{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500182 using Command = FaceDestroyCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700183
Eric Newberryce9c1952020-02-15 15:10:59 -0800184 // Uri is forbidden
Junxiao Shi5ec80222014-03-25 20:08:05 -0700185 ControlParameters p1;
186 p1.setUri("tcp4://192.0.2.1")
187 .setFaceId(4);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500188 BOOST_CHECK_THROW(Command::validateRequest(p1), ArgumentError);
189 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700190
Eric Newberryce9c1952020-02-15 15:10:59 -0800191 // FaceId must be valid
Junxiao Shi5ec80222014-03-25 20:08:05 -0700192 ControlParameters p2;
Davide Pesaventof8503d22017-02-17 01:19:10 -0500193 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500194 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
195 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700196
Eric Newberryce9c1952020-02-15 15:10:59 -0800197 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700198 ControlParameters p3;
199 p3.setFaceId(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500200 BOOST_CHECK_NO_THROW(Command::validateRequest(p3));
201 BOOST_CHECK_NO_THROW(Command::validateResponse(p3));
202 Name n3 = Command::createRequest("/PREFIX", p3).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700203 BOOST_CHECK(Name("ndn:/PREFIX/faces/destroy").isPrefixOf(n3));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700204}
205
Junxiao Shi5ec80222014-03-25 20:08:05 -0700206BOOST_AUTO_TEST_CASE(FibAddNextHop)
207{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500208 using Command = FibAddNextHopCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700209
Eric Newberryce9c1952020-02-15 15:10:59 -0800210 // Cost required in response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700211 ControlParameters p1;
212 p1.setName("ndn:/")
213 .setFaceId(22);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500214 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
215 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
216 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700217 BOOST_CHECK(Name("ndn:/PREFIX/fib/add-nexthop").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700218
Eric Newberryce9c1952020-02-15 15:10:59 -0800219 // Good request, bad response (FaceId must be valid)
Junxiao Shi5ec80222014-03-25 20:08:05 -0700220 ControlParameters p2;
221 p2.setName("ndn:/example")
222 .setFaceId(0)
223 .setCost(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500224 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500225 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500226 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700227
Eric Newberryce9c1952020-02-15 15:10:59 -0800228 // Default request
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500229 Command::applyDefaultsToRequest(p1);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700230 BOOST_REQUIRE(p1.hasCost());
231 BOOST_CHECK_EQUAL(p1.getCost(), 0);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700232
Eric Newberryce9c1952020-02-15 15:10:59 -0800233 // FaceId optional in request
Junxiao Shicaac54e2014-05-20 15:27:01 -0700234 p1.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500235 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
236 Command::applyDefaultsToRequest(p1);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700237 BOOST_REQUIRE(p1.hasFaceId());
238 BOOST_CHECK_EQUAL(p1.getFaceId(), 0);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700239}
240
241BOOST_AUTO_TEST_CASE(FibRemoveNextHop)
242{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500243 using Command = FibRemoveNextHopCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700244
Eric Newberryce9c1952020-02-15 15:10:59 -0800245 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700246 ControlParameters p1;
247 p1.setName("ndn:/")
248 .setFaceId(22);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500249 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
250 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
251 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700252 BOOST_CHECK(Name("ndn:/PREFIX/fib/remove-nexthop").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700253
Eric Newberryce9c1952020-02-15 15:10:59 -0800254 // Good request, bad response (FaceId must be valid)
Junxiao Shi5ec80222014-03-25 20:08:05 -0700255 ControlParameters p2;
256 p2.setName("ndn:/example")
257 .setFaceId(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500258 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500259 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500260 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700261
Eric Newberryce9c1952020-02-15 15:10:59 -0800262 // FaceId is optional in request
Junxiao Shicaac54e2014-05-20 15:27:01 -0700263 p1.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500264 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
265 Command::applyDefaultsToRequest(p1);
Junxiao Shicaac54e2014-05-20 15:27:01 -0700266 BOOST_REQUIRE(p1.hasFaceId());
267 BOOST_CHECK_EQUAL(p1.getFaceId(), 0);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700268}
269
Junxiao Shi22f85682018-01-22 19:23:22 +0000270BOOST_AUTO_TEST_CASE(CsConfigRequest)
271{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500272 using Command = CsConfigCommand;
Junxiao Shi22f85682018-01-22 19:23:22 +0000273
274 // good empty request
275 ControlParameters p1;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500276 Command::validateRequest(p1);
277 Name n1 = Command::createRequest("/PREFIX", p1).getName();
278 BOOST_CHECK(Name("/PREFIX/cs/config").isPrefixOf(n1));
Junxiao Shi22f85682018-01-22 19:23:22 +0000279
280 // good full request
281 ControlParameters p2;
282 p2.setCapacity(1574);
283 p2.setFlagBit(BIT_CS_ENABLE_ADMIT, true);
284 p2.setFlagBit(BIT_CS_ENABLE_SERVE, true);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500285 Command::validateRequest(p2);
Junxiao Shi22f85682018-01-22 19:23:22 +0000286
287 // bad request: Flags but no Mask
288 ControlParameters p3(p2);
289 p3.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500290 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000291
292 // bad request: Mask but no Flags
293 ControlParameters p4(p2);
294 p4.unsetFlags();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500295 BOOST_CHECK_THROW(Command::validateRequest(p4), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000296
297 // bad request: forbidden field
298 ControlParameters p5(p2);
299 p5.setName("/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500300 BOOST_CHECK_THROW(Command::validateRequest(p5), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000301}
302
303BOOST_AUTO_TEST_CASE(CsConfigResponse)
304{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500305 using Command = CsConfigCommand;
Junxiao Shi22f85682018-01-22 19:23:22 +0000306
307 // bad empty response
308 ControlParameters p1;
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500309 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000310
311 // bad response: Mask not allowed
312 ControlParameters p2;
313 p2.setCapacity(1574);
314 p2.setFlagBit(BIT_CS_ENABLE_ADMIT, true);
315 p2.setFlagBit(BIT_CS_ENABLE_SERVE, true);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500316 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi22f85682018-01-22 19:23:22 +0000317
318 // good response
319 ControlParameters p3(p2);
320 p3.unsetMask();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500321 Command::validateResponse(p3);
Junxiao Shi22f85682018-01-22 19:23:22 +0000322}
323
Junxiao Shidf505382018-03-04 13:40:44 +0000324BOOST_AUTO_TEST_CASE(CsEraseRequest)
325{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500326 using Command = CsEraseCommand;
Junxiao Shidf505382018-03-04 13:40:44 +0000327
328 // good no-limit request
329 ControlParameters p1;
330 p1.setName("/u4LYPNU8Q");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500331 Command::validateRequest(p1);
332 Name n1 = Command::createRequest("/PREFIX", p1).getName();
333 BOOST_CHECK(Name("/PREFIX/cs/erase").isPrefixOf(n1));
Junxiao Shidf505382018-03-04 13:40:44 +0000334
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500335 // good limited request
Junxiao Shidf505382018-03-04 13:40:44 +0000336 ControlParameters p2;
337 p2.setName("/IMw1RaLF");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500338 p2.setCount(177);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500339 Command::validateRequest(p2);
Junxiao Shidf505382018-03-04 13:40:44 +0000340
341 // bad request: zero entry
342 ControlParameters p3;
343 p3.setName("/ahMID1jcib");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500344 p3.setCount(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500345 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000346
347 // bad request: forbidden field
348 ControlParameters p4(p2);
349 p4.setCapacity(278);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500350 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000351}
352
353BOOST_AUTO_TEST_CASE(CsEraseResponse)
354{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500355 using Command = CsEraseCommand;
Junxiao Shidf505382018-03-04 13:40:44 +0000356
357 // good normal response
358 ControlParameters p1;
359 p1.setName("/TwiIwCdR");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500360 p1.setCount(1);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500361 Command::validateResponse(p1);
Junxiao Shidf505382018-03-04 13:40:44 +0000362
363 // good limit exceeded request
364 ControlParameters p2;
365 p2.setName("/NMsiy44pr");
366 p2.setCapacity(360);
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500367 p2.setCount(360);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500368 Command::validateResponse(p2);
Junxiao Shidf505382018-03-04 13:40:44 +0000369
370 // good zero-entry response
371 ControlParameters p3;
372 p3.setName("/5f1LRPh1L");
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500373 p3.setCount(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500374 Command::validateResponse(p3);
Junxiao Shidf505382018-03-04 13:40:44 +0000375
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500376 // bad request: missing Count
Junxiao Shidf505382018-03-04 13:40:44 +0000377 ControlParameters p4(p1);
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500378 p4.unsetCount();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500379 BOOST_CHECK_THROW(Command::validateResponse(p4), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000380
381 // bad request: zero capacity
382 ControlParameters p5(p1);
383 p5.setCapacity(0);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500384 BOOST_CHECK_THROW(Command::validateResponse(p5), ArgumentError);
Junxiao Shidf505382018-03-04 13:40:44 +0000385}
386
Junxiao Shi5ec80222014-03-25 20:08:05 -0700387BOOST_AUTO_TEST_CASE(StrategyChoiceSet)
388{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500389 using Command = StrategyChoiceSetCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700390
Eric Newberryce9c1952020-02-15 15:10:59 -0800391 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700392 ControlParameters p1;
393 p1.setName("ndn:/")
394 .setStrategy("ndn:/strategy/P");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500395 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
396 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
397 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700398 BOOST_CHECK(Name("ndn:/PREFIX/strategy-choice/set").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700399
Eric Newberryce9c1952020-02-15 15:10:59 -0800400 // Strategy is required in both requests and responses
Junxiao Shi5ec80222014-03-25 20:08:05 -0700401 ControlParameters p2;
402 p2.setName("ndn:/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500403 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
404 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700405}
406
407BOOST_AUTO_TEST_CASE(StrategyChoiceUnset)
408{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500409 using Command = StrategyChoiceUnsetCommand;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700410
Eric Newberryce9c1952020-02-15 15:10:59 -0800411 // Good request, good response
Junxiao Shi5ec80222014-03-25 20:08:05 -0700412 ControlParameters p1;
413 p1.setName("ndn:/example");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500414 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
415 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
416 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700417 BOOST_CHECK(Name("ndn:/PREFIX/strategy-choice/unset").isPrefixOf(n1));
Junxiao Shi5ec80222014-03-25 20:08:05 -0700418
Eric Newberryce9c1952020-02-15 15:10:59 -0800419 // Strategy is forbidden
Junxiao Shi5ec80222014-03-25 20:08:05 -0700420 ControlParameters p2;
421 p2.setName("ndn:/example")
422 .setStrategy("ndn:/strategy/P");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500423 BOOST_CHECK_THROW(Command::validateRequest(p2), ArgumentError);
424 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700425
Eric Newberryce9c1952020-02-15 15:10:59 -0800426 // Name must have at least one component
Junxiao Shi5ec80222014-03-25 20:08:05 -0700427 ControlParameters p3;
428 p3.setName("ndn:/");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500429 BOOST_CHECK_THROW(Command::validateRequest(p3), ArgumentError);
430 BOOST_CHECK_THROW(Command::validateResponse(p3), ArgumentError);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700431}
432
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700433BOOST_AUTO_TEST_CASE(RibRegister)
434{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500435 using Command = RibRegisterCommand;
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700436
Eric Newberryce9c1952020-02-15 15:10:59 -0800437 // Good request, response missing many fields
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700438 ControlParameters p1;
439 p1.setName("ndn:/");
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500440 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
441 BOOST_CHECK_THROW(Command::validateResponse(p1), ArgumentError);
442 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700443 BOOST_CHECK(Name("ndn:/PREFIX/rib/register").isPrefixOf(n1));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700444
Eric Newberryce9c1952020-02-15 15:10:59 -0800445 // Default request
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500446 Command::applyDefaultsToRequest(p1);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700447 BOOST_REQUIRE(p1.hasOrigin());
Davide Pesaventoe8e48c22017-04-13 00:35:33 -0400448 BOOST_CHECK_EQUAL(p1.getOrigin(), ROUTE_ORIGIN_APP);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700449 BOOST_REQUIRE(p1.hasCost());
450 BOOST_CHECK_EQUAL(p1.getCost(), 0);
451 BOOST_REQUIRE(p1.hasFlags());
452 BOOST_CHECK_EQUAL(p1.getFlags(), static_cast<uint64_t>(ROUTE_FLAG_CHILD_INHERIT));
Alexander Afanasyev21f13b02014-07-17 16:17:34 -0700453 BOOST_CHECK_EQUAL(p1.hasExpirationPeriod(), false);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700454
Eric Newberryce9c1952020-02-15 15:10:59 -0800455 // Good request, good response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700456 ControlParameters p2;
457 p2.setName("ndn:/example")
458 .setFaceId(2)
459 .setCost(6);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500460 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
461 Command::applyDefaultsToRequest(p2);
Alexander Afanasyev21f13b02014-07-17 16:17:34 -0700462 BOOST_CHECK_EQUAL(p2.hasExpirationPeriod(), false);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500463 BOOST_CHECK_NO_THROW(Command::validateResponse(p2));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700464}
465
466BOOST_AUTO_TEST_CASE(RibUnregister)
467{
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500468 using Command = RibUnregisterCommand;
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700469
Eric Newberryce9c1952020-02-15 15:10:59 -0800470 // Good request, good response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700471 ControlParameters p1;
472 p1.setName("ndn:/")
473 .setFaceId(22)
474 .setOrigin(ROUTE_ORIGIN_STATIC);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500475 BOOST_CHECK_NO_THROW(Command::validateRequest(p1));
476 BOOST_CHECK_NO_THROW(Command::validateResponse(p1));
477 Name n1 = Command::createRequest("/PREFIX", p1).getName();
Junxiao Shi5de006b2014-10-26 20:20:52 -0700478 BOOST_CHECK(Name("ndn:/PREFIX/rib/unregister").isPrefixOf(n1));
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700479
Eric Newberryce9c1952020-02-15 15:10:59 -0800480 // Good request, bad response (FaceId must be valid)
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700481 ControlParameters p2;
482 p2.setName("ndn:/example")
483 .setFaceId(0)
484 .setOrigin(ROUTE_ORIGIN_APP);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500485 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
Davide Pesaventof8503d22017-02-17 01:19:10 -0500486 p2.setFaceId(INVALID_FACE_ID);
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500487 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700488
Eric Newberryce9c1952020-02-15 15:10:59 -0800489 // FaceId is optional in request, required in response
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700490 p2.unsetFaceId();
Davide Pesaventoaebf5d72024-12-26 16:04:12 -0500491 BOOST_CHECK_NO_THROW(Command::validateRequest(p2));
492 BOOST_CHECK_THROW(Command::validateResponse(p2), ArgumentError);
Junxiao Shi5f6c74f2014-04-18 16:29:44 -0700493}
494
Junxiao Shi7357ef22016-09-07 02:39:37 +0000495BOOST_AUTO_TEST_SUITE_END() // TestControlCommand
496BOOST_AUTO_TEST_SUITE_END() // Nfd
497BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi5ec80222014-03-25 20:08:05 -0700498
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400499} // namespace ndn::tests