Skip to content

Commit a6764a8

Browse files
committed
UnitTest: Timeout
1 parent 23134ee commit a6764a8

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

modules/UnitTest/UnitTest.mpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ namespace CppUtils::UnitTest
2828
struct Test final
2929
{
3030
std::string name;
31-
std::function<void()> function;
31+
std::function<void(std::stop_token)> function;
32+
std::chrono::seconds timeout = std::chrono::seconds{10};
3233
};
3334

3435
class TestException: public std::runtime_error
@@ -72,7 +73,30 @@ namespace CppUtils::UnitTest
7273
try
7374
{
7475
auto chronoLogger = Log::ChronoLogger{"Test", settings.verbose and settings.chrono};
75-
test.function();
76+
77+
auto promise = std::promise<void>{};
78+
auto future = promise.get_future();
79+
80+
auto worker = std::jthread{[promise = std::move(promise), function = test.function](std::stop_token stopToken) mutable {
81+
try
82+
{
83+
function(stopToken);
84+
promise.set_value();
85+
}
86+
catch (...)
87+
{
88+
promise.set_exception(std::current_exception());
89+
}
90+
}};
91+
92+
if (future.wait_for(test.timeout) == std::future_status::timeout)
93+
{
94+
worker.request_stop();
95+
worker.detach();
96+
throw TestException{std::format("Test timed out after {}s", test.timeout.count())};
97+
}
98+
99+
future.get();
76100
}
77101
catch (const TestException&)
78102
{
@@ -176,9 +200,14 @@ namespace CppUtils::UnitTest
176200
testRunner.addTestSuite(name, std::move(tests));
177201
}
178202

179-
inline auto addTest(std::string name, std::function<void()> function) -> void
203+
inline auto addTest(std::string name, std::function<void(std::stop_token)> function, std::chrono::seconds timeout = std::chrono::seconds{10}) -> void
180204
{
181-
tests.emplace_back(std::move(name), function);
205+
tests.emplace_back(std::move(name), std::move(function), timeout);
206+
}
207+
208+
inline auto addTest(std::string name, std::function<void()> function, std::chrono::seconds timeout = std::chrono::seconds{10}) -> void
209+
{
210+
tests.emplace_back(std::move(name), [function = std::move(function)](std::stop_token) { function(); }, timeout);
182211
}
183212

184213
// Todo C++23: std::stacktrace stacktrace = std::current_stacktrace()

0 commit comments

Comments
 (0)