blob: 2be63317f3d138407cf9a11a6a50851cc6f1030e [file] [log] [blame]
Junxiao Shi96dc0c42014-01-30 23:51:59 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
Alexander Afanasyev0eb70652014-02-27 18:35:07 -08007#include "face/tcp-factory.hpp"
Junxiao Shi96dc0c42014-01-30 23:51:59 -07008#include <ndn-cpp-dev/security/key-chain.hpp>
9
Junxiao Shid9ee45c2014-02-27 15:38:11 -070010#include "tests/test-common.hpp"
Junxiao Shi7e2413b2014-03-02 11:15:09 -070011#include "tests/core/limited-io.hpp"
Junxiao Shi96dc0c42014-01-30 23:51:59 -070012
13namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070014namespace tests {
Junxiao Shi96dc0c42014-01-30 23:51:59 -070015
Junxiao Shid9ee45c2014-02-27 15:38:11 -070016BOOST_FIXTURE_TEST_SUITE(FaceTcp, BaseFixture)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070017
18BOOST_AUTO_TEST_CASE(ChannelMap)
19{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -080020 TcpFactory factory;
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080021
Alexander Afanasyevd6655302014-02-28 08:41:28 -080022 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
23 shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070024 BOOST_CHECK_EQUAL(channel1, channel1a);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080025
Alexander Afanasyevd6655302014-02-28 08:41:28 -080026 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shi96dc0c42014-01-30 23:51:59 -070027 BOOST_CHECK_NE(channel1, channel2);
28}
29
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030class EndToEndFixture : protected BaseFixture
Junxiao Shi96dc0c42014-01-30 23:51:59 -070031{
32public:
33 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080034 channel1_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070035 {
36 BOOST_CHECK(!static_cast<bool>(m_face1));
37 m_face1 = newFace;
38 m_face1->onReceiveInterest +=
39 bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
40 m_face1->onReceiveData +=
41 bind(&EndToEndFixture::face1_onReceiveData, this, _1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080042 m_face1->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080043 bind(&EndToEndFixture::face1_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070044
Junxiao Shi7e2413b2014-03-02 11:15:09 -070045 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070046 }
47
48 void
49 channel1_onConnectFailed(const std::string& reason)
50 {
51 BOOST_CHECK_MESSAGE(false, reason);
52
Junxiao Shi7e2413b2014-03-02 11:15:09 -070053 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070054 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080055
Junxiao Shi96dc0c42014-01-30 23:51:59 -070056 void
57 face1_onReceiveInterest(const Interest& interest)
58 {
59 m_face1_receivedInterests.push_back(interest);
60
Junxiao Shi7e2413b2014-03-02 11:15:09 -070061 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070062 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080063
Junxiao Shi96dc0c42014-01-30 23:51:59 -070064 void
65 face1_onReceiveData(const Data& data)
66 {
67 m_face1_receivedDatas.push_back(data);
68
Junxiao Shi7e2413b2014-03-02 11:15:09 -070069 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070070 }
71
72 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080073 face1_onFail()
74 {
75 m_face1.reset();
Junxiao Shi7e2413b2014-03-02 11:15:09 -070076 m_limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080077 }
78
79 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080080 channel2_onFaceCreated(const shared_ptr<Face>& newFace)
Junxiao Shi96dc0c42014-01-30 23:51:59 -070081 {
82 BOOST_CHECK(!static_cast<bool>(m_face2));
83 m_face2 = newFace;
84 m_face2->onReceiveInterest +=
85 bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
86 m_face2->onReceiveData +=
87 bind(&EndToEndFixture::face2_onReceiveData, this, _1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -080088 m_face2->onFail +=
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080089 bind(&EndToEndFixture::face2_onFail, this);
Junxiao Shi96dc0c42014-01-30 23:51:59 -070090
Junxiao Shi7e2413b2014-03-02 11:15:09 -070091 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -070092 }
93
94 void
95 channel2_onConnectFailed(const std::string& reason)
96 {
97 BOOST_CHECK_MESSAGE(false, reason);
98
Junxiao Shi7e2413b2014-03-02 11:15:09 -070099 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700100 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800101
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700102 void
103 face2_onReceiveInterest(const Interest& interest)
104 {
105 m_face2_receivedInterests.push_back(interest);
106
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700107 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700108 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800109
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700110 void
111 face2_onReceiveData(const Data& data)
112 {
113 m_face2_receivedDatas.push_back(data);
114
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700115 m_limitedIo.afterOp();
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700116 }
117
118 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800119 face2_onFail()
120 {
121 m_face2.reset();
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700122 m_limitedIo.afterOp();
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800123 }
124
125 void
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800126 channel_onFaceCreated(const shared_ptr<Face>& newFace)
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800127 {
128 m_faces.push_back(newFace);
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700129 m_limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800130 }
131
132 void
133 channel_onConnectFailed(const std::string& reason)
134 {
135 BOOST_CHECK_MESSAGE(false, reason);
136
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700137 m_limitedIo.afterOp();
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800138 }
139
140 void
141 checkFaceList(size_t shouldBe)
142 {
143 BOOST_CHECK_EQUAL(m_faces.size(), shouldBe);
144 }
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800145
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700146public:
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700147 LimitedIo m_limitedIo;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700148
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800149 shared_ptr<Face> m_face1;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700150 std::vector<Interest> m_face1_receivedInterests;
151 std::vector<Data> m_face1_receivedDatas;
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800152 shared_ptr<Face> m_face2;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700153 std::vector<Interest> m_face2_receivedInterests;
154 std::vector<Data> m_face2_receivedDatas;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800155
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800156 std::list< shared_ptr<Face> > m_faces;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700157};
158
159
160BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
161{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800162 TcpFactory factory;
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700163
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800164 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
165 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800166
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700167 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
168 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800169
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700170 channel2->connect("127.0.0.1", "20070",
171 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
172 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800173 time::seconds(4));
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700174
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700175 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
176 "TcpChannel error: cannot connect or cannot accept connection");
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700177
178 BOOST_REQUIRE(static_cast<bool>(m_face1));
179 BOOST_REQUIRE(static_cast<bool>(m_face2));
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800180
181 BOOST_CHECK_EQUAL(m_face1->isLocal(), true);
182 BOOST_CHECK_EQUAL(m_face2->isLocal(), true);
183
184 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(m_face1)), true);
185 BOOST_CHECK_EQUAL(static_cast<bool>(dynamic_pointer_cast<LocalFace>(m_face2)), true);
186
187 // integrated tests needs to check that TcpFace for non-loopback fails these tests...
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800188
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700189 Interest interest1("ndn:/TpnzGvW9R");
190 Data data1 ("ndn:/KfczhUqVix");
191 data1.setContent(0, 0);
192 Interest interest2("ndn:/QWiIMfj5sL");
193 Data data2 ("ndn:/XNBV796f");
194 data2.setContent(0, 0);
195
196 ndn::SignatureSha256WithRsa fakeSignature;
197 fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800198
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700199 // set fake signature on data1 and data2
200 data1.setSignature(fakeSignature);
201 data2.setSignature(fakeSignature);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800202
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700203 m_face1->sendInterest(interest1);
204 m_face1->sendData (data1 );
205 m_face2->sendInterest(interest2);
206 m_face2->sendData (data2 );
207
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700208 BOOST_CHECK_MESSAGE(m_limitedIo.run(4, time::seconds(10)) == LimitedIo::EXCEED_OPS,
209 "TcpChannel error: cannot send or receive Interest/Data packets");
210
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700211
212 BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
213 BOOST_REQUIRE_EQUAL(m_face1_receivedDatas .size(), 1);
214 BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
215 BOOST_REQUIRE_EQUAL(m_face2_receivedDatas .size(), 1);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800216
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700217 BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
218 BOOST_CHECK_EQUAL(m_face1_receivedDatas [0].getName(), data2.getName());
219 BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
220 BOOST_CHECK_EQUAL(m_face2_receivedDatas [0].getName(), data1.getName());
221}
222
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800223BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
224{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800225 TcpFactory factory;
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800226
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800227 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
228 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800229
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800230 channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
231 bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800232
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800233 channel2->connect("127.0.0.1", "20070",
234 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
235 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800236 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800237
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700238 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
239 "TcpChannel error: cannot connect or cannot accept connection");
240
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800241
242 BOOST_CHECK_EQUAL(m_faces.size(), 2);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800243
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800244 shared_ptr<TcpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800245 channel3->connect("127.0.0.1", "20070",
246 bind(&EndToEndFixture::channel_onFaceCreated, this, _1),
247 bind(&EndToEndFixture::channel_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800248 time::seconds(4)); // very short timeout
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800249
250
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800251 shared_ptr<TcpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800252
253 BOOST_CHECK_NE(channel3, channel4);
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800254
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700255 scheduler::schedule(time::seconds(1),
256 bind(&TcpChannel::connect, channel4, "127.0.0.1", "20070",
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800257 // does not work without static_cast
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700258 static_cast<TcpChannel::FaceCreatedCallback>(
259 bind(&EndToEndFixture::channel_onFaceCreated, this, _1)),
260 static_cast<TcpChannel::ConnectFailedCallback>(
261 bind(&EndToEndFixture::channel_onConnectFailed, this, _1)),
262 time::seconds(4)));
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800263
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800264 scheduler::schedule(time::seconds(0.5),
265 bind(&EndToEndFixture::checkFaceList, this, 4));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800266
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700267 BOOST_CHECK_MESSAGE(m_limitedIo.run(4,// 2 connects and 2 accepts
268 time::seconds(10)) == LimitedIo::EXCEED_OPS,
269 "TcpChannel error: cannot connect or cannot accept multiple connections");
Alexander Afanasyev7329e022014-02-27 14:47:22 -0800270
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800271 BOOST_CHECK_EQUAL(m_faces.size(), 6);
272}
273
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800274
275BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
276{
Alexander Afanasyev0eb70652014-02-27 18:35:07 -0800277 TcpFactory factory;
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800278
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800279 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
280 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800281
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800282 channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated, this, _1),
283 bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800284
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800285 channel2->connect("127.0.0.1", "20070",
286 bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
287 bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
Alexander Afanasyevc1e2ee02014-02-25 17:02:07 -0800288 time::seconds(4)); // very short timeout
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800289
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700290 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
291 "TcpChannel error: cannot connect or cannot accept connection");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800292
293 BOOST_CHECK_EQUAL(channel1->size(), 1);
294 BOOST_CHECK_EQUAL(channel2->size(), 1);
295
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800296 BOOST_REQUIRE(static_cast<bool>(m_face1));
297 BOOST_CHECK(static_cast<bool>(m_face2));
298
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700299 // Face::close must be invoked during io run to be counted as an op
300 scheduler::schedule(time::seconds(0.1), bind(&Face::close, m_face1));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800301
Junxiao Shi7e2413b2014-03-02 11:15:09 -0700302 BOOST_CHECK_MESSAGE(m_limitedIo.run(2, time::seconds(10)) == LimitedIo::EXCEED_OPS,
303 "FaceClosing error: cannot properly close faces");
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800304
305 // both faces should get closed
306 BOOST_CHECK(!static_cast<bool>(m_face1));
307 BOOST_CHECK(!static_cast<bool>(m_face2));
Alexander Afanasyev5f1ec252014-02-28 10:59:17 -0800308
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800309 BOOST_CHECK_EQUAL(channel1->size(), 0);
310 BOOST_CHECK_EQUAL(channel2->size(), 0);
311}
312
313
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700314BOOST_AUTO_TEST_SUITE_END()
315
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700316} // namespace tests
Junxiao Shi96dc0c42014-01-30 23:51:59 -0700317} // namespace nfd