v3.37.0: load testing for test scripts and suites

POST /api/test/run takes an optional iterations count (the PWA's
Iterations field): the run repeats, successful iterations are discarded
(steps/log cleared, only load.done and the timing grow), the first error
stops the loop and keeps that iteration's report, a stop ends it after
the current iteration, and a card session change between iterations is
an error.  The SCP80 counter state is shared across iterations, so
packets continue from what the previous run consumed.

The status gains a load block (iteration/done/failed_iteration/
elapsed_ms/avg_ms; disabled for a normal run).  The suite runner was
split into a per-iteration body (_test_suite_execute_once) + the
single-run finaliser, and two load workers own the loops.

Review fixes: a raised runner error finalises as error (no stuck
running state), a suite-internal session change is an error, a stopped
member ends the suite loop, the final status keeps a warning from any
iteration, avg_ms covers the attempted iterations, and each suite
iteration's counters_before is read fresh.

1041 Python + 1069 frontend; simple-v475.
This commit is contained in:
2026-10-23 23:44:42 +03:00
parent 851ff65af6
commit 2181ef6bbf
13 changed files with 937 additions and 64 deletions
+3 -3
View File
@@ -264,12 +264,12 @@ class TestProactiveChainOwnership(unittest.TestCase):
take.assert_called_once()
def test_every_run_end_resumes_the_poll(self):
# the two worker bodies, their two exception paths and the spawn
# failure all call the helper
# the two worker bodies, their two exception paths, the spawn failure
# and the two load workers (v3.37.0) all call the helper
import inspect
src = inspect.getsource(S)
self.assertEqual(src.count('\n _sim_resume_poll()'), 2)
self.assertEqual(src.count('\n _sim_resume_poll()'), 3)
self.assertEqual(src.count('\n _sim_resume_poll()'), 5)
if __name__ == '__main__':