blob: f7f4a9a349bb7083a3e24ab4404c392186323f40 [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
28namespace ndn {
29namespace nfd {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070030namespace tests {
31
Junxiao Shi85d90832016-08-04 03:19:46 +000032using namespace ndn::tests;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070033
Junxiao Shi7357ef22016-09-07 02:39:37 +000034BOOST_AUTO_TEST_SUITE(Mgmt)
35BOOST_AUTO_TEST_SUITE(Nfd)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070036
Junxiao Shi034c1882016-06-24 18:06:51 +000037class CommandFixture : public ControllerFixture
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070038{
39protected:
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000040 void
41 respond(const ControlResponse& responsePayload)
42 {
43 auto responseData = makeData(face.sentInterests.at(0).getName());
44 responseData->setContent(responsePayload.wireEncode());
45 face.receive(*responseData);
Davide Pesavento0f830802018-01-16 23:58:58 -050046 this->advanceClocks(1_ms);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000047 }
48
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070049protected:
Davide Pesavento187e9f92023-03-20 22:46:22 -040050 Controller::CommandSuccessCallback succeedCallback = [this] (const auto& params) {
Davide Pesavento2e481fc2021-07-02 18:20:03 -040051 succeeds.push_back(params);
52 };
Junxiao Shi034c1882016-06-24 18:06:51 +000053 std::vector<ControlParameters> succeeds;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070054};
55
Junxiao Shi600f7112016-07-16 11:57:18 +000056// This test suite focuses on ControlCommand functionality of Controller.
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050057// Individual commands are tested in control-command.t.cpp
58// StatusDataset functionality is tested in status-dataset.t.cpp
Junxiao Shi7357ef22016-09-07 02:39:37 +000059BOOST_FIXTURE_TEST_SUITE(TestController, CommandFixture)
Junxiao Shib1990df2015-11-05 00:14:44 +000060
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000061static ControlParameters
62makeFaceCreateResponse()
63{
64 ControlParameters resp;
65 resp.setFaceId(22)
66 .setUri("tcp4://192.0.2.1:6363")
67 .setLocalUri("tcp4://192.0.2.2:10847")
68 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT)
Eric Newberryd567aab2018-01-27 16:38:24 -070069 .setFlags(0x7);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000070 return resp;
71}
72
Junxiao Shi600f7112016-07-16 11:57:18 +000073BOOST_AUTO_TEST_CASE(Success)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070074{
75 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070076 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070077
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000078 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -050079 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070080
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080081 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
82 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070083
Junxiao Shi5de006b2014-10-26 20:20:52 -070084 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
Davide Pesavento8fbffe42022-06-15 18:36:03 -040085 BOOST_CHECK(requestInterest.isSigned());
86 BOOST_CHECK(requestInterest.isParametersDigestValid());
Junxiao Shi415b17c2014-11-12 00:43:25 -070087 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070088
Davide Pesavento8fbffe42022-06-15 18:36:03 -040089 // 6 components: /localhost/nfd/faces/create/<parameters>/params-sha256=...
90 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 6);
91 ControlParameters requestParams(requestInterest.getName()[4].blockFromValue());
92 FaceCreateCommand command;
93 BOOST_CHECK_NO_THROW(command.validateRequest(requestParams));
94 BOOST_CHECK_EQUAL(requestParams.getUri(), parameters.getUri());
95
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000096 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070097 ControlResponse responsePayload(201, "created");
98 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000099 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700100
Junxiao Shi034c1882016-06-24 18:06:51 +0000101 BOOST_CHECK_EQUAL(failCodes.size(), 0);
102 BOOST_REQUIRE_EQUAL(succeeds.size(), 1);
103 BOOST_CHECK_EQUAL(succeeds.back().getUri(), responseBody.getUri());
104 BOOST_CHECK_EQUAL(succeeds.back().getFaceId(), responseBody.getFaceId());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700105}
106
Junxiao Shi600f7112016-07-16 11:57:18 +0000107BOOST_AUTO_TEST_CASE(SuccessNoCallback)
108{
109 ControlParameters parameters;
110 parameters.setUri("tcp4://192.0.2.1:6363");
111
Junxiao Shie7c7f152016-08-20 22:36:22 +0000112 controller.start<FaceCreateCommand>(parameters, nullptr, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500113 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000114
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000115 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi600f7112016-07-16 11:57:18 +0000116 ControlResponse responsePayload(201, "created");
117 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000118 this->respond(responsePayload);
Junxiao Shi600f7112016-07-16 11:57:18 +0000119
120 BOOST_CHECK_EQUAL(failCodes.size(), 0);
121}
122
123BOOST_AUTO_TEST_CASE(OptionsPrefix)
124{
125 ControlParameters parameters;
126 parameters.setName("/ndn/com/example");
127 parameters.setFaceId(400);
128
129 CommandOptions options;
130 options.setPrefix("/localhop/net/example/router1/nfd");
131
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000132 controller.start<RibRegisterCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500133 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000134
135 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
136 const Interest& requestInterest = face.sentInterests[0];
137
138 FaceCreateCommand command;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000139 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(requestInterest.getName()));
Davide Pesavento8fbffe42022-06-15 18:36:03 -0400140 BOOST_CHECK(requestInterest.isSigned());
141 BOOST_CHECK(requestInterest.isParametersDigestValid());
Junxiao Shi600f7112016-07-16 11:57:18 +0000142}
143
144BOOST_AUTO_TEST_CASE(InvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700145{
146 ControlParameters parameters;
147 parameters.setName("ndn:/should-not-have-this-field");
148 // Uri is missing
149
Davide Pesavento8fbffe42022-06-15 18:36:03 -0400150 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback),
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700151 ControlCommand::ArgumentError);
152}
153
Junxiao Shi54f727d2016-08-08 20:29:11 +0000154BOOST_AUTO_TEST_CASE(ValidationFailure)
155{
156 this->setValidationResult(false);
157
158 ControlParameters parameters;
159 parameters.setUri("tcp4://192.0.2.1:6363");
160
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000161 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500162 this->advanceClocks(1_ms);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000163
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000164 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi54f727d2016-08-08 20:29:11 +0000165 ControlResponse responsePayload(201, "created");
166 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000167 this->respond(responsePayload);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000168
169 BOOST_CHECK_EQUAL(succeeds.size(), 0);
170 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
171 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_VALIDATION);
172}
173
Junxiao Shi600f7112016-07-16 11:57:18 +0000174BOOST_AUTO_TEST_CASE(ErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700175{
176 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700177 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700178
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000179 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500180 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700181
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700182 ControlResponse responsePayload(401, "Not Authenticated");
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000183 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700184
Junxiao Shi034c1882016-06-24 18:06:51 +0000185 BOOST_CHECK_EQUAL(succeeds.size(), 0);
186 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
187 BOOST_CHECK_EQUAL(failCodes.back(), 401);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700188}
189
Junxiao Shi600f7112016-07-16 11:57:18 +0000190BOOST_AUTO_TEST_CASE(InvalidResponse)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700191{
192 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700193 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700194
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000195 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500196 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700197
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000198 ControlParameters responseBody = makeFaceCreateResponse();
199 responseBody.unsetFaceId() // FaceId is missing
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700200 .setName("ndn:/should-not-have-this-field");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700201 ControlResponse responsePayload(201, "created");
202 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000203 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700204
Junxiao Shi034c1882016-06-24 18:06:51 +0000205 BOOST_CHECK_EQUAL(succeeds.size(), 0);
206 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700207}
208
Junxiao Shi600f7112016-07-16 11:57:18 +0000209BOOST_AUTO_TEST_CASE(Nack)
Junxiao Shib1990df2015-11-05 00:14:44 +0000210{
211 ControlParameters parameters;
212 parameters.setUri("tcp4://192.0.2.1:6363");
213
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000214 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500215 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000216
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800217 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
218 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shib1990df2015-11-05 00:14:44 +0000219
Junxiao Shi034c1882016-06-24 18:06:51 +0000220 auto responseNack = makeNack(requestInterest, lp::NackReason::NO_ROUTE);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800221 face.receive(responseNack);
Davide Pesavento0f830802018-01-16 23:58:58 -0500222 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000223
Junxiao Shi034c1882016-06-24 18:06:51 +0000224 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
225 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
Junxiao Shib1990df2015-11-05 00:14:44 +0000226}
227
Junxiao Shi600f7112016-07-16 11:57:18 +0000228BOOST_AUTO_TEST_CASE(Timeout)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700229{
230 ControlParameters parameters;
231 parameters.setUri("tcp4://192.0.2.1:6363");
232
233 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500234 options.setTimeout(50_ms);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700235
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000236 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500237 this->advanceClocks(1_ms); // express Interest
238 this->advanceClocks(51_ms); // timeout
Junxiao Shi5de006b2014-10-26 20:20:52 -0700239
Junxiao Shi034c1882016-06-24 18:06:51 +0000240 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
241 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700242}
243
Junxiao Shi600f7112016-07-16 11:57:18 +0000244BOOST_AUTO_TEST_CASE(FailureNoCallback)
245{
246 ControlParameters parameters;
247 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700248
Junxiao Shi600f7112016-07-16 11:57:18 +0000249 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500250 options.setTimeout(50_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000251
252 controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500253 this->advanceClocks(1_ms); // express Interest
254 this->advanceClocks(51_ms); // timeout
Junxiao Shi600f7112016-07-16 11:57:18 +0000255
256 BOOST_CHECK_EQUAL(succeeds.size(), 0);
257}
258
Junxiao Shi7357ef22016-09-07 02:39:37 +0000259BOOST_AUTO_TEST_SUITE_END() // TestController
260BOOST_AUTO_TEST_SUITE_END() // Nfd
261BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi034c1882016-06-24 18:06:51 +0000262
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700263} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700264} // namespace nfd
265} // namespace ndn