blob: bc9aa1ac68e8ed409171f89bfe69b1c71edd738d [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi7b6b79d2014-03-26 20:59:35 -07002/**
Junxiao Shi034c1882016-06-24 18:06:51 +00003 * Copyright (c) 2013-2016 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
22#include "management/nfd-controller.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070023#include "management/nfd-control-response.hpp"
24
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070025#include <boost/tuple/tuple.hpp>
26
Junxiao Shi034c1882016-06-24 18:06:51 +000027#include "nfd-controller-fixture.hpp"
Junxiao Shib1990df2015-11-05 00:14:44 +000028#include "../make-interest-data.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070029
30namespace ndn {
31namespace nfd {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070032namespace tests {
33
Junxiao Shi85d90832016-08-04 03:19:46 +000034using namespace ndn::tests;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070035
Junxiao Shib1990df2015-11-05 00:14:44 +000036BOOST_AUTO_TEST_SUITE(Management)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070037
Junxiao Shi034c1882016-06-24 18:06:51 +000038class CommandFixture : public ControllerFixture
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070039{
40protected:
41 CommandFixture()
Junxiao Shi034c1882016-06-24 18:06:51 +000042 : succeedCallback(bind(&CommandFixture::succeed, this, _1))
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070043 {
44 }
45
46private:
47 void
Junxiao Shi034c1882016-06-24 18:06:51 +000048 succeed(const ControlParameters& parameters)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070049 {
Junxiao Shi034c1882016-06-24 18:06:51 +000050 succeeds.push_back(parameters);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070051 }
52
53protected:
Junxiao Shi034c1882016-06-24 18:06:51 +000054 Controller::CommandSucceedCallback succeedCallback;
55 std::vector<ControlParameters> succeeds;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070056};
57
Junxiao Shi600f7112016-07-16 11:57:18 +000058// This test suite focuses on ControlCommand functionality of Controller.
59// Individual commands are tested in nfd-control-command.t.cpp
60// StatusDataset functionality is tested in nfd-status-dataset.t.cpp
Junxiao Shib1990df2015-11-05 00:14:44 +000061BOOST_FIXTURE_TEST_SUITE(TestNfdController, CommandFixture)
62
Junxiao Shi600f7112016-07-16 11:57:18 +000063BOOST_AUTO_TEST_CASE(Success)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070064{
65 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070066 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070067
68 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +000069 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +000070 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070071
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080072 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
73 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070074
75 FaceCreateCommand command;
Junxiao Shi5de006b2014-10-26 20:20:52 -070076 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
77 // 9 components: ndn:/localhost/nfd/faces/create/<parameters>/<signed Interest x4>
Junxiao Shi6a90f372014-10-13 20:29:30 -070078 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 9);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070079 ControlParameters request;
80 // 4th component: <parameters>
Junxiao Shi6a90f372014-10-13 20:29:30 -070081 BOOST_REQUIRE_NO_THROW(request.wireDecode(requestInterest.getName().at(4).blockFromValue()));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070082 BOOST_CHECK_NO_THROW(command.validateRequest(request));
83 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi415b17c2014-11-12 00:43:25 -070084 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070085
86 ControlParameters responseBody;
87 responseBody.setUri("tcp4://192.0.2.1:6363")
Yukai Tud93c5fc2015-08-25 11:37:16 +080088 .setFaceId(22)
89 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070090 ControlResponse responsePayload(201, "created");
91 responsePayload.setBody(responseBody.wireEncode());
92
Junxiao Shi034c1882016-06-24 18:06:51 +000093 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +000094 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080095 face.receive(*responseData);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080096
Junxiao Shi600f7112016-07-16 11:57:18 +000097 this->advanceClocks(time::milliseconds(1));
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
110 controller.start<FaceCreateCommand>(parameters, nullptr, failCallback);
111 this->advanceClocks(time::milliseconds(1));
112
113 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
114 const Interest& requestInterest = face.sentInterests[0];
115
116 ControlParameters responseBody;
117 responseBody.setUri("tcp4://192.0.2.1:6363")
118 .setFaceId(22)
119 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
120 ControlResponse responsePayload(201, "created");
121 responsePayload.setBody(responseBody.wireEncode());
122
123 auto responseData = makeData(requestInterest.getName());
124 responseData->setContent(responsePayload.wireEncode());
125 face.receive(*responseData);
126
127 BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(1)));
128
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
141 BOOST_CHECK_NO_THROW(controller.start<RibRegisterCommand>(
142 parameters, succeedCallback, failCallback, options));
143 this->advanceClocks(time::milliseconds(1));
144
145 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
146 const Interest& requestInterest = face.sentInterests[0];
147
148 FaceCreateCommand command;
149 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(
150 requestInterest.getName()));
151}
152
153BOOST_AUTO_TEST_CASE(InvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700154{
155 ControlParameters parameters;
156 parameters.setName("ndn:/should-not-have-this-field");
157 // Uri is missing
158
159 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000160 parameters, succeedCallback, failCallback),
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700161 ControlCommand::ArgumentError);
162}
163
Junxiao Shi600f7112016-07-16 11:57:18 +0000164BOOST_AUTO_TEST_CASE(ErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700165{
166 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700167 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700168
169 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000170 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000171 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700172
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800173 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
174 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700175
176 ControlResponse responsePayload(401, "Not Authenticated");
177
Junxiao Shi034c1882016-06-24 18:06:51 +0000178 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +0000179 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800180 face.receive(*responseData);
Junxiao Shi600f7112016-07-16 11:57:18 +0000181 this->advanceClocks(time::milliseconds(1));
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
193 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000194 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000195 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700196
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800197 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
198 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700199
200 ControlParameters responseBody;
201 responseBody.setUri("tcp4://192.0.2.1:6363")
202 .setName("ndn:/should-not-have-this-field");
203 // FaceId is missing
204 ControlResponse responsePayload(201, "created");
205 responsePayload.setBody(responseBody.wireEncode());
206
Junxiao Shi034c1882016-06-24 18:06:51 +0000207 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +0000208 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800209 face.receive(*responseData);
Junxiao Shi600f7112016-07-16 11:57:18 +0000210 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700211
Junxiao Shi034c1882016-06-24 18:06:51 +0000212 BOOST_CHECK_EQUAL(succeeds.size(), 0);
213 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700214}
215
Junxiao Shi600f7112016-07-16 11:57:18 +0000216BOOST_AUTO_TEST_CASE(Nack)
Junxiao Shib1990df2015-11-05 00:14:44 +0000217{
218 ControlParameters parameters;
219 parameters.setUri("tcp4://192.0.2.1:6363");
220
221 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000222 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000223 this->advanceClocks(time::milliseconds(1));
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);
Junxiao Shi600f7112016-07-16 11:57:18 +0000230 this->advanceClocks(time::milliseconds(1));
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;
242 options.setTimeout(time::milliseconds(50));
243
244 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000245 parameters, succeedCallback, failCallback, options));
Junxiao Shi600f7112016-07-16 11:57:18 +0000246 this->advanceClocks(time::milliseconds(1), 101); // Face's PIT granularity is 100ms
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;
258 options.setTimeout(time::milliseconds(50));
259
260 controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
261 BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(100), 10));
262 // timeout
263
264 BOOST_CHECK_EQUAL(succeeds.size(), 0);
265}
266
267BOOST_AUTO_TEST_SUITE_END() // TestNfdController
268BOOST_AUTO_TEST_SUITE_END() // Management
Junxiao Shi034c1882016-06-24 18:06:51 +0000269
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700270} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700271} // namespace nfd
272} // namespace ndn