blob: 525d0d0f28d096db77b6d9ed013f4b50b4c8cea0 [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
25#include "../transport/dummy-face.hpp"
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070026
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070027#include <boost/tuple/tuple.hpp>
28
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070029#include "boost-test.hpp"
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070030
31namespace ndn {
32namespace nfd {
33
Alexander Afanasyevd1b5c412014-03-27 15:03:51 -070034BOOST_AUTO_TEST_SUITE(ManagementTestNfdController)
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070035
36class CommandFixture
37{
38protected:
39 CommandFixture()
40 : face(makeDummyFace())
41 , controller(*face)
42 , commandSucceedCallback(bind(&CommandFixture::onCommandSucceed, this, _1))
43 , commandFailCallback(bind(&CommandFixture::onCommandFail, this, _1, _2))
44 {
45 }
46
47private:
48 void
49 onCommandSucceed(const ControlParameters& parameters)
50 {
51 commandSucceedHistory.push_back(boost::make_tuple(parameters));
52 }
53
54 void
55 onCommandFail(uint32_t code, const std::string& reason)
56 {
57 commandFailHistory.push_back(boost::make_tuple(code, reason));
58 }
59
60protected:
61 shared_ptr<DummyFace> face;
62 Controller controller;
63 KeyChain keyChain;
64
65 Controller::CommandSucceedCallback commandSucceedCallback;
66 typedef boost::tuple<ControlParameters> CommandSucceedArgs;
67 std::vector<CommandSucceedArgs> commandSucceedHistory;
68
69 Controller::CommandFailCallback commandFailCallback;
70 typedef boost::tuple<uint32_t,std::string> CommandFailArgs;
71 std::vector<CommandFailArgs> commandFailHistory;
72};
73
74BOOST_FIXTURE_TEST_CASE(CommandSuccess, CommandFixture)
75{
76 ControlParameters parameters;
77 parameters.setUri("tcp://example.com");
78
79 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
80 parameters,
81 commandSucceedCallback,
82 commandFailCallback));
83 face->processEvents(time::milliseconds(1));
84
85 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
86 const Interest& commandInterest = face->m_sentInterests[0];
87
88 FaceCreateCommand command;
89 BOOST_CHECK(command.getPrefix().isPrefixOf(commandInterest.getName()));
90 // 9 components: ndn:/localhost/nfd/face/create/<parameters>/<command Interest signature x4>
91 BOOST_REQUIRE_EQUAL(commandInterest.getName().size(), 9);
92 ControlParameters request;
93 // 4th component: <parameters>
94 BOOST_REQUIRE_NO_THROW(request.wireDecode(commandInterest.getName().at(4).blockFromValue()));
95 BOOST_CHECK_NO_THROW(command.validateRequest(request));
96 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi5c785d62014-04-20 18:10:20 -070097 BOOST_CHECK_EQUAL(commandInterest.getInterestLifetime(), Controller::getDefaultCommandTimeout());
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070098
99 ControlParameters responseBody;
100 responseBody.setUri("tcp4://192.0.2.1:6363")
101 .setFaceId(22);
102 ControlResponse responsePayload(201, "created");
103 responsePayload.setBody(responseBody.wireEncode());
104
105 Data responseData(commandInterest.getName());
106 responseData.setContent(responsePayload.wireEncode());
107 keyChain.sign(responseData);
108 face->receive(responseData);
109 face->processEvents(time::milliseconds(1));
110
111 BOOST_CHECK_EQUAL(commandFailHistory.size(), 0);
112 BOOST_REQUIRE_EQUAL(commandSucceedHistory.size(), 1);
113 const ControlParameters& response = commandSucceedHistory[0].get<0>();
114 BOOST_CHECK_EQUAL(response.getUri(), responseBody.getUri());
115 BOOST_CHECK_EQUAL(response.getFaceId(), responseBody.getFaceId());
116}
117
118BOOST_FIXTURE_TEST_CASE(CommandInvalidRequest, CommandFixture)
119{
120 ControlParameters parameters;
121 parameters.setName("ndn:/should-not-have-this-field");
122 // Uri is missing
123
124 BOOST_CHECK_THROW(controller.start<FaceCreateCommand>(
125 parameters,
126 commandSucceedCallback,
127 commandFailCallback),
128 ControlCommand::ArgumentError);
129}
130
131BOOST_FIXTURE_TEST_CASE(CommandErrorCode, CommandFixture)
132{
133 ControlParameters parameters;
134 parameters.setUri("tcp://example.com");
135
136 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
137 parameters,
138 commandSucceedCallback,
139 commandFailCallback));
140 face->processEvents(time::milliseconds(1));
141
142 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
143 const Interest& commandInterest = face->m_sentInterests[0];
144
145 ControlResponse responsePayload(401, "Not Authenticated");
146
147 Data responseData(commandInterest.getName());
148 responseData.setContent(responsePayload.wireEncode());
149 keyChain.sign(responseData);
150 face->receive(responseData);
151 face->processEvents(time::milliseconds(1));
152
153 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
154 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
155 BOOST_CHECK_EQUAL(commandFailHistory[0].get<0>(), 401);
156}
157
158BOOST_FIXTURE_TEST_CASE(CommandInvalidResponse, CommandFixture)
159{
160 ControlParameters parameters;
161 parameters.setUri("tcp://example.com");
162
163 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
164 parameters,
165 commandSucceedCallback,
166 commandFailCallback));
167 face->processEvents(time::milliseconds(1));
168
169 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
170 const Interest& commandInterest = face->m_sentInterests[0];
171
172 ControlParameters responseBody;
173 responseBody.setUri("tcp4://192.0.2.1:6363")
174 .setName("ndn:/should-not-have-this-field");
175 // FaceId is missing
176 ControlResponse responsePayload(201, "created");
177 responsePayload.setBody(responseBody.wireEncode());
178
179 Data responseData(commandInterest.getName());
180 responseData.setContent(responsePayload.wireEncode());
181 keyChain.sign(responseData);
182 face->receive(responseData);
183 face->processEvents(time::milliseconds(1));
184
185 BOOST_CHECK_EQUAL(commandSucceedHistory.size(), 0);
186 BOOST_REQUIRE_EQUAL(commandFailHistory.size(), 1);
187}
188
189BOOST_AUTO_TEST_SUITE_END()
190
191} // namespace nfd
192} // namespace ndn