blob: 9357094c1fdad519160daddd3e52768ebdbeb6d4 [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 Pesaventodf8fd8a2022-02-21 20:04:21 -05003 * Copyright (c) 2013-2022 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
Junxiao Shi2bea5c42017-08-14 20:10:32 +000038#include <boost/mpl/vector.hpp>
Junxiao Shicf9c6bb2016-07-27 02:18:19 +000039
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -080040namespace ndn {
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040041namespace tests {
Alexander Afanasyev20d2c582014-01-26 15:32:51 -080042
Junxiao Shi2bea5c42017-08-14 20:10:32 +000043static Name
44makeVeryLongName(Name prefix = Name())
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070045{
Eric Newberry06690612016-12-27 12:50:15 -070046 for (size_t i = 0; i <= MAX_NDN_PACKET_SIZE / 10; i++) {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000047 prefix.append("0123456789");
48 }
49 return prefix;
50}
51
52static std::string
53executeCommand(const std::string& cmd)
54{
55 std::string output;
56 char buf[256];
57 FILE* pipe = popen(cmd.data(), "r");
Davide Pesavento39570d92019-12-09 23:52:46 -050058 BOOST_REQUIRE_MESSAGE(pipe != nullptr, "popen(" << cmd << ")");
Junxiao Shi2bea5c42017-08-14 20:10:32 +000059 while (fgets(buf, sizeof(buf), pipe) != nullptr) {
60 output += buf;
61 }
62 pclose(pipe);
63 return output;
64}
65
66template<typename TransportType>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050067class FaceFixture : public KeyChainFixture
Junxiao Shi2bea5c42017-08-14 20:10:32 +000068{
69protected:
70 FaceFixture()
71 : face(TransportType::create(""), m_keyChain)
72 , sched(face.getIoService())
73 {
Eric Newberry06690612016-12-27 12:50:15 -070074 }
Alexander Afanasyev49bb1fb2014-07-21 12:54:01 -070075
Junxiao Shi2bea5c42017-08-14 20:10:32 +000076 /** \brief Send an Interest from a secondary face
77 * \param delay scheduling delay before sending Interest
78 * \param interest the Interest
79 * \param[out] outcome the response, initially '?', 'D' for Data, 'N' for Nack, 'T' for timeout
80 * \return scheduled event id
81 */
Davide Pesaventofd612312019-03-15 18:45:46 -040082 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +000083 sendInterest(time::nanoseconds delay, const Interest& interest, char& outcome)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070084 {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000085 if (face2 == nullptr) {
86 face2 = make_unique<Face>(TransportType::create(""), face.getIoService(), m_keyChain);
87 }
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -070088
Junxiao Shi2bea5c42017-08-14 20:10:32 +000089 outcome = '?';
Junxiao Shia5f233e2019-03-18 09:39:22 -060090 return sched.schedule(delay, [this, interest, &outcome] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +000091 face2->expressInterest(interest,
92 [&] (const Interest&, const Data&) { outcome = 'D'; },
93 [&] (const Interest&, const lp::Nack&) { outcome = 'N'; },
94 [&] (const Interest&) { outcome = 'T'; });
95 });
96 }
97
Davide Pesaventofd612312019-03-15 18:45:46 -040098 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +000099 sendInterest(time::nanoseconds delay, const Interest& interest)
100 {
101 static char ignoredOutcome;
102 return sendInterest(delay, interest, ignoredOutcome);
103 }
104
105 /** \brief Stop io_service after a delay
106 * \return scheduled event id
107 */
Davide Pesaventofd612312019-03-15 18:45:46 -0400108 scheduler::EventId
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000109 terminateAfter(time::nanoseconds delay)
110 {
Junxiao Shia5f233e2019-03-18 09:39:22 -0600111 return sched.schedule(delay, [this] { face.getIoService().stop(); });
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700112 }
Junxiao Shicf9c6bb2016-07-27 02:18:19 +0000113
114protected:
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000115 Face face;
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000116 unique_ptr<Face> face2;
Davide Pesavento39570d92019-12-09 23:52:46 -0500117 Scheduler sched;
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700118};
119
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000120using Transports = boost::mpl::vector<UnixTransport, TcpTransport>;
121
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000122BOOST_AUTO_TEST_SUITE(Consumer)
123
124BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestData, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700125{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000126 int nData = 0;
Davide Pesavento39570d92019-12-09 23:52:46 -0500127 this->face.expressInterest(*makeInterest("/localhost", true),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000128 [&] (const Interest&, const Data&) { ++nData; },
129 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
130 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700131
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000132 this->face.processEvents();
133 BOOST_CHECK_EQUAL(nData, 1);
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700134}
Alexander Afanasyev90164962014-03-06 08:29:59 +0000135
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000136BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestNack, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700137{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000138 int nNacks = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600139 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-nack"),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000140 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
141 [&] (const Interest&, const lp::Nack&) { ++nNacks; },
142 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700143
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000144 this->face.processEvents();
145 BOOST_CHECK_EQUAL(nNacks, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700146}
147
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000148BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestTimeout, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700149{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000150 // add route toward null face so Interest would timeout instead of getting Nacked
151 executeCommand("nfdc route add /localhost/non-existent-should-timeout null://");
152 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait for FIB update to take effect
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700153
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000154 int nTimeouts = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600155 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-timeout", false, 1_s),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000156 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
157 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
158 [&] (const Interest&) { ++nTimeouts; });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700159
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000160 this->face.processEvents();
161 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700162}
163
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000164BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedInterest, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700165{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000166 BOOST_CHECK_THROW(do {
Junxiao Shib55e5d32018-07-18 13:32:00 -0600167 this->face.expressInterest(*makeInterest(makeVeryLongName()), nullptr, nullptr, nullptr);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000168 this->face.processEvents();
169 } while (false), Face::OversizedPacketError);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700170}
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400171
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000172BOOST_AUTO_TEST_SUITE_END() // Consumer
173
174BOOST_AUTO_TEST_SUITE(Producer)
175
176BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegisterUnregisterPrefix, TransportType, Transports, FaceFixture<TransportType>)
177{
Davide Pesavento0f830802018-01-16 23:58:58 -0500178 this->terminateAfter(4_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000179
180 int nRegSuccess = 0, nUnregSuccess = 0;
Davide Pesavento720e25c2019-07-14 01:33:52 -0400181 auto handle = this->face.registerPrefix("/Hello/World",
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000182 [&] (const Name&) { ++nRegSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400183 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000184
Junxiao Shia5f233e2019-03-18 09:39:22 -0600185 this->sched.schedule(1_s, [&nRegSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000186 BOOST_CHECK_EQUAL(nRegSuccess, 1);
187 std::string output = executeCommand("nfdc route list | grep /Hello/World");
188 BOOST_CHECK(!output.empty());
189 });
190
Davide Pesavento720e25c2019-07-14 01:33:52 -0400191 this->sched.schedule(2_s, [&] {
192 handle.unregister(
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000193 [&] { ++nUnregSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400194 [] (const auto& msg) { BOOST_ERROR("unexpected unregister prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000195 });
196
Junxiao Shia5f233e2019-03-18 09:39:22 -0600197 this->sched.schedule(3_s, [&nUnregSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000198 BOOST_CHECK_EQUAL(nUnregSuccess, 1);
199
200 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
201 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
202 BOOST_CHECK(output.empty());
203 });
204
205 this->face.processEvents();
206}
207
208BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegularFilter, TransportType, Transports, FaceFixture<TransportType>)
209{
Davide Pesavento0f830802018-01-16 23:58:58 -0500210 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000211
212 int nInterests1 = 0, nRegSuccess1 = 0, nRegSuccess2 = 0;
213 this->face.setInterestFilter("/Hello/World",
214 [&] (const InterestFilter&, const Interest&) { ++nInterests1; },
215 [&] (const Name&) { ++nRegSuccess1; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400216 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000217 this->face.setInterestFilter("/Los/Angeles/Lakers",
218 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); },
219 [&] (const Name&) { ++nRegSuccess2; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400220 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000221
Junxiao Shia5f233e2019-03-18 09:39:22 -0600222 this->sched.schedule(500_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000223 std::string output = executeCommand("nfdc route list | grep /Hello/World");
224 BOOST_CHECK(!output.empty());
225 });
226
227 char interestOutcome;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600228 this->sendInterest(1_s, *makeInterest("/Hello/World/regular", false, 50_ms), interestOutcome);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000229
230 this->face.processEvents();
231 BOOST_CHECK_EQUAL(interestOutcome, 'T');
232 BOOST_CHECK_EQUAL(nInterests1, 1);
233 BOOST_CHECK_EQUAL(nRegSuccess1, 1);
234 BOOST_CHECK_EQUAL(nRegSuccess2, 1);
235}
236
237BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilter, TransportType, Transports, FaceFixture<TransportType>)
238{
Davide Pesavento0f830802018-01-16 23:58:58 -0500239 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000240
241 int nRegSuccess = 0;
242 std::set<Name> receivedInterests;
243 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500244 [&] (auto&&, const auto& interest) { receivedInterests.insert(interest.getName()); },
245 [&] (auto&&) { ++nRegSuccess; },
246 [] (auto&&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000247
Junxiao Shia5f233e2019-03-18 09:39:22 -0600248 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000249 std::string output = executeCommand("nfdc route list | grep /Hello/World");
250 BOOST_CHECK(!output.empty());
251 });
252
Junxiao Shib55e5d32018-07-18 13:32:00 -0600253 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
254 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
255 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
256 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000257
258 this->face.processEvents();
259 BOOST_CHECK_EQUAL(nRegSuccess, 1);
260 std::set<Name> expectedInterests{"/Hello/World/a/b", "/Hello/World/a/b/c"};
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500261 BOOST_TEST(receivedInterests == expectedInterests, boost::test_tools::per_element());
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000262}
263
264BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilterNoRegister, TransportType, Transports, FaceFixture<TransportType>)
265{
Davide Pesavento0f830802018-01-16 23:58:58 -0500266 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000267
268 // no Interest shall arrive because prefix isn't registered in forwarder
269 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
Davide Pesavento720e25c2019-07-14 01:33:52 -0400270 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000271
Junxiao Shia5f233e2019-03-18 09:39:22 -0600272 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000273 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
274 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
275 BOOST_CHECK(output.empty());
276 });
277
Junxiao Shib55e5d32018-07-18 13:32:00 -0600278 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
279 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
280 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
281 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000282
283 this->face.processEvents();
284}
285
286BOOST_FIXTURE_TEST_CASE_TEMPLATE(PutDataNack, TransportType, Transports, FaceFixture<TransportType>)
287{
Davide Pesavento0f830802018-01-16 23:58:58 -0500288 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000289
290 this->face.setInterestFilter("/Hello/World",
291 [&] (const InterestFilter&, const Interest& interest) {
292 if (interest.getName().at(2) == name::Component("nack")) {
293 this->face.put(makeNack(interest, lp::NackReason::NO_ROUTE));
294 }
295 else {
296 this->face.put(*makeData(interest.getName()));
297 }
298 },
299 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400300 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000301
302 char outcome1, outcome2;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600303 this->sendInterest(700_ms, *makeInterest("/Hello/World/data", false, 50_ms), outcome1);
304 this->sendInterest(800_ms, *makeInterest("/Hello/World/nack", false, 50_ms), outcome2);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000305
306 this->face.processEvents();
307 BOOST_CHECK_EQUAL(outcome1, 'D');
308 BOOST_CHECK_EQUAL(outcome2, 'N');
309}
310
311BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedData, TransportType, Transports, FaceFixture<TransportType>)
312{
Davide Pesavento0f830802018-01-16 23:58:58 -0500313 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000314
315 this->face.setInterestFilter("/Hello/World",
316 [&] (const InterestFilter&, const Interest& interest) {
317 this->face.put(*makeData(makeVeryLongName(interest.getName())));
318 },
319 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400320 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000321
Junxiao Shib55e5d32018-07-18 13:32:00 -0600322 this->sendInterest(1_s, *makeInterest("/Hello/World/oversized", true, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000323
324 BOOST_CHECK_THROW(this->face.processEvents(), Face::OversizedPacketError);
325}
326
327BOOST_AUTO_TEST_SUITE_END() // Producer
328
Davide Pesavento394977c2020-04-25 21:40:31 -0400329BOOST_FIXTURE_TEST_SUITE(IoRoutine, FaceFixture<UnixTransport>)
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000330
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700331BOOST_AUTO_TEST_CASE(ShutdownWhileSendInProgress) // Bug #3136
332{
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
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700345BOOST_AUTO_TEST_CASE(LargeDelayBetweenFaceConstructorAndProcessEvents) // Bug #2742
346{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000347 std::this_thread::sleep_for(std::chrono::seconds(5)); // simulate setup workload
Davide Pesavento0f830802018-01-16 23:58:58 -0500348 this->face.processEvents(1_s); // should not throw
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000349 BOOST_CHECK(true);
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700350}
351
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800352BOOST_AUTO_TEST_CASE(ProcessEventsBlocksForeverWhenNothingScheduled) // Bug #3957
353{
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800354 std::mutex m;
355 std::condition_variable cv;
356 bool processEventsFinished = false;
357
358 std::thread faceThread([&] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000359 this->face.processEvents();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800360
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000361 processEventsFinished = true;
362 std::lock_guard<std::mutex> lk(m);
363 cv.notify_one();
364 });
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800365
366 {
367 std::unique_lock<std::mutex> lk(m);
368 cv.wait_for(lk, std::chrono::seconds(5), [&] { return processEventsFinished; });
369 }
370
371 BOOST_CHECK_EQUAL(processEventsFinished, true);
372 if (!processEventsFinished) {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000373 this->face.shutdown();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800374 }
375 faceThread.join();
376}
377
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000378BOOST_AUTO_TEST_SUITE_END() // IoRoutine
379
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -0700380} // namespace tests
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -0800381} // namespace ndn