blob: ee796ab9662e302bbe8ee6a4e1976a43376d6dc6 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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
26#include "face/tcp-factory.hpp"
27
28#include "core/network-interface.hpp"
29#include "tests/test-common.hpp"
30#include "tests/limited-io.hpp"
31
32namespace nfd {
33namespace tests {
34
35BOOST_AUTO_TEST_SUITE(Face)
36BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, BaseFixture)
37
38using nfd::Face;
39
40BOOST_AUTO_TEST_CASE(ChannelMap)
41{
42 TcpFactory factory;
43
44 shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
45 shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
46 BOOST_CHECK_EQUAL(channel1, channel1a);
47 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
48
49 shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
50 BOOST_CHECK_NE(channel1, channel2);
51
52 shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
53 BOOST_CHECK_NE(channel2, channel3);
54 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
55}
56
57BOOST_AUTO_TEST_CASE(GetChannels)
58{
59 TcpFactory factory;
60 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
61
62 std::vector<shared_ptr<const Channel>> expectedChannels;
63 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
64 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
65 expectedChannels.push_back(factory.createChannel("::1", "20071"));
66
67 for (const auto& ch : factory.getChannels()) {
68 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), ch);
69 BOOST_REQUIRE(pos != expectedChannels.end());
70 expectedChannels.erase(pos);
71 }
72 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
73}
74
75class FaceCreateFixture : public BaseFixture
76{
77public:
78 void
79 checkError(const std::string& errorActual, const std::string& errorExpected)
80 {
81 BOOST_CHECK_EQUAL(errorActual, errorExpected);
82 }
83
84 void
85 failIfError(const std::string& errorActual)
86 {
87 BOOST_FAIL("No error expected, but got: [" << errorActual << "]");
88 }
89};
90
91BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
92{
93 TcpFactory factory;
94
95 factory.createFace(FaceUri("tcp4://127.0.0.1:6363"),
96 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
97 bind([]{}),
98 bind(&FaceCreateFixture::checkError, this, _1,
99 "No channels available to connect to 127.0.0.1:6363"));
100
101 factory.createChannel("127.0.0.1", "20071");
102
103 factory.createFace(FaceUri("tcp4://127.0.0.1:20070"),
104 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
105 bind([]{}),
106 bind(&FaceCreateFixture::failIfError, this, _1));
107}
108
109BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
110{
111 TcpFactory factory;
112
113 factory.createChannel("127.0.0.1", "20070");
114 factory.createChannel("127.0.0.1", "20071");
115
116 BOOST_CHECK_THROW(factory.createFace(FaceUri("tcp4://127.0.0.1:20070"),
117 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
118 bind([]{}),
119 bind([]{})),
120 ProtocolFactory::Error);
121
122 BOOST_CHECK_THROW(factory.createFace(FaceUri("tcp4://127.0.0.1:20071"),
123 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
124 bind([]{}),
125 bind([]{})),
126 ProtocolFactory::Error);
127}
128
129class FaceCreateTimeoutFixture : public BaseFixture
130{
131public:
132 void
133 onFaceCreated(const shared_ptr<Face>& newFace)
134 {
135 BOOST_CHECK_MESSAGE(false, "Timeout expected");
136 BOOST_CHECK(!static_cast<bool>(face1));
137 face1 = newFace;
138
139 limitedIo.afterOp();
140 }
141
142 void
143 onConnectFailed(const std::string& reason)
144 {
145 BOOST_CHECK_MESSAGE(true, reason);
146
147 limitedIo.afterOp();
148 }
149
150public:
151 LimitedIo limitedIo;
152
153 shared_ptr<Face> face1;
154};
155
156BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
157{
158 TcpFactory factory;
159 shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
160
161 factory.createFace(FaceUri("tcp4://192.0.2.1:20070"),
162 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
163 bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
164 bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
165
166 BOOST_CHECK_MESSAGE(limitedIo.run(1, time::seconds(10)) == LimitedIo::EXCEED_OPS,
167 "TcpChannel error: cannot connect or cannot accept connection");
168
169 BOOST_CHECK_EQUAL(static_cast<bool>(face1), false);
170}
171
172class FakeNetworkInterfaceFixture : public BaseFixture
173{
174public:
175 FakeNetworkInterfaceFixture()
176 {
177 using namespace boost::asio::ip;
178
179 auto fakeInterfaces = make_shared<std::vector<NetworkInterfaceInfo>>();
180
181 fakeInterfaces->push_back(
182 NetworkInterfaceInfo {0, "eth0",
183 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
184 {address_v4::from_string("0.0.0.0")},
185 {address_v6::from_string("::")},
186 address_v4(),
187 IFF_UP});
188 fakeInterfaces->push_back(
189 NetworkInterfaceInfo {1, "eth0",
190 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
191 {address_v4::from_string("192.168.2.1"), address_v4::from_string("192.168.2.2")},
192 {},
193 address_v4::from_string("192.168.2.255"),
194 0});
195 fakeInterfaces->push_back(
196 NetworkInterfaceInfo {2, "eth1",
197 ethernet::Address::fromString("3e:15:c2:8b:65:00"),
198 {address_v4::from_string("198.51.100.1")},
199 {address_v6::from_string("2001:db8::2"), address_v6::from_string("2001:db8::3")},
200 address_v4::from_string("198.51.100.255"),
201 IFF_MULTICAST | IFF_BROADCAST | IFF_UP});
202
203 setDebugNetworkInterfaces(fakeInterfaces);
204 }
205
206 ~FakeNetworkInterfaceFixture()
207 {
208 setDebugNetworkInterfaces(nullptr);
209 }
210};
211
212BOOST_FIXTURE_TEST_CASE(Bug2292, FakeNetworkInterfaceFixture)
213{
214 using namespace boost::asio::ip;
215
216 TcpFactory factory;
217 factory.prohibitEndpoint(tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024));
218 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
219 BOOST_CHECK((factory.m_prohibitedEndpoints ==
220 std::set<tcp::Endpoint> {
221 tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
222 }));
223
224 factory.m_prohibitedEndpoints.clear();
225 factory.prohibitEndpoint(tcp::Endpoint(address_v6::from_string("2001:db8::1"), 2048));
226 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 1);
227 BOOST_CHECK((factory.m_prohibitedEndpoints ==
228 std::set<tcp::Endpoint> {
229 tcp::Endpoint(address_v6::from_string("2001:db8::1"), 2048)
230 }));
231
232 factory.m_prohibitedEndpoints.clear();
233 factory.prohibitEndpoint(tcp::Endpoint(address_v4(), 1024));
234 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 4);
235 BOOST_CHECK((factory.m_prohibitedEndpoints ==
236 std::set<tcp::Endpoint> {
237 tcp::Endpoint(address_v4::from_string("192.168.2.1"), 1024),
238 tcp::Endpoint(address_v4::from_string("192.168.2.2"), 1024),
239 tcp::Endpoint(address_v4::from_string("198.51.100.1"), 1024),
240 tcp::Endpoint(address_v4::from_string("0.0.0.0"), 1024)
241 }));
242
243 factory.m_prohibitedEndpoints.clear();
244 factory.prohibitEndpoint(tcp::Endpoint(address_v6(), 2048));
245 BOOST_REQUIRE_EQUAL(factory.m_prohibitedEndpoints.size(), 3);
246 BOOST_CHECK((factory.m_prohibitedEndpoints ==
247 std::set<tcp::Endpoint> {
248 tcp::Endpoint(address_v6::from_string("2001:db8::2"), 2048),
249 tcp::Endpoint(address_v6::from_string("2001:db8::3"), 2048),
250 tcp::Endpoint(address_v6::from_string("::"), 2048)
251 }));
252}
253
254BOOST_AUTO_TEST_SUITE_END() // TestTcpFactory
255BOOST_AUTO_TEST_SUITE_END() // Face
256
257} // namespace tests
258} // namespace nfd