18
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-15 02:29:07 +01:00

feat(simulation): a real time watchdog ends a test run that hangs

A test run that hung, in the loading or anywhere else, waited until whoever
started it killed it. A watchdog thread now ends a run still going test.wall_timeout
seconds of real time after the start of the simulator, loading included: it says
`test: timeout ... still running after N s of real time` and quits with the
timeout code, whatever the main thread is doing, with no dialog. A test that has
ended but whose simulator doesn't close ends with its own result.

The limit is test.wall_timeout (settings, the scenery's config block) or
--test-wall-timeout, which wins. Not given, it is test.timeout + 600 s: ten
minutes for the loading, and a simulation that runs at least as fast as real
time is never cut short. test.timeout 0 means no watchdog unless the limit is
given; test.wall_timeout 0 turns it off.

run.py passes the case's timeout as --test-wall-timeout and kills a simulator
only 30 s after it. A timeout from the watchdog counts as wall_timeout there, so
a run that hung doesn't pass a case expecting the simulation time to run out;
test_mode_wall_timeout ends while loading on a limit of 2 s.
This commit is contained in:
jerrrrycho
2026-11-08 11:33:36 +01:00
parent 14d25520f3
commit 03a417c7b0
11 changed files with 210 additions and 35 deletions

View File

@@ -81,7 +81,7 @@ test_command_line parse_test_command_line(std::span<char const *const> const Arg
{
result.enabled = true;
}
else if (option == "--test-timeout")
else if (option == "--test-timeout" || option == "--test-wall-timeout")
{
auto const seconds{option_seconds(Arguments, i)};
if (false == seconds.has_value())
@@ -91,7 +91,10 @@ test_command_line parse_test_command_line(std::span<char const *const> const Arg
result.error = std::format("{} needs a number of seconds", option);
continue;
}
result.timeout = seconds;
if (option == "--test-timeout")
result.timeout = seconds;
else
result.wall_timeout = seconds;
}
else if (takes_value(option))
{
@@ -106,6 +109,13 @@ test_command_line parse_test_command_line(std::span<char const *const> const Arg
return result;
}
double wall_clock_limit(std::optional<double> const Given, double const Simulationtimeout)
{
if (Given.has_value())
return *Given;
return Simulationtimeout > 0.0 ? Simulationtimeout + wall_timeout_loading_allowance : 0.0;
}
std::optional<test_verdict> evaluate_frame(test_progress &Progress, test_frame const &Frame, test_limits const &Limits)
{
using enum test_result;