blob: ad7aa0e82fa2eb7a7c7677f2f60e557d6a4378be [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1f481fa2017-01-26 15:14:43 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Junxiao Shi38f4ce92016-08-04 10:01:52 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
Junxiao Shi331ade72016-08-19 14:07:19 +000026#include "nfdc/face-module.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000027
Junxiao Shi1f481fa2017-01-26 15:14:43 +000028#include "execute-command-fixture.hpp"
29#include "status-fixture.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000030
31namespace nfd {
32namespace tools {
Junxiao Shi331ade72016-08-19 14:07:19 +000033namespace nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000034namespace tests {
35
Junxiao Shi1d7fef52017-02-02 05:33:14 +000036using ndn::nfd::FaceQueryFilter;
37
Junxiao Shi331ade72016-08-19 14:07:19 +000038BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi1f481fa2017-01-26 15:14:43 +000039BOOST_AUTO_TEST_SUITE(TestFaceModule)
40
Junxiao Shi36e54292017-02-17 18:43:16 +000041BOOST_FIXTURE_TEST_SUITE(ListCommand, ExecuteCommandFixture)
42
43const std::string NONQUERY_OUTPUT =
44 "faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
45 " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
46 " flags={non-local permanent multi-access}\n"
47 "faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
48 " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
49 " flags={local on-demand point-to-point local-fields}\n";
50
51BOOST_AUTO_TEST_CASE(NormalNonQuery)
52{
53 this->processInterest = [this] (const Interest& interest) {
54 FaceStatus payload1;
55 payload1.setFaceId(134)
56 .setRemoteUri("udp4://233.252.0.4:6363")
57 .setLocalUri("udp4://192.0.2.1:6363")
58 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
59 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
60 .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
61 .setNInInterests(22562)
Junxiao Shif03d4792017-04-06 16:41:22 +000062 .setNInData(22031)
Junxiao Shi36e54292017-02-17 18:43:16 +000063 .setNInNacks(63)
64 .setNOutInterests(30121)
Junxiao Shif03d4792017-04-06 16:41:22 +000065 .setNOutData(20940)
Junxiao Shi36e54292017-02-17 18:43:16 +000066 .setNOutNacks(1218)
67 .setNInBytes(2522915)
68 .setNOutBytes(1353592);
69 FaceStatus payload2;
70 payload2.setFaceId(745)
71 .setRemoteUri("fd://75")
72 .setLocalUri("unix:///var/run/nfd.sock")
73 .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
74 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
75 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
76 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true)
77 .setNInInterests(18998)
Junxiao Shif03d4792017-04-06 16:41:22 +000078 .setNInData(26701)
Junxiao Shi36e54292017-02-17 18:43:16 +000079 .setNInNacks(147)
80 .setNOutInterests(34779)
Junxiao Shif03d4792017-04-06 16:41:22 +000081 .setNOutData(17028)
Junxiao Shi36e54292017-02-17 18:43:16 +000082 .setNOutNacks(1176)
83 .setNInBytes(4672308)
84 .setNOutBytes(8957187);
85 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
86 };
87
88 this->execute("face list");
89 BOOST_CHECK_EQUAL(exitCode, 0);
90 BOOST_CHECK(out.is_equal(NONQUERY_OUTPUT));
91 BOOST_CHECK(err.is_empty());
92}
93
94const std::string QUERY_OUTPUT =
95 "faceid=177 remote=tcp4://53.239.9.114:6363 local=tcp4://164.0.31.106:20396"
96 " counters={in={2325i 1110d 79n 4716834B} out={2278i 485d 841n 308108B}}"
97 " flags={non-local persistent point-to-point}\n";
98
99BOOST_AUTO_TEST_CASE(NormalQuery)
100{
101 this->processInterest = [this] (const Interest& interest) {
102 BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
103 BOOST_CHECK_EQUAL(interest.getName().size(), 5);
104 FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
105 FaceQueryFilter expectedFilter;
106 expectedFilter.setRemoteUri("tcp4://53.239.9.114:6363")
107 .setLocalUri("tcp4://164.0.31.106:20396")
108 .setUriScheme("tcp4");
109 BOOST_CHECK_EQUAL(filter, expectedFilter);
110
111 FaceStatus payload;
112 payload.setFaceId(177)
113 .setRemoteUri("tcp4://53.239.9.114:6363")
114 .setLocalUri("tcp4://164.0.31.106:20396")
115 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
116 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
117 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
118 .setNInInterests(2325)
Junxiao Shif03d4792017-04-06 16:41:22 +0000119 .setNInData(1110)
Junxiao Shi36e54292017-02-17 18:43:16 +0000120 .setNInNacks(79)
121 .setNOutInterests(2278)
Junxiao Shif03d4792017-04-06 16:41:22 +0000122 .setNOutData(485)
Junxiao Shi36e54292017-02-17 18:43:16 +0000123 .setNOutNacks(841)
124 .setNInBytes(4716834)
125 .setNOutBytes(308108);
126 this->sendDataset(interest.getName(), payload);
127 };
128
129 this->execute("face list tcp://53.239.9.114 scheme tcp4 local tcp://164.0.31.106:20396");
130 BOOST_CHECK_EQUAL(exitCode, 0);
131 BOOST_CHECK(out.is_equal(QUERY_OUTPUT));
132 BOOST_CHECK(err.is_empty());
133}
134
135BOOST_AUTO_TEST_CASE(NotFound)
136{
137 this->processInterest = [this] (const Interest& interest) {
138 this->sendEmptyDataset(interest.getName());
139 };
140
141 this->execute("face list scheme udp6");
142 BOOST_CHECK_EQUAL(exitCode, 3);
143 BOOST_CHECK(out.is_empty());
144 BOOST_CHECK(err.is_equal("Face not found\n"));
145}
146
147BOOST_AUTO_TEST_CASE(Error)
148{
149 this->processInterest = nullptr; // no response
150
151 this->execute("face list local udp4://31.67.17.2:6363");
152 BOOST_CHECK_EQUAL(exitCode, 1);
153 BOOST_CHECK(out.is_empty());
154 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
155}
156
157BOOST_AUTO_TEST_SUITE_END() // ListCommand
158
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000159BOOST_FIXTURE_TEST_SUITE(ShowCommand, ExecuteCommandFixture)
160
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000161const std::string NORMAL_OUTPUT = std::string(R"TEXT(
162 faceid=256
163 remote=udp4://84.67.35.111:6363
164 local=udp4://79.91.49.215:6363
165counters={in={28975i 28232d 212n 13307258B} out={19525i 30993d 1038n 6231946B}}
166 flags={non-local on-demand point-to-point}
167)TEXT").substr(1);
168
169BOOST_AUTO_TEST_CASE(Normal)
170{
171 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000172 BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
Junxiao Shi8f803f22017-02-10 03:04:28 +0000173 BOOST_CHECK_EQUAL(interest.getName().size(), 5);
174 FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
175 BOOST_CHECK_EQUAL(filter, FaceQueryFilter().setFaceId(256));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000176
177 FaceStatus payload;
178 payload.setFaceId(256)
179 .setRemoteUri("udp4://84.67.35.111:6363")
180 .setLocalUri("udp4://79.91.49.215:6363")
181 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
182 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
183 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
184 .setNInInterests(28975)
Junxiao Shif03d4792017-04-06 16:41:22 +0000185 .setNInData(28232)
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000186 .setNInNacks(212)
187 .setNOutInterests(19525)
Junxiao Shif03d4792017-04-06 16:41:22 +0000188 .setNOutData(30993)
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000189 .setNOutNacks(1038)
190 .setNInBytes(13307258)
191 .setNOutBytes(6231946);
192
Junxiao Shi8f803f22017-02-10 03:04:28 +0000193 this->sendDataset(interest.getName(), payload);
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000194 };
195
196 this->execute("face show 256");
197 BOOST_CHECK_EQUAL(exitCode, 0);
198 BOOST_CHECK(out.is_equal(NORMAL_OUTPUT));
199 BOOST_CHECK(err.is_empty());
200}
201
202BOOST_AUTO_TEST_CASE(NotFound)
203{
204 this->processInterest = [this] (const Interest& interest) {
205 this->sendEmptyDataset(interest.getName());
206 };
207
208 this->execute("face show 256");
209 BOOST_CHECK_EQUAL(exitCode, 3);
210 BOOST_CHECK(out.is_empty());
Junxiao Shi8f803f22017-02-10 03:04:28 +0000211 BOOST_CHECK(err.is_equal("Face not found\n"));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000212}
213
214BOOST_AUTO_TEST_CASE(Error)
215{
216 this->processInterest = nullptr; // no response
217
218 this->execute("face show 256");
219 BOOST_CHECK_EQUAL(exitCode, 1);
220 BOOST_CHECK(out.is_empty());
Junxiao Shi8f803f22017-02-10 03:04:28 +0000221 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000222}
223
224BOOST_AUTO_TEST_SUITE_END() // ShowCommand
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000225
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000226class ExecuteFaceCreateCommandFixture : public ExecuteCommandFixture
227{
228protected:
229 void
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000230 respond409(const Interest& interest, FacePersistency persistency)
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000231 {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000232 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000233 ControlParameters body;
234 body.setFaceId(1172)
235 .setUri("udp4://100.77.30.65:6363")
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000236 .setLocalUri("udp4://68.62.26.57:24087")
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000237 .setFacePersistency(persistency)
238 .setFlags(0);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000239 this->failCommand(interest, 409, "conflict-409", body);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000240 }
241};
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000242
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000243BOOST_FIXTURE_TEST_SUITE(CreateCommand, ExecuteFaceCreateCommandFixture)
244
245BOOST_AUTO_TEST_CASE(Creating)
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000246{
247 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000248 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000249 BOOST_REQUIRE(req.hasUri());
250 BOOST_CHECK_EQUAL(req.getUri(), "udp4://159.242.33.78:6363");
Junxiao Shi0d976922017-04-01 14:35:21 +0000251 BOOST_CHECK(!req.hasLocalUri());
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000252 BOOST_REQUIRE(req.hasFacePersistency());
253 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
254
255 ControlParameters resp;
256 resp.setFaceId(2130)
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000257 .setUri("udp4://159.242.33.78:6363")
258 .setLocalUri("udp4://179.63.153.45:28835")
Junxiao Shi5c1bb362017-05-11 16:03:38 +0000259 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
260 .setFlags(0);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000261 this->succeedCommand(interest, resp);
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000262 };
263
264 this->execute("face create udp://159.242.33.78");
265 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000266 BOOST_CHECK(out.is_equal("face-created id=2130 local=udp4://179.63.153.45:28835 "
267 "remote=udp4://159.242.33.78:6363 persistency=persistent\n"));
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000268 BOOST_CHECK(err.is_empty());
269}
270
Junxiao Shi0d976922017-04-01 14:35:21 +0000271BOOST_AUTO_TEST_CASE(CreatingWithLocalUri)
272{
273 this->processInterest = [this] (const Interest& interest) {
274 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
275 BOOST_REQUIRE(req.hasUri());
276 BOOST_CHECK_EQUAL(req.getUri(), "udp4://22.91.89.51:19903");
277 BOOST_REQUIRE(req.hasLocalUri());
278 BOOST_CHECK_EQUAL(req.getLocalUri(), "udp4://98.68.23.71:6363");
279 BOOST_REQUIRE(req.hasFacePersistency());
280 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERMANENT);
281
282 ControlParameters resp;
283 resp.setFaceId(301)
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000284 .setUri("udp4://22.91.89.51:19903")
285 .setLocalUri("udp4://98.68.23.71:6363")
Junxiao Shi5c1bb362017-05-11 16:03:38 +0000286 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERMANENT)
287 .setFlags(0);
Junxiao Shi0d976922017-04-01 14:35:21 +0000288 this->succeedCommand(interest, resp);
289 };
290
291 this->execute("face create udp://22.91.89.51:19903 permanent local udp://98.68.23.71");
292 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000293 BOOST_CHECK(out.is_equal("face-created id=301 local=udp4://98.68.23.71:6363 "
294 "remote=udp4://22.91.89.51:19903 persistency=permanent\n"));
Junxiao Shi0d976922017-04-01 14:35:21 +0000295 BOOST_CHECK(err.is_empty());
296}
297
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000298BOOST_AUTO_TEST_CASE(UpgradingPersistency)
299{
300 bool hasUpdateCommand = false;
301 this->processInterest = [this, &hasUpdateCommand] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000302 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
303 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000304 return;
305 }
306
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000307 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000308 hasUpdateCommand = true;
309 BOOST_REQUIRE(req.hasFaceId());
310 BOOST_CHECK_EQUAL(req.getFaceId(), 1172);
311 BOOST_REQUIRE(req.hasFacePersistency());
312 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
313 BOOST_CHECK(!req.hasFlags());
314
315 ControlParameters resp;
316 resp.setFaceId(1172)
317 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
318 .setFlags(0);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000319 this->succeedCommand(interest, resp);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000320 };
321
322 this->execute("face create udp://100.77.30.65");
323 BOOST_CHECK(hasUpdateCommand);
324 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000325 BOOST_CHECK(out.is_equal("face-updated id=1172 local=udp4://68.62.26.57:24087 "
326 "remote=udp4://100.77.30.65:6363 persistency=persistent\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000327 BOOST_CHECK(err.is_empty());
328}
329
330BOOST_AUTO_TEST_CASE(NotDowngradingPersistency)
331{
332 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000333 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERMANENT);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000334 // no command other than faces/create is expected
335 };
336
337 this->execute("face create udp://100.77.30.65");
338 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000339 BOOST_CHECK(out.is_equal("face-exists id=1172 local=udp4://68.62.26.57:24087 "
340 "remote=udp4://100.77.30.65:6363 persistency=permanent\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000341 BOOST_CHECK(err.is_empty());
342}
343
344BOOST_AUTO_TEST_CASE(SamePersistency)
345{
346 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000347 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000348 // no command other than faces/create is expected
349 };
350
351 this->execute("face create udp://100.77.30.65");
352 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000353 BOOST_CHECK(out.is_equal("face-exists id=1172 local=udp4://68.62.26.57:24087 "
354 "remote=udp4://100.77.30.65:6363 persistency=persistent\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000355 BOOST_CHECK(err.is_empty());
356}
357
Junxiao Shi0d976922017-04-01 14:35:21 +0000358BOOST_AUTO_TEST_CASE(ErrorCanonizeRemote)
359{
360 this->execute("face create invalid://");
361 BOOST_CHECK_EQUAL(exitCode, 4);
362 BOOST_CHECK(out.is_empty());
363 BOOST_CHECK(err.is_equal("Error when canonizing 'invalid://': scheme not supported\n"));
364}
365
366BOOST_AUTO_TEST_CASE(ErrorCanonizeLocal)
367{
368 this->execute("face create udp4://24.37.20.47:6363 local invalid://");
369 BOOST_CHECK_EQUAL(exitCode, 4);
370 BOOST_CHECK(out.is_empty());
371 BOOST_CHECK(err.is_equal("Error when canonizing 'invalid://': scheme not supported\n"));
372}
373
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000374BOOST_AUTO_TEST_CASE(ErrorCreate)
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000375{
376 this->processInterest = nullptr; // no response
377
378 this->execute("face create udp://159.242.33.78");
379 BOOST_CHECK_EQUAL(exitCode, 1);
380 BOOST_CHECK(out.is_empty());
381 BOOST_CHECK(err.is_equal("Error 10060 when creating face: request timed out\n"));
382}
383
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000384BOOST_AUTO_TEST_CASE(ErrorConflict)
385{
386 // Current NFD will not report a 409-conflict with a different remote FaceUri, but this is
387 // allowed by FaceMgmt protocol and nfdc should not attempt to upgrade persistency in this case.
388
389 this->processInterest = [this] (const Interest& interest) {
390 // conflict with udp4://100.77.30.65:6363
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000391 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000392 };
393
394 this->execute("face create udp://20.53.73.45");
395 BOOST_CHECK_EQUAL(exitCode, 1);
396 BOOST_CHECK(out.is_empty());
397 BOOST_CHECK(err.is_equal("Error 409 when creating face: conflict-409\n"));
398}
399
400BOOST_AUTO_TEST_CASE(ErrorUpdate)
401{
402 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000403 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
404 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000405 return;
406 }
407
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000408 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000409 // no response to faces/update
410 };
411
412 this->execute("face create udp://100.77.30.65");
413 BOOST_CHECK_EQUAL(exitCode, 1);
414 BOOST_CHECK(out.is_empty());
415 BOOST_CHECK(err.is_equal("Error 10060 when upgrading face persistency: request timed out\n"));
416}
417
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000418BOOST_AUTO_TEST_SUITE_END() // CreateCommand
419
Junxiao Shi05dd4442017-02-06 22:50:07 +0000420BOOST_FIXTURE_TEST_SUITE(DestroyCommand, ExecuteCommandFixture)
421
422BOOST_AUTO_TEST_CASE(NormalByFaceId)
423{
424 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000425 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000426 return;
427 }
428
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000429 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000430 BOOST_REQUIRE(req.hasFaceId());
431 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
432
433 ControlParameters resp;
434 resp.setFaceId(10156);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000435 this->succeedCommand(interest, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000436 };
437
438 this->execute("face destroy 10156");
439 BOOST_CHECK_EQUAL(exitCode, 0);
440 BOOST_CHECK(out.is_equal("face-destroyed id=10156 local=tcp4://151.26.163.27:22967 "
441 "remote=tcp4://198.57.27.40:6363 persistency=persistent\n"));
442 BOOST_CHECK(err.is_empty());
443}
444
445BOOST_AUTO_TEST_CASE(NormalByFaceUri)
446{
447 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000448 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000449 return;
450 }
451
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000452 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000453 BOOST_REQUIRE(req.hasFaceId());
454 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
455
456 ControlParameters resp;
457 resp.setFaceId(2249);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000458 this->succeedCommand(interest, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000459 };
460
461 this->execute("face destroy tcp://32.121.182.82");
462 BOOST_CHECK_EQUAL(exitCode, 0);
463 BOOST_CHECK(out.is_equal("face-destroyed id=2249 local=tcp4://30.99.87.98:31414 "
464 "remote=tcp4://32.121.182.82:6363 persistency=persistent\n"));
465 BOOST_CHECK(err.is_empty());
466}
467
468BOOST_AUTO_TEST_CASE(FaceNotExist)
469{
470 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000471 BOOST_CHECK(this->respondFaceQuery(interest));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000472 };
473
474 this->execute("face destroy 23728");
475 BOOST_CHECK_EQUAL(exitCode, 3);
476 BOOST_CHECK(out.is_empty());
477 BOOST_CHECK(err.is_equal("Face not found\n"));
478}
479
480BOOST_AUTO_TEST_CASE(Ambiguous)
481{
482 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000483 BOOST_CHECK(this->respondFaceQuery(interest));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000484 };
485
486 this->execute("face destroy udp4://225.131.75.231:56363");
487 BOOST_CHECK_EQUAL(exitCode, 5);
488 BOOST_CHECK(out.is_empty());
489 BOOST_CHECK(err.is_equal("Multiple faces match specified remote FaceUri. "
490 "Re-run the command with a FaceId: "
491 "6720 (local=udp4://202.83.168.28:56363), "
492 "31066 (local=udp4://25.90.26.32:56363)\n"));
493}
494
495BOOST_AUTO_TEST_CASE(ErrorCanonization)
496{
497 this->execute("face destroy udp6://32.38.164.64:10445");
498 BOOST_CHECK_EQUAL(exitCode, 4);
499 BOOST_CHECK(out.is_empty());
500 BOOST_CHECK(err.is_equal("Error during remote FaceUri canonization: "
Eric Newberry7d8695d2017-05-29 15:49:10 -0700501 "IPv4/v6 mismatch\n"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000502}
503
504BOOST_AUTO_TEST_CASE(ErrorDataset)
505{
506 this->processInterest = nullptr; // no response to dataset or command
507
508 this->execute("face destroy udp://159.242.33.78");
509 BOOST_CHECK_EQUAL(exitCode, 1);
510 BOOST_CHECK(out.is_empty());
511 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
512}
513
514BOOST_AUTO_TEST_CASE(ErrorCommand)
515{
516 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000517 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000518 return;
519 }
520
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000521 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000522 // no response to command
523 };
524
Junxiao Shi918e5d42017-02-25 03:58:21 +0000525 this->execute("face destroy 10156");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000526 BOOST_CHECK_EQUAL(exitCode, 1);
527 BOOST_CHECK(out.is_empty());
528 BOOST_CHECK(err.is_equal("Error 10060 when destroying face: request timed out\n"));
529}
530
531BOOST_AUTO_TEST_SUITE_END() // DestroyCommand
532
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000533const std::string STATUS_XML = stripXmlSpaces(R"XML(
534 <faces>
535 <face>
536 <faceId>134</faceId>
537 <remoteUri>udp4://233.252.0.4:6363</remoteUri>
538 <localUri>udp4://192.0.2.1:6363</localUri>
539 <faceScope>non-local</faceScope>
540 <facePersistency>permanent</facePersistency>
541 <linkType>multi-access</linkType>
Eric Newberry6d932e82016-11-24 05:05:43 +0000542 <flags/>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000543 <packetCounters>
544 <incomingPackets>
545 <nInterests>22562</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000546 <nData>22031</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000547 <nNacks>63</nNacks>
548 </incomingPackets>
549 <outgoingPackets>
550 <nInterests>30121</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000551 <nData>20940</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000552 <nNacks>1218</nNacks>
553 </outgoingPackets>
554 </packetCounters>
555 <byteCounters>
556 <incomingBytes>2522915</incomingBytes>
557 <outgoingBytes>1353592</outgoingBytes>
558 </byteCounters>
559 </face>
560 <face>
561 <faceId>745</faceId>
562 <remoteUri>fd://75</remoteUri>
563 <localUri>unix:///var/run/nfd.sock</localUri>
564 <faceScope>local</faceScope>
565 <facePersistency>on-demand</facePersistency>
566 <linkType>point-to-point</linkType>
Eric Newberry6d932e82016-11-24 05:05:43 +0000567 <flags>
568 <localFieldsEnabled/>
569 </flags>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000570 <packetCounters>
571 <incomingPackets>
572 <nInterests>18998</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000573 <nData>26701</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000574 <nNacks>147</nNacks>
575 </incomingPackets>
576 <outgoingPackets>
577 <nInterests>34779</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000578 <nData>17028</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000579 <nNacks>1176</nNacks>
580 </outgoingPackets>
581 </packetCounters>
582 <byteCounters>
583 <incomingBytes>4672308</incomingBytes>
584 <outgoingBytes>8957187</outgoingBytes>
585 </byteCounters>
586 </face>
587 </faces>
588)XML");
589
590const std::string STATUS_TEXT =
591 "Faces:\n"
592 " faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
593 " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000594 " flags={non-local permanent multi-access}\n"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000595 " faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
596 " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000597 " flags={local on-demand point-to-point local-fields}\n";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000598
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000599BOOST_FIXTURE_TEST_CASE(Status, StatusFixture<FaceModule>)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000600{
601 this->fetchStatus();
602 FaceStatus payload1;
603 payload1.setFaceId(134)
604 .setRemoteUri("udp4://233.252.0.4:6363")
605 .setLocalUri("udp4://192.0.2.1:6363")
606 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
607 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
608 .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
609 .setNInInterests(22562)
Junxiao Shif03d4792017-04-06 16:41:22 +0000610 .setNInData(22031)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000611 .setNInNacks(63)
612 .setNOutInterests(30121)
Junxiao Shif03d4792017-04-06 16:41:22 +0000613 .setNOutData(20940)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000614 .setNOutNacks(1218)
615 .setNInBytes(2522915)
616 .setNOutBytes(1353592);
617 FaceStatus payload2;
618 payload2.setFaceId(745)
619 .setRemoteUri("fd://75")
620 .setLocalUri("unix:///var/run/nfd.sock")
621 .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
622 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
623 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
Eric Newberry6d932e82016-11-24 05:05:43 +0000624 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000625 .setNInInterests(18998)
Junxiao Shif03d4792017-04-06 16:41:22 +0000626 .setNInData(26701)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000627 .setNInNacks(147)
628 .setNOutInterests(34779)
Junxiao Shif03d4792017-04-06 16:41:22 +0000629 .setNOutData(17028)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000630 .setNOutNacks(1176)
631 .setNInBytes(4672308)
632 .setNOutBytes(8957187);
633 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
634 this->prepareStatusOutput();
635
636 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
637 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
638}
639
640BOOST_AUTO_TEST_SUITE_END() // TestFaceModule
Junxiao Shi331ade72016-08-19 14:07:19 +0000641BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000642
643} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000644} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000645} // namespace tools
646} // namespace nfd