blob: b93149ff438d374aaf6fffc33c640a718da3e34d [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/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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 Shi7b6b79d2014-03-26 20:59:35 -070029
30namespace ndn {
31namespace nfd {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070032namespace tests {
33
Junxiao Shia60d9362014-11-12 09:38:21 -070034using ndn::util::DummyClientFace;
35using ndn::util::makeDummyClientFace;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070036
Alexander Afanasyevd1b5c412014-03-27 15:03:51 -070037BOOST_AUTO_TEST_SUITE(ManagementTestNfdController)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070038
39class CommandFixture
40{
41protected:
42 CommandFixture()
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070043 : face(makeDummyClientFace())
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070044 , controller(*face)
45 , commandSucceedCallback(bind(&CommandFixture::onCommandSucceed, this, _1))
46 , commandFailCallback(bind(&CommandFixture::onCommandFail, this, _1, _2))
47 {
48 }
49
50private:
51 void
52 onCommandSucceed(const ControlParameters& parameters)
53 {
54 commandSucceedHistory.push_back(boost::make_tuple(parameters));
55 }
56
57 void
58 onCommandFail(uint32_t code, const std::string& reason)
59 {
60 commandFailHistory.push_back(boost::make_tuple(code, reason));
61 }
62
63protected:
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070064 shared_ptr<DummyClientFace> face;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070065 Controller controller;
66 KeyChain keyChain;
67
68 Controller::CommandSucceedCallback commandSucceedCallback;
69 typedef boost::tuple<ControlParameters> CommandSucceedArgs;
70 std::vector<CommandSucceedArgs> commandSucceedHistory;
71
72 Controller::CommandFailCallback commandFailCallback;
73 typedef boost::tuple<uint32_t,std::string> CommandFailArgs;
74 std::vector<CommandFailArgs> commandFailHistory;
75};
76
77BOOST_FIXTURE_TEST_CASE(CommandSuccess, CommandFixture)
78{
79 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -070080 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070081
82 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
Junxiao Shi70911652014-08-12 10:14:24 -070083 parameters,
84 commandSucceedCallback,
85 commandFailCallback));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070086 face->processEvents(time::milliseconds(1));
87
Junxiao Shia60d9362014-11-12 09:38:21 -070088 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
89 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070090
91 FaceCreateCommand command;
Junxiao Shi5de006b2014-10-26 20:20:52 -070092 BOOST_CHECK(Name("/localhost/nfd/faces/create").isPrefixOf(requestInterest.getName()));
93 // 9 components: ndn:/localhost/nfd/faces/create/<parameters>/<signed Interest x4>
Junxiao Shi6a90f372014-10-13 20:29:30 -070094 BOOST_REQUIRE_EQUAL(requestInterest.getName().size(), 9);
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070095 ControlParameters request;
96 // 4th component: <parameters>
Junxiao Shi6a90f372014-10-13 20:29:30 -070097 BOOST_REQUIRE_NO_THROW(request.wireDecode(requestInterest.getName().at(4).blockFromValue()));
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070098 BOOST_CHECK_NO_THROW(command.validateRequest(request));
99 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi6a90f372014-10-13 20:29:30 -0700100 BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), Controller::getDefaultCommandTimeout());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700101
102 ControlParameters responseBody;
103 responseBody.setUri("tcp4://192.0.2.1:6363")
104 .setFaceId(22);
105 ControlResponse responsePayload(201, "created");
106 responsePayload.setBody(responseBody.wireEncode());
107
Junxiao Shi6a90f372014-10-13 20:29:30 -0700108 Data responseData(requestInterest.getName());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700109 responseData.setContent(responsePayload.wireEncode());
110 keyChain.sign(responseData);
111 face->receive(responseData);
112 face->processEvents(time::milliseconds(1));
113
114 BOOST_CHECK_EQUAL(commandFailHistory.size(), 0);
115 BOOST_REQUIRE_EQUAL(commandSucceedHistory.size(), 1);
116 const ControlParameters& response = commandSucceedHistory[0].get<0>();
117 BOOST_CHECK_EQUAL(response.getUri(), responseBody.getUri());
118 BOOST_CHECK_EQUAL(response.getFaceId(), responseBody.getFaceId());
119}
120
121BOOST_FIXTURE_TEST_CASE(CommandInvalidRequest, CommandFixture)
122{
123 ControlParameters parameters;
124 parameters.setName("ndn:/should-not-have-this-field");
125 // Uri is missing
126
127 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
128 parameters,
129 commandSucceedCallback,
130 commandFailCallback),
131 ControlCommand::ArgumentError);
132}
133
134BOOST_FIXTURE_TEST_CASE(CommandErrorCode, CommandFixture)
135{
136 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700137 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700138
139 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
140 parameters,
141 commandSucceedCallback,
142 commandFailCallback));
143 face->processEvents(time::milliseconds(1));
144
Junxiao Shia60d9362014-11-12 09:38:21 -0700145 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
146 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700147
148 ControlResponse responsePayload(401, "Not Authenticated");
149
Junxiao Shi6a90f372014-10-13 20:29:30 -0700150 Data responseData(requestInterest.getName());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700151 responseData.setContent(responsePayload.wireEncode());
152 keyChain.sign(responseData);
153 face->receive(responseData);
154 face->processEvents(time::milliseconds(1));
155
156 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
157 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
158 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), 401);
159}
160
161BOOST_FIXTURE_TEST_CASE(CommandInvalidResponse, CommandFixture)
162{
163 ControlParameters parameters;
Junxiao Shi5de006b2014-10-26 20:20:52 -0700164 parameters.setUri("tcp4://192.0.2.1:6363");
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700165
166 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
167 parameters,
168 commandSucceedCallback,
169 commandFailCallback));
170 face->processEvents(time::milliseconds(1));
171
Junxiao Shia60d9362014-11-12 09:38:21 -0700172 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
173 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700174
175 ControlParameters responseBody;
176 responseBody.setUri("tcp4://192.0.2.1:6363")
177 .setName("ndn:/should-not-have-this-field");
178 // FaceId is missing
179 ControlResponse responsePayload(201, "created");
180 responsePayload.setBody(responseBody.wireEncode());
181
Junxiao Shi6a90f372014-10-13 20:29:30 -0700182 Data responseData(requestInterest.getName());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700183 responseData.setContent(responsePayload.wireEncode());
184 keyChain.sign(responseData);
185 face->receive(responseData);
186 face->processEvents(time::milliseconds(1));
187
188 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
189 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
190}
191
Junxiao Shi5de006b2014-10-26 20:20:52 -0700192BOOST_FIXTURE_TEST_CASE(OptionsPrefix, CommandFixture)
193{
194 ControlParameters parameters;
195 parameters.setName("/ndn/com/example");
196 parameters.setFaceId(400);
197
198 CommandOptions options;
199 options.setPrefix("/localhop/net/example/router1/nfd");
200
201 BOOST_CHECK_NO_THROW(controller.start<RibRegisterCommand>(
202 parameters,
203 commandSucceedCallback,
204 commandFailCallback,
205 options));
206 face->processEvents(time::milliseconds(1));
207
Junxiao Shia60d9362014-11-12 09:38:21 -0700208 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
209 const Interest& requestInterest = face->sentInterests[0];
Junxiao Shi5de006b2014-10-26 20:20:52 -0700210
211 FaceCreateCommand command;
212 BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(
213 requestInterest.getName()));
214}
215
216BOOST_FIXTURE_TEST_CASE(OptionsTimeout, CommandFixture)
217{
218 ControlParameters parameters;
219 parameters.setUri("tcp4://192.0.2.1:6363");
220
221 CommandOptions options;
222 options.setTimeout(time::milliseconds(50));
223
224 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
225 parameters,
226 commandSucceedCallback,
227 commandFailCallback,
228 options));
229 face->processEvents(time::milliseconds(300));
230
231 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
232 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), Controller::ERROR_TIMEOUT);
233}
234
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700235BOOST_AUTO_TEST_SUITE_END()
236
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700237} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700238} // namespace nfd
239} // namespace ndn