blob: e9a3c4fa2b42f2517f9a1cb6853ac2e42a955dee [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 Pesavento0f830802018-01-16 23:58:58 -05003 * Copyright (c) 2013-2018 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
Junxiao Shi7357ef22016-09-07 02:39:37 +000022#include "mgmt/nfd/controller.hpp"
23#include "mgmt/nfd/control-response.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070024
Junxiao Shi7357ef22016-09-07 02:39:37 +000025#include "controller-fixture.hpp"
Junxiao Shi2bea5c42017-08-14 20:10:32 +000026#include "make-interest-data.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:
40 CommandFixture()
Junxiao Shi034c1882016-06-24 18:06:51 +000041 : succeedCallback(bind(&CommandFixture::succeed, this, _1))
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070042 {
43 }
44
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000045 void
46 respond(const ControlResponse& responsePayload)
47 {
48 auto responseData = makeData(face.sentInterests.at(0).getName());
49 responseData->setContent(responsePayload.wireEncode());
50 face.receive(*responseData);
Davide Pesavento0f830802018-01-16 23:58:58 -050051 this->advanceClocks(1_ms);
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000052 }
53
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070054private:
55 void
Junxiao Shi034c1882016-06-24 18:06:51 +000056 succeed(const ControlParameters& parameters)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070057 {
Junxiao Shi034c1882016-06-24 18:06:51 +000058 succeeds.push_back(parameters);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070059 }
60
61protected:
Junxiao Shi034c1882016-06-24 18:06:51 +000062 Controller::CommandSucceedCallback succeedCallback;
63 std::vector<ControlParameters> succeeds;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070064};
65
Junxiao Shi600f7112016-07-16 11:57:18 +000066// This test suite focuses on ControlCommand functionality of Controller.
67// Individual commands are tested in nfd-control-command.t.cpp
68// StatusDataset functionality is tested in nfd-status-dataset.t.cpp
Junxiao Shi7357ef22016-09-07 02:39:37 +000069BOOST_FIXTURE_TEST_SUITE(TestController, CommandFixture)
Junxiao Shib1990df2015-11-05 00:14:44 +000070
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000071static ControlParameters
72makeFaceCreateResponse()
73{
74 ControlParameters resp;
75 resp.setFaceId(22)
76 .setUri("tcp4://192.0.2.1:6363")
77 .setLocalUri("tcp4://192.0.2.2:10847")
78 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT)
79 .setFlags(0x7);
80 return resp;
81}
82
Junxiao Shi600f7112016-07-16 11:57:18 +000083BOOST_AUTO_TEST_CASE(Success)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070084{
85 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070086 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070087
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +000088 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -050089 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070090
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080091 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
92 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070093
94 FaceCreateCommand command;
Junxiao Shi5de006b2014-10-26 20:20:52 -070095 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
96 // 9 components: ndn:/localhost/nfd/faces/create/<parameters>/<signed Interest x4>
Junxiao Shi6a90f372014-10-13 20:29:30 -070097 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 9);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070098 ControlParameters request;
99 // 4th component: <parameters>
Junxiao Shi6a90f372014-10-13 20:29:30 -0700100 BOOST_REQUIRE_NO_THROW(request.wireDecode(requestInterest.getName().at(4).blockFromValue()));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700101 BOOST_CHECK_NO_THROW(command.validateRequest(request));
102 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi415b17c2014-11-12 00:43:25 -0700103 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700104
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000105 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700106 ControlResponse responsePayload(201, "created");
107 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000108 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700109
Junxiao Shi034c1882016-06-24 18:06:51 +0000110 BOOST_CHECK_EQUAL(failCodes.size(), 0);
111 BOOST_REQUIRE_EQUAL(succeeds.size(), 1);
112 BOOST_CHECK_EQUAL(succeeds.back().getUri(), responseBody.getUri());
113 BOOST_CHECK_EQUAL(succeeds.back().getFaceId(), responseBody.getFaceId());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700114}
115
Junxiao Shi600f7112016-07-16 11:57:18 +0000116BOOST_AUTO_TEST_CASE(SuccessNoCallback)
117{
118 ControlParameters parameters;
119 parameters.setUri("tcp4://192.0.2.1:6363");
120
Junxiao Shie7c7f152016-08-20 22:36:22 +0000121 controller.start<FaceCreateCommand>(parameters, nullptr, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500122 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000123
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000124 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi600f7112016-07-16 11:57:18 +0000125 ControlResponse responsePayload(201, "created");
126 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000127 this->respond(responsePayload);
Junxiao Shi600f7112016-07-16 11:57:18 +0000128
129 BOOST_CHECK_EQUAL(failCodes.size(), 0);
130}
131
132BOOST_AUTO_TEST_CASE(OptionsPrefix)
133{
134 ControlParameters parameters;
135 parameters.setName("/ndn/com/example");
136 parameters.setFaceId(400);
137
138 CommandOptions options;
139 options.setPrefix("/localhop/net/example/router1/nfd");
140
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000141 controller.start<RibRegisterCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500142 this->advanceClocks(1_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000143
144 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
145 const Interest& requestInterest = face.sentInterests[0];
146
147 FaceCreateCommand command;
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000148 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(requestInterest.getName()));
Junxiao Shi600f7112016-07-16 11:57:18 +0000149}
150
151BOOST_AUTO_TEST_CASE(InvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700152{
153 ControlParameters parameters;
154 parameters.setName("ndn:/should-not-have-this-field");
155 // Uri is missing
156
157 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
Junxiao Shie7c7f152016-08-20 22:36:22 +0000158 parameters, succeedCallback, commandFailCallback),
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700159 ControlCommand::ArgumentError);
160}
161
Junxiao Shi54f727d2016-08-08 20:29:11 +0000162BOOST_AUTO_TEST_CASE(ValidationFailure)
163{
164 this->setValidationResult(false);
165
166 ControlParameters parameters;
167 parameters.setUri("tcp4://192.0.2.1:6363");
168
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000169 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500170 this->advanceClocks(1_ms);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000171
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000172 ControlParameters responseBody = makeFaceCreateResponse();
Junxiao Shi54f727d2016-08-08 20:29:11 +0000173 ControlResponse responsePayload(201, "created");
174 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000175 this->respond(responsePayload);
Junxiao Shi54f727d2016-08-08 20:29:11 +0000176
177 BOOST_CHECK_EQUAL(succeeds.size(), 0);
178 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
179 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_VALIDATION);
180}
181
Junxiao Shi600f7112016-07-16 11:57:18 +0000182BOOST_AUTO_TEST_CASE(ErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700183{
184 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700185 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700186
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000187 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500188 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700189
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700190 ControlResponse responsePayload(401, "Not Authenticated");
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000191 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700192
Junxiao Shi034c1882016-06-24 18:06:51 +0000193 BOOST_CHECK_EQUAL(succeeds.size(), 0);
194 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
195 BOOST_CHECK_EQUAL(failCodes.back(), 401);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700196}
197
Junxiao Shi600f7112016-07-16 11:57:18 +0000198BOOST_AUTO_TEST_CASE(InvalidResponse)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700199{
200 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700201 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700202
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000203 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500204 this->advanceClocks(1_ms);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700205
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000206 ControlParameters responseBody = makeFaceCreateResponse();
207 responseBody.unsetFaceId() // FaceId is missing
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700208 .setName("ndn:/should-not-have-this-field");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700209 ControlResponse responsePayload(201, "created");
210 responsePayload.setBody(responseBody.wireEncode());
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000211 this->respond(responsePayload);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700212
Junxiao Shi034c1882016-06-24 18:06:51 +0000213 BOOST_CHECK_EQUAL(succeeds.size(), 0);
214 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700215}
216
Junxiao Shi600f7112016-07-16 11:57:18 +0000217BOOST_AUTO_TEST_CASE(Nack)
Junxiao Shib1990df2015-11-05 00:14:44 +0000218{
219 ControlParameters parameters;
220 parameters.setUri("tcp4://192.0.2.1:6363");
221
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000222 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
Davide Pesavento0f830802018-01-16 23:58:58 -0500223 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000224
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800225 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
226 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shib1990df2015-11-05 00:14:44 +0000227
Junxiao Shi034c1882016-06-24 18:06:51 +0000228 auto responseNack = makeNack(requestInterest, lp::NackReason::NO_ROUTE);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800229 face.receive(responseNack);
Davide Pesavento0f830802018-01-16 23:58:58 -0500230 this->advanceClocks(1_ms);
Junxiao Shib1990df2015-11-05 00:14:44 +0000231
Junxiao Shi034c1882016-06-24 18:06:51 +0000232 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
233 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
Junxiao Shib1990df2015-11-05 00:14:44 +0000234}
235
Junxiao Shi600f7112016-07-16 11:57:18 +0000236BOOST_AUTO_TEST_CASE(Timeout)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700237{
238 ControlParameters parameters;
239 parameters.setUri("tcp4://192.0.2.1:6363");
240
241 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500242 options.setTimeout(50_ms);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700243
Junxiao Shi8c2ab2e2017-05-05 20:26:34 +0000244 controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500245 this->advanceClocks(1_ms); // express Interest
246 this->advanceClocks(51_ms); // timeout
Junxiao Shi5de006b2014-10-26 20:20:52 -0700247
Junxiao Shi034c1882016-06-24 18:06:51 +0000248 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
249 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700250}
251
Junxiao Shi600f7112016-07-16 11:57:18 +0000252BOOST_AUTO_TEST_CASE(FailureNoCallback)
253{
254 ControlParameters parameters;
255 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700256
Junxiao Shi600f7112016-07-16 11:57:18 +0000257 CommandOptions options;
Davide Pesavento0f830802018-01-16 23:58:58 -0500258 options.setTimeout(50_ms);
Junxiao Shi600f7112016-07-16 11:57:18 +0000259
260 controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
Davide Pesavento0f830802018-01-16 23:58:58 -0500261 this->advanceClocks(1_ms); // express Interest
262 this->advanceClocks(51_ms); // timeout
Junxiao Shi600f7112016-07-16 11:57:18 +0000263
264 BOOST_CHECK_EQUAL(succeeds.size(), 0);
265}
266
Junxiao Shi7357ef22016-09-07 02:39:37 +0000267BOOST_AUTO_TEST_SUITE_END() // TestController
268BOOST_AUTO_TEST_SUITE_END() // Nfd
269BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi034c1882016-06-24 18:06:51 +0000270
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700271} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700272} // namespace nfd
273} // namespace ndn