The crash handler of WITHDUMPGEN builds (on by default) shows a message
box before it writes the dump. It also gets the C++ exceptions nothing
catches, since it replaces the CRT's unhandled exception filter. In test
mode nobody is there to close the box, so a crashing test waited for it
until whatever started it gave up (run.py after the case's timeout,
600 s by default). The dump is still written, the exit code is the
exception's.
- `--test` is looked for before the rest of the command line is read. An
unknown option before it (e.g. `-s x.scn --test-timout 90 --test`) used
to end the run with exit code 0, which a caller reads as a pass.
- `--test-timeout` without a value, or with one that isn't a number of
seconds, fails the run instead of leaving the default or, through atof,
turning the timeout off.
- These, a missing -s, a failed start and an exception caught in main()
end the test through test_manager::conclude(), which writes the usual
`test: error (exit code 5) ... : <reason>` line to stdout and the log.
Before, `eu07 --test` alone exited with 5 and nothing anywhere: the
error went to the log queue and the process ended before the log
thread wrote it. In test mode main() now stops the log thread and
waits for it before _Exit().
Outside the test mode nothing changes: conclude() does nothing there.
The test manager is reached through simulation::test() instead of a global,
the result cell is owned by a unique_ptr until the memory table takes it, the
cell value is compared with a margin, strings are built with std::format and
the --test settings moved to apply_test_mode_settings(). The driver's signal
check is folded into UpdateSpeedPosition(), which updates a speed table entry
and reports a signal at stop the head of the train just passed. The test.*
keys are listed with the other settings at the start of the log.
eu07 --test -s <scenery> [--test-timeout <s>] runs the scenery in ghostview with
the null renderer (models loaded, no textures), a hidden window, no sound,
network or python, and in fixed steps of 0.03 s of simulation time per frame
(three 10 ms physics steps) as fast as it can. Without -seed it uses a fixed
seed, so two runs give byte-identical physicslogs.
The scenery reports its result to the __test.result memory cell, which the
simulator always creates: value 1 passes once every vehicle has stood still for
1 s, value 0 fails at once. The run ends with exit code
0 pass, 1 fail,
2 a train passed a signal at stop (SetVelocity 0 0, as seen in its driver's
speed table; SetVelocity 0 x on automatic block doesn't count),
3 timeout (test.timeout, default 3600 s of simulation time),
4 standstill (every vehicle still for test.standstill s, default 300, with no
result; a pass with test.pass_on_standstill yes),
5 error (no -s, the scenery didn't load or has no vehicles, an exception).
The test.* keys go in the scenery's config block; test.fail_if_stop_overran no
only logs a signal passed at danger. Outside the test mode a signal passed at
danger is logged.
The null renderer gets a ui backend which draws nothing, hands out the null
texture and material instead of throwing, and ends the ui frame. A GL context
is still made for the hidden window, without asking for a version, as parts
of the ui create textures with gl calls of their own. No crash dialog or
message box in test mode; the window code no longer needs a monitor.