blob: 8fccab157e39e46355da336ed92a98c0350b45a8 [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
Spencer Leebb9102f2016-02-28 19:53:50 -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 Leebb9102f2016-02-28 19:53:50 -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
Junxiao Shicde37ad2015-12-24 01:02:05 -070039using nfd::Face;
Spencer Leebb9102f2016-02-28 19:53:50 -070040namespace ip = boost::asio::ip;
Junxiao Shicde37ad2015-12-24 01:02:05 -070041
Spencer Leebb9102f2016-02-28 19:53:50 -070042typedef boost::mpl::vector<ip::address_v4,
43 ip::address_v6> AddressTypes;
44
45class UdpChannelFixture : public BaseFixture
46{
47protected:
48 UdpChannelFixture()
49 : nextPort(7050)
50 {
51 }
52
53 unique_ptr<UdpChannel>
54 makeChannel(const ip::address& addr, uint16_t port = 0)
55 {
56 if (port == 0)
57 port = nextPort++;
58
59 return make_unique<UdpChannel>(udp::Endpoint(addr, port), time::seconds(2));
60 }
61
62 void
63 listen(const ip::address& addr)
64 {
65 listenerEp = udp::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 [] (const std::string& reason) {
75 BOOST_FAIL(reason);
76 });
77 }
78
79 void
80 connect(UdpChannel& channel)
81 {
82 g_io.post([&] {
83 channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
84 [this] (const shared_ptr<Face>& newFace) {
85 BOOST_REQUIRE(newFace != nullptr);
86 connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
87 clientFaces.push_back(newFace);
88 face::Transport::Packet pkt(ndn::encoding::makeStringBlock(300, "hello"));
89 newFace->getTransport()->send(std::move(pkt));
90 limitedIo.afterOp();
91 },
92 [] (const std::string& reason) {
93 BOOST_FAIL(reason);
94 });
95 });
96 }
97
98protected:
99 LimitedIo limitedIo;
100 udp::Endpoint listenerEp;
101 unique_ptr<UdpChannel> listenerChannel;
102 std::vector<shared_ptr<Face>> listenerFaces;
103 std::vector<shared_ptr<Face>> clientFaces;
104
105private:
106 uint16_t nextPort;
107};
108
109BOOST_FIXTURE_TEST_SUITE(TestUdpChannel, UdpChannelFixture)
110
111BOOST_AUTO_TEST_CASE_TEMPLATE(Uri, A, AddressTypes)
112{
113 udp::Endpoint ep(A::loopback(), 7050);
114 auto channel = makeChannel(ep.address(), ep.port());
115 BOOST_CHECK_EQUAL(channel->getUri(), FaceUri(ep));
116}
117
118BOOST_AUTO_TEST_CASE(Listen)
119{
120 auto channel = makeChannel(ip::address_v4());
121 BOOST_CHECK_EQUAL(channel->isListening(), false);
122
123 channel->listen(nullptr, nullptr);
124 BOOST_CHECK_EQUAL(channel->isListening(), true);
125
126 // listen() is idempotent
127 BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
128 BOOST_CHECK_EQUAL(channel->isListening(), true);
129}
130
131BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, AddressTypes)
132{
133 this->listen(A::loopback());
134
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(limitedIo.run(1, time::seconds(1)) == LimitedIo::EXCEED_OPS);
172
173 BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
174 BOOST_CHECK_EQUAL(ch1->size(), 1);
175 BOOST_CHECK_EQUAL(ch2->size(), 1);
176 BOOST_CHECK_EQUAL(ch3->size(), 1);
177 BOOST_CHECK_EQUAL(clientFaces.size(), 4);
178 BOOST_CHECK_EQUAL(clientFaces.at(2), clientFaces.at(3));
179}
180
181BOOST_AUTO_TEST_CASE(FaceClosure)
182{
183 this->listen(ip::address_v4::loopback());
184
185 auto clientChannel = makeChannel(ip::address_v4());
186 this->connect(*clientChannel);
187
188 BOOST_CHECK(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS);
189
190 BOOST_CHECK_EQUAL(listenerChannel->size(), 1);
191 BOOST_CHECK_EQUAL(clientChannel->size(), 1);
192
193 clientFaces.at(0)->close();
194
195 BOOST_CHECK(limitedIo.run(2, time::seconds(5)) == LimitedIo::EXCEED_OPS);
196
197 BOOST_CHECK_EQUAL(listenerChannel->size(), 0);
198 BOOST_CHECK_EQUAL(clientChannel->size(), 0);
199}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700200
201BOOST_AUTO_TEST_SUITE_END() // TestUdpChannel
202BOOST_AUTO_TEST_SUITE_END() // Face
203
204} // namespace tests
Eric Newberrya98bf932015-09-21 00:58:47 -0700205} // namespace nfd