blob: 6479cd62118284d6644468c8b0cf30799f81b6e0 [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/**
Spyridon Mastorakis429634f2015-02-19 17:35:33 -08003 * Copyright (c) 2013-2015 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
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070027#include "boost-test.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070028#include "util/dummy-client-face.hpp"
Junxiao Shib1990df2015-11-05 00:14:44 +000029#include "../make-interest-data.hpp"
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080030#include "../unit-test-time-fixture.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070031
32namespace ndn {
33namespace nfd {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070034namespace tests {
35
Junxiao Shia60d9362014-11-12 09:38:21 -070036using ndn::util::DummyClientFace;
37using ndn::util::makeDummyClientFace;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070038
Junxiao Shib1990df2015-11-05 00:14:44 +000039BOOST_AUTO_TEST_SUITE(Management)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070040
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080041class CommandFixture : public ndn::tests::UnitTestTimeFixture
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070042{
43protected:
44 CommandFixture()
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080045 : face(makeDummyClientFace(io))
Junxiao Shi415b17c2014-11-12 00:43:25 -070046 , controller(*face, keyChain)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070047 , commandSucceedCallback(bind(&CommandFixture::onCommandSucceed, this, _1))
48 , commandFailCallback(bind(&CommandFixture::onCommandFail, this, _1, _2))
49 {
50 }
51
52private:
53 void
54 onCommandSucceed(const ControlParameters& parameters)
55 {
56 commandSucceedHistory.push_back(boost::make_tuple(parameters));
57 }
58
59 void
60 onCommandFail(uint32_t code, const std::string& reason)
61 {
62 commandFailHistory.push_back(boost::make_tuple(code, reason));
63 }
64
65protected:
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070066 shared_ptr<DummyClientFace> face;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070067 KeyChain keyChain;
Junxiao Shi415b17c2014-11-12 00:43:25 -070068 Controller controller;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070069
70 Controller::CommandSucceedCallback commandSucceedCallback;
71 typedef boost::tuple<ControlParameters> CommandSucceedArgs;
72 std::vector<CommandSucceedArgs> commandSucceedHistory;
73
74 Controller::CommandFailCallback commandFailCallback;
75 typedef boost::tuple<uint32_t,std::string> CommandFailArgs;
76 std::vector<CommandFailArgs> commandFailHistory;
77};
78
Junxiao Shib1990df2015-11-05 00:14:44 +000079BOOST_FIXTURE_TEST_SUITE(TestNfdController, CommandFixture)
80
81BOOST_AUTO_TEST_CASE(CommandSuccess)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070082{
83 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070084 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070085
86 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi70911652014-08-12 10:14:24 -070087 parameters,
88 commandSucceedCallback,
89 commandFailCallback));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080090
91 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070092
Junxiao Shia60d9362014-11-12 09:38:21 -070093 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
94 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070095
96 FaceCreateCommand command;
Junxiao Shi5de006b2014-10-26 20:20:52 -070097 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
98 // 9 components: ndn:/localhost/nfd/faces/create/<parameters>/<signed Interest x4>
Junxiao Shi6a90f372014-10-13 20:29:30 -070099 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 9);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700100 ControlParameters request;
101 // 4th component: <parameters>
Junxiao Shi6a90f372014-10-13 20:29:30 -0700102 BOOST_REQUIRE_NO_THROW(request.wireDecode(requestInterest.getName().at(4).blockFromValue()));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700103 BOOST_CHECK_NO_THROW(command.validateRequest(request));
104 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi415b17c2014-11-12 00:43:25 -0700105 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700106
107 ControlParameters responseBody;
108 responseBody.setUri("tcp4://192.0.2.1:6363")
Yukai Tud93c5fc2015-08-25 11:37:16 +0800109 .setFaceId(22)
110 .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700111 ControlResponse responsePayload(201, "created");
112 responsePayload.setBody(responseBody.wireEncode());
113
Junxiao Shib1990df2015-11-05 00:14:44 +0000114 auto responseData = util::makeData(requestInterest.getName());
115 responseData->setContent(responsePayload.wireEncode());
116 face->receive(*responseData);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800117
118 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700119
120 BOOST_CHECK_EQUAL(commandFailHistory.size(), 0);
121 BOOST_REQUIRE_EQUAL(commandSucceedHistory.size(), 1);
122 const ControlParameters& response = commandSucceedHistory[0].get<0>();
123 BOOST_CHECK_EQUAL(response.getUri(), responseBody.getUri());
124 BOOST_CHECK_EQUAL(response.getFaceId(), responseBody.getFaceId());
125}
126
Junxiao Shib1990df2015-11-05 00:14:44 +0000127BOOST_AUTO_TEST_CASE(CommandInvalidRequest)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700128{
129 ControlParameters parameters;
130 parameters.setName("ndn:/should-not-have-this-field");
131 // Uri is missing
132
133 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
134 parameters,
135 commandSucceedCallback,
136 commandFailCallback),
137 ControlCommand::ArgumentError);
138}
139
Junxiao Shib1990df2015-11-05 00:14:44 +0000140BOOST_AUTO_TEST_CASE(CommandErrorCode)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700141{
142 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700143 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700144
145 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
146 parameters,
147 commandSucceedCallback,
148 commandFailCallback));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800149 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700150
Junxiao Shia60d9362014-11-12 09:38:21 -0700151 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
152 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700153
154 ControlResponse responsePayload(401, "Not Authenticated");
155
Junxiao Shib1990df2015-11-05 00:14:44 +0000156 auto responseData = util::makeData(requestInterest.getName());
157 responseData->setContent(responsePayload.wireEncode());
158 face->receive(*responseData);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800159 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700160
161 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
162 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
163 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), 401);
164}
165
Junxiao Shib1990df2015-11-05 00:14:44 +0000166BOOST_AUTO_TEST_CASE(CommandInvalidResponse)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700167{
168 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700169 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700170
171 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
172 parameters,
173 commandSucceedCallback,
174 commandFailCallback));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800175 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700176
Junxiao Shia60d9362014-11-12 09:38:21 -0700177 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
178 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700179
180 ControlParameters responseBody;
181 responseBody.setUri("tcp4://192.0.2.1:6363")
182 .setName("ndn:/should-not-have-this-field");
183 // FaceId is missing
184 ControlResponse responsePayload(201, "created");
185 responsePayload.setBody(responseBody.wireEncode());
186
Junxiao Shib1990df2015-11-05 00:14:44 +0000187 auto responseData = util::makeData(requestInterest.getName());
188 responseData->setContent(responsePayload.wireEncode());
189 face->receive(*responseData);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800190 advanceClocks(time::milliseconds(1));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700191
192 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
193 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
194}
195
Junxiao Shib1990df2015-11-05 00:14:44 +0000196BOOST_AUTO_TEST_CASE(CommandNack)
197{
198 ControlParameters parameters;
199 parameters.setUri("tcp4://192.0.2.1:6363");
200
201 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
202 parameters,
203 commandSucceedCallback,
204 commandFailCallback));
205 advanceClocks(time::milliseconds(1));
206
207 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
208 const Interest& requestInterest = face->sentInterests[0];
209
210 auto responseNack = util::makeNack(requestInterest, lp::NackReason::NO_ROUTE);
211 face->receive(responseNack);
212 advanceClocks(time::milliseconds(1));
213
214 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
215 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), Controller::ERROR_NACK);
216}
217
218BOOST_AUTO_TEST_CASE(OptionsPrefix)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700219{
220 ControlParameters parameters;
221 parameters.setName("/ndn/com/example");
222 parameters.setFaceId(400);
223
224 CommandOptions options;
225 options.setPrefix("/localhop/net/example/router1/nfd");
226
227 BOOST_CHECK_NO_THROW(controller.start<RibRegisterCommand>(
228 parameters,
229 commandSucceedCallback,
230 commandFailCallback,
231 options));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800232 advanceClocks(time::milliseconds(1));
Junxiao Shi5de006b2014-10-26 20:20:52 -0700233
Junxiao Shia60d9362014-11-12 09:38:21 -0700234 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
235 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi5de006b2014-10-26 20:20:52 -0700236
237 FaceCreateCommand command;
238 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(
239 requestInterest.getName()));
240}
241
Junxiao Shib1990df2015-11-05 00:14:44 +0000242BOOST_AUTO_TEST_CASE(OptionsTimeout)
Junxiao Shi5de006b2014-10-26 20:20:52 -0700243{
244 ControlParameters parameters;
245 parameters.setUri("tcp4://192.0.2.1:6363");
246
247 CommandOptions options;
248 options.setTimeout(time::milliseconds(50));
249
250 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
251 parameters,
252 commandSucceedCallback,
253 commandFailCallback,
254 options));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800255 advanceClocks(time::milliseconds(1), 101); // Face's PIT granularity is 100ms
Junxiao Shi5de006b2014-10-26 20:20:52 -0700256
257 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
258 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), Controller::ERROR_TIMEOUT);
259}
260
Junxiao Shib1990df2015-11-05 00:14:44 +0000261BOOST_AUTO_TEST_SUITE_END() // TestController
262BOOST_AUTO_TEST_SUITE_END() // Management
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700263
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700264} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700265} // namespace nfd
266} // namespace ndn