diff --git a/cmake/local-libzmq/LocalLibzmq.cmake b/cmake/local-libzmq/LocalLibzmq.cmake index c4fb722..48bb67a 100644 --- a/cmake/local-libzmq/LocalLibzmq.cmake +++ b/cmake/local-libzmq/LocalLibzmq.cmake @@ -1,7 +1,7 @@ set(LIBZMQ_PREFIX ${CMAKE_BINARY_DIR}/libzmq) -set(ZeroMQ_VERSION 4.3.3) +set(ZeroMQ_VERSION 4.3.4) set(LIBZMQ_URL https://github.com/zeromq/libzmq/releases/download/v${ZeroMQ_VERSION}/zeromq-${ZeroMQ_VERSION}.tar.gz) -set(LIBZMQ_HASH SHA512=4c18d784085179c5b1fcb753a93813095a12c8d34970f2e1bfca6499be6c9d67769c71c68b7ca54ff181b20390043170e89733c22f76ff1ea46494814f7095b1) +set(LIBZMQ_HASH SHA512=e198ef9f82d392754caadd547537666d4fba0afd7d027749b3adae450516bcf284d241d4616cad3cb4ad9af8c10373d456de92dc6d115b037941659f141e7c0e) message(${LIBZMQ_URL}) diff --git a/tests/common.h b/tests/common.h index 2798675..6cfe623 100644 --- a/tests/common.h +++ b/tests/common.h @@ -5,6 +5,16 @@ using namespace oxenmq; +// Apple's mutexes, thread scheduling, and IO handling are garbage and it shows up with lots of +// spurious failures in this test suite (because it expects a system to not suck that badly), so we +// multiply the time-sensitive bits by this factor as a hack to make the test suite work. +constexpr int TIME_DILATION = +#ifdef __APPLE__ + 5; +#else + 1; +#endif + static auto startup = std::chrono::steady_clock::now(); /// Returns a localhost connection string to listen on. It can be considered random, though in @@ -30,7 +40,7 @@ inline void wait_for(Func f) { for (int i = 0; i < 20; i++) { if (f()) break; - std::this_thread::sleep_for(10ms); + std::this_thread::sleep_for(10ms * TIME_DILATION); } auto lock = catch_lock(); UNSCOPED_INFO("done waiting after " << (std::chrono::steady_clock::now() - start).count() << "ns"); @@ -43,7 +53,7 @@ inline void wait_for_conn(std::atomic &c) { } /// Waits enough time for us to receive a reply from a localhost remote. -inline void reply_sleep() { std::this_thread::sleep_for(10ms); } +inline void reply_sleep() { std::this_thread::sleep_for(10ms * TIME_DILATION); } inline OxenMQ::Logger get_logger(std::string prefix = "") { std::string me = "tests/common.h"; diff --git a/tests/test_commands.cpp b/tests/test_commands.cpp index 606fed3..9dea29a 100644 --- a/tests/test_commands.cpp +++ b/tests/test_commands.cpp @@ -470,7 +470,7 @@ TEST_CASE("deferred replies", "[commands][send][deferred]") { std::string msg = m.data.empty() ? ""s : std::string{m.data.front()}; std::thread t{[send=m.send_later(), msg=std::move(msg)] { { auto lock = catch_lock(); UNSCOPED_INFO("sleeping"); } - std::this_thread::sleep_for(50ms); + std::this_thread::sleep_for(50ms * TIME_DILATION); { auto lock = catch_lock(); UNSCOPED_INFO("sending"); } send.reply(msg); }}; @@ -516,7 +516,7 @@ TEST_CASE("deferred replies", "[commands][send][deferred]") { auto lock = catch_lock(); REQUIRE( replies.size() == 0 ); // The server waits 50ms before sending, so we shouldn't have any reply yet } - std::this_thread::sleep_for(60ms); // We're at least 70ms in now so the 50ms-delayed server responses should have arrived + std::this_thread::sleep_for(60ms * TIME_DILATION); // We're at least 70ms in now so the 50ms-delayed server responses should have arrived { std::lock_guard lq{reply_mut}; auto lock = catch_lock(); diff --git a/tests/test_connect.cpp b/tests/test_connect.cpp index 0b4b846..b6cf109 100644 --- a/tests/test_connect.cpp +++ b/tests/test_connect.cpp @@ -279,7 +279,7 @@ TEST_CASE("SN disconnections", "[connect][disconnect]") { lmq[2]->send(pubkey[1], "sn.hi"); lmq[1]->send(pubkey[0], "BYE"); lmq[0]->send(pubkey[2], "sn.hi"); - std::this_thread::sleep_for(50ms); + std::this_thread::sleep_for(50ms * TIME_DILATION); auto lock = catch_lock(); REQUIRE(his == 5); diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 93df350..0d78470 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -15,9 +15,10 @@ TEST_CASE("timer test", "[timer][basic]") { auto start = std::chrono::steady_clock::now(); wait_for([&] { return ticks.load() > 3; }); { + auto elapsed_ms = std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count(); auto lock = catch_lock(); REQUIRE( ticks.load() > 3 ); - REQUIRE( std::chrono::steady_clock::now() - start < 40ms ); + REQUIRE( elapsed_ms < 50 * TIME_DILATION ); } } @@ -35,13 +36,13 @@ TEST_CASE("timer squelch", "[timer][squelch]") { // finishes, by which point we set `done` and so should get exactly 1 tick. auto timer = omq.add_timer([&] { if (first.exchange(false)) { - std::this_thread::sleep_for(30ms); + std::this_thread::sleep_for(30ms * TIME_DILATION); ticks++; done = true; } else if (!done) { ticks++; } - }, 5ms, true /* squelch */); + }, 5ms * TIME_DILATION, true /* squelch */); omq.start(); wait_for([&] { return done.load(); }); @@ -58,7 +59,7 @@ TEST_CASE("timer squelch", "[timer][squelch]") { std::atomic ticks2 = 0; auto timer2 = omq.add_timer([&] { if (first2.exchange(false)) { - std::this_thread::sleep_for(30ms); + std::this_thread::sleep_for(40ms); done2 = true; } else if (!done2) { ticks2++; @@ -82,13 +83,13 @@ TEST_CASE("timer cancel", "[timer][cancel]") { std::atomic ticks = 0; // We set up *and cancel* this timer before omq starts, so it should never fire - auto notimer = omq.add_timer([&] { ticks += 1000; }, 5ms); + auto notimer = omq.add_timer([&] { ticks += 1000; }, 5ms * TIME_DILATION); omq.cancel_timer(notimer); TimerID timer = omq.add_timer([&] { if (++ticks == 3) omq.cancel_timer(timer); - }, 5ms); + }, 5ms * TIME_DILATION); omq.start();