blob: d28d8a3094362b609cd88b93a292a921897edfb6 [file] [log] [blame]
Yukai Tu2d6d5632015-10-26 11:06:02 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi84d62cb2017-07-12 16:15:18 +00002/*
Davide Pesaventod91fe6d2023-10-04 21:40:02 -04003 * Copyright (c) 2014-2023, 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
Davide Pesavento22fba352017-10-17 15:53:51 -040026#include "websocket-transport-fixture.hpp"
27
28#include <boost/mpl/vector.hpp>
Yukai Tu2d6d5632015-10-26 11:06:02 -070029
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040030namespace nfd::tests {
31
32using namespace nfd::face;
Yukai Tu2d6d5632015-10-26 11:06:02 -070033
Yukai Tu2d6d5632015-10-26 11:06:02 -070034BOOST_AUTO_TEST_SUITE(Face)
Davide Pesavento22fba352017-10-17 15:53:51 -040035BOOST_FIXTURE_TEST_SUITE(TestWebSocketTransport, IpTransportFixture<WebSocketTransportFixture>)
Yukai Tu2d6d5632015-10-26 11:06:02 -070036
Davide Pesavento22fba352017-10-17 15:53:51 -040037using WebSocketTransportFixtures = boost::mpl::vector<
38 GENERATE_IP_TRANSPORT_FIXTURE_INSTANTIATIONS(WebSocketTransportFixture)
39>;
Junxiao Shicde37ad2015-12-24 01:02:05 -070040
Davide Pesavento22fba352017-10-17 15:53:51 -040041BOOST_FIXTURE_TEST_CASE_TEMPLATE(StaticProperties, T, WebSocketTransportFixtures, T)
Yukai Tu2d6d5632015-10-26 11:06:02 -070042{
Davide Pesavento22fba352017-10-17 15:53:51 -040043 TRANSPORT_TEST_INIT();
Yukai Tu2d6d5632015-10-26 11:06:02 -070044
Davide Pesavento22fba352017-10-17 15:53:51 -040045 checkStaticPropertiesInitialized(*this->transport);
Yukai Tu2d6d5632015-10-26 11:06:02 -070046
Davide Pesavento22fba352017-10-17 15:53:51 -040047 BOOST_CHECK_EQUAL(this->transport->getLocalUri(), FaceUri(ip::tcp::endpoint(this->address, 20070), "ws"));
48 BOOST_CHECK_EQUAL(this->transport->getRemoteUri(), FaceUri(this->remoteEp, "wsclient"));
49 BOOST_CHECK_EQUAL(this->transport->getScope(),
50 this->addressScope == AddressScope::Loopback ? ndn::nfd::FACE_SCOPE_LOCAL
51 : ndn::nfd::FACE_SCOPE_NON_LOCAL);
52 BOOST_CHECK_EQUAL(this->transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
53 BOOST_CHECK_EQUAL(this->transport->getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
54 BOOST_CHECK_EQUAL(this->transport->getMtu(), MTU_UNLIMITED);
Eric Newberryb49313d2017-12-24 20:22:27 -070055 BOOST_CHECK_EQUAL(this->transport->getSendQueueCapacity(), QUEUE_UNSUPPORTED);
Yukai Tu2d6d5632015-10-26 11:06:02 -070056}
57
Davide Pesavento22fba352017-10-17 15:53:51 -040058using StaticPropertiesV4MappedFixtures = boost::mpl::vector<
59 IpTransportFixture<WebSocketTransportFixture, AddressFamily::V4, AddressScope::Loopback>,
60 IpTransportFixture<WebSocketTransportFixture, AddressFamily::V4, AddressScope::Global>
61>;
62
63BOOST_FIXTURE_TEST_CASE_TEMPLATE(StaticPropertiesV4Mapped, T, StaticPropertiesV4MappedFixtures, T)
Weiwei Liu93606232016-02-26 16:32:11 -070064{
Davide Pesavento22fba352017-10-17 15:53:51 -040065 TRANSPORT_TEST_CHECK_PRECONDITIONS();
Davide Pesaventod91fe6d2023-10-04 21:40:02 -040066 auto mappedAddr = ip::make_address_v6(ip::v4_mapped, this->address.to_v4());
Davide Pesavento22fba352017-10-17 15:53:51 -040067 BOOST_REQUIRE(mappedAddr.is_v4_mapped());
Davide Pesavento279af1c2022-08-29 20:18:32 -040068 WebSocketTransportFixture::initialize(this->interface, mappedAddr);
Weiwei Liu93606232016-02-26 16:32:11 -070069
Davide Pesavento22fba352017-10-17 15:53:51 -040070 checkStaticPropertiesInitialized(*this->transport);
Weiwei Liu93606232016-02-26 16:32:11 -070071
Davide Pesavento22fba352017-10-17 15:53:51 -040072 BOOST_CHECK_EQUAL(this->transport->getLocalUri(), FaceUri(ip::tcp::endpoint(mappedAddr, 20070), "ws"));
73 BOOST_CHECK_EQUAL(this->transport->getRemoteUri(), FaceUri(this->remoteEp, "wsclient"));
74 BOOST_CHECK_EQUAL(this->transport->getScope(),
75 this->addressScope == AddressScope::Loopback ? ndn::nfd::FACE_SCOPE_LOCAL
76 : ndn::nfd::FACE_SCOPE_NON_LOCAL);
77 BOOST_CHECK_EQUAL(this->transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
78 BOOST_CHECK_EQUAL(this->transport->getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
79 BOOST_CHECK_EQUAL(this->transport->getMtu(), MTU_UNLIMITED);
Eric Newberry4a4ccfe2016-07-21 22:51:04 -070080}
81
Davide Pesavento32065652017-01-15 01:52:21 -050082BOOST_AUTO_TEST_CASE(PersistencyChange)
83{
Davide Pesavento22fba352017-10-17 15:53:51 -040084 TRANSPORT_TEST_INIT();
Davide Pesavento32065652017-01-15 01:52:21 -050085
86 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND), true);
87 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERSISTENT), false);
88 BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERMANENT), false);
89}
90
Davide Pesavento22fba352017-10-17 15:53:51 -040091BOOST_FIXTURE_TEST_CASE_TEMPLATE(PingPong, T, WebSocketTransportFixtures, T)
Yukai Tu2d6d5632015-10-26 11:06:02 -070092{
Davide Pesavento14e71f02019-03-28 17:35:25 -040093 TRANSPORT_TEST_INIT(500_ms, 300_ms);
Yukai Tu2d6d5632015-10-26 11:06:02 -070094
Davide Pesavento22fba352017-10-17 15:53:51 -040095 BOOST_CHECK_EQUAL(this->limitedIo.run(2, // clientHandlePing, serverHandlePong
Davide Pesavento14e71f02019-03-28 17:35:25 -040096 1500_ms), LimitedIo::EXCEED_OPS);
Weiwei Liu93606232016-02-26 16:32:11 -070097
Davide Pesavento22fba352017-10-17 15:53:51 -040098 BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
99 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPings, 1);
100 BOOST_CHECK_EQUAL(this->transport->getCounters().nInPongs, 1);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700101
102 this->clientShouldPong = false;
Davide Pesavento22fba352017-10-17 15:53:51 -0400103 BOOST_CHECK_EQUAL(this->limitedIo.run(2, // clientHandlePing, serverHandlePongTimeout
Davide Pesavento14e71f02019-03-28 17:35:25 -0400104 2_s), LimitedIo::EXCEED_OPS);
Weiwei Liu93606232016-02-26 16:32:11 -0700105
Davide Pesavento22fba352017-10-17 15:53:51 -0400106 BOOST_CHECK_MESSAGE(this->transport->getState() == TransportState::FAILED ||
107 this->transport->getState() == TransportState::CLOSED,
108 "expected FAILED or CLOSED state, actual state=" << this->transport->getState());
109 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPings, 2);
110 BOOST_CHECK_EQUAL(this->transport->getCounters().nInPongs, 1);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700111}
112
Davide Pesavento22fba352017-10-17 15:53:51 -0400113BOOST_FIXTURE_TEST_CASE_TEMPLATE(Send, T, WebSocketTransportFixtures, T)
Yukai Tu2d6d5632015-10-26 11:06:02 -0700114{
Davide Pesavento22fba352017-10-17 15:53:51 -0400115 TRANSPORT_TEST_INIT();
116
117 auto block1 = ndn::encoding::makeStringBlock(300, "hello");
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400118 this->transport->send(block1);
Davide Pesavento22fba352017-10-17 15:53:51 -0400119 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // clientHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400120 1_s), LimitedIo::EXCEED_OPS);
Davide Pesavento22fba352017-10-17 15:53:51 -0400121 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 1);
122 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size());
123
124 auto block2 = ndn::encoding::makeStringBlock(301, "world");
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400125 this->transport->send(block2);
Davide Pesavento22fba352017-10-17 15:53:51 -0400126 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // clientHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400127 1_s), LimitedIo::EXCEED_OPS);
Davide Pesavento22fba352017-10-17 15:53:51 -0400128 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 2);
129 BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size() + block2.size());
130
131 BOOST_REQUIRE_EQUAL(this->clientReceivedMessages.size(), 2);
132 BOOST_CHECK_EQUAL_COLLECTIONS(
133 reinterpret_cast<const uint8_t*>(this->clientReceivedMessages[0].data()),
134 reinterpret_cast<const uint8_t*>(this->clientReceivedMessages[0].data()) + this->clientReceivedMessages[0].size(),
135 block1.begin(), block1.end());
136 BOOST_CHECK_EQUAL_COLLECTIONS(
137 reinterpret_cast<const uint8_t*>(this->clientReceivedMessages[1].data()),
138 reinterpret_cast<const uint8_t*>(this->clientReceivedMessages[1].data()) + this->clientReceivedMessages[1].size(),
139 block2.begin(), block2.end());
140 BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
141}
142
143BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveNormal, T, WebSocketTransportFixtures, T)
144{
145 TRANSPORT_TEST_INIT();
Yukai Tu2d6d5632015-10-26 11:06:02 -0700146
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400147 auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
Davide Pesaventodeb54272022-03-11 18:51:05 -0500148 this->client.send(this->clientHdl, pkt1.data(), pkt1.size(), websocketpp::frame::opcode::binary);
Davide Pesavento22fba352017-10-17 15:53:51 -0400149 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400150 1_s), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700151
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400152 BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 1);
153 BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size());
154
155 auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
Davide Pesaventodeb54272022-03-11 18:51:05 -0500156 this->client.send(this->clientHdl, pkt2.data(), pkt2.size(), websocketpp::frame::opcode::binary);
Davide Pesavento22fba352017-10-17 15:53:51 -0400157 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400158 1_s), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700159
Davide Pesavento22fba352017-10-17 15:53:51 -0400160 BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 2);
161 BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size() + pkt2.size());
162 BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
163
164 BOOST_REQUIRE_EQUAL(this->serverReceivedPackets->size(), 2);
165 BOOST_CHECK(this->serverReceivedPackets->at(0).packet == pkt1);
166 BOOST_CHECK(this->serverReceivedPackets->at(1).packet == pkt2);
Teng Liangd94b7b32022-07-10 21:29:37 +0800167 BOOST_CHECK(this->serverReceivedPackets->at(0).endpoint == EndpointId{});
168 BOOST_CHECK(this->serverReceivedPackets->at(1).endpoint == EndpointId{});
Yukai Tu2d6d5632015-10-26 11:06:02 -0700169}
170
Davide Pesavento22fba352017-10-17 15:53:51 -0400171BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveMalformed, T, WebSocketTransportFixtures, T)
Yukai Tu2d6d5632015-10-26 11:06:02 -0700172{
Davide Pesavento22fba352017-10-17 15:53:51 -0400173 TRANSPORT_TEST_INIT();
Yukai Tu2d6d5632015-10-26 11:06:02 -0700174
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400175 auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
Davide Pesaventodeb54272022-03-11 18:51:05 -0500176 this->client.send(this->clientHdl, pkt1.data(), pkt1.size() - 1, // truncated
Davide Pesavento22fba352017-10-17 15:53:51 -0400177 websocketpp::frame::opcode::binary);
178 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400179 1_s), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700180
181 // bad packet is dropped
Davide Pesavento22fba352017-10-17 15:53:51 -0400182 BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
183 BOOST_CHECK_EQUAL(this->serverReceivedPackets->size(), 0);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700184
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400185 auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
Davide Pesaventodeb54272022-03-11 18:51:05 -0500186 this->client.send(this->clientHdl, pkt2.data(), pkt2.size(), websocketpp::frame::opcode::binary);
Davide Pesavento22fba352017-10-17 15:53:51 -0400187 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
Davide Pesavento14e71f02019-03-28 17:35:25 -0400188 1_s), LimitedIo::EXCEED_OPS);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700189
190 // next valid packet is still received normally
Davide Pesavento22fba352017-10-17 15:53:51 -0400191 BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
192 BOOST_REQUIRE_EQUAL(this->serverReceivedPackets->size(), 1);
193 BOOST_CHECK(this->serverReceivedPackets->at(0).packet == pkt2);
Yukai Tu2d6d5632015-10-26 11:06:02 -0700194}
195
Davide Pesavento22fba352017-10-17 15:53:51 -0400196BOOST_FIXTURE_TEST_CASE_TEMPLATE(Close, T, WebSocketTransportFixtures, T)
Weiwei Liu93606232016-02-26 16:32:11 -0700197{
Davide Pesavento22fba352017-10-17 15:53:51 -0400198 TRANSPORT_TEST_INIT();
Weiwei Liu93606232016-02-26 16:32:11 -0700199
200 int nStateChanges = 0;
Davide Pesavento22fba352017-10-17 15:53:51 -0400201 this->transport->afterStateChange.connect(
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400202 [&nStateChanges] (auto oldState, auto newState) {
Weiwei Liu93606232016-02-26 16:32:11 -0700203 switch (nStateChanges) {
204 case 0:
205 BOOST_CHECK_EQUAL(oldState, TransportState::UP);
206 BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
207 break;
208 case 1:
209 BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
210 BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
211 break;
212 default:
213 BOOST_CHECK(false);
214 }
215 nStateChanges++;
216 });
217
Davide Pesavento22fba352017-10-17 15:53:51 -0400218 this->transport->close();
Weiwei Liu93606232016-02-26 16:32:11 -0700219 BOOST_CHECK_EQUAL(nStateChanges, 2);
220}
221
Davide Pesavento22fba352017-10-17 15:53:51 -0400222BOOST_FIXTURE_TEST_CASE_TEMPLATE(RemoteClose, T, WebSocketTransportFixtures, T)
Weiwei Liu93606232016-02-26 16:32:11 -0700223{
Davide Pesavento22fba352017-10-17 15:53:51 -0400224 TRANSPORT_TEST_INIT();
Weiwei Liu93606232016-02-26 16:32:11 -0700225
226 int nStateChanges = 0;
Davide Pesavento22fba352017-10-17 15:53:51 -0400227 this->transport->afterStateChange.connect(
Davide Pesaventob3a23ca2019-05-04 20:40:21 -0400228 [&nStateChanges] (auto oldState, auto newState) {
Weiwei Liu93606232016-02-26 16:32:11 -0700229 switch (nStateChanges) {
230 case 0:
231 BOOST_CHECK_EQUAL(oldState, TransportState::UP);
232 BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
233 break;
234 case 1:
235 BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
236 BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
237 break;
238 default:
239 BOOST_CHECK(false);
240 }
241 nStateChanges++;
242 });
243
Davide Pesavento22fba352017-10-17 15:53:51 -0400244 this->client.close(this->clientHdl, websocketpp::close::status::going_away, "");
245 BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleClose
Davide Pesavento14e71f02019-03-28 17:35:25 -0400246 1_s), LimitedIo::EXCEED_OPS);
Weiwei Liu93606232016-02-26 16:32:11 -0700247
248 BOOST_CHECK_EQUAL(nStateChanges, 2);
249}
250
Eric Newberryb49313d2017-12-24 20:22:27 -0700251BOOST_FIXTURE_TEST_CASE_TEMPLATE(SendQueueLength, T, WebSocketTransportFixtures, T)
252{
253 TRANSPORT_TEST_INIT();
254
255 BOOST_CHECK_EQUAL(this->transport->getSendQueueLength(), QUEUE_UNSUPPORTED);
256}
257
Yukai Tu2d6d5632015-10-26 11:06:02 -0700258BOOST_AUTO_TEST_SUITE_END() // TestWebSocketTransport
259BOOST_AUTO_TEST_SUITE_END() // Face
260
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400261} // namespace nfd::tests