test(redos): the dead row had the wrong payload, and the last wall clock is retired
Both rows that could not go red are decided, each by measurement.
test_lexicon.py::test_redos_pathological_subagent_input_returns_fast is REVIVED,
not retired. The row was not dead because the seed form is safe -- it was dead
because both earlier payloads made the prefix match at ONE start position, and
the cost is per-prefix-match. Repeating `spawn an agent that ` instead makes it
match K times, each driving its own O(N) lazy scan for a keyword never supplied:
K x O(N) against the seed's `(?:.*?\s+)?`, K x O(1) against the shipped
`{0,12}?` bound. Measured through scan_lexicon at 1500/3000/6000/12000 words:
seed 0.091/0.283/1.085/4.091s (exponent 1.92), shipped 0.047/0.051/0.094/0.190s
(exponent 1.01). Verified red with the seed form patched in: 4.21s against the
2.0s bound. The nesting the old comment blamed was a red herring.
test_output.py::test_pathological_input_returns_within_a_bound moves to CPU time
with a 20.0s bound, and the "or a hang" half of its claim is retired. The wall
clock was kept because a blocking hang burns no CPU -- true in general, and
inapplicable to a path with no open(), socket, subprocess, thread, lock or sleep
anywhere on it. Same payload, idle vs ~4x oversubscription: wall 3.30 -> 21.63s
(2x over the old 10.0s bound), cpu 3.30 -> 7.62s. It guarded a mode it could not
have while paying the full false-red premium. No in-repo vulnerable form can
turn this row red, so the bound was proved live against what it actually guards
-- a future pattern quadratic on long runs, `A+\s*EXFILTRATE` -- which failed it
at 64.77s CPU, 3.2x over.
redos_clock.py and the clock's pin test both documented this row as the
deliberate wall-clock holdout; both corrected.
792 passed, 6/6 documented gaps hold.
This commit is contained in:
parent
c48a2923ac
commit
2466d260d3
3 changed files with 78 additions and 47 deletions
|
|
@ -16,10 +16,13 @@ to drift back to a wall clock without a single test going red.
|
|||
What this clock gives up: a scan that BLOCKS forever burns no CPU, so it would
|
||||
hang the suite instead of failing it. Acceptable for every caller here — these
|
||||
scanners are pure regex over an in-memory string, with no I/O and no locks, so
|
||||
the only way they can be slow is by spending cycles. It is also why
|
||||
``test_output.py::test_pathological_input_returns_within_a_bound`` deliberately
|
||||
keeps a wall clock: that row claims to catch "a hang or a blowup", and only a
|
||||
wall clock catches the first.
|
||||
the only way they can be slow is by spending cycles. That is not a concession
|
||||
made grudgingly per row: ``test_pathological_input_returns_within_a_bound`` was
|
||||
the last holdout, kept on a wall clock precisely to catch a blocking hang, and
|
||||
it was retired once the path was checked for anything that could block and
|
||||
found to contain none. A wall clock that guards an impossible mode still
|
||||
charges the full false-red premium — measured there at 21.6s against a 10.0s
|
||||
bound under load, on a scan that spent 7.6s.
|
||||
"""
|
||||
import time
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue