mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
chore: TSAN fix async-signal-unsafe (#2824)
Co-authored-by: Sergey Kuznetsov <skuznetsov@ripple.com>
This commit is contained in:
@@ -40,6 +40,7 @@ struct StopperTest : virtual public ::testing::Test {
|
||||
protected:
|
||||
// Order here is important, stopper_ should die before mockCallback_, otherwise UB
|
||||
testing::StrictMock<testing::MockFunction<void(boost::asio::yield_context)>> mockCallback_;
|
||||
testing::StrictMock<testing::MockFunction<void()>> mockCompleteCallback_;
|
||||
Stopper stopper_;
|
||||
};
|
||||
|
||||
@@ -60,6 +61,22 @@ TEST_F(StopperTest, stopCalledMultipleTimes)
|
||||
stopper_.stop();
|
||||
}
|
||||
|
||||
TEST_F(StopperTest, stopCallsCompletionCallback)
|
||||
{
|
||||
stopper_.setOnStop(mockCallback_.AsStdFunction());
|
||||
stopper_.setOnComplete(mockCompleteCallback_.AsStdFunction());
|
||||
EXPECT_CALL(mockCallback_, Call);
|
||||
EXPECT_CALL(mockCompleteCallback_, Call);
|
||||
stopper_.stop();
|
||||
}
|
||||
|
||||
TEST_F(StopperTest, stopWithoutCompletionCallback)
|
||||
{
|
||||
stopper_.setOnStop(mockCallback_.AsStdFunction());
|
||||
EXPECT_CALL(mockCallback_, Call);
|
||||
stopper_.stop();
|
||||
}
|
||||
|
||||
struct StopperMakeCallbackTest : util::prometheus::WithPrometheus, SyncAsioContextTest {
|
||||
struct ServerMock : web::ServerTag {
|
||||
MOCK_METHOD(void, stop, (boost::asio::yield_context), ());
|
||||
|
||||
@@ -70,7 +70,7 @@ TEST_F(SignalsHandlerAssertTest, CantCreateTwoSignalsHandlers)
|
||||
{
|
||||
auto makeHandler = []() {
|
||||
return SignalsHandler{
|
||||
ClioConfigDefinition{{"graceful_period", ConfigValue{ConfigType::Double}.defaultValue(10.f)}}, []() {}
|
||||
ClioConfigDefinition{{"graceful_period", ConfigValue{ConfigType::Double}.defaultValue(1.f)}}, []() {}
|
||||
};
|
||||
};
|
||||
auto const handler = makeHandler();
|
||||
@@ -96,7 +96,11 @@ TEST_F(SignalsHandlerTests, OneSignal)
|
||||
handler_.subscribeToStop(stopHandler_.AsStdFunction());
|
||||
handler_.subscribeToStop(anotherStopHandler_.AsStdFunction());
|
||||
EXPECT_CALL(stopHandler_, Call());
|
||||
EXPECT_CALL(anotherStopHandler_, Call()).WillOnce([this]() { allowTestToFinish(); });
|
||||
EXPECT_CALL(anotherStopHandler_, Call()).WillOnce([this] {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
handler_.notifyGracefulShutdownComplete();
|
||||
allowTestToFinish();
|
||||
});
|
||||
std::raise(SIGINT);
|
||||
|
||||
wait();
|
||||
@@ -113,21 +117,44 @@ protected:
|
||||
TEST_F(SignalsHandlerTimeoutTests, OneSignalTimeout)
|
||||
{
|
||||
handler_.subscribeToStop(stopHandler_.AsStdFunction());
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([] { std::this_thread::sleep_for(std::chrono::milliseconds(2)); });
|
||||
EXPECT_CALL(forceExitHandler_, Call());
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([] {
|
||||
// Don't notify completion, let it timeout
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
});
|
||||
EXPECT_CALL(forceExitHandler_, Call()).WillOnce([this]() { allowTestToFinish(); });
|
||||
std::raise(SIGINT);
|
||||
|
||||
wait();
|
||||
}
|
||||
|
||||
TEST_F(SignalsHandlerTests, TwoSignals)
|
||||
{
|
||||
handler_.subscribeToStop(stopHandler_.AsStdFunction());
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([] { std::raise(SIGINT); });
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([] {
|
||||
// Raise second signal during graceful shutdown
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
std::raise(SIGINT);
|
||||
});
|
||||
EXPECT_CALL(forceExitHandler_, Call()).WillOnce([this]() { allowTestToFinish(); });
|
||||
std::raise(SIGINT);
|
||||
|
||||
wait();
|
||||
}
|
||||
|
||||
TEST_F(SignalsHandlerTests, GracefulShutdownCompletes)
|
||||
{
|
||||
handler_.subscribeToStop(stopHandler_.AsStdFunction());
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([this] {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
handler_.notifyGracefulShutdownComplete();
|
||||
allowTestToFinish();
|
||||
});
|
||||
EXPECT_CALL(forceExitHandler_, Call()).Times(0);
|
||||
std::raise(SIGINT);
|
||||
|
||||
wait();
|
||||
}
|
||||
|
||||
struct SignalsHandlerPriorityTestsBundle {
|
||||
std::string name;
|
||||
SignalsHandler::Priority stopHandlerPriority;
|
||||
@@ -164,9 +191,10 @@ TEST_P(SignalsHandlerPriorityTests, Priority)
|
||||
EXPECT_CALL(stopHandler_, Call()).WillOnce([&] { stopHandlerCalled = true; });
|
||||
EXPECT_CALL(anotherStopHandler_, Call()).WillOnce([&] {
|
||||
EXPECT_TRUE(stopHandlerCalled);
|
||||
handler_.notifyGracefulShutdownComplete();
|
||||
allowTestToFinish();
|
||||
});
|
||||
std::raise(SIGINT);
|
||||
|
||||
std::raise(SIGINT);
|
||||
wait();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user