Skip to content

test(timing): measure CPU time and corroborate before failing on loaded runners - #163

Merged
rennf93 merged 1 commit into
masterfrom
test/load-tolerant-timing
Oct 15, 2026
Merged

rennf93 merged 1 commit into
masterfrom
test/load-tolerant-timing

Conversation

@rennf93

@rennf93 rennf93 commented Oct 15, 2026

Copy link
Copy Markdown
Member

Master CI failed its last two runs (2026-10-14) on timing assertions that a loaded runner can miss, and PR #162 hit the same one. The failures, verbatim from runs 38613193702, 38593971238 and 38639913718:

  • test_lazy_init_returns_quickly_with_blocking_background_init - assert 0.6880667630000517 < 0.5 (also 0.5635 and 0.6231)
  • test_bounded_scan_stays_under_five_milliseconds_on_all_three_fill_shapes - many_prefixes_one_terminator at size=524288: bounded CPU 0.005967s exceeded the 0.005s ceiling
  • docker-test: hostname fragment timed out with failing tail, and the template and ldap extensible-match detect did not return within the deadline tests

Changes, each keeping the test able to fail on a real regression:

  • Lazy init: the stub never blocked, so the 0.5s bound could not catch a regression either. The background init now blocks for 2s and the test asserts ordering (the call returns before the background init finishes). A lazy init that awaited it fails with assert ['cloud'] == []; the old test passed under that mutation.
  • Bounded scan: the 5ms ceiling scales linearly with size and must be breached at every size, so a single contention-inflated min-of-5 no longer fails it. A 4x slowdown of bounded_search fails at both sizes, and swapping in a raw compiled.search fails as well. _REPS is unchanged and there is no retry.
  • ReDoS protection and hostname fragment: the deadline is now the child's CPU time around detect() (time.process_time()), and wall clock only guards against a hang (60s), since forkserver start-up and imports alone outran the 1-2s wall join under Docker load. An injected (a+)+$ scan fails with detect used 4.459s of CPU, exceeding the 2.0s deadline, and the nested-star hostname probe fails with used 3.776s of CPU.

The sync tree is regenerated with scripts/unasync.py (the hand-maintained ReDoS mirror edited by hand), and --check passes. Local gate: 21568 passed, 4 skipped, 100% coverage, quality and pre-commit clean.

…ed runners

The lazy-init returns-quickly test asserted a 0.5s wall bound that a loaded runner exceeded (0.56 to 0.69s) while its stub never blocked, so it could not fail on a real regression either. It now blocks the background init for 2s and asserts ordering: the call returns while that init is unfinished.

The scan-window 5ms CPU ceiling is scaled per size and must be breached at every size, so one contention-inflated min-of-5 no longer fails it while a quadratic or constant-factor regression still does.

The built-in ReDoS detect tests and the hostname fragment test joined a forkserver child under a 1s or 2s wall deadline, which start-up alone outruns under load. The wall join is now a 60s hang guard and the budget is the child's CPU time.
@rennf93 rennf93 added the no-issue Chore or dependency PR that does not need an issue label Oct 15, 2026
@github-actions github-actions Bot added the tests Test suite changes label Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Detection gate report

All detection gate shards passed.

Shard arbiter-grammar

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: n/a. Total false-positive rate: n/a.
Documented known gaps: 0. Documented known false positives: 0. Both stay in the denominators.

Full per-case output is in the job log.

Shard benchmarks-and-rest

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: 378/386 (97.9%). Total false-positive rate: 23/370 (6.2%).
Documented known gaps: 8. Documented known false positives: 23. Both stay in the denominators.

Category Recall False positives
cmd_injection 38/46 (82.6%) 10/370 (2.7%)
cms_probing 36/36 (100.0%) 0/370 (0.0%)
code_injection 3/3 (100.0%) 0/370 (0.0%)
deserialization 18/18 (100.0%) 0/370 (0.0%)
dir_traversal 10/10 (100.0%) 0/370 (0.0%)
file_inclusion 16/16 (100.0%) 3/370 (0.8%)
file_upload 32/32 (100.0%) 0/370 (0.0%)
http_split 4/4 (100.0%) 0/370 (0.0%)
ldap 25/25 (100.0%) 0/370 (0.0%)
nosql 10/10 (100.0%) 0/370 (0.0%)
path_traversal 13/13 (100.0%) 0/370 (0.0%)
proto_pollution 8/8 (100.0%) 0/370 (0.0%)
recon 23/23 (100.0%) 0/370 (0.0%)
sensitive_file 16/16 (100.0%) 0/370 (0.0%)
sqli 38/38 (100.0%) 6/370 (1.6%)
ssrf 32/32 (100.0%) 4/370 (1.1%)
template 13/13 (100.0%) 1/370 (0.3%)
xml 4/4 (100.0%) 0/370 (0.0%)
xss 39/39 (100.0%) 0/370 (0.0%)

Full per-case output is in the job log.

Shard builtin-safety

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: n/a. Total false-positive rate: n/a.
Documented known gaps: 0. Documented known false positives: 0. Both stay in the denominators.

Full per-case output is in the job log.

Shard cpu-load-arbiter-grammar

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: n/a. Total false-positive rate: n/a.
Documented known gaps: 0. Documented known false positives: 0. Both stay in the denominators.

Full per-case output is in the job log.

Shard cpu-load-benchmarks-and-rest

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: 378/386 (97.9%). Total false-positive rate: 23/370 (6.2%).
Documented known gaps: 8. Documented known false positives: 23. Both stay in the denominators.

Category Recall False positives
cmd_injection 38/46 (82.6%) 10/370 (2.7%)
cms_probing 36/36 (100.0%) 0/370 (0.0%)
code_injection 3/3 (100.0%) 0/370 (0.0%)
deserialization 18/18 (100.0%) 0/370 (0.0%)
dir_traversal 10/10 (100.0%) 0/370 (0.0%)
file_inclusion 16/16 (100.0%) 3/370 (0.8%)
file_upload 32/32 (100.0%) 0/370 (0.0%)
http_split 4/4 (100.0%) 0/370 (0.0%)
ldap 25/25 (100.0%) 0/370 (0.0%)
nosql 10/10 (100.0%) 0/370 (0.0%)
path_traversal 13/13 (100.0%) 0/370 (0.0%)
proto_pollution 8/8 (100.0%) 0/370 (0.0%)
recon 23/23 (100.0%) 0/370 (0.0%)
sensitive_file 16/16 (100.0%) 0/370 (0.0%)
sqli 38/38 (100.0%) 6/370 (1.6%)
ssrf 32/32 (100.0%) 4/370 (1.1%)
template 13/13 (100.0%) 1/370 (0.3%)
xml 4/4 (100.0%) 0/370 (0.0%)
xss 39/39 (100.0%) 0/370 (0.0%)

Full per-case output is in the job log.

Shard cpu-load-builtin-safety

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: n/a. Total false-positive rate: n/a.
Documented known gaps: 0. Documented known false positives: 0. Both stay in the denominators.

Full per-case output is in the job log.

Shard hardening-canaries

Gate green: no category regressed against its committed baseline and no benign string is newly flagged.

Total recall: n/a. Total false-positive rate: n/a.
Documented known gaps: 0. Documented known false positives: 0. Both stay in the denominators.

Full per-case output is in the job log.

@rennf93
rennf93 merged commit 81303e2 into master Oct 15, 2026
40 checks passed
@rennf93
rennf93 deleted the test/load-tolerant-timing branch October 15, 2026 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-issue Chore or dependency PR that does not need an issue tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant