blob: fa527e91b7c043fe98fac0918247995e5b75c5e2 [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
Junxiao Shid9ee45c2014-02-27 15:38:11 -070082class EndToEndFixture : protected BaseFixture
Junxiao Shi96dc0c42014-01-30 23:51:59 -070083{
84public:
85 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080086 channel1_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070087 {
Junxiao Shi79494162014-04-02 18:25:11 -070088 BOOST_CHECK(!static_cast<bool>(face1));
89 face1 = newFace;
90 face1->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -070091 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -070092 face1->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -070093 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -070094 face1->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080095 bind(&EndToEndFixture::face1_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070096
Junxiao Shi79494162014-04-02 18:25:11 -070097 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070098 }
99
100 void
101 channel1_onConnectFailed(const std::string& reason)
102 {
103 BOOST_CHECK_MESSAGE(false, reason);
104
Junxiao Shi79494162014-04-02 18:25:11 -0700105 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700106 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800107
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700108 void
109 face1_onReceiveInterest(const Interest& interest)
110 {
Junxiao Shi79494162014-04-02 18:25:11 -0700111 face1_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700112
Junxiao Shi79494162014-04-02 18:25:11 -0700113 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700114 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800115
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700116 void
117 face1_onReceiveData(const Data& data)
118 {
Junxiao Shi79494162014-04-02 18:25:11 -0700119 face1_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700120
Junxiao Shi79494162014-04-02 18:25:11 -0700121 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700122 }
123
124 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800125 face1_onFail()
126 {
Junxiao Shi79494162014-04-02 18:25:11 -0700127 face1.reset();
128 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800129 }
130
131 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800132 channel2_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700133 {
Junxiao Shi79494162014-04-02 18:25:11 -0700134 BOOST_CHECK(!static_cast<bool>(face2));
135 face2 = newFace;
136 face2->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700137 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700138 face2->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700139 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700140 face2->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800141 bind(&EndToEndFixture::face2_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700142
Junxiao Shi79494162014-04-02 18:25:11 -0700143 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700144 }
145
146 void
147 channel2_onConnectFailed(const std::string& reason)
148 {
149 BOOST_CHECK_MESSAGE(false, reason);
150
Junxiao Shi79494162014-04-02 18:25:11 -0700151 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700152 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800153
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700154 void
155 face2_onReceiveInterest(const Interest& interest)
156 {
Junxiao Shi79494162014-04-02 18:25:11 -0700157 face2_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700158
Junxiao Shi79494162014-04-02 18:25:11 -0700159 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700160 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800161
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700162 void
163 face2_onReceiveData(const Data& data)
164 {
Junxiao Shi79494162014-04-02 18:25:11 -0700165 face2_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700166
Junxiao Shi79494162014-04-02 18:25:11 -0700167 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700168 }
169
170 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800171 face2_onFail()
172 {
Junxiao Shi79494162014-04-02 18:25:11 -0700173 face2.reset();
174 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800175 }
176
177 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800178 channel_onFaceCreated(const shared_ptr<Face>& newFace)
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800179 {
Junxiao Shi79494162014-04-02 18:25:11 -0700180 faces.push_back(newFace);
181 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800182 }
183
184 void
185 channel_onConnectFailed(const std::string& reason)
186 {
187 BOOST_CHECK_MESSAGE(false, reason);
188
Junxiao Shi79494162014-04-02 18:25:11 -0700189 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800190 }
191
192 void
193 checkFaceList(size_t shouldBe)
194 {
Junxiao Shi79494162014-04-02 18:25:11 -0700195 BOOST_CHECK_EQUAL(faces.size(), shouldBe);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800196 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800197
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700198public:
Junxiao Shi79494162014-04-02 18:25:11 -0700199 LimitedIo limitedIo;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700200
Junxiao Shi79494162014-04-02 18:25:11 -0700201 shared_ptr<Face> face1;
202 std::vector<Interest> face1_receivedInterests;
203 std::vector<Data> face1_receivedDatas;
204 shared_ptr<Face> face2;
205 std::vector<Interest> face2_receivedInterests;
206 std::vector<Data> face2_receivedDatas;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800207
Junxiao Shi79494162014-04-02 18:25:11 -0700208 std::list< shared_ptr<Face> > faces;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700209};
210
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000211BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700212{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600213 TcpFactory factory1;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700214
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600215 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
216 factory1.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800217
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700218 BOOST_CHECK_EQUAL(channel1->isListening(), false);
219
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700220 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
221 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800222
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700223 BOOST_CHECK_EQUAL(channel1->isListening(), true);
224
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600225 TcpFactory factory2;
226
227 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
228 factory2.createChannel("127.0.0.2", "20071");
229
230 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
231 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
232 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700233
Junxiao Shi79494162014-04-02 18:25:11 -0700234 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700235 "TcpChannel error: cannot connect or cannot accept connection");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700236
Junxiao Shi79494162014-04-02 18:25:11 -0700237 BOOST_REQUIRE(static_cast<bool>(face1));
238 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800239
Junxiao Shi79494162014-04-02 18:25:11 -0700240 BOOST_CHECK(face1->isOnDemand());
241 BOOST_CHECK(!face2->isOnDemand());
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700242
Junxiao Shi79494162014-04-02 18:25:11 -0700243 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp4://127.0.0.1:20070");
244 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp4://127.0.0.1:20070");
245 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000246
Junxiao Shi79494162014-04-02 18:25:11 -0700247 BOOST_CHECK_EQUAL(face1->isLocal(), true);
248 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000249
Junxiao Shi79494162014-04-02 18:25:11 -0700250 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
251 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000252
253 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
254
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700255 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
256 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
257 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
258 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000259
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700260 face1->sendInterest(*interest1);
261 face1->sendInterest(*interest1);
262 face1->sendInterest(*interest1);
263 face1->sendData (*data1 );
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700264 size_t nBytesSent1 = interest1->wireEncode().size() * 3 + data1->wireEncode().size();
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700265 face2->sendInterest(*interest2);
266 face2->sendData (*data2 );
267 face2->sendData (*data2 );
268 face2->sendData (*data2 );
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000269
Junxiao Shi79494162014-04-02 18:25:11 -0700270 BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000271 "TcpChannel error: cannot send or receive Interest/Data packets");
272
Junxiao Shi79494162014-04-02 18:25:11 -0700273 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
274 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
275 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
276 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000277
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700278 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
279 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
280 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
281 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000282
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700283 // needed to ensure NOutBytes counters are accurate
284 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1));
285
Junxiao Shi79494162014-04-02 18:25:11 -0700286 const FaceCounters& counters1 = face1->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700287 BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
288 BOOST_CHECK_EQUAL(counters1.getNInDatas() , 3);
289 BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
290 BOOST_CHECK_EQUAL(counters1.getNOutDatas() , 1);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700291 BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000292
Junxiao Shi79494162014-04-02 18:25:11 -0700293 const FaceCounters& counters2 = face2->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700294 BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
295 BOOST_CHECK_EQUAL(counters2.getNInDatas() , 1);
296 BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
297 BOOST_CHECK_EQUAL(counters2.getNOutDatas() , 3);
Junxiao Shi5dd26c32014-07-20 23:15:14 -0700298 BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000299}
300
301BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
302{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600303 TcpFactory factory1;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000304
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600305 shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
306 shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000307
308 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
309 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
310
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600311 TcpFactory factory2;
312
313 factory2.createChannel("::2", "20070");
314
315 factory2.createFace(FaceUri("tcp://[::1]:20070"),
316 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
317 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000318
Junxiao Shi79494162014-04-02 18:25:11 -0700319 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000320 "TcpChannel error: cannot connect or cannot accept connection");
321
Junxiao Shi79494162014-04-02 18:25:11 -0700322 BOOST_REQUIRE(static_cast<bool>(face1));
323 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000324
Junxiao Shi79494162014-04-02 18:25:11 -0700325 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp6://[::1]:20070");
326 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp6://[::1]:20070");
327 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000328
Junxiao Shi79494162014-04-02 18:25:11 -0700329 BOOST_CHECK_EQUAL(face1->isLocal(), true);
330 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800331
Junxiao Shi79494162014-04-02 18:25:11 -0700332 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
333 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800334
335 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800336
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700337 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
338 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
339 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
340 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700341
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700342 face1->sendInterest(*interest1);
343 face1->sendData (*data1 );
344 face2->sendInterest(*interest2);
345 face2->sendData (*data2 );
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700346
Junxiao Shi79494162014-04-02 18:25:11 -0700347 BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700348 "TcpChannel error: cannot send or receive Interest/Data packets");
349
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700350
Junxiao Shi79494162014-04-02 18:25:11 -0700351 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
352 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
353 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
354 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800355
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700356 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
357 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
358 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
359 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700360}
361
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800362BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
363{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800364 TcpFactory factory;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800365
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800366 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
367 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800368
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800369 channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
370 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800371
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800372 channel2->connect("127.0.0.1", "20070",
373 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
374 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800375 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800376
Junxiao Shi79494162014-04-02 18:25:11 -0700377 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700378 "TcpChannel error: cannot connect or cannot accept connection");
379
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800380
Junxiao Shi79494162014-04-02 18:25:11 -0700381 BOOST_CHECK_EQUAL(faces.size(), 2);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800382
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800383 shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800384 channel3->connect("127.0.0.1", "20070",
385 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
386 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800387 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800388
389
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800390 shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800391
392 BOOST_CHECK_NE(channel3, channel4);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800393
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700394 scheduler::schedule(time::seconds(1),
395 bind(&TcpChannel::connect, channel4, "127.0.0.1", "20070",
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800396 // does not work without static_cast
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700397 static_cast<TcpChannel::FaceCreatedCallback>(
398 bind(&EndToEndFixture::channel_onFaceCreated, this, _1)),
399 static_cast<TcpChannel::ConnectFailedCallback>(
400 bind(&EndToEndFixture::channel_onConnectFailed, this, _1)),
401 time::seconds(4)));
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800402
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700403 scheduler::schedule(time::milliseconds(500),
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800404 bind(&EndToEndFixture::checkFaceList, this, 4));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800405
Junxiao Shi79494162014-04-02 18:25:11 -0700406 BOOST_CHECK_MESSAGE(limitedIo.run(4,// 2 connects and 2 accepts
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700407 time::seconds(10)) == LimitedIo::EXCEED_OPS,
408 "TcpChannel error: cannot connect or cannot accept multiple connections");
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800409
Junxiao Shi79494162014-04-02 18:25:11 -0700410 BOOST_CHECK_EQUAL(faces.size(), 6);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800411}
412
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800413
414BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
415{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800416 TcpFactory factory;
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800417
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800418 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
419 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800420
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800421 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
422 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800423
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800424 channel2->connect("127.0.0.1", "20070",
425 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
426 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800427 time::seconds(4)); // very short timeout
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800428
Junxiao Shi79494162014-04-02 18:25:11 -0700429 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700430 "TcpChannel error: cannot connect or cannot accept connection");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800431
432 BOOST_CHECK_EQUAL(channel1->size(), 1);
433 BOOST_CHECK_EQUAL(channel2->size(), 1);
434
Junxiao Shi79494162014-04-02 18:25:11 -0700435 BOOST_REQUIRE(static_cast<bool>(face1));
436 BOOST_CHECK(static_cast<bool>(face2));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800437
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700438 // Face::close must be invoked during io run to be counted as an op
Junxiao Shi79494162014-04-02 18:25:11 -0700439 scheduler::schedule(time::milliseconds(100), bind(&Face::close, face1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800440
Junxiao Shi79494162014-04-02 18:25:11 -0700441 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700442 "FaceClosing error: cannot properly close faces");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800443
444 // both faces should get closed
Junxiao Shi79494162014-04-02 18:25:11 -0700445 BOOST_CHECK(!static_cast<bool>(face1));
446 BOOST_CHECK(!static_cast<bool>(face2));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800447
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800448 BOOST_CHECK_EQUAL(channel1->size(), 0);
449 BOOST_CHECK_EQUAL(channel2->size(), 0);
450}
451
452
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700453
454
455class SimpleEndToEndFixture : protected BaseFixture
456{
457public:
458 void
459 onFaceCreated(const shared_ptr<Face>& face)
460 {
461 face->onReceiveInterest +=
462 bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1);
463 face->onReceiveData +=
464 bind(&SimpleEndToEndFixture::onReceiveData, this, _1);
465 face->onFail +=
466 bind(&SimpleEndToEndFixture::onFail, this, face);
467
468 if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
469 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
470 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
471
472 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
473 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
474 }
475
476 limitedIo.afterOp();
477 }
478
479 void
480 onConnectFailed(const std::string& reason)
481 {
482 BOOST_CHECK_MESSAGE(false, reason);
483
484 limitedIo.afterOp();
485 }
486
487 void
488 onReceiveInterest(const Interest& interest)
489 {
490 receivedInterests.push_back(interest);
491
492 limitedIo.afterOp();
493 }
494
495 void
496 onReceiveData(const Data& data)
497 {
498 receivedDatas.push_back(data);
499
500 limitedIo.afterOp();
501 }
502
503 void
504 onFail(const shared_ptr<Face>& face)
505 {
506 limitedIo.afterOp();
507 }
508
509public:
510 LimitedIo limitedIo;
511
512 std::vector<Interest> receivedInterests;
513 std::vector<Data> receivedDatas;
514};
515
516
517BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalFaceCorruptedInput, Dataset,
518 CorruptedPackets, SimpleEndToEndFixture)
519{
520 TcpFactory factory;
521
522 shared_ptr<TcpChannel> channel = factory.createChannel("127.0.0.1", "20070");
523 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
524 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
525 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
526
527 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
528 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve("127.0.0.1", "20070"));
529
530 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
531 time::seconds(1)) == LimitedIo::EXCEED_TIME,
532 "Exception thrown for " + Dataset::getName());
533}
534
535BOOST_FIXTURE_TEST_CASE_TEMPLATE(FaceCorruptedInput, Dataset,
536 CorruptedPackets, SimpleEndToEndFixture)
537{
538 // tests with non-local Face
539 std::string someIpv4Address;
540 std::list< shared_ptr<NetworkInterfaceInfo> > ifs = listNetworkInterfaces();
541 for (std::list< shared_ptr<NetworkInterfaceInfo> >::const_iterator i = ifs.begin();
542 i != ifs.end();
543 ++i)
544 {
545 if (!(*i)->isLoopback() && (*i)->isUp() && !(*i)->ipv4Addresses.empty())
546 {
547 someIpv4Address = (*i)->ipv4Addresses[0].to_string();
548 break;
549 }
550 }
551 if (someIpv4Address.empty())
552 {
553 BOOST_TEST_MESSAGE("Test with non-local Face cannot be run "
554 "(no non-local interface with IPv4 address available)");
555 return;
556 }
557
558 TcpFactory factory;
559
560 shared_ptr<TcpChannel> channel = factory.createChannel(someIpv4Address, "20070");
561 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
562 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
563 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
564
565
566 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
567 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve(someIpv4Address, "20070"));
568
569 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
570 time::seconds(1)) == LimitedIo::EXCEED_TIME,
571 "Exception thrown for " + Dataset::getName());
572}
573
Alexander Afanasyev18861802014-06-13 17:49:03 -0700574class FaceCreateTimeoutFixture : protected BaseFixture
575{
576public:
577 void
578 onFaceCreated(const shared_ptr<Face>& newFace)
579 {
580 BOOST_CHECK_MESSAGE(false, "Timeout expected");
581 BOOST_CHECK(!static_cast<bool>(face1));
582 face1 = newFace;
583
584 limitedIo.afterOp();
585 }
586
587 void
588 onConnectFailed(const std::string& reason)
589 {
590 BOOST_CHECK_MESSAGE(true, reason);
591
592 limitedIo.afterOp();
593 }
594
595public:
596 LimitedIo limitedIo;
597
598 shared_ptr<Face> face1;
599};
600
601
602BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
603{
604 TcpFactory factory;
605 shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
606
607 factory.createFace(FaceUri("tcp://192.0.2.1:20070"),
608 bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
609 bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
610
611 BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(10)) == LimitedIo::EXCEED_OPS,
612 "TcpChannel error: cannot connect or cannot accept connection");
613
614 BOOST_CHECK_EQUAL(static_cast<bool>(face1), false);
615}
616
617
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700618BOOST_AUTO_TEST_SUITE_END()
619
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700620} // namespace tests
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700621} // namespace nfd