Skip to content

Commit 7c8152d

Browse files
authored
test: Fix flaky test (#2729)
1 parent 0425d34 commit 7c8152d

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

tests/unit/web/ng/impl/WsConnectionTests.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@
4444
#include <gtest/gtest.h>
4545

4646
#include <chrono>
47+
#include <condition_variable>
4748
#include <cstddef>
4849
#include <memory>
50+
#include <mutex>
4951
#include <ranges>
5052
#include <string>
5153
#include <thread>
@@ -108,32 +110,39 @@ TEST_F(WebWsConnectionTests, WasUpgraded)
108110
});
109111
}
110112

111-
// This test is either flaky or incorrect
112-
// see https://github.com/XRPLF/clio/issues/2700
113-
TEST_F(WebWsConnectionTests, DISABLED_DisconnectClientOnInactivity)
113+
TEST_F(WebWsConnectionTests, DisconnectClientOnInactivity)
114114
{
115115
boost::asio::io_context clientCtx;
116116
auto work = boost::asio::make_work_guard(clientCtx);
117117
std::thread clientThread{[&clientCtx]() { clientCtx.run(); }};
118118

119-
util::spawn(clientCtx, [&work, this](boost::asio::yield_context yield) {
119+
std::mutex mutex;
120+
std::condition_variable cv;
121+
bool finished{false};
122+
123+
util::spawn(clientCtx, [&](boost::asio::yield_context yield) {
120124
auto expectedSuccess =
121125
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
122126
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
123-
boost::asio::steady_timer timer{yield.get_executor(), std::chrono::milliseconds{5}};
124-
timer.async_wait(yield);
127+
std::unique_lock lock{mutex};
128+
// Wait for 2 seconds to not block the test infinitely in case of failure
129+
auto const gotNotified = cv.wait_for(lock, std::chrono::seconds{2}, [&finished]() { return finished; });
130+
[&]() { EXPECT_TRUE(gotNotified); }();
125131
work.reset();
126132
});
127133

128-
runSpawn([this](boost::asio::yield_context yield) {
134+
runSpawn([&, this](boost::asio::yield_context yield) {
129135
auto wsConnection = acceptConnection(yield);
130136
wsConnection->setTimeout(std::chrono::milliseconds{1});
131-
// Client will not respond to pings because there is no reading operation scheduled for it.
132137

133-
auto const start = std::chrono::steady_clock::now();
138+
// Client will not respond to pings because there is no reading operation scheduled for it.
134139
auto const receivedMessage = wsConnection->receive(yield);
135-
auto const end = std::chrono::steady_clock::now();
136-
EXPECT_LT(end - start, std::chrono::milliseconds{4}); // Should be 2 ms, double it in case of slow CI.
140+
141+
{
142+
std::unique_lock lock{mutex};
143+
finished = true;
144+
cv.notify_one();
145+
}
137146

138147
EXPECT_FALSE(receivedMessage.has_value());
139148
EXPECT_EQ(receivedMessage.error().value(), boost::asio::error::no_permission);

0 commit comments

Comments
 (0)