From 06e4118dd462d1b406467094945dcbf6f5889eca Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Thu, 29 Oct 2026 00:11:48 +0100 Subject: [PATCH] test(radar): make bulk deadline test independent of host load (ticket-257) --- project/TICKETS.md | 1 + project/ticket-257/README.md | 37 ++++++++++++++++++++++++++++++++++ project/ticket-257/intent.json | 24 ++++++++++++++++++++++ tests/test_ticket_radar.py | 21 +++++++++++++++---- 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 project/ticket-257/README.md create mode 100644 project/ticket-257/intent.json diff --git a/project/TICKETS.md b/project/TICKETS.md index 63d4ea8..a6882d1 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -156,4 +156,5 @@ This file indexes governance tickets without taking ownership of | **ticket-251** | [`README.md`](./ticket-251/README.md) | - | - | - | - | - | | **ticket-252** | [`README.md`](./ticket-252/README.md) | - | - | - | - | - | | **ticket-253** | [`README.md`](./ticket-253/README.md) | - | - | - | - | - | +| **ticket-256** | [`README.md`](./ticket-256/README.md) | - | - | - | - | - | diff --git a/project/ticket-257/README.md b/project/ticket-257/README.md new file mode 100644 index 0000000..ec35b35 --- /dev/null +++ b/project/ticket-257/README.md @@ -0,0 +1,37 @@ +# Ticket 257: Deterministic bulk deadline radar test + +- **ID**: ticket-257 +- **Owner**: agent:antigravity +- **Status**: IN_PROGRESS +- **Workflow state**: EDIT +- **Created**: 2026-10-28 + +## Goal and scope + +SESSION_EXECUTION_AUTHORIZATION: the user asked to remove recurring load-sensitive +verification failures. `tests/test_ticket_radar.py::test_failure_bulk_deadline_preserves_remaining_tickets` +failed intermittently on `main` and on unrelated branches (ticket-256 PR 315: 1 pass in +4 runs; `main`: 2 of 3 passes at load average 50-70). It used a 0.35 s bulk deadline and a +0.2 s fake radar, so Python subprocess start-up time decided the outcome. + +Test-only change; no production code is modified. + +## Changes + +- The fake radar answers its first call immediately and blocks on every later call. +- `BULK_SECONDS` and `ASSESSMENT_SECONDS` are set to 2.0 s, so the first call never + depends on start-up speed and the remaining calls are cut by the bulk deadline. +- Assertions keep the original intent: total radar time is bounded, at most two radar + calls happen, the first ticket is enriched, all other tickets keep their human text and + every ticket plus its operational event is preserved. + +## Acceptance criteria + +- [x] AC-01: The test passed 6 of 6 consecutive runs at load average above 15. +- [x] AC-02: The whole `tests/test_ticket_radar.py` file passes. +- [x] AC-03: `./project/governance-check.sh` passes. + +## Tracking boundary + +This directory contains the minimal reviewed intent. Optional participant prose +and raw command logs are not required delivery output. diff --git a/project/ticket-257/intent.json b/project/ticket-257/intent.json new file mode 100644 index 0000000..4448c15 --- /dev/null +++ b/project/ticket-257/intent.json @@ -0,0 +1,24 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-257", + "summary": "Deterministic bulk deadline radar test", + "workstream": "application", + "classification": { + "kind": "BUG", + "priority": "P2", + "origin": "regression" + }, + "allowedPaths": [ + "project/ticket-257/**", + "TODO.md", + "project/TICKETS.md", + "tests/test_ticket_radar.py" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md" + ], + "stacks": [], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null +} diff --git a/tests/test_ticket_radar.py b/tests/test_ticket_radar.py index 0555479..32a8a46 100644 --- a/tests/test_ticket_radar.py +++ b/tests/test_ticket_radar.py @@ -336,8 +336,21 @@ def capture_pipe(command, **kwargs): def test_failure_bulk_deadline_preserves_remaining_tickets(tmp_path, fake_radar, monkeypatch): - fake_radar("time.sleep(0.2)\n") - monkeypatch.setattr(radar, "BULK_SECONDS", 0.35) + # Deterministic under host load: the first radar call answers immediately and + # every later call blocks until the bulk deadline, so no outcome depends on + # how long a Python subprocess takes to start. + marker = tmp_path / "radar-called" + fake_radar( + prelude=f""" + marker = {str(marker)!r} + if os.path.exists(marker): + time.sleep(60) + open(marker, 'w').close() + """ + ) + bulk_seconds = 2.0 + monkeypatch.setattr(radar, "BULK_SECONDS", bulk_seconds) + monkeypatch.setattr(radar, "ASSESSMENT_SECONDS", bulk_seconds) elapsed = [] original_bundle = radar._bundle @@ -353,11 +366,11 @@ def measured_bundle(*args): tickets = pf.create_tickets_bulk( [{"name": f"Bulk {index}", "description": DESCRIPTION} for index in range(12)] ) - assert sum(elapsed) < 1.5 + assert sum(elapsed) < bulk_seconds + 1.5 assert len(elapsed) <= 2 assert len(tickets) == 12 assert radar.ADVISORY_HEADING in tickets[0].description - assert all(ticket.description == DESCRIPTION for ticket in tickets[2:]) + assert all(ticket.description == DESCRIPTION for ticket in tickets[1:]) assert len(pf.list_tickets()) == 12 assert len(pf.store.operational_events()) == 12