blob: a87c5dc818aa32ae6496e5547eb9733be337f91e [file] [log] [blame]
Junxiao Shi96dc0c42014-01-30 23:51:59 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Steve DiBenedettoef04f272014-06-04 14:28:31 -06003 * Copyright (c) 2014, Regents of the University of California,
4 * 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
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Junxiao Shi96dc0c42014-01-30 23:51:59 -070025
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080026#include "face/tcp-factory.hpp"
Alexander Afanasyev650028d2014-04-25 18:39:10 -070027#include "core/resolver.hpp"
28#include "core/network-interface.hpp"
Alexander Afanasyev4a771362014-04-24 21:29:33 -070029#include <ndn-cxx/security/key-chain.hpp>
Junxiao Shi96dc0c42014-01-30 23:51:59 -070030
Junxiao Shid9ee45c2014-02-27 15:38:11 -070031#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070032#include "tests/limited-io.hpp"
Alexander Afanasyev650028d2014-04-25 18:39:10 -070033#include "dummy-stream-sender.hpp"
34#include "packet-datasets.hpp"
Junxiao Shi96dc0c42014-01-30 23:51:59 -070035
36namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070037namespace tests {
Junxiao Shi96dc0c42014-01-30 23:51:59 -070038
Junxiao Shid9ee45c2014-02-27 15:38:11 -070039BOOST_FIXTURE_TEST_SUITE(FaceTcp, BaseFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070040
41BOOST_AUTO_TEST_CASE(ChannelMap)
42{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080043 TcpFactory factory;
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080044
Alexander Afanasyevd6655302014-02-28 08:41:28 -080045 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
46 shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070047 BOOST_CHECK_EQUAL(channel1, channel1a);
Junxiao Shi61e3cc52014-03-03 20:40:28 -070048 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080049
Alexander Afanasyevd6655302014-02-28 08:41:28 -080050 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070051 BOOST_CHECK_NE(channel1, channel2);
Junxiao Shi61e3cc52014-03-03 20:40:28 -070052
53 shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
54 BOOST_CHECK_NE(channel2, channel3);
55 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070056}
57
Steve DiBenedettoef04f272014-06-04 14:28:31 -060058BOOST_AUTO_TEST_CASE(GetChannels)
59{
60 TcpFactory factory;
61 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
62
63 std::vector<shared_ptr<const Channel> > expectedChannels;
64 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
65 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
66 expectedChannels.push_back(factory.createChannel("::1", "20071"));
67
68 std::list<shared_ptr<const Channel> > channels = factory.getChannels();
69 for (std::list<shared_ptr<const Channel> >::const_iterator i = channels.begin();
70 i != channels.end(); ++i)
71 {
72 std::vector<shared_ptr<const Channel> >::iterator pos =
73 std::find(expectedChannels.begin(), expectedChannels.end(), *i);
74
75 BOOST_REQUIRE(pos != expectedChannels.end());
76 expectedChannels.erase(pos);
77 }
78
79 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
80}
81
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070082class FaceCreateFixture : protected BaseFixture
83{
84public:
85 void
86 ignore()
87 {
88 }
89
90 void
91 checkError(const std::string& errorActual, const std::string& errorExpected)
92 {
93 BOOST_CHECK_EQUAL(errorActual, errorExpected);
94 }
95
96 void
97 failIfError(const std::string& errorActual)
98 {
99 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
100 }
101};
102
103BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
104{
105 TcpFactory factory = TcpFactory();
106
107 factory.createFace(FaceUri("tcp4://127.0.0.1"),
108 bind(&FaceCreateFixture::ignore, this),
109 bind(&FaceCreateFixture::failIfError, this, _1));
110
111 factory.createFace(FaceUri("tcp4://127.0.0.1/"),
112 bind(&FaceCreateFixture::ignore, this),
113 bind(&FaceCreateFixture::failIfError, this, _1));
114
115 factory.createFace(FaceUri("tcp4://127.0.0.1/path"),
116 bind(&FaceCreateFixture::ignore, this),
117 bind(&FaceCreateFixture::checkError, this, _1, "Invalid URI"));
118
119}
120
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700121class EndToEndFixture : protected BaseFixture
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700122{
123public:
124 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800125 channel1_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700126 {
Junxiao Shi79494162014-04-02 18:25:11 -0700127 BOOST_CHECK(!static_cast<bool>(face1));
128 face1 = newFace;
129 face1->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700130 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700131 face1->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700132 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700133 face1->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800134 bind(&EndToEndFixture::face1_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700135
Junxiao Shi79494162014-04-02 18:25:11 -0700136 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700137 }
138
139 void
140 channel1_onConnectFailed(const std::string& reason)
141 {
142 BOOST_CHECK_MESSAGE(false, reason);
143
Junxiao Shi79494162014-04-02 18:25:11 -0700144 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700145 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800146
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700147 void
148 face1_onReceiveInterest(const Interest& interest)
149 {
Junxiao Shi79494162014-04-02 18:25:11 -0700150 face1_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700151
Junxiao Shi79494162014-04-02 18:25:11 -0700152 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700153 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800154
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700155 void
156 face1_onReceiveData(const Data& data)
157 {
Junxiao Shi79494162014-04-02 18:25:11 -0700158 face1_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700159
Junxiao Shi79494162014-04-02 18:25:11 -0700160 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700161 }
162
163 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800164 face1_onFail()
165 {
Junxiao Shi79494162014-04-02 18:25:11 -0700166 face1.reset();
167 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800168 }
169
170 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800171 channel2_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700172 {
Junxiao Shi79494162014-04-02 18:25:11 -0700173 BOOST_CHECK(!static_cast<bool>(face2));
174 face2 = newFace;
175 face2->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700176 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700177 face2->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700178 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700179 face2->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800180 bind(&EndToEndFixture::face2_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700181
Junxiao Shi79494162014-04-02 18:25:11 -0700182 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700183 }
184
185 void
186 channel2_onConnectFailed(const std::string& reason)
187 {
188 BOOST_CHECK_MESSAGE(false, reason);
189
Junxiao Shi79494162014-04-02 18:25:11 -0700190 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700191 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800192
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700193 void
194 face2_onReceiveInterest(const Interest& interest)
195 {
Junxiao Shi79494162014-04-02 18:25:11 -0700196 face2_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700197
Junxiao Shi79494162014-04-02 18:25:11 -0700198 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700199 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800200
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700201 void
202 face2_onReceiveData(const Data& data)
203 {
Junxiao Shi79494162014-04-02 18:25:11 -0700204 face2_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700205
Junxiao Shi79494162014-04-02 18:25:11 -0700206 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700207 }
208
209 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800210 face2_onFail()
211 {
Junxiao Shi79494162014-04-02 18:25:11 -0700212 face2.reset();
213 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800214 }
215
216 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800217 channel_onFaceCreated(const shared_ptr<Face>& newFace)
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800218 {
Junxiao Shi79494162014-04-02 18:25:11 -0700219 faces.push_back(newFace);
220 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800221 }
222
223 void
224 channel_onConnectFailed(const std::string& reason)
225 {
226 BOOST_CHECK_MESSAGE(false, reason);
227
Junxiao Shi79494162014-04-02 18:25:11 -0700228 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800229 }
230
231 void
232 checkFaceList(size_t shouldBe)
233 {
Junxiao Shi79494162014-04-02 18:25:11 -0700234 BOOST_CHECK_EQUAL(faces.size(), shouldBe);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800235 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800236
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200237 void
238 connect(const shared_ptr<TcpChannel>& channel,
239 const std::string& remoteHost,
240 const std::string& remotePort)
241 {
242 channel->connect(remoteHost, remotePort,
243 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
244 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
245 }
246
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700247public:
Junxiao Shi79494162014-04-02 18:25:11 -0700248 LimitedIo limitedIo;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700249
Junxiao Shi79494162014-04-02 18:25:11 -0700250 shared_ptr<Face> face1;
251 std::vector<Interest> face1_receivedInterests;
252 std::vector<Data> face1_receivedDatas;
253 shared_ptr<Face> face2;
254 std::vector<Interest> face2_receivedInterests;
255 std::vector<Data> face2_receivedDatas;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800256
Junxiao Shi79494162014-04-02 18:25:11 -0700257 std::list< shared_ptr<Face> > faces;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700258};
259
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000260BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700261{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600262 TcpFactory factory1;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700263
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600264 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
265 factory1.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800266
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700267 BOOST_CHECK_EQUAL(channel1->isListening(), false);
268
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700269 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
270 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800271
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700272 BOOST_CHECK_EQUAL(channel1->isListening(), true);
273
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600274 TcpFactory factory2;
275
276 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
277 factory2.createChannel("127.0.0.2", "20071");
278
279 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
280 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
281 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700282
Junxiao Shi79494162014-04-02 18:25:11 -0700283 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700284 "TcpChannel error: cannot connect or cannot accept connection");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700285
Junxiao Shi79494162014-04-02 18:25:11 -0700286 BOOST_REQUIRE(static_cast<bool>(face1));
287 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800288
Junxiao Shi79494162014-04-02 18:25:11 -0700289 BOOST_CHECK(face1->isOnDemand());
290 BOOST_CHECK(!face2->isOnDemand());
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700291
Junxiao Shi79494162014-04-02 18:25:11 -0700292 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp4://127.0.0.1:20070");
293 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp4://127.0.0.1:20070");
294 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000295
Junxiao Shi79494162014-04-02 18:25:11 -0700296 BOOST_CHECK_EQUAL(face1->isLocal(), true);
297 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000298
Junxiao Shi79494162014-04-02 18:25:11 -0700299 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
300 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000301
302 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
303
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700304 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
305 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
306 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
307 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000308
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700309 face1->sendInterest(*interest1);
310 face1->sendInterest(*interest1);
311 face1->sendInterest(*interest1);
312 face1->sendData (*data1 );
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700313 size_t nBytesSent1 = interest1->wireEncode().size() * 3 + data1->wireEncode().size();
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700314 face2->sendInterest(*interest2);
315 face2->sendData (*data2 );
316 face2->sendData (*data2 );
317 face2->sendData (*data2 );
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000318
Junxiao Shi79494162014-04-02 18:25:11 -0700319 BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000320 "TcpChannel error: cannot send or receive Interest/Data packets");
321
Junxiao Shi79494162014-04-02 18:25:11 -0700322 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
323 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
324 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
325 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000326
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700327 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
328 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
329 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
330 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000331
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700332 // needed to ensure NOutBytes counters are accurate
333 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1));
334
Junxiao Shi79494162014-04-02 18:25:11 -0700335 const FaceCounters& counters1 = face1->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700336 BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
337 BOOST_CHECK_EQUAL(counters1.getNInDatas() , 3);
338 BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
339 BOOST_CHECK_EQUAL(counters1.getNOutDatas() , 1);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700340 BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000341
Junxiao Shi79494162014-04-02 18:25:11 -0700342 const FaceCounters& counters2 = face2->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700343 BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
344 BOOST_CHECK_EQUAL(counters2.getNInDatas() , 1);
345 BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
346 BOOST_CHECK_EQUAL(counters2.getNOutDatas() , 3);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700347 BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000348}
349
350BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
351{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600352 TcpFactory factory1;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000353
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600354 shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
355 shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000356
357 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
358 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
359
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600360 TcpFactory factory2;
361
362 factory2.createChannel("::2", "20070");
363
364 factory2.createFace(FaceUri("tcp://[::1]:20070"),
365 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
366 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000367
Junxiao Shi79494162014-04-02 18:25:11 -0700368 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000369 "TcpChannel error: cannot connect or cannot accept connection");
370
Junxiao Shi79494162014-04-02 18:25:11 -0700371 BOOST_REQUIRE(static_cast<bool>(face1));
372 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000373
Junxiao Shi79494162014-04-02 18:25:11 -0700374 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp6://[::1]:20070");
375 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp6://[::1]:20070");
376 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000377
Junxiao Shi79494162014-04-02 18:25:11 -0700378 BOOST_CHECK_EQUAL(face1->isLocal(), true);
379 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800380
Junxiao Shi79494162014-04-02 18:25:11 -0700381 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
382 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800383
384 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800385
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700386 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
387 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
388 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
389 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700390
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700391 face1->sendInterest(*interest1);
392 face1->sendData (*data1 );
393 face2->sendInterest(*interest2);
394 face2->sendData (*data2 );
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700395
Junxiao Shi79494162014-04-02 18:25:11 -0700396 BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700397 "TcpChannel error: cannot send or receive Interest/Data packets");
398
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700399
Junxiao Shi79494162014-04-02 18:25:11 -0700400 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
401 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
402 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
403 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800404
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700405 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
406 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
407 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
408 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700409}
410
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800411BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
412{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800413 TcpFactory factory;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800414
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800415 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
416 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800417
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800418 channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
419 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800420
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800421 channel2->connect("127.0.0.1", "20070",
422 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
423 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800424 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800425
Junxiao Shi79494162014-04-02 18:25:11 -0700426 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700427 "TcpChannel error: cannot connect or cannot accept connection");
428
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800429
Junxiao Shi79494162014-04-02 18:25:11 -0700430 BOOST_CHECK_EQUAL(faces.size(), 2);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800431
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800432 shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800433 channel3->connect("127.0.0.1", "20070",
434 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
435 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800436 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800437
438
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800439 shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800440
441 BOOST_CHECK_NE(channel3, channel4);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800442
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700443 scheduler::schedule(time::seconds(1),
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200444 bind(&EndToEndFixture::connect, this, channel4, "127.0.0.1", "20070"));
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800445
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700446 scheduler::schedule(time::milliseconds(500),
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800447 bind(&EndToEndFixture::checkFaceList, this, 4));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800448
Junxiao Shi79494162014-04-02 18:25:11 -0700449 BOOST_CHECK_MESSAGE(limitedIo.run(4,// 2 connects and 2 accepts
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700450 time::seconds(10)) == LimitedIo::EXCEED_OPS,
451 "TcpChannel error: cannot connect or cannot accept multiple connections");
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800452
Junxiao Shi79494162014-04-02 18:25:11 -0700453 BOOST_CHECK_EQUAL(faces.size(), 6);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800454}
455
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800456
457BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
458{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800459 TcpFactory factory;
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800460
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800461 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
462 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800463
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800464 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
465 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800466
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800467 channel2->connect("127.0.0.1", "20070",
468 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
469 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800470 time::seconds(4)); // very short timeout
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800471
Junxiao Shi79494162014-04-02 18:25:11 -0700472 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700473 "TcpChannel error: cannot connect or cannot accept connection");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800474
475 BOOST_CHECK_EQUAL(channel1->size(), 1);
476 BOOST_CHECK_EQUAL(channel2->size(), 1);
477
Junxiao Shi79494162014-04-02 18:25:11 -0700478 BOOST_REQUIRE(static_cast<bool>(face1));
479 BOOST_CHECK(static_cast<bool>(face2));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800480
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700481 // Face::close must be invoked during io run to be counted as an op
Junxiao Shi79494162014-04-02 18:25:11 -0700482 scheduler::schedule(time::milliseconds(100), bind(&Face::close, face1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800483
Junxiao Shi79494162014-04-02 18:25:11 -0700484 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700485 "FaceClosing error: cannot properly close faces");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800486
487 // both faces should get closed
Junxiao Shi79494162014-04-02 18:25:11 -0700488 BOOST_CHECK(!static_cast<bool>(face1));
489 BOOST_CHECK(!static_cast<bool>(face2));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800490
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800491 BOOST_CHECK_EQUAL(channel1->size(), 0);
492 BOOST_CHECK_EQUAL(channel2->size(), 0);
493}
494
495
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700496
497
498class SimpleEndToEndFixture : protected BaseFixture
499{
500public:
501 void
502 onFaceCreated(const shared_ptr<Face>& face)
503 {
504 face->onReceiveInterest +=
505 bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1);
506 face->onReceiveData +=
507 bind(&SimpleEndToEndFixture::onReceiveData, this, _1);
508 face->onFail +=
509 bind(&SimpleEndToEndFixture::onFail, this, face);
510
511 if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
512 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
513 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
514
515 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
516 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
517 }
518
519 limitedIo.afterOp();
520 }
521
522 void
523 onConnectFailed(const std::string& reason)
524 {
525 BOOST_CHECK_MESSAGE(false, reason);
526
527 limitedIo.afterOp();
528 }
529
530 void
531 onReceiveInterest(const Interest& interest)
532 {
533 receivedInterests.push_back(interest);
534
535 limitedIo.afterOp();
536 }
537
538 void
539 onReceiveData(const Data& data)
540 {
541 receivedDatas.push_back(data);
542
543 limitedIo.afterOp();
544 }
545
546 void
547 onFail(const shared_ptr<Face>& face)
548 {
549 limitedIo.afterOp();
550 }
551
552public:
553 LimitedIo limitedIo;
554
555 std::vector<Interest> receivedInterests;
556 std::vector<Data> receivedDatas;
557};
558
559
560BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalFaceCorruptedInput, Dataset,
561 CorruptedPackets, SimpleEndToEndFixture)
562{
563 TcpFactory factory;
564
565 shared_ptr<TcpChannel> channel = factory.createChannel("127.0.0.1", "20070");
566 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
567 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
568 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
569
570 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
571 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve("127.0.0.1", "20070"));
572
573 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
574 time::seconds(1)) == LimitedIo::EXCEED_TIME,
575 "Exception thrown for " + Dataset::getName());
576}
577
578BOOST_FIXTURE_TEST_CASE_TEMPLATE(FaceCorruptedInput, Dataset,
579 CorruptedPackets, SimpleEndToEndFixture)
580{
581 // tests with non-local Face
582 std::string someIpv4Address;
583 std::list< shared_ptr<NetworkInterfaceInfo> > ifs = listNetworkInterfaces();
584 for (std::list< shared_ptr<NetworkInterfaceInfo> >::const_iterator i = ifs.begin();
585 i != ifs.end();
586 ++i)
587 {
588 if (!(*i)->isLoopback() && (*i)->isUp() && !(*i)->ipv4Addresses.empty())
589 {
590 someIpv4Address = (*i)->ipv4Addresses[0].to_string();
591 break;
592 }
593 }
594 if (someIpv4Address.empty())
595 {
596 BOOST_TEST_MESSAGE("Test with non-local Face cannot be run "
597 "(no non-local interface with IPv4 address available)");
598 return;
599 }
600
601 TcpFactory factory;
602
603 shared_ptr<TcpChannel> channel = factory.createChannel(someIpv4Address, "20070");
604 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
605 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
606 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
607
608
609 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
610 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve(someIpv4Address, "20070"));
611
612 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
613 time::seconds(1)) == LimitedIo::EXCEED_TIME,
614 "Exception thrown for " + Dataset::getName());
615}
616
Alexander Afanasyev18861802014-06-13 17:49:03 -0700617class FaceCreateTimeoutFixture : protected BaseFixture
618{
619public:
620 void
621 onFaceCreated(const shared_ptr<Face>& newFace)
622 {
623 BOOST_CHECK_MESSAGE(false, "Timeout expected");
624 BOOST_CHECK(!static_cast<bool>(face1));
625 face1 = newFace;
626
627 limitedIo.afterOp();
628 }
629
630 void
631 onConnectFailed(const std::string& reason)
632 {
633 BOOST_CHECK_MESSAGE(true, reason);
634
635 limitedIo.afterOp();
636 }
637
638public:
639 LimitedIo limitedIo;
640
641 shared_ptr<Face> face1;
642};
643
Alexander Afanasyev18861802014-06-13 17:49:03 -0700644BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
645{
646 TcpFactory factory;
647 shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
648
649 factory.createFace(FaceUri("tcp://192.0.2.1:20070"),
650 bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
651 bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
652
653 BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(10)) == LimitedIo::EXCEED_OPS,
654 "TcpChannel error: cannot connect or cannot accept connection");
655
656 BOOST_CHECK_EQUAL(static_cast<bool>(face1), false);
657}
658
Davide Pesavento3f5655f2014-08-30 21:38:59 +0200659BOOST_FIXTURE_TEST_CASE(Bug1856, EndToEndFixture)
660{
661 TcpFactory factory1;
662
663 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
664 factory1.createChannel("127.0.0.1", "20071");
665
666 BOOST_CHECK_EQUAL(channel1->isListening(), false);
667
668 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
669 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
670
671 BOOST_CHECK_EQUAL(channel1->isListening(), true);
672
673 TcpFactory factory2;
674
675 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
676 factory2.createChannel("127.0.0.2", "20071");
677
678 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
679 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
680 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
681
682 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
683 "TcpChannel error: cannot connect or cannot accept connection");
684
685 BOOST_REQUIRE(static_cast<bool>(face1));
686 BOOST_REQUIRE(static_cast<bool>(face2));
687
688 std::ostringstream hugeName;
689 hugeName << "/huge-name/";
690 for (size_t i = 0; i < MAX_NDN_PACKET_SIZE; i++)
691 hugeName << 'a';
692
693 shared_ptr<Interest> interest = makeInterest("ndn:/KfczhUqVix");
694 shared_ptr<Interest> hugeInterest = makeInterest(hugeName.str());
695
696 face1->sendInterest(*hugeInterest);
697 face2->sendInterest(*interest);
698 face2->sendInterest(*interest);
699
700 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1));
701 BOOST_TEST_MESSAGE("Unexpected assertion test passed");
702}
Alexander Afanasyev18861802014-06-13 17:49:03 -0700703
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700704BOOST_AUTO_TEST_SUITE_END()
705
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700706} // namespace tests
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700707} // namespace nfd