blob: 99c2d5b8fcb4d1a5ab812fceb07ce0f283601ff8 [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
Davide Pesaventob499a602014-11-18 22:36:56 +010063 std::vector<shared_ptr<const Channel>> expectedChannels;
Steve DiBenedettoef04f272014-06-04 14:28:31 -060064 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
Davide Pesaventob499a602014-11-18 22:36:56 +010068 for (const auto& ch : factory.getChannels()) {
69 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), ch);
70 BOOST_REQUIRE(pos != expectedChannels.end());
71 expectedChannels.erase(pos);
72 }
Steve DiBenedettoef04f272014-06-04 14:28:31 -060073 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
74}
75
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -070076class FaceCreateFixture : protected BaseFixture
77{
78public:
79 void
80 ignore()
81 {
82 }
83
84 void
85 checkError(const std::string& errorActual, const std::string& errorExpected)
86 {
87 BOOST_CHECK_EQUAL(errorActual, errorExpected);
88 }
89
90 void
91 failIfError(const std::string& errorActual)
92 {
93 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
94 }
95};
96
97BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
98{
99 TcpFactory factory = TcpFactory();
100
101 factory.createFace(FaceUri("tcp4://127.0.0.1"),
102 bind(&FaceCreateFixture::ignore, this),
103 bind(&FaceCreateFixture::failIfError, this, _1));
104
105 factory.createFace(FaceUri("tcp4://127.0.0.1/"),
106 bind(&FaceCreateFixture::ignore, this),
107 bind(&FaceCreateFixture::failIfError, this, _1));
108
109 factory.createFace(FaceUri("tcp4://127.0.0.1/path"),
110 bind(&FaceCreateFixture::ignore, this),
111 bind(&FaceCreateFixture::checkError, this, _1, "Invalid URI"));
Alexander Afanasyev86bc91a2014-08-28 22:29:16 -0700112}
113
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700114class EndToEndFixture : protected BaseFixture
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700115{
116public:
117 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800118 channel1_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700119 {
Junxiao Shi79494162014-04-02 18:25:11 -0700120 BOOST_CHECK(!static_cast<bool>(face1));
121 face1 = newFace;
122 face1->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700123 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700124 face1->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700125 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700126 face1->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800127 bind(&EndToEndFixture::face1_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700128
Junxiao Shi79494162014-04-02 18:25:11 -0700129 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700130 }
131
132 void
133 channel1_onConnectFailed(const std::string& reason)
134 {
135 BOOST_CHECK_MESSAGE(false, reason);
136
Junxiao Shi79494162014-04-02 18:25:11 -0700137 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700138 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800139
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700140 void
141 face1_onReceiveInterest(const Interest& interest)
142 {
Junxiao Shi79494162014-04-02 18:25:11 -0700143 face1_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700144
Junxiao Shi79494162014-04-02 18:25:11 -0700145 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700146 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800147
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700148 void
149 face1_onReceiveData(const Data& data)
150 {
Junxiao Shi79494162014-04-02 18:25:11 -0700151 face1_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700152
Junxiao Shi79494162014-04-02 18:25:11 -0700153 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700154 }
155
156 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800157 face1_onFail()
158 {
Junxiao Shi79494162014-04-02 18:25:11 -0700159 face1.reset();
160 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800161 }
162
163 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800164 channel2_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700165 {
Junxiao Shi79494162014-04-02 18:25:11 -0700166 BOOST_CHECK(!static_cast<bool>(face2));
167 face2 = newFace;
168 face2->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700169 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700170 face2->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700171 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700172 face2->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800173 bind(&EndToEndFixture::face2_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700174
Junxiao Shi79494162014-04-02 18:25:11 -0700175 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700176 }
177
178 void
179 channel2_onConnectFailed(const std::string& reason)
180 {
181 BOOST_CHECK_MESSAGE(false, reason);
182
Junxiao Shi79494162014-04-02 18:25:11 -0700183 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700184 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800185
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700186 void
187 face2_onReceiveInterest(const Interest& interest)
188 {
Junxiao Shi79494162014-04-02 18:25:11 -0700189 face2_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700190
Junxiao Shi79494162014-04-02 18:25:11 -0700191 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700192 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800193
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700194 void
195 face2_onReceiveData(const Data& data)
196 {
Junxiao Shi79494162014-04-02 18:25:11 -0700197 face2_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700198
Junxiao Shi79494162014-04-02 18:25:11 -0700199 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700200 }
201
202 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800203 face2_onFail()
204 {
Junxiao Shi79494162014-04-02 18:25:11 -0700205 face2.reset();
206 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800207 }
208
209 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800210 channel_onFaceCreated(const shared_ptr<Face>& newFace)
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800211 {
Junxiao Shi79494162014-04-02 18:25:11 -0700212 faces.push_back(newFace);
213 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800214 }
215
216 void
217 channel_onConnectFailed(const std::string& reason)
218 {
219 BOOST_CHECK_MESSAGE(false, reason);
220
Junxiao Shi79494162014-04-02 18:25:11 -0700221 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800222 }
223
224 void
225 checkFaceList(size_t shouldBe)
226 {
Junxiao Shi79494162014-04-02 18:25:11 -0700227 BOOST_CHECK_EQUAL(faces.size(), shouldBe);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800228 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800229
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200230 void
231 connect(const shared_ptr<TcpChannel>& channel,
232 const std::string& remoteHost,
233 const std::string& remotePort)
234 {
235 channel->connect(remoteHost, remotePort,
236 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
237 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
238 }
239
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700240public:
Junxiao Shi79494162014-04-02 18:25:11 -0700241 LimitedIo limitedIo;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700242
Junxiao Shi79494162014-04-02 18:25:11 -0700243 shared_ptr<Face> face1;
244 std::vector<Interest> face1_receivedInterests;
245 std::vector<Data> face1_receivedDatas;
246 shared_ptr<Face> face2;
247 std::vector<Interest> face2_receivedInterests;
248 std::vector<Data> face2_receivedDatas;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800249
Davide Pesaventob499a602014-11-18 22:36:56 +0100250 std::list<shared_ptr<Face>> faces;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700251};
252
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000253BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700254{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600255 TcpFactory factory1;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700256
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600257 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
258 factory1.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800259
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700260 BOOST_CHECK_EQUAL(channel1->isListening(), false);
261
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700262 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
263 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800264
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700265 BOOST_CHECK_EQUAL(channel1->isListening(), true);
266
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600267 TcpFactory factory2;
268
269 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
270 factory2.createChannel("127.0.0.2", "20071");
271
272 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
273 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
274 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700275
Junxiao Shi79494162014-04-02 18:25:11 -0700276 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700277 "TcpChannel error: cannot connect or cannot accept connection");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700278
Junxiao Shi79494162014-04-02 18:25:11 -0700279 BOOST_REQUIRE(static_cast<bool>(face1));
280 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800281
Junxiao Shi79494162014-04-02 18:25:11 -0700282 BOOST_CHECK(face1->isOnDemand());
283 BOOST_CHECK(!face2->isOnDemand());
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700284
Junxiao Shi79494162014-04-02 18:25:11 -0700285 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp4://127.0.0.1:20070");
286 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp4://127.0.0.1:20070");
287 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000288
Junxiao Shi79494162014-04-02 18:25:11 -0700289 BOOST_CHECK_EQUAL(face1->isLocal(), true);
290 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000291
Junxiao Shi79494162014-04-02 18:25:11 -0700292 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
293 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000294
295 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
296
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700297 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
298 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
299 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
300 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000301
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700302 face1->sendInterest(*interest1);
303 face1->sendInterest(*interest1);
304 face1->sendInterest(*interest1);
305 face1->sendData (*data1 );
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700306 size_t nBytesSent1 = interest1->wireEncode().size() * 3 + data1->wireEncode().size();
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700307 face2->sendInterest(*interest2);
308 face2->sendData (*data2 );
309 face2->sendData (*data2 );
310 face2->sendData (*data2 );
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000311
Junxiao Shi79494162014-04-02 18:25:11 -0700312 BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000313 "TcpChannel error: cannot send or receive Interest/Data packets");
314
Junxiao Shi79494162014-04-02 18:25:11 -0700315 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
316 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
317 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
318 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000319
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700320 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
321 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
322 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
323 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000324
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700325 // needed to ensure NOutBytes counters are accurate
326 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1));
327
Junxiao Shi79494162014-04-02 18:25:11 -0700328 const FaceCounters& counters1 = face1->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700329 BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
330 BOOST_CHECK_EQUAL(counters1.getNInDatas() , 3);
331 BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
332 BOOST_CHECK_EQUAL(counters1.getNOutDatas() , 1);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700333 BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000334
Junxiao Shi79494162014-04-02 18:25:11 -0700335 const FaceCounters& counters2 = face2->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700336 BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
337 BOOST_CHECK_EQUAL(counters2.getNInDatas() , 1);
338 BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
339 BOOST_CHECK_EQUAL(counters2.getNOutDatas() , 3);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700340 BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000341}
342
343BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
344{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600345 TcpFactory factory1;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000346
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600347 shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
348 shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000349
350 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
351 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
352
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600353 TcpFactory factory2;
354
355 factory2.createChannel("::2", "20070");
356
357 factory2.createFace(FaceUri("tcp://[::1]:20070"),
358 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
359 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000360
Junxiao Shi79494162014-04-02 18:25:11 -0700361 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000362 "TcpChannel error: cannot connect or cannot accept connection");
363
Junxiao Shi79494162014-04-02 18:25:11 -0700364 BOOST_REQUIRE(static_cast<bool>(face1));
365 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000366
Junxiao Shi79494162014-04-02 18:25:11 -0700367 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp6://[::1]:20070");
368 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp6://[::1]:20070");
369 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000370
Junxiao Shi79494162014-04-02 18:25:11 -0700371 BOOST_CHECK_EQUAL(face1->isLocal(), true);
372 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800373
Junxiao Shi79494162014-04-02 18:25:11 -0700374 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
375 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800376
377 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800378
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700379 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
380 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
381 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
382 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700383
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700384 face1->sendInterest(*interest1);
385 face1->sendData (*data1 );
386 face2->sendInterest(*interest2);
387 face2->sendData (*data2 );
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700388
Junxiao Shi79494162014-04-02 18:25:11 -0700389 BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700390 "TcpChannel error: cannot send or receive Interest/Data packets");
391
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700392
Junxiao Shi79494162014-04-02 18:25:11 -0700393 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
394 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
395 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
396 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800397
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700398 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
399 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
400 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
401 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700402}
403
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800404BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
405{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800406 TcpFactory factory;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800407
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800408 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
409 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800410
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800411 channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
412 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800413
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800414 channel2->connect("127.0.0.1", "20070",
415 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
416 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800417 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800418
Junxiao Shi79494162014-04-02 18:25:11 -0700419 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700420 "TcpChannel error: cannot connect or cannot accept connection");
421
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800422
Junxiao Shi79494162014-04-02 18:25:11 -0700423 BOOST_CHECK_EQUAL(faces.size(), 2);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800424
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800425 shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800426 channel3->connect("127.0.0.1", "20070",
427 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
428 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800429 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800430
431
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800432 shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800433
434 BOOST_CHECK_NE(channel3, channel4);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800435
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700436 scheduler::schedule(time::seconds(1),
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200437 bind(&EndToEndFixture::connect, this, channel4, "127.0.0.1", "20070"));
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800438
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700439 scheduler::schedule(time::milliseconds(500),
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800440 bind(&EndToEndFixture::checkFaceList, this, 4));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800441
Junxiao Shi79494162014-04-02 18:25:11 -0700442 BOOST_CHECK_MESSAGE(limitedIo.run(4,// 2 connects and 2 accepts
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700443 time::seconds(10)) == LimitedIo::EXCEED_OPS,
444 "TcpChannel error: cannot connect or cannot accept multiple connections");
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800445
Junxiao Shi79494162014-04-02 18:25:11 -0700446 BOOST_CHECK_EQUAL(faces.size(), 6);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800447}
448
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800449
450BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
451{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800452 TcpFactory factory;
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800453
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800454 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
455 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800456
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800457 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
458 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800459
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800460 channel2->connect("127.0.0.1", "20070",
461 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
462 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800463 time::seconds(4)); // very short timeout
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800464
Junxiao Shi79494162014-04-02 18:25:11 -0700465 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700466 "TcpChannel error: cannot connect or cannot accept connection");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800467
468 BOOST_CHECK_EQUAL(channel1->size(), 1);
469 BOOST_CHECK_EQUAL(channel2->size(), 1);
470
Junxiao Shi79494162014-04-02 18:25:11 -0700471 BOOST_REQUIRE(static_cast<bool>(face1));
472 BOOST_CHECK(static_cast<bool>(face2));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800473
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700474 // Face::close must be invoked during io run to be counted as an op
Junxiao Shi79494162014-04-02 18:25:11 -0700475 scheduler::schedule(time::milliseconds(100), bind(&Face::close, face1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800476
Junxiao Shi79494162014-04-02 18:25:11 -0700477 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700478 "FaceClosing error: cannot properly close faces");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800479
480 // both faces should get closed
Junxiao Shi79494162014-04-02 18:25:11 -0700481 BOOST_CHECK(!static_cast<bool>(face1));
482 BOOST_CHECK(!static_cast<bool>(face2));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800483
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800484 BOOST_CHECK_EQUAL(channel1->size(), 0);
485 BOOST_CHECK_EQUAL(channel2->size(), 0);
486}
487
488
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700489class SimpleEndToEndFixture : protected BaseFixture
490{
491public:
492 void
493 onFaceCreated(const shared_ptr<Face>& face)
494 {
495 face->onReceiveInterest +=
496 bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1);
497 face->onReceiveData +=
498 bind(&SimpleEndToEndFixture::onReceiveData, this, _1);
499 face->onFail +=
500 bind(&SimpleEndToEndFixture::onFail, this, face);
501
502 if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
503 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
504 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
505
506 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
507 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
508 }
509
510 limitedIo.afterOp();
511 }
512
513 void
514 onConnectFailed(const std::string& reason)
515 {
516 BOOST_CHECK_MESSAGE(false, reason);
517
518 limitedIo.afterOp();
519 }
520
521 void
522 onReceiveInterest(const Interest& interest)
523 {
524 receivedInterests.push_back(interest);
525
526 limitedIo.afterOp();
527 }
528
529 void
530 onReceiveData(const Data& data)
531 {
532 receivedDatas.push_back(data);
533
534 limitedIo.afterOp();
535 }
536
537 void
538 onFail(const shared_ptr<Face>& face)
539 {
540 limitedIo.afterOp();
541 }
542
543public:
544 LimitedIo limitedIo;
545
546 std::vector<Interest> receivedInterests;
547 std::vector<Data> receivedDatas;
548};
549
550
551BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalFaceCorruptedInput, Dataset,
552 CorruptedPackets, SimpleEndToEndFixture)
553{
554 TcpFactory factory;
555
556 shared_ptr<TcpChannel> channel = factory.createChannel("127.0.0.1", "20070");
557 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
558 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
559 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
560
561 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
562 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve("127.0.0.1", "20070"));
563
564 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
565 time::seconds(1)) == LimitedIo::EXCEED_TIME,
566 "Exception thrown for " + Dataset::getName());
567}
568
569BOOST_FIXTURE_TEST_CASE_TEMPLATE(FaceCorruptedInput, Dataset,
570 CorruptedPackets, SimpleEndToEndFixture)
571{
572 // tests with non-local Face
573 std::string someIpv4Address;
Davide Pesaventob499a602014-11-18 22:36:56 +0100574 for (const auto& netif : listNetworkInterfaces()) {
575 if (!netif.isLoopback() && netif.isUp() && !netif.ipv4Addresses.empty()) {
576 someIpv4Address = netif.ipv4Addresses[0].to_string();
577 break;
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700578 }
Davide Pesaventob499a602014-11-18 22:36:56 +0100579 }
580 if (someIpv4Address.empty()) {
581 BOOST_TEST_MESSAGE("Test with non-local Face cannot be run "
582 "(no non-local interface with IPv4 address available)");
583 return;
584 }
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700585
586 TcpFactory factory;
587
588 shared_ptr<TcpChannel> channel = factory.createChannel(someIpv4Address, "20070");
589 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
590 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
591 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
592
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700593 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
594 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve(someIpv4Address, "20070"));
595
596 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
597 time::seconds(1)) == LimitedIo::EXCEED_TIME,
598 "Exception thrown for " + Dataset::getName());
599}
600
Alexander Afanasyev18861802014-06-13 17:49:03 -0700601class FaceCreateTimeoutFixture : protected BaseFixture
602{
603public:
604 void
605 onFaceCreated(const shared_ptr<Face>& newFace)
606 {
607 BOOST_CHECK_MESSAGE(false, "Timeout expected");
608 BOOST_CHECK(!static_cast<bool>(face1));
609 face1 = newFace;
610
611 limitedIo.afterOp();
612 }
613
614 void
615 onConnectFailed(const std::string& reason)
616 {
617 BOOST_CHECK_MESSAGE(true, reason);
618
619 limitedIo.afterOp();
620 }
621
622public:
623 LimitedIo limitedIo;
624
625 shared_ptr<Face> face1;
626};
627
Alexander Afanasyev18861802014-06-13 17:49:03 -0700628BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
629{
630 TcpFactory factory;
631 shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
632
633 factory.createFace(FaceUri("tcp://192.0.2.1:20070"),
634 bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
635 bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
636
637 BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(10)) == LimitedIo::EXCEED_OPS,
638 "TcpChannel error: cannot connect or cannot accept connection");
639
640 BOOST_CHECK_EQUAL(static_cast<bool>(face1), false);
641}
642
Davide Pesavento3f5655f2014-08-30 21:38:59 +0200643BOOST_FIXTURE_TEST_CASE(Bug1856, EndToEndFixture)
644{
645 TcpFactory factory1;
646
647 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
648 factory1.createChannel("127.0.0.1", "20071");
649
650 BOOST_CHECK_EQUAL(channel1->isListening(), false);
651
652 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
653 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
654
655 BOOST_CHECK_EQUAL(channel1->isListening(), true);
656
657 TcpFactory factory2;
658
659 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
660 factory2.createChannel("127.0.0.2", "20071");
661
662 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
663 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
664 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
665
666 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
667 "TcpChannel error: cannot connect or cannot accept connection");
668
669 BOOST_REQUIRE(static_cast<bool>(face1));
670 BOOST_REQUIRE(static_cast<bool>(face2));
671
672 std::ostringstream hugeName;
673 hugeName << "/huge-name/";
Junxiao Shi39cd6332014-11-06 21:53:18 -0700674 for (size_t i = 0; i < ndn::MAX_NDN_PACKET_SIZE; i++)
Davide Pesavento3f5655f2014-08-30 21:38:59 +0200675 hugeName << 'a';
676
677 shared_ptr<Interest> interest = makeInterest("ndn:/KfczhUqVix");
678 shared_ptr<Interest> hugeInterest = makeInterest(hugeName.str());
679
680 face1->sendInterest(*hugeInterest);
681 face2->sendInterest(*interest);
682 face2->sendInterest(*interest);
683
684 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1));
685 BOOST_TEST_MESSAGE("Unexpected assertion test passed");
686}
Alexander Afanasyev18861802014-06-13 17:49:03 -0700687
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700688BOOST_AUTO_TEST_SUITE_END()
689
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700690} // namespace tests
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700691} // namespace nfd