blob: 6760d5e27e5e6b78890310fc7a68b6f24e967043 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi2bea5c42017-08-14 20:10:32 +00002/*
Davide Pesavento187e9f92023-03-20 22:46:22 -04003 * Copyright (c) 2013-2023 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 Shi7b6b79d2014-03-26 20:59:35 -070020 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/mgmt/nfd/controller.hpp"
23#include "ndn-cxx/mgmt/nfd/control-response.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070024
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050025#include "tests/test-common.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "tests/unit/mgmt/nfd/controller-fixture.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070027
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040028namespace ndn::tests {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070029
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040030using namespace ndn::nfd;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070031
Junxiao Shi7357ef22016-09-07 02:39:37 +000032BOOST_AUTO_TEST_SUITE(Mgmt)
33BOOST_AUTO_TEST_SUITE(Nfd)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070034
Junxiao Shi034c1882016-06-24 18:06:51 +000035class CommandFixture : public ControllerFixture
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070036{
37protected:
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000038 void
39 respond(const ControlResponse& responsePayload)
40 {
41 auto responseData = makeData(face.sentInterests.at(0).getName());
42 responseData->setContent(responsePayload.wireEncode());
43 face.receive(*responseData);
Davide Pesavento0f830802018-01-16 23:58:58 -050044 this->advanceClocks(1_ms);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000045 }
46
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070047protected:
Davide Pesavento09103432023-03-24 20:30:41 -040048 CommandSuccessCallback succeedCallback = [this] (const auto& params) {
Davide Pesavento2e481fc2021-07-02 18:20:03 -040049 succeeds.push_back(params);
50 };
Junxiao Shi034c1882016-06-24 18:06:51 +000051 std::vector<ControlParameters> succeeds;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070052};
53
Junxiao Shi600f7112016-07-16 11:57:18 +000054// This test suite focuses on ControlCommand functionality of Controller.
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050055// Individual commands are tested in control-command.t.cpp
56// StatusDataset functionality is tested in status-dataset.t.cpp
Junxiao Shi7357ef22016-09-07 02:39:37 +000057BOOST_FIXTURE_TEST_SUITE(TestController, CommandFixture)
Junxiao Shib1990df2015-11-05 00:14:44 +000058
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000059static ControlParameters
60makeFaceCreateResponse()
61{
62 ControlParameters resp;
63 resp.setFaceId(22)
64 .setUri("tcp4://192.0.2.1:6363")
65 .setLocalUri("tcp4://192.0.2.2:10847")
66 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT)
Eric Newberryd567aab2018-01-27 16:38:24 -070067 .setFlags(0x7);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000068 return resp;
69}
70
Junxiao Shi600f7112016-07-16 11:57:18 +000071BOOST_AUTO_TEST_CASE(Success)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070072{
73 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070074 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070075
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000076 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -050077 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070078
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080079 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
80 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070081
Junxiao Shi5de006b2014-10-26 20:20:52 -070082 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
Davide Pesavento8fbffe42022-06-15 18:36:03 -040083 BOOST_CHECK(requestInterest.isSigned());
84 BOOST_CHECK(requestInterest.isParametersDigestValid());
Junxiao Shi415b17c2014-11-12 00:43:25 -070085 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070086
Davide Pesavento8fbffe42022-06-15 18:36:03 -040087 // 6 components: /localhost/nfd/faces/create/<parameters>/params-sha256=...
88 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 6);
89 ControlParameters requestParams(requestInterest.getName()[4].blockFromValue());
90 FaceCreateCommand command;
91 BOOST_CHECK_NO_THROW(command.validateRequest(requestParams));
92 BOOST_CHECK_EQUAL(requestParams.getUri(), parameters.getUri());
93
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000094 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070095 ControlResponse responsePayload(201, "created");
96 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000097 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070098
Junxiao Shi034c1882016-06-24 18:06:51 +000099 BOOST_CHECK_EQUAL(failCodes.size(), 0);
100 BOOST_REQUIRE_EQUAL(succeeds.size(), 1);
101 BOOST_CHECK_EQUAL(succeeds.back().getUri(), responseBody.getUri());
102 BOOST_CHECK_EQUAL(succeeds.back().getFaceId(), responseBody.getFaceId());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700103}
104
Junxiao Shi600f7112016-07-16 11:57:18 +0000105BOOST_AUTO_TEST_CASE(SuccessNoCallback)
106{
107 ControlParameters parameters;
108 parameters.setUri("tcp4://192.0.2.1:6363");
109
Junxiao Shie7c7f152016-08-20 22:36:22 +0000110 controller.start<FaceCreateCommand>(parameters, nullptr, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500111 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000112
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000113 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi600f7112016-07-16 11:57:18 +0000114 ControlResponse responsePayload(201, "created");
115 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000116 this->respond(responsePayload);
Junxiao Shi600f7112016-07-16 11:57:18 +0000117
118 BOOST_CHECK_EQUAL(failCodes.size(), 0);
119}
120
121BOOST_AUTO_TEST_CASE(OptionsPrefix)
122{
123 ControlParameters parameters;
124 parameters.setName("/ndn/com/example");
125 parameters.setFaceId(400);
126
127 CommandOptions options;
128 options.setPrefix("/localhop/net/example/router1/nfd");
129
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000130 controller.start<RibRegisterCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500131 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000132
133 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
134 const Interest& requestInterest = face.sentInterests[0];
135
136 FaceCreateCommand command;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000137 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(requestInterest.getName()));
Davide Pesavento8fbffe42022-06-15 18:36:03 -0400138 BOOST_CHECK(requestInterest.isSigned());
139 BOOST_CHECK(requestInterest.isParametersDigestValid());
Junxiao Shi600f7112016-07-16 11:57:18 +0000140}
141
142BOOST_AUTO_TEST_CASE(InvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700143{
144 ControlParameters parameters;
145 parameters.setName("ndn:/should-not-have-this-field");
146 // Uri is missing
147
Davide Pesavento8fbffe42022-06-15 18:36:03 -0400148 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback),
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700149 ControlCommand::ArgumentError);
150}
151
Junxiao Shi54f727d2016-08-08 20:29:11 +0000152BOOST_AUTO_TEST_CASE(ValidationFailure)
153{
154 this->setValidationResult(false);
155
156 ControlParameters parameters;
157 parameters.setUri("tcp4://192.0.2.1:6363");
158
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000159 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500160 this->advanceClocks(1_ms);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000161
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000162 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi54f727d2016-08-08 20:29:11 +0000163 ControlResponse responsePayload(201, "created");
164 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000165 this->respond(responsePayload);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000166
167 BOOST_CHECK_EQUAL(succeeds.size(), 0);
168 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
169 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_VALIDATION);
170}
171
Junxiao Shi600f7112016-07-16 11:57:18 +0000172BOOST_AUTO_TEST_CASE(ErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700173{
174 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700175 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700176
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000177 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500178 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700179
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700180 ControlResponse responsePayload(401, "Not Authenticated");
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000181 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700182
Junxiao Shi034c1882016-06-24 18:06:51 +0000183 BOOST_CHECK_EQUAL(succeeds.size(), 0);
184 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
185 BOOST_CHECK_EQUAL(failCodes.back(), 401);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700186}
187
Junxiao Shi600f7112016-07-16 11:57:18 +0000188BOOST_AUTO_TEST_CASE(InvalidResponse)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700189{
190 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700191 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700192
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000193 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500194 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700195
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000196 ControlParameters responseBody = makeFaceCreateResponse();
197 responseBody.unsetFaceId() // FaceId is missing
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700198 .setName("ndn:/should-not-have-this-field");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700199 ControlResponse responsePayload(201, "created");
200 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000201 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700202
Junxiao Shi034c1882016-06-24 18:06:51 +0000203 BOOST_CHECK_EQUAL(succeeds.size(), 0);
204 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700205}
206
Junxiao Shi600f7112016-07-16 11:57:18 +0000207BOOST_AUTO_TEST_CASE(Nack)
Junxiao Shib1990df2015-11-05 00:14:44 +0000208{
209 ControlParameters parameters;
210 parameters.setUri("tcp4://192.0.2.1:6363");
211
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000212 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500213 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000214
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800215 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
216 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shib1990df2015-11-05 00:14:44 +0000217
Junxiao Shi034c1882016-06-24 18:06:51 +0000218 auto responseNack = makeNack(requestInterest, lp::NackReason::NO_ROUTE);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800219 face.receive(responseNack);
Davide Pesavento0f830802018-01-16 23:58:58 -0500220 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000221
Junxiao Shi034c1882016-06-24 18:06:51 +0000222 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
223 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
Junxiao Shib1990df2015-11-05 00:14:44 +0000224}
225
Junxiao Shi600f7112016-07-16 11:57:18 +0000226BOOST_AUTO_TEST_CASE(Timeout)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700227{
228 ControlParameters parameters;
229 parameters.setUri("tcp4://192.0.2.1:6363");
230
231 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500232 options.setTimeout(50_ms);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700233
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000234 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500235 this->advanceClocks(1_ms); // express Interest
236 this->advanceClocks(51_ms); // timeout
Junxiao Shi5de006b2014-10-26 20:20:52 -0700237
Junxiao Shi034c1882016-06-24 18:06:51 +0000238 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
239 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700240}
241
Junxiao Shi600f7112016-07-16 11:57:18 +0000242BOOST_AUTO_TEST_CASE(FailureNoCallback)
243{
244 ControlParameters parameters;
245 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700246
Junxiao Shi600f7112016-07-16 11:57:18 +0000247 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500248 options.setTimeout(50_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000249
250 controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500251 this->advanceClocks(1_ms); // express Interest
252 this->advanceClocks(51_ms); // timeout
Junxiao Shi600f7112016-07-16 11:57:18 +0000253
254 BOOST_CHECK_EQUAL(succeeds.size(), 0);
255}
256
Junxiao Shi7357ef22016-09-07 02:39:37 +0000257BOOST_AUTO_TEST_SUITE_END() // TestController
258BOOST_AUTO_TEST_SUITE_END() // Nfd
259BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi034c1882016-06-24 18:06:51 +0000260
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400261} // namespace ndn::tests