blob: f8dae5dac40aa98b2d4993a500ed0b151268b0a7 [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"
Eric Newberry42602412016-08-27 09:33:18 -070030#include "factory-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 },
Eric Newberry42602412016-08-27 09:33:18 -070074 &failIfError);
Spencer Leed5fe0cf2016-02-06 03:55:24 -070075 }
76
77 void
78 connect(TcpChannel& channel)
79 {
Eric Newberryf40551a2016-09-05 15:41:16 -070080 channel.connect(listenerEp, false,
Spencer Leed5fe0cf2016-02-06 03:55:24 -070081 [this] (const shared_ptr<Face>& newFace) {
82 BOOST_REQUIRE(newFace != nullptr);
83 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
84 clientFaces.push_back(newFace);
85 limitedIo.afterOp();
86 },
Eric Newberry42602412016-08-27 09:33:18 -070087 &failIfError);
Spencer Leed5fe0cf2016-02-06 03:55:24 -070088 }
89
90protected:
91 LimitedIo limitedIo;
92 tcp::Endpoint listenerEp;
93 unique_ptr<TcpChannel> listenerChannel;
94 std::vector<shared_ptr<Face>> listenerFaces;
95 std::vector<shared_ptr<Face>> clientFaces;
96
97private:
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020098 uint16_t m_nextPort;
Spencer Leed5fe0cf2016-02-06 03:55:24 -070099};
100
101BOOST_FIXTURE_TEST_SUITE(TestTcpChannel, TcpChannelFixture)
102
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200103BOOST_AUTO_TEST_CASE_TEMPLATE(Uri, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700104{
105 tcp::Endpoint ep(A::loopback(), 7050);
106 auto channel = makeChannel(ep.address(), ep.port());
107 BOOST_CHECK_EQUAL(channel->getUri(), FaceUri(ep));
108}
109
110BOOST_AUTO_TEST_CASE(Listen)
111{
112 auto channel = makeChannel(ip::address_v4());
113 BOOST_CHECK_EQUAL(channel->isListening(), false);
114
115 channel->listen(nullptr, nullptr);
116 BOOST_CHECK_EQUAL(channel->isListening(), true);
117
118 // listen() is idempotent
119 BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
120 BOOST_CHECK_EQUAL(channel->isListening(), true);
121}
122
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200123BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700124{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200125 auto address = getTestIp<A>(LoopbackAddress::Yes);
126 SKIP_IF_IP_UNAVAILABLE(address);
127 this->listen(address);
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700128
129 BOOST_CHECK_EQUAL(listenerChannel->isListening(), true);
130 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
131
132 auto ch1 = makeChannel(A());
133 this->connect(*ch1);
134
135 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
136
137 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
138 BOOST_CHECK_EQUAL(ch1->size(), 1);
139 BOOST_CHECK_EQUAL(ch1->isListening(), false);
140
141 auto ch2 = makeChannel(A());
142 auto ch3 = makeChannel(A());
143 this->connect(*ch2);
144 this->connect(*ch3);
145
146 BOOST_CHECK(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS);
147
148 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
149 BOOST_CHECK_EQUAL(ch1->size(), 1);
150 BOOST_CHECK_EQUAL(ch2->size(), 1);
151 BOOST_CHECK_EQUAL(ch3->size(), 1);
152 BOOST_CHECK_EQUAL(clientFaces.size(), 3);
153
154 // check face persistency
155 for (const auto& face : listenerFaces) {
156 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
157 }
158 for (const auto& face : clientFaces) {
159 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
160 }
161
162 // connect twice to the same endpoint
163 this->connect(*ch3);
164
165 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
166 BOOST_CHECK_EQUAL(ch1->size(), 1);
167 BOOST_CHECK_EQUAL(ch2->size(), 1);
168 BOOST_CHECK_EQUAL(ch3->size(), 1);
169 BOOST_CHECK_EQUAL(clientFaces.size(), 4);
170 BOOST_CHECK_EQUAL(clientFaces.at(2), clientFaces.at(3));
171}
172
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200173BOOST_AUTO_TEST_CASE_TEMPLATE(ConnectTimeout, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700174{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200175 auto address = getTestIp<A>(LoopbackAddress::Yes);
176 SKIP_IF_IP_UNAVAILABLE(address);
177 // do not listen
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700178
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200179 auto channel = makeChannel(A());
Eric Newberryf40551a2016-09-05 15:41:16 -0700180 channel->connect(tcp::Endpoint(address, 7040), false,
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700181 [this] (const shared_ptr<Face>&) {
182 BOOST_FAIL("Connect succeeded when it should have failed");
183 this->limitedIo.afterOp();
184 },
Eric Newberry42602412016-08-27 09:33:18 -0700185 [this] (uint32_t status, const std::string& reason) {
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700186 BOOST_CHECK_EQUAL(reason.empty(), false);
187 this->limitedIo.afterOp();
188 },
189 time::seconds(1));
190
191 BOOST_CHECK(limitedIo.run(1, time::seconds(2)) == LimitedIo::EXCEED_OPS);
192 BOOST_CHECK_EQUAL(channel->size(), 0);
193}
194
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200195BOOST_AUTO_TEST_CASE_TEMPLATE(FaceClosure, A, AddressFamilies)
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700196{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200197 auto address = getTestIp<A>(LoopbackAddress::Yes);
198 SKIP_IF_IP_UNAVAILABLE(address);
199 this->listen(address);
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700200
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200201 auto clientChannel = makeChannel(A());
Spencer Leed5fe0cf2016-02-06 03:55:24 -0700202 this->connect(*clientChannel);
203
204 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
205
206 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
207 BOOST_CHECK_EQUAL(clientChannel->size(), 1);
208
209 clientFaces.at(0)->close();
210
211 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
212
213 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
214 BOOST_CHECK_EQUAL(clientChannel->size(), 0);
215}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700216
217BOOST_AUTO_TEST_SUITE_END() // TestTcpChannel
218BOOST_AUTO_TEST_SUITE_END() // Face
219
220} // namespace tests
Eric Newberrya98bf932015-09-21 00:58:47 -0700221} // namespace nfd