blob: f829aa2df6d48e8edb9324b6ffe97f13380d3c2b [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Spencer Leed5fe0cf2016-02-06 03:55:24 -07003 * Copyright (c) 2014-2016, Regents of the University of California,
Eric Newberrya98bf932015-09-21 00:58:47 -07004 * 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.
10 *
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/>.
24 */
25
Junxiao Shicde37ad2015-12-24 01:02:05 -070026#include "face/tcp-channel.hpp"
27
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020028#include "test-ip.hpp"
Spencer Leed5fe0cf2016-02-06 03:55:24 -070029#include "tests/limited-io.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/test-common.hpp"
Eric Newberrya98bf932015-09-21 00:58:47 -070031
Spencer Leed5fe0cf2016-02-06 03:55:24 -070032#include <boost/mpl/vector.hpp>
33
Eric Newberrya98bf932015-09-21 00:58:47 -070034namespace nfd {
Junxiao Shicde37ad2015-12-24 01:02:05 -070035namespace tests {
Eric Newberrya98bf932015-09-21 00:58:47 -070036
Junxiao Shicde37ad2015-12-24 01:02:05 -070037BOOST_AUTO_TEST_SUITE(Face)
Eric Newberrya98bf932015-09-21 00:58:47 -070038
Spencer Leed5fe0cf2016-02-06 03:55:24 -070039using nfd::Face;
40namespace ip = boost::asio::ip;
41
42typedef boost::mpl::vector<ip::address_v4,
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020043 ip::address_v6> AddressFamilies;
Spencer Leed5fe0cf2016-02-06 03:55:24 -070044
45class TcpChannelFixture : public BaseFixture
46{
47protected:
48 TcpChannelFixture()
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020049 : m_nextPort(7050)
Spencer Leed5fe0cf2016-02-06 03:55:24 -070050 {
51 }
52
53 unique_ptr<TcpChannel>
54 makeChannel(const ip::address& addr, uint16_t port = 0)
55 {
56 if (port == 0)
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020057 port = m_nextPort++;
Spencer Leed5fe0cf2016-02-06 03:55:24 -070058
59 return make_unique<TcpChannel>(tcp::Endpoint(addr, port));
60 }
61
62 void
63 listen(const ip::address& addr)
64 {
65 listenerEp = tcp::Endpoint(addr, 7030);
66 listenerChannel = makeChannel(addr, 7030);
67 listenerChannel->listen(
68 [this] (const shared_ptr<Face>& newFace) {
69 BOOST_REQUIRE(newFace != nullptr);
70 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
71 listenerFaces.push_back(newFace);
72 limitedIo.afterOp();
73 },
74 [this] (const std::string& reason) {
75 BOOST_FAIL(reason);
76 limitedIo.afterOp();
77 });
78 }
79
80 void
81 connect(TcpChannel& channel)
82 {
83 channel.connect(listenerEp,
84 [this] (const shared_ptr<Face>& newFace) {
85 BOOST_REQUIRE(newFace != nullptr);
86 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
87 clientFaces.push_back(newFace);
88 limitedIo.afterOp();
89 },
90 [this] (const std::string& reason) {
91 BOOST_FAIL(reason);
92 limitedIo.afterOp();
93 });
94 }
95
96protected:
97 LimitedIo limitedIo;
98 tcp::Endpoint listenerEp;
99 unique_ptr<TcpChannel> listenerChannel;
100 std::vector<shared_ptr<Face>> listenerFaces;
101 std::vector<shared_ptr<Face>> clientFaces;
102
103private:
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200104 uint16_t m_nextPort;
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700105};
106
107BOOST_FIXTURE_TEST_SUITE(TestTcpChannel, TcpChannelFixture)
108
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200109BOOST_AUTO_TEST_CASE_TEMPLATE(Uri, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700110{
111 tcp::Endpoint ep(A::loopback(), 7050);
112 auto channel = makeChannel(ep.address(), ep.port());
113 BOOST_CHECK_EQUAL(channel->getUri(), FaceUri(ep));
114}
115
116BOOST_AUTO_TEST_CASE(Listen)
117{
118 auto channel = makeChannel(ip::address_v4());
119 BOOST_CHECK_EQUAL(channel->isListening(), false);
120
121 channel->listen(nullptr, nullptr);
122 BOOST_CHECK_EQUAL(channel->isListening(), true);
123
124 // listen() is idempotent
125 BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
126 BOOST_CHECK_EQUAL(channel->isListening(), true);
127}
128
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200129BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700130{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200131 auto address = getTestIp<A>(LoopbackAddress::Yes);
132 SKIP_IF_IP_UNAVAILABLE(address);
133 this->listen(address);
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700134
135 BOOST_CHECK_EQUAL(listenerChannel->isListening(), true);
136 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
137
138 auto ch1 = makeChannel(A());
139 this->connect(*ch1);
140
141 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
142
143 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
144 BOOST_CHECK_EQUAL(ch1->size(), 1);
145 BOOST_CHECK_EQUAL(ch1->isListening(), false);
146
147 auto ch2 = makeChannel(A());
148 auto ch3 = makeChannel(A());
149 this->connect(*ch2);
150 this->connect(*ch3);
151
152 BOOST_CHECK(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS);
153
154 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
155 BOOST_CHECK_EQUAL(ch1->size(), 1);
156 BOOST_CHECK_EQUAL(ch2->size(), 1);
157 BOOST_CHECK_EQUAL(ch3->size(), 1);
158 BOOST_CHECK_EQUAL(clientFaces.size(), 3);
159
160 // check face persistency
161 for (const auto& face : listenerFaces) {
162 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
163 }
164 for (const auto& face : clientFaces) {
165 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
166 }
167
168 // connect twice to the same endpoint
169 this->connect(*ch3);
170
171 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
172 BOOST_CHECK_EQUAL(ch1->size(), 1);
173 BOOST_CHECK_EQUAL(ch2->size(), 1);
174 BOOST_CHECK_EQUAL(ch3->size(), 1);
175 BOOST_CHECK_EQUAL(clientFaces.size(), 4);
176 BOOST_CHECK_EQUAL(clientFaces.at(2), clientFaces.at(3));
177}
178
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200179BOOST_AUTO_TEST_CASE_TEMPLATE(ConnectTimeout, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700180{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200181 auto address = getTestIp<A>(LoopbackAddress::Yes);
182 SKIP_IF_IP_UNAVAILABLE(address);
183 // do not listen
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700184
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200185 auto channel = makeChannel(A());
186 channel->connect(tcp::Endpoint(address, 7040),
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700187 [this] (const shared_ptr<Face>&) {
188 BOOST_FAIL("Connect succeeded when it should have failed");
189 this->limitedIo.afterOp();
190 },
191 [this] (const std::string& reason) {
192 BOOST_CHECK_EQUAL(reason.empty(), false);
193 this->limitedIo.afterOp();
194 },
195 time::seconds(1));
196
197 BOOST_CHECK(limitedIo.run(1, time::seconds(2)) == LimitedIo::EXCEED_OPS);
198 BOOST_CHECK_EQUAL(channel->size(), 0);
199}
200
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200201BOOST_AUTO_TEST_CASE_TEMPLATE(FaceClosure, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700202{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200203 auto address = getTestIp<A>(LoopbackAddress::Yes);
204 SKIP_IF_IP_UNAVAILABLE(address);
205 this->listen(address);
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700206
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200207 auto clientChannel = makeChannel(A());
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700208 this->connect(*clientChannel);
209
210 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
211
212 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
213 BOOST_CHECK_EQUAL(clientChannel->size(), 1);
214
215 clientFaces.at(0)->close();
216
217 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
218
219 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
220 BOOST_CHECK_EQUAL(clientChannel->size(), 0);
221}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700222
223BOOST_AUTO_TEST_SUITE_END() // TestTcpChannel
224BOOST_AUTO_TEST_SUITE_END() // Face
225
226} // namespace tests
Eric Newberrya98bf932015-09-21 00:58:47 -0700227} // namespace nfd