blob: dc4cf361d3ccfa3bfe7b1e752acd3585c801d54f [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi909ffef2017-07-07 22:12:27 +00002/*
Davide Pesavento0c526032024-01-31 21:14:01 -05003 * Copyright (c) 2013-2024 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080020 */
21
Davide Pesavento394977c2020-04-25 21:40:31 -040022#define BOOST_TEST_MODULE ndn-cxx Integration (Face)
Davide Pesavento7e780642018-11-24 15:51:34 -050023#include "tests/boost-test.hpp"
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080024
Davide Pesavento7e780642018-11-24 15:51:34 -050025#include "ndn-cxx/face.hpp"
26#include "ndn-cxx/transport/tcp-transport.hpp"
27#include "ndn-cxx/transport/unix-transport.hpp"
28#include "ndn-cxx/util/scheduler.hpp"
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080029
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050030#include "tests/key-chain-fixture.hpp"
31#include "tests/test-common.hpp"
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070032
Junxiao Shicf9c6bb2016-07-27 02:18:19 +000033#include <stdio.h>
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -080034#include <condition_variable>
Davide Pesavento7e780642018-11-24 15:51:34 -050035#include <mutex>
36#include <thread>
37
Davide Pesavento49e1e872023-11-11 00:45:23 -050038#include <boost/mp11/list.hpp>
Junxiao Shicf9c6bb2016-07-27 02:18:19 +000039
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040040namespace ndn::tests {
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080041
Junxiao Shi2bea5c42017-08-14 20:10:32 +000042static Name
43makeVeryLongName(Name prefix = Name())
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070044{
Eric Newberry06690612016-12-27 12:50:15 -070045 for (size_t i = 0; i <= MAX_NDN_PACKET_SIZE / 10; i++) {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000046 prefix.append("0123456789");
47 }
48 return prefix;
49}
50
51static std::string
52executeCommand(const std::string& cmd)
53{
54 std::string output;
55 char buf[256];
56 FILE* pipe = popen(cmd.data(), "r");
Davide Pesavento39570d92019-12-09 23:52:46 -050057 BOOST_REQUIRE_MESSAGE(pipe != nullptr, "popen(" << cmd << ")");
Junxiao Shi2bea5c42017-08-14 20:10:32 +000058 while (fgets(buf, sizeof(buf), pipe) != nullptr) {
59 output += buf;
60 }
61 pclose(pipe);
62 return output;
63}
64
65template<typename TransportType>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050066class FaceFixture : public KeyChainFixture
Junxiao Shi2bea5c42017-08-14 20:10:32 +000067{
68protected:
69 FaceFixture()
70 : face(TransportType::create(""), m_keyChain)
Davide Pesavento2f46d652023-11-09 23:40:01 -050071 , sched(face.getIoContext())
Junxiao Shi2bea5c42017-08-14 20:10:32 +000072 {
Eric Newberry06690612016-12-27 12:50:15 -070073 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -070074
Junxiao Shi2bea5c42017-08-14 20:10:32 +000075 /** \brief Send an Interest from a secondary face
76 * \param delay scheduling delay before sending Interest
77 * \param interest the Interest
78 * \param[out] outcome the response, initially '?', 'D' for Data, 'N' for Nack, 'T' for timeout
79 * \return scheduled event id
80 */
Davide Pesaventofd612312019-03-15 18:45:46 -040081 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +000082 sendInterest(time::nanoseconds delay, const Interest& interest, char& outcome)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070083 {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000084 if (face2 == nullptr) {
Davide Pesavento2f46d652023-11-09 23:40:01 -050085 face2 = make_unique<Face>(TransportType::create(""), face.getIoContext(), m_keyChain);
Junxiao Shi2bea5c42017-08-14 20:10:32 +000086 }
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070087
Junxiao Shi2bea5c42017-08-14 20:10:32 +000088 outcome = '?';
Junxiao Shia5f233e2019-03-18 09:39:22 -060089 return sched.schedule(delay, [this, interest, &outcome] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000090 face2->expressInterest(interest,
91 [&] (const Interest&, const Data&) { outcome = 'D'; },
92 [&] (const Interest&, const lp::Nack&) { outcome = 'N'; },
93 [&] (const Interest&) { outcome = 'T'; });
94 });
95 }
96
Davide Pesaventofd612312019-03-15 18:45:46 -040097 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +000098 sendInterest(time::nanoseconds delay, const Interest& interest)
99 {
100 static char ignoredOutcome;
101 return sendInterest(delay, interest, ignoredOutcome);
102 }
103
Davide Pesavento2f46d652023-11-09 23:40:01 -0500104 /** \brief Stop io_context after a delay
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000105 * \return scheduled event id
106 */
Davide Pesaventofd612312019-03-15 18:45:46 -0400107 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000108 terminateAfter(time::nanoseconds delay)
109 {
Davide Pesavento2f46d652023-11-09 23:40:01 -0500110 return sched.schedule(delay, [this] { face.getIoContext().stop(); });
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700111 }
Junxiao Shicf9c6bb2016-07-27 02:18:19 +0000112
113protected:
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000114 Face face;
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000115 unique_ptr<Face> face2;
Davide Pesavento39570d92019-12-09 23:52:46 -0500116 Scheduler sched;
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700117};
118
Davide Pesavento49e1e872023-11-11 00:45:23 -0500119using Transports = boost::mp11::mp_list<UnixTransport, TcpTransport>;
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000120
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000121BOOST_AUTO_TEST_SUITE(Consumer)
122
123BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestData, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700124{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000125 int nData = 0;
Davide Pesavento39570d92019-12-09 23:52:46 -0500126 this->face.expressInterest(*makeInterest("/localhost", true),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000127 [&] (const Interest&, const Data&) { ++nData; },
128 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
129 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700130
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000131 this->face.processEvents();
132 BOOST_CHECK_EQUAL(nData, 1);
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700133}
Alexander Afanasyev90164962014-03-06 08:29:59 +0000134
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000135BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestNack, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700136{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000137 int nNacks = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600138 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-nack"),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000139 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
140 [&] (const Interest&, const lp::Nack&) { ++nNacks; },
141 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700142
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000143 this->face.processEvents();
144 BOOST_CHECK_EQUAL(nNacks, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700145}
146
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000147BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestTimeout, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700148{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000149 // add route toward null face so Interest would timeout instead of getting Nacked
150 executeCommand("nfdc route add /localhost/non-existent-should-timeout null://");
151 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait for FIB update to take effect
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700152
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000153 int nTimeouts = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600154 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-timeout", false, 1_s),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000155 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
156 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
157 [&] (const Interest&) { ++nTimeouts; });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700158
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000159 this->face.processEvents();
160 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700161}
162
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000163BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedInterest, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700164{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000165 BOOST_CHECK_THROW(do {
Junxiao Shib55e5d32018-07-18 13:32:00 -0600166 this->face.expressInterest(*makeInterest(makeVeryLongName()), nullptr, nullptr, nullptr);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000167 this->face.processEvents();
168 } while (false), Face::OversizedPacketError);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700169}
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400170
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000171BOOST_AUTO_TEST_SUITE_END() // Consumer
172
173BOOST_AUTO_TEST_SUITE(Producer)
174
175BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegisterUnregisterPrefix, TransportType, Transports, FaceFixture<TransportType>)
176{
Davide Pesavento0f830802018-01-16 23:58:58 -0500177 this->terminateAfter(4_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000178
179 int nRegSuccess = 0, nUnregSuccess = 0;
Davide Pesavento720e25c2019-07-14 01:33:52 -0400180 auto handle = this->face.registerPrefix("/Hello/World",
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000181 [&] (const Name&) { ++nRegSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400182 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000183
Junxiao Shia5f233e2019-03-18 09:39:22 -0600184 this->sched.schedule(1_s, [&nRegSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000185 BOOST_CHECK_EQUAL(nRegSuccess, 1);
186 std::string output = executeCommand("nfdc route list | grep /Hello/World");
187 BOOST_CHECK(!output.empty());
188 });
189
Davide Pesavento720e25c2019-07-14 01:33:52 -0400190 this->sched.schedule(2_s, [&] {
191 handle.unregister(
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000192 [&] { ++nUnregSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400193 [] (const auto& msg) { BOOST_ERROR("unexpected unregister prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000194 });
195
Junxiao Shia5f233e2019-03-18 09:39:22 -0600196 this->sched.schedule(3_s, [&nUnregSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000197 BOOST_CHECK_EQUAL(nUnregSuccess, 1);
198
199 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
200 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
201 BOOST_CHECK(output.empty());
202 });
203
204 this->face.processEvents();
205}
206
207BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegularFilter, TransportType, Transports, FaceFixture<TransportType>)
208{
Davide Pesavento0f830802018-01-16 23:58:58 -0500209 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000210
211 int nInterests1 = 0, nRegSuccess1 = 0, nRegSuccess2 = 0;
212 this->face.setInterestFilter("/Hello/World",
213 [&] (const InterestFilter&, const Interest&) { ++nInterests1; },
214 [&] (const Name&) { ++nRegSuccess1; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400215 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000216 this->face.setInterestFilter("/Los/Angeles/Lakers",
217 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); },
218 [&] (const Name&) { ++nRegSuccess2; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400219 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000220
Junxiao Shia5f233e2019-03-18 09:39:22 -0600221 this->sched.schedule(500_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000222 std::string output = executeCommand("nfdc route list | grep /Hello/World");
223 BOOST_CHECK(!output.empty());
224 });
225
226 char interestOutcome;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600227 this->sendInterest(1_s, *makeInterest("/Hello/World/regular", false, 50_ms), interestOutcome);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000228
229 this->face.processEvents();
230 BOOST_CHECK_EQUAL(interestOutcome, 'T');
231 BOOST_CHECK_EQUAL(nInterests1, 1);
232 BOOST_CHECK_EQUAL(nRegSuccess1, 1);
233 BOOST_CHECK_EQUAL(nRegSuccess2, 1);
234}
235
236BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilter, TransportType, Transports, FaceFixture<TransportType>)
237{
Davide Pesavento0f830802018-01-16 23:58:58 -0500238 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000239
240 int nRegSuccess = 0;
241 std::set<Name> receivedInterests;
242 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500243 [&] (auto&&, const auto& interest) { receivedInterests.insert(interest.getName()); },
244 [&] (auto&&) { ++nRegSuccess; },
245 [] (auto&&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000246
Junxiao Shia5f233e2019-03-18 09:39:22 -0600247 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000248 std::string output = executeCommand("nfdc route list | grep /Hello/World");
249 BOOST_CHECK(!output.empty());
250 });
251
Junxiao Shib55e5d32018-07-18 13:32:00 -0600252 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
253 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
254 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
255 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000256
257 this->face.processEvents();
258 BOOST_CHECK_EQUAL(nRegSuccess, 1);
259 std::set<Name> expectedInterests{"/Hello/World/a/b", "/Hello/World/a/b/c"};
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500260 BOOST_TEST(receivedInterests == expectedInterests, boost::test_tools::per_element());
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000261}
262
263BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilterNoRegister, TransportType, Transports, FaceFixture<TransportType>)
264{
Davide Pesavento0f830802018-01-16 23:58:58 -0500265 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000266
267 // no Interest shall arrive because prefix isn't registered in forwarder
268 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
Davide Pesavento720e25c2019-07-14 01:33:52 -0400269 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000270
Junxiao Shia5f233e2019-03-18 09:39:22 -0600271 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000272 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
273 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
274 BOOST_CHECK(output.empty());
275 });
276
Junxiao Shib55e5d32018-07-18 13:32:00 -0600277 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
278 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
279 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
280 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000281
282 this->face.processEvents();
283}
284
285BOOST_FIXTURE_TEST_CASE_TEMPLATE(PutDataNack, TransportType, Transports, FaceFixture<TransportType>)
286{
Davide Pesavento0f830802018-01-16 23:58:58 -0500287 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000288
289 this->face.setInterestFilter("/Hello/World",
290 [&] (const InterestFilter&, const Interest& interest) {
291 if (interest.getName().at(2) == name::Component("nack")) {
292 this->face.put(makeNack(interest, lp::NackReason::NO_ROUTE));
293 }
294 else {
295 this->face.put(*makeData(interest.getName()));
296 }
297 },
298 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400299 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000300
301 char outcome1, outcome2;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600302 this->sendInterest(700_ms, *makeInterest("/Hello/World/data", false, 50_ms), outcome1);
303 this->sendInterest(800_ms, *makeInterest("/Hello/World/nack", false, 50_ms), outcome2);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000304
305 this->face.processEvents();
306 BOOST_CHECK_EQUAL(outcome1, 'D');
307 BOOST_CHECK_EQUAL(outcome2, 'N');
308}
309
310BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedData, TransportType, Transports, FaceFixture<TransportType>)
311{
Davide Pesavento0f830802018-01-16 23:58:58 -0500312 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000313
314 this->face.setInterestFilter("/Hello/World",
315 [&] (const InterestFilter&, const Interest& interest) {
316 this->face.put(*makeData(makeVeryLongName(interest.getName())));
317 },
318 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400319 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000320
Junxiao Shib55e5d32018-07-18 13:32:00 -0600321 this->sendInterest(1_s, *makeInterest("/Hello/World/oversized", true, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000322
323 BOOST_CHECK_THROW(this->face.processEvents(), Face::OversizedPacketError);
324}
325
326BOOST_AUTO_TEST_SUITE_END() // Producer
327
Davide Pesavento394977c2020-04-25 21:40:31 -0400328BOOST_FIXTURE_TEST_SUITE(IoRoutine, FaceFixture<UnixTransport>)
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000329
Davide Pesavento0c526032024-01-31 21:14:01 -0500330BOOST_AUTO_TEST_CASE(ShutdownWhileSendInProgress,
331 * ut::description("test for bug #3136"))
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700332{
Junxiao Shib55e5d32018-07-18 13:32:00 -0600333 this->face.expressInterest(*makeInterest("/Hello/World"), nullptr, nullptr, nullptr);
Davide Pesavento0f830802018-01-16 23:58:58 -0500334 this->face.processEvents(1_s);
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700335
Junxiao Shib55e5d32018-07-18 13:32:00 -0600336 this->face.expressInterest(*makeInterest("/Bye/World/1"), nullptr, nullptr, nullptr);
337 this->face.expressInterest(*makeInterest("/Bye/World/2"), nullptr, nullptr, nullptr);
338 this->face.expressInterest(*makeInterest("/Bye/World/3"), nullptr, nullptr, nullptr);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000339 this->face.shutdown();
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700340
Davide Pesavento0f830802018-01-16 23:58:58 -0500341 this->face.processEvents(1_s); // should not segfault
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000342 BOOST_CHECK(true);
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700343}
344
Davide Pesavento0c526032024-01-31 21:14:01 -0500345BOOST_AUTO_TEST_CASE(LargeDelayBetweenFaceConstructorAndProcessEvents,
346 * ut::description("test for bug #2742"))
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700347{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000348 std::this_thread::sleep_for(std::chrono::seconds(5)); // simulate setup workload
Davide Pesavento0f830802018-01-16 23:58:58 -0500349 this->face.processEvents(1_s); // should not throw
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000350 BOOST_CHECK(true);
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700351}
352
Davide Pesavento0c526032024-01-31 21:14:01 -0500353BOOST_AUTO_TEST_CASE(ProcessEventsBlocksForeverWhenNothingScheduled,
354 * ut::description("test for bug #3957"))
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800355{
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800356 std::mutex m;
357 std::condition_variable cv;
358 bool processEventsFinished = false;
359
360 std::thread faceThread([&] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000361 this->face.processEvents();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800362
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000363 processEventsFinished = true;
364 std::lock_guard<std::mutex> lk(m);
365 cv.notify_one();
366 });
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800367
368 {
369 std::unique_lock<std::mutex> lk(m);
370 cv.wait_for(lk, std::chrono::seconds(5), [&] { return processEventsFinished; });
371 }
372
373 BOOST_CHECK_EQUAL(processEventsFinished, true);
374 if (!processEventsFinished) {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000375 this->face.shutdown();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800376 }
377 faceThread.join();
378}
379
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000380BOOST_AUTO_TEST_SUITE_END() // IoRoutine
381
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400382} // namespace ndn::tests