blob: d9450126a794c6db336a1ead078da343bb805f6f [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Spencer Leebb9102f2016-02-28 19:53:50 -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/udp-channel.hpp"
Spencer Leebb9102f2016-02-28 19:53:50 -070027#include "face/transport.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070028
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020029#include "test-ip.hpp"
Spencer Leebb9102f2016-02-28 19:53:50 -070030#include "tests/limited-io.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070031#include "tests/test-common.hpp"
Eric Newberrya98bf932015-09-21 00:58:47 -070032
Spencer Leebb9102f2016-02-28 19:53:50 -070033#include <boost/mpl/vector.hpp>
34
Eric Newberrya98bf932015-09-21 00:58:47 -070035namespace nfd {
Junxiao Shicde37ad2015-12-24 01:02:05 -070036namespace tests {
Eric Newberrya98bf932015-09-21 00:58:47 -070037
Junxiao Shicde37ad2015-12-24 01:02:05 -070038BOOST_AUTO_TEST_SUITE(Face)
Eric Newberrya98bf932015-09-21 00:58:47 -070039
Junxiao Shicde37ad2015-12-24 01:02:05 -070040using nfd::Face;
Spencer Leebb9102f2016-02-28 19:53:50 -070041namespace ip = boost::asio::ip;
Junxiao Shicde37ad2015-12-24 01:02:05 -070042
Spencer Leebb9102f2016-02-28 19:53:50 -070043typedef boost::mpl::vector<ip::address_v4,
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020044 ip::address_v6> AddressFamilies;
Spencer Leebb9102f2016-02-28 19:53:50 -070045
46class UdpChannelFixture : public BaseFixture
47{
48protected:
49 UdpChannelFixture()
50 : nextPort(7050)
51 {
52 }
53
54 unique_ptr<UdpChannel>
55 makeChannel(const ip::address& addr, uint16_t port = 0)
56 {
57 if (port == 0)
58 port = nextPort++;
59
60 return make_unique<UdpChannel>(udp::Endpoint(addr, port), time::seconds(2));
61 }
62
63 void
64 listen(const ip::address& addr)
65 {
66 listenerEp = udp::Endpoint(addr, 7030);
67 listenerChannel = makeChannel(addr, 7030);
68 listenerChannel->listen(
69 [this] (const shared_ptr<Face>& newFace) {
70 BOOST_REQUIRE(newFace != nullptr);
71 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
72 listenerFaces.push_back(newFace);
73 limitedIo.afterOp();
74 },
75 [] (const std::string& reason) {
76 BOOST_FAIL(reason);
77 });
78 }
79
80 void
81 connect(UdpChannel& channel)
82 {
83 g_io.post([&] {
84 channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
85 [this] (const shared_ptr<Face>& newFace) {
86 BOOST_REQUIRE(newFace != nullptr);
87 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
88 clientFaces.push_back(newFace);
89 face::Transport::Packet pkt(ndn::encoding::makeStringBlock(300, "hello"));
90 newFace->getTransport()->send(std::move(pkt));
91 limitedIo.afterOp();
92 },
93 [] (const std::string& reason) {
94 BOOST_FAIL(reason);
95 });
96 });
97 }
98
99protected:
100 LimitedIo limitedIo;
101 udp::Endpoint listenerEp;
102 unique_ptr<UdpChannel> listenerChannel;
103 std::vector<shared_ptr<Face>> listenerFaces;
104 std::vector<shared_ptr<Face>> clientFaces;
105
106private:
107 uint16_t nextPort;
108};
109
110BOOST_FIXTURE_TEST_SUITE(TestUdpChannel, UdpChannelFixture)
111
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200112BOOST_AUTO_TEST_CASE_TEMPLATE(Uri, A, AddressFamilies)
Spencer Leebb9102f2016-02-28 19:53:50 -0700113{
114 udp::Endpoint ep(A::loopback(), 7050);
115 auto channel = makeChannel(ep.address(), ep.port());
116 BOOST_CHECK_EQUAL(channel->getUri(), FaceUri(ep));
117}
118
119BOOST_AUTO_TEST_CASE(Listen)
120{
121 auto channel = makeChannel(ip::address_v4());
122 BOOST_CHECK_EQUAL(channel->isListening(), false);
123
124 channel->listen(nullptr, nullptr);
125 BOOST_CHECK_EQUAL(channel->isListening(), true);
126
127 // listen() is idempotent
128 BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
129 BOOST_CHECK_EQUAL(channel->isListening(), true);
130}
131
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200132BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, AddressFamilies)
Spencer Leebb9102f2016-02-28 19:53:50 -0700133{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200134 auto address = getTestIp<A>(LoopbackAddress::Yes);
135 SKIP_IF_IP_UNAVAILABLE(address);
136 this->listen(address);
Spencer Leebb9102f2016-02-28 19:53:50 -0700137
138 BOOST_CHECK_EQUAL(listenerChannel->isListening(), true);
139 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
140
141 auto ch1 = makeChannel(A());
142 this->connect(*ch1);
143
144 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
145
146 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
147 BOOST_CHECK_EQUAL(ch1->size(), 1);
148 BOOST_CHECK_EQUAL(ch1->isListening(), false);
149
150 auto ch2 = makeChannel(A());
151 auto ch3 = makeChannel(A());
152 this->connect(*ch2);
153 this->connect(*ch3);
154
155 BOOST_CHECK(limitedIo.run(4, time::seconds(1)) == LimitedIo::EXCEED_OPS);
156
157 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
158 BOOST_CHECK_EQUAL(ch1->size(), 1);
159 BOOST_CHECK_EQUAL(ch2->size(), 1);
160 BOOST_CHECK_EQUAL(ch3->size(), 1);
161 BOOST_CHECK_EQUAL(clientFaces.size(), 3);
162
163 // check face persistency
164 for (const auto& face : listenerFaces) {
165 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
166 }
167 for (const auto& face : clientFaces) {
168 BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
169 }
170
171 // connect twice to the same endpoint
172 this->connect(*ch3);
173
174 BOOST_CHECK(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS);
175
176 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
177 BOOST_CHECK_EQUAL(ch1->size(), 1);
178 BOOST_CHECK_EQUAL(ch2->size(), 1);
179 BOOST_CHECK_EQUAL(ch3->size(), 1);
180 BOOST_CHECK_EQUAL(clientFaces.size(), 4);
181 BOOST_CHECK_EQUAL(clientFaces.at(2), clientFaces.at(3));
182}
183
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200184BOOST_AUTO_TEST_CASE_TEMPLATE(FaceClosure, A, AddressFamilies)
Spencer Leebb9102f2016-02-28 19:53:50 -0700185{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200186 auto address = getTestIp<A>(LoopbackAddress::Yes);
187 SKIP_IF_IP_UNAVAILABLE(address);
188 this->listen(address);
Spencer Leebb9102f2016-02-28 19:53:50 -0700189
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200190 auto clientChannel = makeChannel(A());
Spencer Leebb9102f2016-02-28 19:53:50 -0700191 this->connect(*clientChannel);
192
193 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
194
195 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
196 BOOST_CHECK_EQUAL(clientChannel->size(), 1);
197
198 clientFaces.at(0)->close();
199
200 BOOST_CHECK(limitedIo.run(2, time::seconds(5)) == LimitedIo::EXCEED_OPS);
201
202 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
203 BOOST_CHECK_EQUAL(clientChannel->size(), 0);
204}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700205
206BOOST_AUTO_TEST_SUITE_END() // TestUdpChannel
207BOOST_AUTO_TEST_SUITE_END() // Face
208
209} // namespace tests
Eric Newberrya98bf932015-09-21 00:58:47 -0700210} // namespace nfd