blob: aac5443d346a1b8cba776c847a4d9bf929b66b97 [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 Pesaventofd612312019-03-15 18:45:46 -04003 * Copyright (c) 2013-2019 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
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080022#define BOOST_TEST_MODULE ndn-cxx Integrated Tests (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 Pesavento7e780642018-11-24 15:51:34 -050030#include "tests/identity-management-fixture.hpp"
31#include "tests/make-interest-data.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");
58 BOOST_REQUIRE_MESSAGE(pipe != nullptr, "cannot execute '" << cmd << "'");
59 while (fgets(buf, sizeof(buf), pipe) != nullptr) {
60 output += buf;
61 }
62 pclose(pipe);
63 return output;
64}
65
66template<typename TransportType>
67class FaceFixture : public IdentityManagementFixture
68{
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;
116 Scheduler sched;
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000117 unique_ptr<Face> face2;
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700118};
119
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000120using Transports = boost::mpl::vector<UnixTransport, TcpTransport>;
121
122BOOST_FIXTURE_TEST_SUITE(TestFace, FaceFixture<UnixTransport>)
123
124BOOST_AUTO_TEST_SUITE(Consumer)
125
126BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestData, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700127{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000128 int nData = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600129 this->face.expressInterest(*makeInterest("/", true),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000130 [&] (const Interest&, const Data&) { ++nData; },
131 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
132 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700133
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000134 this->face.processEvents();
135 BOOST_CHECK_EQUAL(nData, 1);
Alexander Afanasyevee8bb1e2014-05-02 17:39:54 -0700136}
Alexander Afanasyev90164962014-03-06 08:29:59 +0000137
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000138BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestNack, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700139{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000140 int nNacks = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600141 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-nack"),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000142 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
143 [&] (const Interest&, const lp::Nack&) { ++nNacks; },
144 [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700145
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000146 this->face.processEvents();
147 BOOST_CHECK_EQUAL(nNacks, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700148}
149
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000150BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestTimeout, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700151{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000152 // add route toward null face so Interest would timeout instead of getting Nacked
153 executeCommand("nfdc route add /localhost/non-existent-should-timeout null://");
154 std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait for FIB update to take effect
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700155
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000156 int nTimeouts = 0;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600157 this->face.expressInterest(*makeInterest("/localhost/non-existent-should-timeout", false, 1_s),
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000158 [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
159 [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
160 [&] (const Interest&) { ++nTimeouts; });
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700161
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000162 this->face.processEvents();
163 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700164}
165
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000166BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedInterest, TransportType, Transports, FaceFixture<TransportType>)
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700167{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000168 BOOST_CHECK_THROW(do {
Junxiao Shib55e5d32018-07-18 13:32:00 -0600169 this->face.expressInterest(*makeInterest(makeVeryLongName()), nullptr, nullptr, nullptr);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000170 this->face.processEvents();
171 } while (false), Face::OversizedPacketError);
Alexander Afanasyev984ad192014-05-02 19:11:15 -0700172}
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400173
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000174BOOST_AUTO_TEST_SUITE_END() // Consumer
175
176BOOST_AUTO_TEST_SUITE(Producer)
177
178BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegisterUnregisterPrefix, TransportType, Transports, FaceFixture<TransportType>)
179{
Davide Pesavento0f830802018-01-16 23:58:58 -0500180 this->terminateAfter(4_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000181
182 int nRegSuccess = 0, nUnregSuccess = 0;
Davide Pesavento720e25c2019-07-14 01:33:52 -0400183 auto handle = this->face.registerPrefix("/Hello/World",
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000184 [&] (const Name&) { ++nRegSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400185 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000186
Junxiao Shia5f233e2019-03-18 09:39:22 -0600187 this->sched.schedule(1_s, [&nRegSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000188 BOOST_CHECK_EQUAL(nRegSuccess, 1);
189 std::string output = executeCommand("nfdc route list | grep /Hello/World");
190 BOOST_CHECK(!output.empty());
191 });
192
Davide Pesavento720e25c2019-07-14 01:33:52 -0400193 this->sched.schedule(2_s, [&] {
194 handle.unregister(
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000195 [&] { ++nUnregSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400196 [] (const auto& msg) { BOOST_ERROR("unexpected unregister prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000197 });
198
Junxiao Shia5f233e2019-03-18 09:39:22 -0600199 this->sched.schedule(3_s, [&nUnregSuccess] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000200 BOOST_CHECK_EQUAL(nUnregSuccess, 1);
201
202 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
203 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
204 BOOST_CHECK(output.empty());
205 });
206
207 this->face.processEvents();
208}
209
210BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegularFilter, TransportType, Transports, FaceFixture<TransportType>)
211{
Davide Pesavento0f830802018-01-16 23:58:58 -0500212 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000213
214 int nInterests1 = 0, nRegSuccess1 = 0, nRegSuccess2 = 0;
215 this->face.setInterestFilter("/Hello/World",
216 [&] (const InterestFilter&, const Interest&) { ++nInterests1; },
217 [&] (const Name&) { ++nRegSuccess1; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400218 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000219 this->face.setInterestFilter("/Los/Angeles/Lakers",
220 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); },
221 [&] (const Name&) { ++nRegSuccess2; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400222 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000223
Junxiao Shia5f233e2019-03-18 09:39:22 -0600224 this->sched.schedule(500_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000225 std::string output = executeCommand("nfdc route list | grep /Hello/World");
226 BOOST_CHECK(!output.empty());
227 });
228
229 char interestOutcome;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600230 this->sendInterest(1_s, *makeInterest("/Hello/World/regular", false, 50_ms), interestOutcome);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000231
232 this->face.processEvents();
233 BOOST_CHECK_EQUAL(interestOutcome, 'T');
234 BOOST_CHECK_EQUAL(nInterests1, 1);
235 BOOST_CHECK_EQUAL(nRegSuccess1, 1);
236 BOOST_CHECK_EQUAL(nRegSuccess2, 1);
237}
238
239BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilter, TransportType, Transports, FaceFixture<TransportType>)
240{
Davide Pesavento0f830802018-01-16 23:58:58 -0500241 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000242
243 int nRegSuccess = 0;
244 std::set<Name> receivedInterests;
245 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
246 [&] (const InterestFilter&, const Interest& interest) { receivedInterests.insert(interest.getName()); },
247 [&] (const Name&) { ++nRegSuccess; },
Davide Pesavento720e25c2019-07-14 01:33:52 -0400248 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000249
Junxiao Shia5f233e2019-03-18 09:39:22 -0600250 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000251 std::string output = executeCommand("nfdc route list | grep /Hello/World");
252 BOOST_CHECK(!output.empty());
253 });
254
Junxiao Shib55e5d32018-07-18 13:32:00 -0600255 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
256 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
257 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
258 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000259
260 this->face.processEvents();
261 BOOST_CHECK_EQUAL(nRegSuccess, 1);
262 std::set<Name> expectedInterests{"/Hello/World/a/b", "/Hello/World/a/b/c"};
263 BOOST_CHECK_EQUAL_COLLECTIONS(receivedInterests.begin(), receivedInterests.end(),
264 expectedInterests.begin(), expectedInterests.end());
265}
266
267BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilterNoRegister, TransportType, Transports, FaceFixture<TransportType>)
268{
Davide Pesavento0f830802018-01-16 23:58:58 -0500269 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000270
271 // no Interest shall arrive because prefix isn't registered in forwarder
272 this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
Davide Pesavento720e25c2019-07-14 01:33:52 -0400273 [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000274
Junxiao Shia5f233e2019-03-18 09:39:22 -0600275 this->sched.schedule(700_ms, [] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000276 // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
277 std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
278 BOOST_CHECK(output.empty());
279 });
280
Junxiao Shib55e5d32018-07-18 13:32:00 -0600281 this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
282 this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
283 this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
284 this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000285
286 this->face.processEvents();
287}
288
289BOOST_FIXTURE_TEST_CASE_TEMPLATE(PutDataNack, TransportType, Transports, FaceFixture<TransportType>)
290{
Davide Pesavento0f830802018-01-16 23:58:58 -0500291 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000292
293 this->face.setInterestFilter("/Hello/World",
294 [&] (const InterestFilter&, const Interest& interest) {
295 if (interest.getName().at(2) == name::Component("nack")) {
296 this->face.put(makeNack(interest, lp::NackReason::NO_ROUTE));
297 }
298 else {
299 this->face.put(*makeData(interest.getName()));
300 }
301 },
302 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400303 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000304
305 char outcome1, outcome2;
Junxiao Shib55e5d32018-07-18 13:32:00 -0600306 this->sendInterest(700_ms, *makeInterest("/Hello/World/data", false, 50_ms), outcome1);
307 this->sendInterest(800_ms, *makeInterest("/Hello/World/nack", false, 50_ms), outcome2);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000308
309 this->face.processEvents();
310 BOOST_CHECK_EQUAL(outcome1, 'D');
311 BOOST_CHECK_EQUAL(outcome2, 'N');
312}
313
314BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedData, TransportType, Transports, FaceFixture<TransportType>)
315{
Davide Pesavento0f830802018-01-16 23:58:58 -0500316 this->terminateAfter(2_s);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000317
318 this->face.setInterestFilter("/Hello/World",
319 [&] (const InterestFilter&, const Interest& interest) {
320 this->face.put(*makeData(makeVeryLongName(interest.getName())));
321 },
322 nullptr,
Davide Pesavento720e25c2019-07-14 01:33:52 -0400323 [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000324
Junxiao Shib55e5d32018-07-18 13:32:00 -0600325 this->sendInterest(1_s, *makeInterest("/Hello/World/oversized", true, 50_ms));
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000326
327 BOOST_CHECK_THROW(this->face.processEvents(), Face::OversizedPacketError);
328}
329
330BOOST_AUTO_TEST_SUITE_END() // Producer
331
332BOOST_AUTO_TEST_SUITE(IoRoutine)
333
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700334BOOST_AUTO_TEST_CASE(ShutdownWhileSendInProgress) // Bug #3136
335{
Junxiao Shib55e5d32018-07-18 13:32:00 -0600336 this->face.expressInterest(*makeInterest("/Hello/World"), nullptr, nullptr, nullptr);
Davide Pesavento0f830802018-01-16 23:58:58 -0500337 this->face.processEvents(1_s);
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700338
Junxiao Shib55e5d32018-07-18 13:32:00 -0600339 this->face.expressInterest(*makeInterest("/Bye/World/1"), nullptr, nullptr, nullptr);
340 this->face.expressInterest(*makeInterest("/Bye/World/2"), nullptr, nullptr, nullptr);
341 this->face.expressInterest(*makeInterest("/Bye/World/3"), nullptr, nullptr, nullptr);
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000342 this->face.shutdown();
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700343
Davide Pesavento0f830802018-01-16 23:58:58 -0500344 this->face.processEvents(1_s); // should not segfault
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000345 BOOST_CHECK(true);
Alexander Afanasyevfba1ac62015-08-26 15:19:13 -0700346}
347
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700348BOOST_AUTO_TEST_CASE(LargeDelayBetweenFaceConstructorAndProcessEvents) // Bug #2742
349{
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000350 std::this_thread::sleep_for(std::chrono::seconds(5)); // simulate setup workload
Davide Pesavento0f830802018-01-16 23:58:58 -0500351 this->face.processEvents(1_s); // should not throw
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000352 BOOST_CHECK(true);
Alexander Afanasyeve508f142015-09-01 15:14:45 -0700353}
354
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800355BOOST_AUTO_TEST_CASE(ProcessEventsBlocksForeverWhenNothingScheduled) // Bug #3957
356{
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800357 std::mutex m;
358 std::condition_variable cv;
359 bool processEventsFinished = false;
360
361 std::thread faceThread([&] {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000362 this->face.processEvents();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800363
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000364 processEventsFinished = true;
365 std::lock_guard<std::mutex> lk(m);
366 cv.notify_one();
367 });
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800368
369 {
370 std::unique_lock<std::mutex> lk(m);
371 cv.wait_for(lk, std::chrono::seconds(5), [&] { return processEventsFinished; });
372 }
373
374 BOOST_CHECK_EQUAL(processEventsFinished, true);
375 if (!processEventsFinished) {
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000376 this->face.shutdown();
Alexander Afanasyeva54d5a62017-02-11 19:01:34 -0800377 }
378 faceThread.join();
379}
380
Junxiao Shi2bea5c42017-08-14 20:10:32 +0000381BOOST_AUTO_TEST_SUITE_END() // IoRoutine
382
383BOOST_AUTO_TEST_SUITE_END() // TestFace
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -0800384
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -0700385} // namespace tests
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -0800386} // namespace ndn