blob: 1beb5db36bae6ff17e7fc26ecb6dfaf25440a70e [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 Shi034c1882016-06-24 18:06:51 +000034using ndn::util::makeData;
35using ndn::util::makeNack;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070036
Junxiao Shib1990df2015-11-05 00:14:44 +000037BOOST_AUTO_TEST_SUITE(Management)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070038
Junxiao Shi034c1882016-06-24 18:06:51 +000039class CommandFixture : public ControllerFixture
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070040{
41protected:
42 CommandFixture()
Junxiao Shi034c1882016-06-24 18:06:51 +000043 : succeedCallback(bind(&CommandFixture::succeed, this, _1))
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070044 {
45 }
46
47private:
48 void
Junxiao Shi034c1882016-06-24 18:06:51 +000049 succeed(const ControlParameters& parameters)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070050 {
Junxiao Shi034c1882016-06-24 18:06:51 +000051 succeeds.push_back(parameters);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070052 }
53
54protected:
Junxiao Shi034c1882016-06-24 18:06:51 +000055 Controller::CommandSucceedCallback succeedCallback;
56 std::vector<ControlParameters> succeeds;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070057};
58
Junxiao Shi600f7112016-07-16 11:57:18 +000059// This test suite focuses on ControlCommand functionality of Controller.
60// Individual commands are tested in nfd-control-command.t.cpp
61// StatusDataset functionality is tested in nfd-status-dataset.t.cpp
Junxiao Shib1990df2015-11-05 00:14:44 +000062BOOST_FIXTURE_TEST_SUITE(TestNfdController, CommandFixture)
63
Junxiao Shi600f7112016-07-16 11:57:18 +000064BOOST_AUTO_TEST_CASE(Success)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070065{
66 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070067 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070068
69 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +000070 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +000071 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070072
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080073 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
74 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070075
76 FaceCreateCommand command;
Junxiao Shi5de006b2014-10-26 20:20:52 -070077 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
78 // 9 components: ndn:/localhost/nfd/faces/create/<parameters>/<signed Interest x4>
Junxiao Shi6a90f372014-10-13 20:29:30 -070079 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 9);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070080 ControlParameters request;
81 // 4th component: <parameters>
Junxiao Shi6a90f372014-10-13 20:29:30 -070082 BOOST_REQUIRE_NO_THROW(request.wireDecode(requestInterest.getName().at(4).blockFromValue()));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070083 BOOST_CHECK_NO_THROW(command.validateRequest(request));
84 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi415b17c2014-11-12 00:43:25 -070085 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070086
87 ControlParameters responseBody;
88 responseBody.setUri("tcp4://192.0.2.1:6363")
Yukai Tud93c5fc2015-08-25 11:37:16 +080089 .setFaceId(22)
90 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070091 ControlResponse responsePayload(201, "created");
92 responsePayload.setBody(responseBody.wireEncode());
93
Junxiao Shi034c1882016-06-24 18:06:51 +000094 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +000095 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080096 face.receive(*responseData);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080097
Junxiao Shi600f7112016-07-16 11:57:18 +000098 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070099
Junxiao Shi034c1882016-06-24 18:06:51 +0000100 BOOST_CHECK_EQUAL(failCodes.size(), 0);
101 BOOST_REQUIRE_EQUAL(succeeds.size(), 1);
102 BOOST_CHECK_EQUAL(succeeds.back().getUri(), responseBody.getUri());
103 BOOST_CHECK_EQUAL(succeeds.back().getFaceId(), responseBody.getFaceId());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700104}
105
Junxiao Shi600f7112016-07-16 11:57:18 +0000106BOOST_AUTO_TEST_CASE(SuccessNoCallback)
107{
108 ControlParameters parameters;
109 parameters.setUri("tcp4://192.0.2.1:6363");
110
111 controller.start<FaceCreateCommand>(parameters, nullptr, failCallback);
112 this->advanceClocks(time::milliseconds(1));
113
114 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
115 const Interest& requestInterest = face.sentInterests[0];
116
117 ControlParameters responseBody;
118 responseBody.setUri("tcp4://192.0.2.1:6363")
119 .setFaceId(22)
120 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
121 ControlResponse responsePayload(201, "created");
122 responsePayload.setBody(responseBody.wireEncode());
123
124 auto responseData = makeData(requestInterest.getName());
125 responseData->setContent(responsePayload.wireEncode());
126 face.receive(*responseData);
127
128 BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(1)));
129
130 BOOST_CHECK_EQUAL(failCodes.size(), 0);
131}
132
133BOOST_AUTO_TEST_CASE(OptionsPrefix)
134{
135 ControlParameters parameters;
136 parameters.setName("/ndn/com/example");
137 parameters.setFaceId(400);
138
139 CommandOptions options;
140 options.setPrefix("/localhop/net/example/router1/nfd");
141
142 BOOST_CHECK_NO_THROW(controller.start<RibRegisterCommand>(
143 parameters, succeedCallback, failCallback, options));
144 this->advanceClocks(time::milliseconds(1));
145
146 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
147 const Interest& requestInterest = face.sentInterests[0];
148
149 FaceCreateCommand command;
150 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(
151 requestInterest.getName()));
152}
153
154BOOST_AUTO_TEST_CASE(InvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700155{
156 ControlParameters parameters;
157 parameters.setName("ndn:/should-not-have-this-field");
158 // Uri is missing
159
160 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000161 parameters, succeedCallback, failCallback),
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700162 ControlCommand::ArgumentError);
163}
164
Junxiao Shi600f7112016-07-16 11:57:18 +0000165BOOST_AUTO_TEST_CASE(ErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700166{
167 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700168 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700169
170 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000171 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000172 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700173
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800174 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
175 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700176
177 ControlResponse responsePayload(401, "Not Authenticated");
178
Junxiao Shi034c1882016-06-24 18:06:51 +0000179 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +0000180 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800181 face.receive(*responseData);
Junxiao Shi600f7112016-07-16 11:57:18 +0000182 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700183
Junxiao Shi034c1882016-06-24 18:06:51 +0000184 BOOST_CHECK_EQUAL(succeeds.size(), 0);
185 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
186 BOOST_CHECK_EQUAL(failCodes.back(), 401);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700187}
188
Junxiao Shi600f7112016-07-16 11:57:18 +0000189BOOST_AUTO_TEST_CASE(InvalidResponse)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700190{
191 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700192 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700193
194 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000195 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000196 this->advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700197
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800198 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
199 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700200
201 ControlParameters responseBody;
202 responseBody.setUri("tcp4://192.0.2.1:6363")
203 .setName("ndn:/should-not-have-this-field");
204 // FaceId is missing
205 ControlResponse responsePayload(201, "created");
206 responsePayload.setBody(responseBody.wireEncode());
207
Junxiao Shi034c1882016-06-24 18:06:51 +0000208 auto responseData = makeData(requestInterest.getName());
Junxiao Shib1990df2015-11-05 00:14:44 +0000209 responseData->setContent(responsePayload.wireEncode());
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800210 face.receive(*responseData);
Junxiao Shi600f7112016-07-16 11:57:18 +0000211 this->advanceClocks(time::milliseconds(1));
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
222 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000223 parameters, succeedCallback, failCallback));
Junxiao Shi600f7112016-07-16 11:57:18 +0000224 this->advanceClocks(time::milliseconds(1));
Junxiao Shib1990df2015-11-05 00:14:44 +0000225
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800226 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
227 const Interest& requestInterest = face.sentInterests[0];
Junxiao Shib1990df2015-11-05 00:14:44 +0000228
Junxiao Shi034c1882016-06-24 18:06:51 +0000229 auto responseNack = makeNack(requestInterest, lp::NackReason::NO_ROUTE);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800230 face.receive(responseNack);
Junxiao Shi600f7112016-07-16 11:57:18 +0000231 this->advanceClocks(time::milliseconds(1));
Junxiao Shib1990df2015-11-05 00:14:44 +0000232
Junxiao Shi034c1882016-06-24 18:06:51 +0000233 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
234 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
Junxiao Shib1990df2015-11-05 00:14:44 +0000235}
236
Junxiao Shi600f7112016-07-16 11:57:18 +0000237BOOST_AUTO_TEST_CASE(Timeout)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700238{
239 ControlParameters parameters;
240 parameters.setUri("tcp4://192.0.2.1:6363");
241
242 CommandOptions options;
243 options.setTimeout(time::milliseconds(50));
244
245 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi034c1882016-06-24 18:06:51 +0000246 parameters, succeedCallback, failCallback, options));
Junxiao Shi600f7112016-07-16 11:57:18 +0000247 this->advanceClocks(time::milliseconds(1), 101); // Face's PIT granularity is 100ms
Junxiao Shi5de006b2014-10-26 20:20:52 -0700248
Junxiao Shi034c1882016-06-24 18:06:51 +0000249 BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
250 BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
Junxiao Shi5de006b2014-10-26 20:20:52 -0700251}
252
Junxiao Shi600f7112016-07-16 11:57:18 +0000253BOOST_AUTO_TEST_CASE(FailureNoCallback)
254{
255 ControlParameters parameters;
256 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700257
Junxiao Shi600f7112016-07-16 11:57:18 +0000258 CommandOptions options;
259 options.setTimeout(time::milliseconds(50));
260
261 controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
262 BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(100), 10));
263 // timeout
264
265 BOOST_CHECK_EQUAL(succeeds.size(), 0);
266}
267
268BOOST_AUTO_TEST_SUITE_END() // TestNfdController
269BOOST_AUTO_TEST_SUITE_END() // Management
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