blob: 5d537abac37dae105954ed61131c56c35444fa6b [file] [log] [blame]
Yukai Tu2d6d5632015-10-26 11:06:02 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento32065652017-01-15 01:52:21 -05003 * Copyright (c) 2014-2017, Regents of the University of California,
Yukai Tu2d6d5632015-10-26 11:06:02 -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
26#include "face/websocket-transport.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070027#include "face/face.hpp"
Yukai Tu2d6d5632015-10-26 11:06:02 -070028
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020029#include "dummy-receive-link-service.hpp"
30#include "test-ip.hpp"
31#include "transport-test-common.hpp"
Yukai Tu2d6d5632015-10-26 11:06:02 -070032#include "tests/limited-io.hpp"
33
34namespace nfd {
35namespace face {
36namespace tests {
37
38using namespace nfd::tests;
39namespace ip = boost::asio::ip;
40
41BOOST_AUTO_TEST_SUITE(Face)
42
Junxiao Shicde37ad2015-12-24 01:02:05 -070043using nfd::Face;
44
Yukai Tu2d6d5632015-10-26 11:06:02 -070045/** \brief a fixture that accepts a single WebSocket connection from a client
46 */
47class SingleWebSocketFixture : public BaseFixture
48{
49public:
50 SingleWebSocketFixture()
51 : transport(nullptr)
52 , serverReceivedPackets(nullptr)
53 , clientShouldPong(true)
54 {
55 }
56
57 /** \brief initialize server and start listening
58 */
59 void
60 serverListen(const ip::tcp::endpoint& ep,
Weiwei Liu93606232016-02-26 16:32:11 -070061 const time::milliseconds& pongTimeout = time::seconds(1))
Yukai Tu2d6d5632015-10-26 11:06:02 -070062 {
63 server.clear_access_channels(websocketpp::log::alevel::all);
64 server.clear_error_channels(websocketpp::log::elevel::all);
65
66 server.init_asio(&g_io);
67 server.set_open_handler(bind(&SingleWebSocketFixture::serverHandleOpen, this, _1));
68 server.set_close_handler(bind(&SingleWebSocketFixture::serverHandleClose, this));
69 server.set_message_handler(bind(&SingleWebSocketFixture::serverHandleMessage, this, _2));
70 server.set_pong_handler(bind(&SingleWebSocketFixture::serverHandlePong, this));
71 server.set_pong_timeout_handler(bind(&SingleWebSocketFixture::serverHandlePongTimeout, this));
72 server.set_pong_timeout(pongTimeout.count());
73
74 server.set_reuse_addr(true);
75
76 server.listen(ep);
77 server.start_accept();
78 }
79
80 /** \brief initialize client and connect to server
81 */
82 void
83 clientConnect(const std::string& uri)
84 {
85 client.clear_access_channels(websocketpp::log::alevel::all);
86 client.clear_error_channels(websocketpp::log::elevel::all);
87
88 client.init_asio(&g_io);
89 client.set_open_handler(bind(&SingleWebSocketFixture::clientHandleOpen, this, _1));
90 client.set_message_handler(bind(&SingleWebSocketFixture::clientHandleMessage, this, _2));
91 client.set_ping_handler(bind(&SingleWebSocketFixture::clientHandlePing, this));
92
93 websocketpp::lib::error_code ec;
Davide Pesavento3495b802016-09-19 02:36:59 +020094 auto con = client.get_connection(uri, ec);
Davide Pesaventoeee53aa2016-04-11 17:20:21 +020095 BOOST_REQUIRE_EQUAL(ec, websocketpp::lib::error_code());
Yukai Tu2d6d5632015-10-26 11:06:02 -070096
97 client.connect(con);
98 }
99
100 void
Weiwei Liu93606232016-02-26 16:32:11 -0700101 makeFace(const time::milliseconds& pingInterval = time::seconds(10))
Yukai Tu2d6d5632015-10-26 11:06:02 -0700102 {
Junxiao Shicde37ad2015-12-24 01:02:05 -0700103 face = make_unique<Face>(
Yukai Tu2d6d5632015-10-26 11:06:02 -0700104 make_unique<DummyReceiveLinkService>(),
105 make_unique<WebSocketTransport>(serverHdl, ref(server), pingInterval));
106 transport = static_cast<WebSocketTransport*>(face->getTransport());
107 serverReceivedPackets = &static_cast<DummyReceiveLinkService*>(face->getLinkService())->receivedPackets;
108 }
109
110 /** \brief initialize both server and client, and have each other connected, create Transport
111 */
112 void
113 endToEndInitialize(const ip::tcp::endpoint& ep,
Weiwei Liu93606232016-02-26 16:32:11 -0700114 const time::milliseconds& pingInterval = time::seconds(10),
115 const time::milliseconds& pongTimeout = time::seconds(1))
Yukai Tu2d6d5632015-10-26 11:06:02 -0700116 {
117 this->serverListen(ep, pongTimeout);
Eric Newberry4a4ccfe2016-07-21 22:51:04 -0700118 std::string uri;
119 if (ep.address().is_v6()) {
120 uri = "ws://[" + ep.address().to_string() + "]:" + to_string(ep.port());
121 }
122 else {
123 uri = "ws://" + ep.address().to_string() + ":" + to_string(ep.port());
124 }
Yukai Tu2d6d5632015-10-26 11:06:02 -0700125 this->clientConnect(uri);
126 BOOST_REQUIRE_EQUAL(limitedIo.run(2, // serverHandleOpen, clientHandleOpen
127 time::seconds(1)), LimitedIo::EXCEED_OPS);
128 this->makeFace(pingInterval);
129 }
130
131private:
132 void
133 serverHandleOpen(websocketpp::connection_hdl hdl)
134 {
Davide Pesavento3495b802016-09-19 02:36:59 +0200135 websocketpp::lib::error_code ec;
136 auto con = server.get_con_from_hdl(hdl, ec);
137 BOOST_REQUIRE_EQUAL(ec, websocketpp::lib::error_code());
138 BOOST_REQUIRE(con);
139 remoteEp = con->get_socket().remote_endpoint();
140
Yukai Tu2d6d5632015-10-26 11:06:02 -0700141 serverHdl = hdl;
142 limitedIo.afterOp();
143 }
144
145 void
146 serverHandleClose()
147 {
148 if (transport == nullptr) {
149 return;
150 }
151
152 transport->close();
153 limitedIo.afterOp();
154 }
155
156 void
157 serverHandleMessage(websocket::Server::message_ptr msg)
158 {
159 if (transport == nullptr) {
160 return;
161 }
162
163 transport->receiveMessage(msg->get_payload());
164 limitedIo.afterOp();
165 }
166
167 void
168 serverHandlePong()
169 {
170 if (transport == nullptr) {
171 return;
172 }
173
174 transport->handlePong();
175 limitedIo.afterOp();
176 }
177
178 void
179 serverHandlePongTimeout()
180 {
181 if (transport == nullptr) {
182 return;
183 }
184
185 transport->handlePongTimeout();
186 limitedIo.afterOp();
187 }
188
189 void
190 clientHandleOpen(websocketpp::connection_hdl hdl)
191 {
192 clientHdl = hdl;
193 limitedIo.afterOp();
194 }
195
196 void
197 clientHandleMessage(websocket::Client::message_ptr msg)
198 {
199 clientReceivedMessages.push_back(msg->get_payload());
200 limitedIo.afterOp();
201 }
202
203 bool
204 clientHandlePing()
205 {
206 limitedIo.afterOp();
207 return clientShouldPong;
208 }
209
210public:
211 LimitedIo limitedIo;
212
213 websocket::Server server;
214 websocketpp::connection_hdl serverHdl;
Davide Pesavento3495b802016-09-19 02:36:59 +0200215 ip::tcp::endpoint remoteEp;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700216 unique_ptr<Face> face;
Yukai Tu2d6d5632015-10-26 11:06:02 -0700217 WebSocketTransport* transport;
218 std::vector<Transport::Packet>* serverReceivedPackets;
219
220 websocket::Client client;
221 websocketpp::connection_hdl clientHdl;
222 bool clientShouldPong;
223 std::vector<std::string> clientReceivedMessages;
224};
225
226BOOST_FIXTURE_TEST_SUITE(TestWebSocketTransport, SingleWebSocketFixture)
227
Weiwei Liu93606232016-02-26 16:32:11 -0700228BOOST_AUTO_TEST_CASE(StaticPropertiesLocalIpv4)
Yukai Tu2d6d5632015-10-26 11:06:02 -0700229{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200230 auto address = getTestIp<ip::address_v4>(LoopbackAddress::Yes);
231 SKIP_IF_IP_UNAVAILABLE(address);
Davide Pesavento3495b802016-09-19 02:36:59 +0200232 ip::tcp::endpoint ep(address, 20070);
233 this->endToEndInitialize(ep);
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200234
Yukai Tu2d6d5632015-10-26 11:06:02 -0700235 checkStaticPropertiesInitialized(*transport);
236
Davide Pesavento3495b802016-09-19 02:36:59 +0200237 BOOST_CHECK_EQUAL(transport->getLocalUri(), FaceUri(ep, "ws"));
238 BOOST_CHECK_EQUAL(transport->getRemoteUri(), FaceUri(remoteEp, "wsclient"));
Yukai Tu2d6d5632015-10-26 11:06:02 -0700239 BOOST_CHECK_EQUAL(transport->getScope(), ndn::nfd::FACE_SCOPE_LOCAL);
240 BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
241 BOOST_CHECK_EQUAL(transport->getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
242 BOOST_CHECK_EQUAL(transport->getMtu(), MTU_UNLIMITED);
243}
244
Weiwei Liu93606232016-02-26 16:32:11 -0700245BOOST_AUTO_TEST_CASE(StaticPropertiesNonLocalIpv4)
246{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200247 auto address = getTestIp<ip::address_v4>(LoopbackAddress::No);
Weiwei Liu93606232016-02-26 16:32:11 -0700248 SKIP_IF_IP_UNAVAILABLE(address);
Davide Pesavento3495b802016-09-19 02:36:59 +0200249 ip::tcp::endpoint ep(address, 20070);
250 this->endToEndInitialize(ep);
Weiwei Liu93606232016-02-26 16:32:11 -0700251
Weiwei Liu93606232016-02-26 16:32:11 -0700252 checkStaticPropertiesInitialized(*transport);
253
Davide Pesavento3495b802016-09-19 02:36:59 +0200254 BOOST_CHECK_EQUAL(transport->getLocalUri(), FaceUri(ep, "ws"));
255 BOOST_CHECK_EQUAL(transport->getRemoteUri(), FaceUri(remoteEp, "wsclient"));
Weiwei Liu93606232016-02-26 16:32:11 -0700256 BOOST_CHECK_EQUAL(transport->getScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
257 BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
258 BOOST_CHECK_EQUAL(transport->getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
259 BOOST_CHECK_EQUAL(transport->getMtu(), MTU_UNLIMITED);
260}
261
Eric Newberry4a4ccfe2016-07-21 22:51:04 -0700262BOOST_AUTO_TEST_CASE(StaticPropertiesLocalIpv4MappedIpv6)
263{
264 auto address4 = getTestIp<ip::address_v4>(LoopbackAddress::Yes);
265 SKIP_IF_IP_UNAVAILABLE(address4);
266 auto address6 = ip::address_v6::v4_mapped(address4);
267 BOOST_REQUIRE(address6.is_v4_mapped());
Davide Pesavento3495b802016-09-19 02:36:59 +0200268 ip::tcp::endpoint ep(address6, 20070);
269 this->endToEndInitialize(ep);
Eric Newberry4a4ccfe2016-07-21 22:51:04 -0700270
271 checkStaticPropertiesInitialized(*transport);
272
Davide Pesavento3495b802016-09-19 02:36:59 +0200273 BOOST_CHECK_EQUAL(transport->getLocalUri(), FaceUri(ep, "ws"));
274 BOOST_CHECK_EQUAL(transport->getRemoteUri(), FaceUri(remoteEp, "wsclient"));
Eric Newberry4a4ccfe2016-07-21 22:51:04 -0700275 BOOST_CHECK_EQUAL(transport->getScope(), ndn::nfd::FACE_SCOPE_LOCAL);
276 BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
277 BOOST_CHECK_EQUAL(transport->getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
278 BOOST_CHECK_EQUAL(transport->getMtu(), MTU_UNLIMITED);
279}
280
Davide Pesavento32065652017-01-15 01:52:21 -0500281BOOST_AUTO_TEST_CASE(PersistencyChange)
282{
283 auto address = getTestIp<ip::address_v4>();
284 SKIP_IF_IP_UNAVAILABLE(address);
285 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
286
287 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND), true);
288 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERSISTENT), false);
289 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERMANENT), false);
290}
291
Yukai Tu2d6d5632015-10-26 11:06:02 -0700292BOOST_AUTO_TEST_CASE(PingPong)
293{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200294 auto address = getTestIp<ip::address_v4>();
295 SKIP_IF_IP_UNAVAILABLE(address);
296 this->endToEndInitialize(ip::tcp::endpoint(address, 20070),
297 time::milliseconds(500), time::milliseconds(300));
Yukai Tu2d6d5632015-10-26 11:06:02 -0700298
299 BOOST_CHECK_EQUAL(limitedIo.run(2, // clientHandlePing, serverHandlePong
300 time::milliseconds(1500)), LimitedIo::EXCEED_OPS);
Weiwei Liu93606232016-02-26 16:32:11 -0700301
Yukai Tu2d6d5632015-10-26 11:06:02 -0700302 BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
Junxiao Shi57df2882015-11-11 06:12:35 -0700303 BOOST_CHECK_EQUAL(transport->getCounters().nOutPings, 1);
304 BOOST_CHECK_EQUAL(transport->getCounters().nInPongs, 1);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700305
306 this->clientShouldPong = false;
307 BOOST_CHECK_EQUAL(limitedIo.run(2, // clientHandlePing, serverHandlePongTimeout
Weiwei Liu93606232016-02-26 16:32:11 -0700308 time::seconds(2)), LimitedIo::EXCEED_OPS);
309
Yukai Tu2d6d5632015-10-26 11:06:02 -0700310 BOOST_CHECK_MESSAGE(transport->getState() == TransportState::FAILED ||
311 transport->getState() == TransportState::CLOSED,
312 "expect FAILED or CLOSED state, actual state=" << transport->getState());
Junxiao Shi57df2882015-11-11 06:12:35 -0700313 BOOST_CHECK_EQUAL(transport->getCounters().nOutPings, 2);
314 BOOST_CHECK_EQUAL(transport->getCounters().nInPongs, 1);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700315}
316
317BOOST_AUTO_TEST_CASE(Send)
318{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200319 auto address = getTestIp<ip::address_v4>();
320 SKIP_IF_IP_UNAVAILABLE(address);
321 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
Yukai Tu2d6d5632015-10-26 11:06:02 -0700322
323 Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
324 transport->send(Transport::Packet(Block(pkt1)));
325 BOOST_CHECK_EQUAL(limitedIo.run(1, // clientHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700326 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700327
328 Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
329 transport->send(Transport::Packet(Block(pkt2)));
330 BOOST_CHECK_EQUAL(limitedIo.run(1, // clientHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700331 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700332
333 BOOST_REQUIRE_EQUAL(clientReceivedMessages.size(), 2);
334 BOOST_CHECK_EQUAL_COLLECTIONS(
335 reinterpret_cast<const uint8_t*>(clientReceivedMessages[0].data()),
336 reinterpret_cast<const uint8_t*>(clientReceivedMessages[0].data()) + clientReceivedMessages[0].size(),
337 pkt1.begin(), pkt1.end());
338 BOOST_CHECK_EQUAL_COLLECTIONS(
339 reinterpret_cast<const uint8_t*>(clientReceivedMessages[1].data()),
340 reinterpret_cast<const uint8_t*>(clientReceivedMessages[1].data()) + clientReceivedMessages[1].size(),
341 pkt2.begin(), pkt2.end());
342}
343
Weiwei Liu93606232016-02-26 16:32:11 -0700344BOOST_AUTO_TEST_CASE(ReceiveNormal)
Yukai Tu2d6d5632015-10-26 11:06:02 -0700345{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200346 auto address = getTestIp<ip::address_v4>();
347 SKIP_IF_IP_UNAVAILABLE(address);
348 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
Yukai Tu2d6d5632015-10-26 11:06:02 -0700349
350 Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
351 client.send(clientHdl, pkt1.wire(), pkt1.size(), websocketpp::frame::opcode::binary);
352 BOOST_CHECK_EQUAL(limitedIo.run(1, // serverHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700353 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700354
355 Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
356 client.send(clientHdl, pkt2.wire(), pkt2.size(), websocketpp::frame::opcode::binary);
357 BOOST_CHECK_EQUAL(limitedIo.run(1, // serverHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700358 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700359
360 BOOST_REQUIRE_EQUAL(serverReceivedPackets->size(), 2);
361 BOOST_CHECK(serverReceivedPackets->at(0).packet == pkt1);
362 BOOST_CHECK(serverReceivedPackets->at(1).packet == pkt2);
363 BOOST_CHECK_EQUAL(serverReceivedPackets->at(0).remoteEndpoint, serverReceivedPackets->at(1).remoteEndpoint);
364}
365
366BOOST_AUTO_TEST_CASE(ReceiveMalformed)
367{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200368 auto address = getTestIp<ip::address_v4>();
369 SKIP_IF_IP_UNAVAILABLE(address);
370 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
Yukai Tu2d6d5632015-10-26 11:06:02 -0700371
372 Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
373 client.send(clientHdl, pkt1.wire(), pkt1.size() - 1, // truncated
374 websocketpp::frame::opcode::binary);
375 BOOST_CHECK_EQUAL(limitedIo.run(1, // serverHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700376 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700377
378 // bad packet is dropped
379 BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
380 BOOST_CHECK_EQUAL(serverReceivedPackets->size(), 0);
381
382 Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
383 client.send(clientHdl, pkt2.wire(), pkt2.size(), websocketpp::frame::opcode::binary);
384 BOOST_CHECK_EQUAL(limitedIo.run(1, // serverHandleMessage
Weiwei Liu93606232016-02-26 16:32:11 -0700385 time::seconds(1)), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700386
387 // next valid packet is still received normally
388 BOOST_REQUIRE_EQUAL(serverReceivedPackets->size(), 1);
389 BOOST_CHECK(serverReceivedPackets->at(0).packet == pkt2);
390}
391
Weiwei Liu93606232016-02-26 16:32:11 -0700392BOOST_AUTO_TEST_CASE(Close)
393{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200394 auto address = getTestIp<ip::address_v4>();
395 SKIP_IF_IP_UNAVAILABLE(address);
396 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
Weiwei Liu93606232016-02-26 16:32:11 -0700397
398 int nStateChanges = 0;
399 transport->afterStateChange.connect(
400 [&nStateChanges] (TransportState oldState, TransportState newState) {
401 switch (nStateChanges) {
402 case 0:
403 BOOST_CHECK_EQUAL(oldState, TransportState::UP);
404 BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
405 break;
406 case 1:
407 BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
408 BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
409 break;
410 default:
411 BOOST_CHECK(false);
412 }
413 nStateChanges++;
414 });
415
416 transport->close();
417 BOOST_CHECK_EQUAL(nStateChanges, 2);
418}
419
420BOOST_AUTO_TEST_CASE(RemoteClose)
421{
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200422 auto address = getTestIp<ip::address_v4>();
423 SKIP_IF_IP_UNAVAILABLE(address);
424 this->endToEndInitialize(ip::tcp::endpoint(address, 20070));
Weiwei Liu93606232016-02-26 16:32:11 -0700425
426 int nStateChanges = 0;
427 transport->afterStateChange.connect(
428 [&nStateChanges] (TransportState oldState, TransportState newState) {
429 switch (nStateChanges) {
430 case 0:
431 BOOST_CHECK_EQUAL(oldState, TransportState::UP);
432 BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
433 break;
434 case 1:
435 BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
436 BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
437 break;
438 default:
439 BOOST_CHECK(false);
440 }
441 nStateChanges++;
442 });
443
444 client.close(clientHdl, websocketpp::close::status::going_away, "");
445 BOOST_CHECK_EQUAL(limitedIo.run(1, // serverHandleClose
446 time::seconds(1)), LimitedIo::EXCEED_OPS);
447
448 BOOST_CHECK_EQUAL(nStateChanges, 2);
449}
450
Yukai Tu2d6d5632015-10-26 11:06:02 -0700451BOOST_AUTO_TEST_SUITE_END() // TestWebSocketTransport
452BOOST_AUTO_TEST_SUITE_END() // Face
453
454} // namespace tests
455} // namespace face
456} // namespace nfd