blob: 166f25740b4dbe061b56eadb683804811c3e4b21 [file] [log] [blame]
Junxiao Shi96dc0c42014-01-30 23:51:59 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Junxiao Shi96dc0c42014-01-30 23:51:59 -070024
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080025#include "face/tcp-factory.hpp"
Alexander Afanasyev650028d2014-04-25 18:39:10 -070026#include "core/resolver.hpp"
27#include "core/network-interface.hpp"
Alexander Afanasyev4a771362014-04-24 21:29:33 -070028#include <ndn-cxx/security/key-chain.hpp>
Junxiao Shi96dc0c42014-01-30 23:51:59 -070029
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070031#include "tests/limited-io.hpp"
Alexander Afanasyev650028d2014-04-25 18:39:10 -070032#include "dummy-stream-sender.hpp"
33#include "packet-datasets.hpp"
Junxiao Shi96dc0c42014-01-30 23:51:59 -070034
35namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036namespace tests {
Junxiao Shi96dc0c42014-01-30 23:51:59 -070037
Junxiao Shid9ee45c2014-02-27 15:38:11 -070038BOOST_FIXTURE_TEST_SUITE(FaceTcp, BaseFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070039
40BOOST_AUTO_TEST_CASE(ChannelMap)
41{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080042 TcpFactory factory;
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080043
Alexander Afanasyevd6655302014-02-28 08:41:28 -080044 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
45 shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070046 BOOST_CHECK_EQUAL(channel1, channel1a);
Junxiao Shi61e3cc52014-03-03 20:40:28 -070047 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080048
Alexander Afanasyevd6655302014-02-28 08:41:28 -080049 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070050 BOOST_CHECK_NE(channel1, channel2);
Junxiao Shi61e3cc52014-03-03 20:40:28 -070051
52 shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
53 BOOST_CHECK_NE(channel2, channel3);
54 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070055}
56
Junxiao Shid9ee45c2014-02-27 15:38:11 -070057class EndToEndFixture : protected BaseFixture
Junxiao Shi96dc0c42014-01-30 23:51:59 -070058{
59public:
60 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080061 channel1_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070062 {
Junxiao Shi79494162014-04-02 18:25:11 -070063 BOOST_CHECK(!static_cast<bool>(face1));
64 face1 = newFace;
65 face1->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -070066 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -070067 face1->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -070068 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -070069 face1->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080070 bind(&EndToEndFixture::face1_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070071
Junxiao Shi79494162014-04-02 18:25:11 -070072 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070073 }
74
75 void
76 channel1_onConnectFailed(const std::string& reason)
77 {
78 BOOST_CHECK_MESSAGE(false, reason);
79
Junxiao Shi79494162014-04-02 18:25:11 -070080 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070081 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080082
Junxiao Shi96dc0c42014-01-30 23:51:59 -070083 void
84 face1_onReceiveInterest(const Interest& interest)
85 {
Junxiao Shi79494162014-04-02 18:25:11 -070086 face1_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070087
Junxiao Shi79494162014-04-02 18:25:11 -070088 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070089 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080090
Junxiao Shi96dc0c42014-01-30 23:51:59 -070091 void
92 face1_onReceiveData(const Data& data)
93 {
Junxiao Shi79494162014-04-02 18:25:11 -070094 face1_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070095
Junxiao Shi79494162014-04-02 18:25:11 -070096 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070097 }
98
99 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800100 face1_onFail()
101 {
Junxiao Shi79494162014-04-02 18:25:11 -0700102 face1.reset();
103 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800104 }
105
106 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800107 channel2_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700108 {
Junxiao Shi79494162014-04-02 18:25:11 -0700109 BOOST_CHECK(!static_cast<bool>(face2));
110 face2 = newFace;
111 face2->onReceiveInterest +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700112 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700113 face2->onReceiveData +=
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700114 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
Junxiao Shi79494162014-04-02 18:25:11 -0700115 face2->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800116 bind(&EndToEndFixture::face2_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700117
Junxiao Shi79494162014-04-02 18:25:11 -0700118 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700119 }
120
121 void
122 channel2_onConnectFailed(const std::string& reason)
123 {
124 BOOST_CHECK_MESSAGE(false, reason);
125
Junxiao Shi79494162014-04-02 18:25:11 -0700126 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700127 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800128
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700129 void
130 face2_onReceiveInterest(const Interest& interest)
131 {
Junxiao Shi79494162014-04-02 18:25:11 -0700132 face2_receivedInterests.push_back(interest);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700133
Junxiao Shi79494162014-04-02 18:25:11 -0700134 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700135 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800136
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700137 void
138 face2_onReceiveData(const Data& data)
139 {
Junxiao Shi79494162014-04-02 18:25:11 -0700140 face2_receivedDatas.push_back(data);
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700141
Junxiao Shi79494162014-04-02 18:25:11 -0700142 limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700143 }
144
145 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800146 face2_onFail()
147 {
Junxiao Shi79494162014-04-02 18:25:11 -0700148 face2.reset();
149 limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800150 }
151
152 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800153 channel_onFaceCreated(const shared_ptr<Face>& newFace)
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800154 {
Junxiao Shi79494162014-04-02 18:25:11 -0700155 faces.push_back(newFace);
156 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800157 }
158
159 void
160 channel_onConnectFailed(const std::string& reason)
161 {
162 BOOST_CHECK_MESSAGE(false, reason);
163
Junxiao Shi79494162014-04-02 18:25:11 -0700164 limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800165 }
166
167 void
168 checkFaceList(size_t shouldBe)
169 {
Junxiao Shi79494162014-04-02 18:25:11 -0700170 BOOST_CHECK_EQUAL(faces.size(), shouldBe);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800171 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800172
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700173public:
Junxiao Shi79494162014-04-02 18:25:11 -0700174 LimitedIo limitedIo;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700175
Junxiao Shi79494162014-04-02 18:25:11 -0700176 shared_ptr<Face> face1;
177 std::vector<Interest> face1_receivedInterests;
178 std::vector<Data> face1_receivedDatas;
179 shared_ptr<Face> face2;
180 std::vector<Interest> face2_receivedInterests;
181 std::vector<Data> face2_receivedDatas;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800182
Junxiao Shi79494162014-04-02 18:25:11 -0700183 std::list< shared_ptr<Face> > faces;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700184};
185
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000186BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700187{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600188 TcpFactory factory1;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700189
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600190 shared_ptr<TcpChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
191 factory1.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800192
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700193 BOOST_CHECK_EQUAL(channel1->isListening(), false);
194
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700195 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
196 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800197
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700198 BOOST_CHECK_EQUAL(channel1->isListening(), true);
199
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600200 TcpFactory factory2;
201
202 shared_ptr<TcpChannel> channel2 = factory2.createChannel("127.0.0.2", "20070");
203 factory2.createChannel("127.0.0.2", "20071");
204
205 factory2.createFace(FaceUri("tcp://127.0.0.1:20070"),
206 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
207 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700208
Junxiao Shi79494162014-04-02 18:25:11 -0700209 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700210 "TcpChannel error: cannot connect or cannot accept connection");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700211
Junxiao Shi79494162014-04-02 18:25:11 -0700212 BOOST_REQUIRE(static_cast<bool>(face1));
213 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800214
Junxiao Shi79494162014-04-02 18:25:11 -0700215 BOOST_CHECK(face1->isOnDemand());
216 BOOST_CHECK(!face2->isOnDemand());
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700217
Junxiao Shi79494162014-04-02 18:25:11 -0700218 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp4://127.0.0.1:20070");
219 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp4://127.0.0.1:20070");
220 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000221
Junxiao Shi79494162014-04-02 18:25:11 -0700222 BOOST_CHECK_EQUAL(face1->isLocal(), true);
223 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000224
Junxiao Shi79494162014-04-02 18:25:11 -0700225 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
226 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000227
228 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
229
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700230 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
231 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
232 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
233 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000234
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700235 face1->sendInterest(*interest1);
236 face1->sendInterest(*interest1);
237 face1->sendInterest(*interest1);
238 face1->sendData (*data1 );
239 face2->sendInterest(*interest2);
240 face2->sendData (*data2 );
241 face2->sendData (*data2 );
242 face2->sendData (*data2 );
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000243
Junxiao Shi79494162014-04-02 18:25:11 -0700244 BOOST_CHECK_MESSAGE(limitedIo.run(8, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000245 "TcpChannel error: cannot send or receive Interest/Data packets");
246
247
Junxiao Shi79494162014-04-02 18:25:11 -0700248 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
249 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 3);
250 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 3);
251 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000252
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700253 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
254 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
255 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
256 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000257
Junxiao Shi79494162014-04-02 18:25:11 -0700258 const FaceCounters& counters1 = face1->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700259 BOOST_CHECK_EQUAL(counters1.getNInInterests() , 1);
260 BOOST_CHECK_EQUAL(counters1.getNInDatas() , 3);
261 BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 3);
262 BOOST_CHECK_EQUAL(counters1.getNOutDatas() , 1);
Alexander Afanasyev7e698e62014-03-07 16:48:35 +0000263
Junxiao Shi79494162014-04-02 18:25:11 -0700264 const FaceCounters& counters2 = face2->getCounters();
Junxiao Shi6e694322014-04-03 10:27:13 -0700265 BOOST_CHECK_EQUAL(counters2.getNInInterests() , 3);
266 BOOST_CHECK_EQUAL(counters2.getNInDatas() , 1);
267 BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 1);
268 BOOST_CHECK_EQUAL(counters2.getNOutDatas() , 3);
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000269}
270
271BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
272{
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600273 TcpFactory factory1;
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000274
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600275 shared_ptr<TcpChannel> channel1 = factory1.createChannel("::1", "20070");
276 shared_ptr<TcpChannel> channel2 = factory1.createChannel("::1", "20071");
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000277
278 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
279 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
280
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600281 TcpFactory factory2;
282
283 factory2.createChannel("::2", "20070");
284
285 factory2.createFace(FaceUri("tcp://[::1]:20070"),
286 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
287 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000288
Junxiao Shi79494162014-04-02 18:25:11 -0700289 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000290 "TcpChannel error: cannot connect or cannot accept connection");
291
Junxiao Shi79494162014-04-02 18:25:11 -0700292 BOOST_REQUIRE(static_cast<bool>(face1));
293 BOOST_REQUIRE(static_cast<bool>(face2));
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000294
Junxiao Shi79494162014-04-02 18:25:11 -0700295 BOOST_CHECK_EQUAL(face2->getRemoteUri().toString(), "tcp6://[::1]:20070");
296 BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "tcp6://[::1]:20070");
297 // face1 has an unknown remoteUri, since the source port is automatically chosen by OS
Alexander Afanasyeva39b90b2014-03-05 15:31:00 +0000298
Junxiao Shi79494162014-04-02 18:25:11 -0700299 BOOST_CHECK_EQUAL(face1->isLocal(), true);
300 BOOST_CHECK_EQUAL(face2->isLocal(), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800301
Junxiao Shi79494162014-04-02 18:25:11 -0700302 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face1)), true);
303 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(face2)), true);
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800304
305 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800306
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700307 shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
308 shared_ptr<Data> data1 = makeData("ndn:/KfczhUqVix");
309 shared_ptr<Interest> interest2 = makeInterest("ndn:/QWiIMfj5sL");
310 shared_ptr<Data> data2 = makeData("ndn:/XNBV796f");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700311
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700312 face1->sendInterest(*interest1);
313 face1->sendData (*data1 );
314 face2->sendInterest(*interest2);
315 face2->sendData (*data2 );
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700316
Junxiao Shi79494162014-04-02 18:25:11 -0700317 BOOST_CHECK_MESSAGE(limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700318 "TcpChannel error: cannot send or receive Interest/Data packets");
319
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700320
Junxiao Shi79494162014-04-02 18:25:11 -0700321 BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
322 BOOST_REQUIRE_EQUAL(face1_receivedDatas .size(), 1);
323 BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
324 BOOST_REQUIRE_EQUAL(face2_receivedDatas .size(), 1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800325
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700326 BOOST_CHECK_EQUAL(face1_receivedInterests[0].getName(), interest2->getName());
327 BOOST_CHECK_EQUAL(face1_receivedDatas [0].getName(), data2->getName());
328 BOOST_CHECK_EQUAL(face2_receivedInterests[0].getName(), interest1->getName());
329 BOOST_CHECK_EQUAL(face2_receivedDatas [0].getName(), data1->getName());
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700330}
331
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800332BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
333{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800334 TcpFactory factory;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800335
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800336 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
337 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800338
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800339 channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
340 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800341
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800342 channel2->connect("127.0.0.1", "20070",
343 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
344 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800345 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800346
Junxiao Shi79494162014-04-02 18:25:11 -0700347 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700348 "TcpChannel error: cannot connect or cannot accept connection");
349
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800350
Junxiao Shi79494162014-04-02 18:25:11 -0700351 BOOST_CHECK_EQUAL(faces.size(), 2);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800352
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800353 shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800354 channel3->connect("127.0.0.1", "20070",
355 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
356 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800357 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800358
359
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800360 shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800361
362 BOOST_CHECK_NE(channel3, channel4);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800363
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700364 scheduler::schedule(time::seconds(1),
365 bind(&TcpChannel::connect, channel4, "127.0.0.1", "20070",
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800366 // does not work without static_cast
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700367 static_cast<TcpChannel::FaceCreatedCallback>(
368 bind(&EndToEndFixture::channel_onFaceCreated, this, _1)),
369 static_cast<TcpChannel::ConnectFailedCallback>(
370 bind(&EndToEndFixture::channel_onConnectFailed, this, _1)),
371 time::seconds(4)));
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800372
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700373 scheduler::schedule(time::milliseconds(500),
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800374 bind(&EndToEndFixture::checkFaceList, this, 4));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800375
Junxiao Shi79494162014-04-02 18:25:11 -0700376 BOOST_CHECK_MESSAGE(limitedIo.run(4,// 2 connects and 2 accepts
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700377 time::seconds(10)) == LimitedIo::EXCEED_OPS,
378 "TcpChannel error: cannot connect or cannot accept multiple connections");
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800379
Junxiao Shi79494162014-04-02 18:25:11 -0700380 BOOST_CHECK_EQUAL(faces.size(), 6);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800381}
382
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800383
384BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
385{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800386 TcpFactory factory;
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800387
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800388 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
389 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800390
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800391 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
392 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800393
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800394 channel2->connect("127.0.0.1", "20070",
395 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
396 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800397 time::seconds(4)); // very short timeout
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800398
Junxiao Shi79494162014-04-02 18:25:11 -0700399 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700400 "TcpChannel error: cannot connect or cannot accept connection");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800401
402 BOOST_CHECK_EQUAL(channel1->size(), 1);
403 BOOST_CHECK_EQUAL(channel2->size(), 1);
404
Junxiao Shi79494162014-04-02 18:25:11 -0700405 BOOST_REQUIRE(static_cast<bool>(face1));
406 BOOST_CHECK(static_cast<bool>(face2));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800407
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700408 // Face::close must be invoked during io run to be counted as an op
Junxiao Shi79494162014-04-02 18:25:11 -0700409 scheduler::schedule(time::milliseconds(100), bind(&Face::close, face1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800410
Junxiao Shi79494162014-04-02 18:25:11 -0700411 BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700412 "FaceClosing error: cannot properly close faces");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800413
414 // both faces should get closed
Junxiao Shi79494162014-04-02 18:25:11 -0700415 BOOST_CHECK(!static_cast<bool>(face1));
416 BOOST_CHECK(!static_cast<bool>(face2));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800417
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800418 BOOST_CHECK_EQUAL(channel1->size(), 0);
419 BOOST_CHECK_EQUAL(channel2->size(), 0);
420}
421
422
Alexander Afanasyev650028d2014-04-25 18:39:10 -0700423
424
425class SimpleEndToEndFixture : protected BaseFixture
426{
427public:
428 void
429 onFaceCreated(const shared_ptr<Face>& face)
430 {
431 face->onReceiveInterest +=
432 bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1);
433 face->onReceiveData +=
434 bind(&SimpleEndToEndFixture::onReceiveData, this, _1);
435 face->onFail +=
436 bind(&SimpleEndToEndFixture::onFail, this, face);
437
438 if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
439 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
440 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
441
442 static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
443 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
444 }
445
446 limitedIo.afterOp();
447 }
448
449 void
450 onConnectFailed(const std::string& reason)
451 {
452 BOOST_CHECK_MESSAGE(false, reason);
453
454 limitedIo.afterOp();
455 }
456
457 void
458 onReceiveInterest(const Interest& interest)
459 {
460 receivedInterests.push_back(interest);
461
462 limitedIo.afterOp();
463 }
464
465 void
466 onReceiveData(const Data& data)
467 {
468 receivedDatas.push_back(data);
469
470 limitedIo.afterOp();
471 }
472
473 void
474 onFail(const shared_ptr<Face>& face)
475 {
476 limitedIo.afterOp();
477 }
478
479public:
480 LimitedIo limitedIo;
481
482 std::vector<Interest> receivedInterests;
483 std::vector<Data> receivedDatas;
484};
485
486
487BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalFaceCorruptedInput, Dataset,
488 CorruptedPackets, SimpleEndToEndFixture)
489{
490 TcpFactory factory;
491
492 shared_ptr<TcpChannel> channel = factory.createChannel("127.0.0.1", "20070");
493 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
494 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
495 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
496
497 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
498 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve("127.0.0.1", "20070"));
499
500 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
501 time::seconds(1)) == LimitedIo::EXCEED_TIME,
502 "Exception thrown for " + Dataset::getName());
503}
504
505BOOST_FIXTURE_TEST_CASE_TEMPLATE(FaceCorruptedInput, Dataset,
506 CorruptedPackets, SimpleEndToEndFixture)
507{
508 // tests with non-local Face
509 std::string someIpv4Address;
510 std::list< shared_ptr<NetworkInterfaceInfo> > ifs = listNetworkInterfaces();
511 for (std::list< shared_ptr<NetworkInterfaceInfo> >::const_iterator i = ifs.begin();
512 i != ifs.end();
513 ++i)
514 {
515 if (!(*i)->isLoopback() && (*i)->isUp() && !(*i)->ipv4Addresses.empty())
516 {
517 someIpv4Address = (*i)->ipv4Addresses[0].to_string();
518 break;
519 }
520 }
521 if (someIpv4Address.empty())
522 {
523 BOOST_TEST_MESSAGE("Test with non-local Face cannot be run "
524 "(no non-local interface with IPv4 address available)");
525 return;
526 }
527
528 TcpFactory factory;
529
530 shared_ptr<TcpChannel> channel = factory.createChannel(someIpv4Address, "20070");
531 channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated, this, _1),
532 bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
533 BOOST_REQUIRE_EQUAL(channel->isListening(), true);
534
535
536 DummyStreamSender<boost::asio::ip::tcp, Dataset> sender;
537 sender.start(Resolver<boost::asio::ip::tcp>::syncResolve(someIpv4Address, "20070"));
538
539 BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS,
540 time::seconds(1)) == LimitedIo::EXCEED_TIME,
541 "Exception thrown for " + Dataset::getName());
542}
543
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700544BOOST_AUTO_TEST_SUITE_END()
545
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700546} // namespace tests
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700547} // namespace nfd