blob: 33e022ce093a802c47a8b21683e5158d87e0aec9 [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry84d3adc2017-08-09 23:31:40 -04002/*
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}}"
Eric Newberry84d3adc2017-08-09 23:31:40 -040049 " flags={local on-demand point-to-point local-fields lp-reliability}\n";
Junxiao Shi36e54292017-02-17 18:43:16 +000050
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)
Eric Newberry84d3adc2017-08-09 23:31:40 -040077 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true)
Junxiao Shi36e54292017-02-17 18:43:16 +000078 .setNInInterests(18998)
Junxiao Shif03d4792017-04-06 16:41:22 +000079 .setNInData(26701)
Junxiao Shi36e54292017-02-17 18:43:16 +000080 .setNInNacks(147)
81 .setNOutInterests(34779)
Junxiao Shif03d4792017-04-06 16:41:22 +000082 .setNOutData(17028)
Junxiao Shi36e54292017-02-17 18:43:16 +000083 .setNOutNacks(1176)
84 .setNInBytes(4672308)
85 .setNOutBytes(8957187);
86 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
87 };
88
89 this->execute("face list");
90 BOOST_CHECK_EQUAL(exitCode, 0);
91 BOOST_CHECK(out.is_equal(NONQUERY_OUTPUT));
92 BOOST_CHECK(err.is_empty());
93}
94
95const std::string QUERY_OUTPUT =
96 "faceid=177 remote=tcp4://53.239.9.114:6363 local=tcp4://164.0.31.106:20396"
97 " counters={in={2325i 1110d 79n 4716834B} out={2278i 485d 841n 308108B}}"
98 " flags={non-local persistent point-to-point}\n";
99
100BOOST_AUTO_TEST_CASE(NormalQuery)
101{
102 this->processInterest = [this] (const Interest& interest) {
103 BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
104 BOOST_CHECK_EQUAL(interest.getName().size(), 5);
105 FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
106 FaceQueryFilter expectedFilter;
107 expectedFilter.setRemoteUri("tcp4://53.239.9.114:6363")
108 .setLocalUri("tcp4://164.0.31.106:20396")
109 .setUriScheme("tcp4");
110 BOOST_CHECK_EQUAL(filter, expectedFilter);
111
112 FaceStatus payload;
113 payload.setFaceId(177)
114 .setRemoteUri("tcp4://53.239.9.114:6363")
115 .setLocalUri("tcp4://164.0.31.106:20396")
116 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
117 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
118 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
119 .setNInInterests(2325)
Junxiao Shif03d4792017-04-06 16:41:22 +0000120 .setNInData(1110)
Junxiao Shi36e54292017-02-17 18:43:16 +0000121 .setNInNacks(79)
122 .setNOutInterests(2278)
Junxiao Shif03d4792017-04-06 16:41:22 +0000123 .setNOutData(485)
Junxiao Shi36e54292017-02-17 18:43:16 +0000124 .setNOutNacks(841)
125 .setNInBytes(4716834)
126 .setNOutBytes(308108);
127 this->sendDataset(interest.getName(), payload);
128 };
129
130 this->execute("face list tcp://53.239.9.114 scheme tcp4 local tcp://164.0.31.106:20396");
131 BOOST_CHECK_EQUAL(exitCode, 0);
132 BOOST_CHECK(out.is_equal(QUERY_OUTPUT));
133 BOOST_CHECK(err.is_empty());
134}
135
136BOOST_AUTO_TEST_CASE(NotFound)
137{
138 this->processInterest = [this] (const Interest& interest) {
139 this->sendEmptyDataset(interest.getName());
140 };
141
142 this->execute("face list scheme udp6");
143 BOOST_CHECK_EQUAL(exitCode, 3);
144 BOOST_CHECK(out.is_empty());
145 BOOST_CHECK(err.is_equal("Face not found\n"));
146}
147
148BOOST_AUTO_TEST_CASE(Error)
149{
150 this->processInterest = nullptr; // no response
151
152 this->execute("face list local udp4://31.67.17.2:6363");
153 BOOST_CHECK_EQUAL(exitCode, 1);
154 BOOST_CHECK(out.is_empty());
155 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
156}
157
158BOOST_AUTO_TEST_SUITE_END() // ListCommand
159
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000160BOOST_FIXTURE_TEST_SUITE(ShowCommand, ExecuteCommandFixture)
161
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000162const std::string NORMAL_OUTPUT = std::string(R"TEXT(
163 faceid=256
164 remote=udp4://84.67.35.111:6363
165 local=udp4://79.91.49.215:6363
166counters={in={28975i 28232d 212n 13307258B} out={19525i 30993d 1038n 6231946B}}
167 flags={non-local on-demand point-to-point}
168)TEXT").substr(1);
169
170BOOST_AUTO_TEST_CASE(Normal)
171{
172 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000173 BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
Junxiao Shi8f803f22017-02-10 03:04:28 +0000174 BOOST_CHECK_EQUAL(interest.getName().size(), 5);
175 FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
176 BOOST_CHECK_EQUAL(filter, FaceQueryFilter().setFaceId(256));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000177
178 FaceStatus payload;
179 payload.setFaceId(256)
180 .setRemoteUri("udp4://84.67.35.111:6363")
181 .setLocalUri("udp4://79.91.49.215:6363")
182 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
183 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
184 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
185 .setNInInterests(28975)
Junxiao Shif03d4792017-04-06 16:41:22 +0000186 .setNInData(28232)
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000187 .setNInNacks(212)
188 .setNOutInterests(19525)
Junxiao Shif03d4792017-04-06 16:41:22 +0000189 .setNOutData(30993)
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000190 .setNOutNacks(1038)
191 .setNInBytes(13307258)
192 .setNOutBytes(6231946);
193
Junxiao Shi8f803f22017-02-10 03:04:28 +0000194 this->sendDataset(interest.getName(), payload);
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000195 };
196
197 this->execute("face show 256");
198 BOOST_CHECK_EQUAL(exitCode, 0);
199 BOOST_CHECK(out.is_equal(NORMAL_OUTPUT));
200 BOOST_CHECK(err.is_empty());
201}
202
203BOOST_AUTO_TEST_CASE(NotFound)
204{
205 this->processInterest = [this] (const Interest& interest) {
206 this->sendEmptyDataset(interest.getName());
207 };
208
209 this->execute("face show 256");
210 BOOST_CHECK_EQUAL(exitCode, 3);
211 BOOST_CHECK(out.is_empty());
Junxiao Shi8f803f22017-02-10 03:04:28 +0000212 BOOST_CHECK(err.is_equal("Face not found\n"));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000213}
214
215BOOST_AUTO_TEST_CASE(Error)
216{
217 this->processInterest = nullptr; // no response
218
219 this->execute("face show 256");
220 BOOST_CHECK_EQUAL(exitCode, 1);
221 BOOST_CHECK(out.is_empty());
Junxiao Shi8f803f22017-02-10 03:04:28 +0000222 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000223}
224
225BOOST_AUTO_TEST_SUITE_END() // ShowCommand
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000226
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000227class ExecuteFaceCreateCommandFixture : public ExecuteCommandFixture
228{
229protected:
230 void
Eric Newberry84d3adc2017-08-09 23:31:40 -0400231 respond409(const Interest& interest, FacePersistency persistency, bool enableLpReliability = false)
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000232 {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000233 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000234 ControlParameters body;
235 body.setFaceId(1172)
236 .setUri("udp4://100.77.30.65:6363")
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000237 .setLocalUri("udp4://68.62.26.57:24087")
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000238 .setFacePersistency(persistency)
239 .setFlags(0);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400240 if (enableLpReliability) {
241 body.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true, false);
242 }
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000243 this->failCommand(interest, 409, "conflict-409", body);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000244 }
245};
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000246
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000247BOOST_FIXTURE_TEST_SUITE(CreateCommand, ExecuteFaceCreateCommandFixture)
248
249BOOST_AUTO_TEST_CASE(Creating)
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000250{
251 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000252 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000253 BOOST_REQUIRE(req.hasUri());
254 BOOST_CHECK_EQUAL(req.getUri(), "udp4://159.242.33.78:6363");
Junxiao Shi0d976922017-04-01 14:35:21 +0000255 BOOST_CHECK(!req.hasLocalUri());
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000256 BOOST_REQUIRE(req.hasFacePersistency());
257 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
258
259 ControlParameters resp;
260 resp.setFaceId(2130)
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000261 .setUri("udp4://159.242.33.78:6363")
262 .setLocalUri("udp4://179.63.153.45:28835")
Junxiao Shi5c1bb362017-05-11 16:03:38 +0000263 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
264 .setFlags(0);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000265 this->succeedCommand(interest, resp);
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000266 };
267
268 this->execute("face create udp://159.242.33.78");
269 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000270 BOOST_CHECK(out.is_equal("face-created id=2130 local=udp4://179.63.153.45:28835 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400271 "remote=udp4://159.242.33.78:6363 persistency=persistent "
272 "reliability=off\n"));
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000273 BOOST_CHECK(err.is_empty());
274}
275
Eric Newberry84d3adc2017-08-09 23:31:40 -0400276BOOST_AUTO_TEST_CASE(CreatingWithParams)
Junxiao Shi0d976922017-04-01 14:35:21 +0000277{
278 this->processInterest = [this] (const Interest& interest) {
279 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
280 BOOST_REQUIRE(req.hasUri());
281 BOOST_CHECK_EQUAL(req.getUri(), "udp4://22.91.89.51:19903");
282 BOOST_REQUIRE(req.hasLocalUri());
283 BOOST_CHECK_EQUAL(req.getLocalUri(), "udp4://98.68.23.71:6363");
284 BOOST_REQUIRE(req.hasFacePersistency());
285 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERMANENT);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400286 BOOST_CHECK(req.hasFlags());
287 BOOST_CHECK(req.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
Junxiao Shi0d976922017-04-01 14:35:21 +0000288
289 ControlParameters resp;
290 resp.setFaceId(301)
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000291 .setUri("udp4://22.91.89.51:19903")
292 .setLocalUri("udp4://98.68.23.71:6363")
Junxiao Shi5c1bb362017-05-11 16:03:38 +0000293 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERMANENT)
Eric Newberry84d3adc2017-08-09 23:31:40 -0400294 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true, false);
Junxiao Shi0d976922017-04-01 14:35:21 +0000295 this->succeedCommand(interest, resp);
296 };
297
Eric Newberry84d3adc2017-08-09 23:31:40 -0400298 this->execute("face create udp://22.91.89.51:19903 permanent local udp://98.68.23.71 reliability on");
Junxiao Shi0d976922017-04-01 14:35:21 +0000299 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000300 BOOST_CHECK(out.is_equal("face-created id=301 local=udp4://98.68.23.71:6363 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400301 "remote=udp4://22.91.89.51:19903 persistency=permanent "
302 "reliability=on\n"));
Junxiao Shi0d976922017-04-01 14:35:21 +0000303 BOOST_CHECK(err.is_empty());
304}
305
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000306BOOST_AUTO_TEST_CASE(UpgradingPersistency)
307{
308 bool hasUpdateCommand = false;
309 this->processInterest = [this, &hasUpdateCommand] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000310 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
311 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000312 return;
313 }
314
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000315 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000316 hasUpdateCommand = true;
317 BOOST_REQUIRE(req.hasFaceId());
318 BOOST_CHECK_EQUAL(req.getFaceId(), 1172);
319 BOOST_REQUIRE(req.hasFacePersistency());
320 BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
321 BOOST_CHECK(!req.hasFlags());
322
323 ControlParameters resp;
324 resp.setFaceId(1172)
325 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
326 .setFlags(0);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000327 this->succeedCommand(interest, resp);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000328 };
329
330 this->execute("face create udp://100.77.30.65");
331 BOOST_CHECK(hasUpdateCommand);
332 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000333 BOOST_CHECK(out.is_equal("face-updated id=1172 local=udp4://68.62.26.57:24087 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400334 "remote=udp4://100.77.30.65:6363 persistency=persistent "
335 "reliability=off\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000336 BOOST_CHECK(err.is_empty());
337}
338
339BOOST_AUTO_TEST_CASE(NotDowngradingPersistency)
340{
341 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000342 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERMANENT);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000343 // no command other than faces/create is expected
344 };
345
346 this->execute("face create udp://100.77.30.65");
347 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000348 BOOST_CHECK(out.is_equal("face-exists id=1172 local=udp4://68.62.26.57:24087 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400349 "remote=udp4://100.77.30.65:6363 persistency=permanent "
350 "reliability=off\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000351 BOOST_CHECK(err.is_empty());
352}
353
354BOOST_AUTO_TEST_CASE(SamePersistency)
355{
356 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000357 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000358 // no command other than faces/create is expected
359 };
360
361 this->execute("face create udp://100.77.30.65");
362 BOOST_CHECK_EQUAL(exitCode, 0);
Junxiao Shi1cce2a32017-05-02 02:39:55 +0000363 BOOST_CHECK(out.is_equal("face-exists id=1172 local=udp4://68.62.26.57:24087 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400364 "remote=udp4://100.77.30.65:6363 persistency=persistent "
365 "reliability=off\n"));
366 BOOST_CHECK(err.is_empty());
367}
368
369BOOST_AUTO_TEST_CASE(EnablingReliability)
370{
371 bool hasUpdateCommand = false;
372 this->processInterest = [this, &hasUpdateCommand] (const Interest& interest) {
373 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
374 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERSISTENT);
375 return;
376 }
377
378 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
379 hasUpdateCommand = true;
380 BOOST_REQUIRE(req.hasFaceId());
381 BOOST_CHECK_EQUAL(req.getFaceId(), 1172);
382 BOOST_CHECK(req.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
383 BOOST_CHECK(req.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
384
385 ControlParameters resp;
386 resp.setFaceId(1172)
387 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
388 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true, false);
389 this->succeedCommand(interest, resp);
390 };
391
392 this->execute("face create udp://100.77.30.65 reliability on");
393 BOOST_CHECK_EQUAL(exitCode, 0);
394 BOOST_CHECK(out.is_equal("face-updated id=1172 local=udp4://68.62.26.57:24087 "
395 "remote=udp4://100.77.30.65:6363 persistency=persistent "
396 "reliability=on\n"));
397 BOOST_CHECK(err.is_empty());
398}
399
400BOOST_AUTO_TEST_CASE(DisablingReliability)
401{
402 bool hasUpdateCommand = false;
403 this->processInterest = [this, &hasUpdateCommand] (const Interest& interest) {
404 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
405 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERSISTENT, true);
406 return;
407 }
408
409 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
410 hasUpdateCommand = true;
411 BOOST_REQUIRE(req.hasFaceId());
412 BOOST_CHECK_EQUAL(req.getFaceId(), 1172);
413 BOOST_CHECK(req.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
414 BOOST_CHECK(!req.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
415
416 ControlParameters resp;
417 resp.setFaceId(1172)
418 .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
419 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false, false);
420 this->succeedCommand(interest, resp);
421 };
422
423 this->execute("face create udp://100.77.30.65 reliability off");
424 BOOST_CHECK_EQUAL(exitCode, 0);
425 BOOST_CHECK(out.is_equal("face-updated id=1172 local=udp4://68.62.26.57:24087 "
426 "remote=udp4://100.77.30.65:6363 persistency=persistent "
427 "reliability=off\n"));
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000428 BOOST_CHECK(err.is_empty());
429}
430
Junxiao Shi0d976922017-04-01 14:35:21 +0000431BOOST_AUTO_TEST_CASE(ErrorCanonizeRemote)
432{
433 this->execute("face create invalid://");
434 BOOST_CHECK_EQUAL(exitCode, 4);
435 BOOST_CHECK(out.is_empty());
436 BOOST_CHECK(err.is_equal("Error when canonizing 'invalid://': scheme not supported\n"));
437}
438
439BOOST_AUTO_TEST_CASE(ErrorCanonizeLocal)
440{
441 this->execute("face create udp4://24.37.20.47:6363 local invalid://");
442 BOOST_CHECK_EQUAL(exitCode, 4);
443 BOOST_CHECK(out.is_empty());
444 BOOST_CHECK(err.is_equal("Error when canonizing 'invalid://': scheme not supported\n"));
445}
446
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000447BOOST_AUTO_TEST_CASE(ErrorCreate)
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000448{
449 this->processInterest = nullptr; // no response
450
451 this->execute("face create udp://159.242.33.78");
452 BOOST_CHECK_EQUAL(exitCode, 1);
453 BOOST_CHECK(out.is_empty());
454 BOOST_CHECK(err.is_equal("Error 10060 when creating face: request timed out\n"));
455}
456
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000457BOOST_AUTO_TEST_CASE(ErrorConflict)
458{
459 // Current NFD will not report a 409-conflict with a different remote FaceUri, but this is
460 // allowed by FaceMgmt protocol and nfdc should not attempt to upgrade persistency in this case.
461
462 this->processInterest = [this] (const Interest& interest) {
463 // conflict with udp4://100.77.30.65:6363
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000464 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000465 };
466
467 this->execute("face create udp://20.53.73.45");
468 BOOST_CHECK_EQUAL(exitCode, 1);
469 BOOST_CHECK(out.is_empty());
470 BOOST_CHECK(err.is_equal("Error 409 when creating face: conflict-409\n"));
471}
472
473BOOST_AUTO_TEST_CASE(ErrorUpdate)
474{
475 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000476 if (parseCommand(interest, "/localhost/nfd/faces/create")) {
477 this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000478 return;
479 }
480
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000481 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000482 // no response to faces/update
483 };
484
485 this->execute("face create udp://100.77.30.65");
486 BOOST_CHECK_EQUAL(exitCode, 1);
487 BOOST_CHECK(out.is_empty());
488 BOOST_CHECK(err.is_equal("Error 10060 when upgrading face persistency: request timed out\n"));
489}
490
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000491BOOST_AUTO_TEST_SUITE_END() // CreateCommand
492
Junxiao Shi05dd4442017-02-06 22:50:07 +0000493BOOST_FIXTURE_TEST_SUITE(DestroyCommand, ExecuteCommandFixture)
494
495BOOST_AUTO_TEST_CASE(NormalByFaceId)
496{
497 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000498 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000499 return;
500 }
501
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000502 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000503 BOOST_REQUIRE(req.hasFaceId());
504 BOOST_CHECK_EQUAL(req.getFaceId(), 10156);
505
506 ControlParameters resp;
507 resp.setFaceId(10156);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000508 this->succeedCommand(interest, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000509 };
510
511 this->execute("face destroy 10156");
512 BOOST_CHECK_EQUAL(exitCode, 0);
513 BOOST_CHECK(out.is_equal("face-destroyed id=10156 local=tcp4://151.26.163.27:22967 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400514 "remote=tcp4://198.57.27.40:6363 persistency=persistent "
515 "reliability=off\n"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000516 BOOST_CHECK(err.is_empty());
517}
518
519BOOST_AUTO_TEST_CASE(NormalByFaceUri)
520{
521 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000522 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000523 return;
524 }
525
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000526 ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000527 BOOST_REQUIRE(req.hasFaceId());
528 BOOST_CHECK_EQUAL(req.getFaceId(), 2249);
529
530 ControlParameters resp;
531 resp.setFaceId(2249);
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000532 this->succeedCommand(interest, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000533 };
534
535 this->execute("face destroy tcp://32.121.182.82");
536 BOOST_CHECK_EQUAL(exitCode, 0);
537 BOOST_CHECK(out.is_equal("face-destroyed id=2249 local=tcp4://30.99.87.98:31414 "
Eric Newberry84d3adc2017-08-09 23:31:40 -0400538 "remote=tcp4://32.121.182.82:6363 persistency=persistent "
539 "reliability=off\n"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000540 BOOST_CHECK(err.is_empty());
541}
542
543BOOST_AUTO_TEST_CASE(FaceNotExist)
544{
545 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000546 BOOST_CHECK(this->respondFaceQuery(interest));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000547 };
548
549 this->execute("face destroy 23728");
550 BOOST_CHECK_EQUAL(exitCode, 3);
551 BOOST_CHECK(out.is_empty());
552 BOOST_CHECK(err.is_equal("Face not found\n"));
553}
554
555BOOST_AUTO_TEST_CASE(Ambiguous)
556{
557 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000558 BOOST_CHECK(this->respondFaceQuery(interest));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000559 };
560
561 this->execute("face destroy udp4://225.131.75.231:56363");
562 BOOST_CHECK_EQUAL(exitCode, 5);
563 BOOST_CHECK(out.is_empty());
564 BOOST_CHECK(err.is_equal("Multiple faces match specified remote FaceUri. "
565 "Re-run the command with a FaceId: "
566 "6720 (local=udp4://202.83.168.28:56363), "
567 "31066 (local=udp4://25.90.26.32:56363)\n"));
568}
569
570BOOST_AUTO_TEST_CASE(ErrorCanonization)
571{
572 this->execute("face destroy udp6://32.38.164.64:10445");
573 BOOST_CHECK_EQUAL(exitCode, 4);
574 BOOST_CHECK(out.is_empty());
575 BOOST_CHECK(err.is_equal("Error during remote FaceUri canonization: "
Eric Newberry7d8695d2017-05-29 15:49:10 -0700576 "IPv4/v6 mismatch\n"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000577}
578
579BOOST_AUTO_TEST_CASE(ErrorDataset)
580{
581 this->processInterest = nullptr; // no response to dataset or command
582
583 this->execute("face destroy udp://159.242.33.78");
584 BOOST_CHECK_EQUAL(exitCode, 1);
585 BOOST_CHECK(out.is_empty());
586 BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
587}
588
589BOOST_AUTO_TEST_CASE(ErrorCommand)
590{
591 this->processInterest = [this] (const Interest& interest) {
Junxiao Shi918e5d42017-02-25 03:58:21 +0000592 if (this->respondFaceQuery(interest)) {
Junxiao Shi05dd4442017-02-06 22:50:07 +0000593 return;
594 }
595
Junxiao Shi1a25a6e2017-03-06 03:09:47 +0000596 MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000597 // no response to command
598 };
599
Junxiao Shi918e5d42017-02-25 03:58:21 +0000600 this->execute("face destroy 10156");
Junxiao Shi05dd4442017-02-06 22:50:07 +0000601 BOOST_CHECK_EQUAL(exitCode, 1);
602 BOOST_CHECK(out.is_empty());
603 BOOST_CHECK(err.is_equal("Error 10060 when destroying face: request timed out\n"));
604}
605
606BOOST_AUTO_TEST_SUITE_END() // DestroyCommand
607
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000608const std::string STATUS_XML = stripXmlSpaces(R"XML(
609 <faces>
610 <face>
611 <faceId>134</faceId>
612 <remoteUri>udp4://233.252.0.4:6363</remoteUri>
613 <localUri>udp4://192.0.2.1:6363</localUri>
614 <faceScope>non-local</faceScope>
615 <facePersistency>permanent</facePersistency>
616 <linkType>multi-access</linkType>
Eric Newberry6d932e82016-11-24 05:05:43 +0000617 <flags/>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000618 <packetCounters>
619 <incomingPackets>
620 <nInterests>22562</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000621 <nData>22031</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000622 <nNacks>63</nNacks>
623 </incomingPackets>
624 <outgoingPackets>
625 <nInterests>30121</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000626 <nData>20940</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000627 <nNacks>1218</nNacks>
628 </outgoingPackets>
629 </packetCounters>
630 <byteCounters>
631 <incomingBytes>2522915</incomingBytes>
632 <outgoingBytes>1353592</outgoingBytes>
633 </byteCounters>
634 </face>
635 <face>
636 <faceId>745</faceId>
637 <remoteUri>fd://75</remoteUri>
638 <localUri>unix:///var/run/nfd.sock</localUri>
639 <faceScope>local</faceScope>
640 <facePersistency>on-demand</facePersistency>
641 <linkType>point-to-point</linkType>
Eric Newberry6d932e82016-11-24 05:05:43 +0000642 <flags>
643 <localFieldsEnabled/>
Eric Newberry84d3adc2017-08-09 23:31:40 -0400644 <lpReliabilityEnabled/>
Eric Newberry6d932e82016-11-24 05:05:43 +0000645 </flags>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000646 <packetCounters>
647 <incomingPackets>
648 <nInterests>18998</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000649 <nData>26701</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000650 <nNacks>147</nNacks>
651 </incomingPackets>
652 <outgoingPackets>
653 <nInterests>34779</nInterests>
Junxiao Shif03d4792017-04-06 16:41:22 +0000654 <nData>17028</nData>
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000655 <nNacks>1176</nNacks>
656 </outgoingPackets>
657 </packetCounters>
658 <byteCounters>
659 <incomingBytes>4672308</incomingBytes>
660 <outgoingBytes>8957187</outgoingBytes>
661 </byteCounters>
662 </face>
663 </faces>
664)XML");
665
666const std::string STATUS_TEXT =
667 "Faces:\n"
668 " faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
669 " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000670 " flags={non-local permanent multi-access}\n"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000671 " faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
672 " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
Eric Newberry84d3adc2017-08-09 23:31:40 -0400673 " flags={local on-demand point-to-point local-fields lp-reliability}\n";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000674
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000675BOOST_FIXTURE_TEST_CASE(Status, StatusFixture<FaceModule>)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000676{
677 this->fetchStatus();
678 FaceStatus payload1;
679 payload1.setFaceId(134)
680 .setRemoteUri("udp4://233.252.0.4:6363")
681 .setLocalUri("udp4://192.0.2.1:6363")
682 .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
683 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
684 .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
685 .setNInInterests(22562)
Junxiao Shif03d4792017-04-06 16:41:22 +0000686 .setNInData(22031)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000687 .setNInNacks(63)
688 .setNOutInterests(30121)
Junxiao Shif03d4792017-04-06 16:41:22 +0000689 .setNOutData(20940)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000690 .setNOutNacks(1218)
691 .setNInBytes(2522915)
692 .setNOutBytes(1353592);
693 FaceStatus payload2;
694 payload2.setFaceId(745)
695 .setRemoteUri("fd://75")
696 .setLocalUri("unix:///var/run/nfd.sock")
697 .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
698 .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
699 .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
Eric Newberry6d932e82016-11-24 05:05:43 +0000700 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true)
Eric Newberry84d3adc2017-08-09 23:31:40 -0400701 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000702 .setNInInterests(18998)
Junxiao Shif03d4792017-04-06 16:41:22 +0000703 .setNInData(26701)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000704 .setNInNacks(147)
705 .setNOutInterests(34779)
Junxiao Shif03d4792017-04-06 16:41:22 +0000706 .setNOutData(17028)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000707 .setNOutNacks(1176)
708 .setNInBytes(4672308)
709 .setNOutBytes(8957187);
710 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
711 this->prepareStatusOutput();
712
713 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
714 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
715}
716
717BOOST_AUTO_TEST_SUITE_END() // TestFaceModule
Junxiao Shi331ade72016-08-19 14:07:19 +0000718BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000719
720} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000721} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000722} // namespace tools
723} // namespace nfd