blob: 3792f2c32f8d09abc8b2b2854dfd879596dc8623 [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 Afanasyev4abdbf12014-08-11 12:48:54 -070025#include "../dummy-client-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 {
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070033namespace tests {
34
35using namespace ::ndn::tests;
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;
80 parameters.setUri("tcp://example.com");
81
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
88 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
89 const Interest& commandInterest = face->m_sentInterests[0];
90
91 FaceCreateCommand command;
92 BOOST_CHECK(command.getPrefix().isPrefixOf(commandInterest.getName()));
93 // 9 components: ndn:/localhost/nfd/face/create/<parameters>/<command Interest signature x4>
94 BOOST_REQUIRE_EQUAL(commandInterest.getName().size(), 9);
95 ControlParameters request;
96 // 4th component: <parameters>
97 BOOST_REQUIRE_NO_THROW(request.wireDecode(commandInterest.getName().at(4).blockFromValue()));
98 BOOST_CHECK_NO_THROW(command.validateRequest(request));
99 BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
Junxiao Shi5c785d62014-04-20 18:10:20 -0700100 BOOST_CHECK_EQUAL(commandInterest.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
108 Data responseData(commandInterest.getName());
109 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;
137 parameters.setUri("tcp://example.com");
138
139 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
140 parameters,
141 commandSucceedCallback,
142 commandFailCallback));
143 face->processEvents(time::milliseconds(1));
144
145 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
146 const Interest& commandInterest = face->m_sentInterests[0];
147
148 ControlResponse responsePayload(401, "Not Authenticated");
149
150 Data responseData(commandInterest.getName());
151 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;
164 parameters.setUri("tcp://example.com");
165
166 BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
167 parameters,
168 commandSucceedCallback,
169 commandFailCallback));
170 face->processEvents(time::milliseconds(1));
171
172 BOOST_REQUIRE_EQUAL(face->m_sentInterests.size(), 1);
173 const Interest& commandInterest = face->m_sentInterests[0];
174
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
182 Data responseData(commandInterest.getName());
183 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
192BOOST_AUTO_TEST_SUITE_END()
193
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700194} // namespace tests
Junxiao Shi7b6b79d2014-03-26 20:59:35 -0700195} // namespace nfd
196} // namespace ndn