Files
tai/research/async-pty-process-testing/gem5-test-infrastructure-commit.md
T

51 lines
3.2 KiB
Markdown
Raw Normal View History

# gem5 test infrastructure — Timer-based timeout + typed exceptions
## Metadata
| Field | Value |
|---|---|
| Institute | Molodetz Institute — Research & Retrieval Division |
| Subject | async-pty-process-testing |
| Document type | Source Dossier |
| Tier | 1 |
| Source title | tests: Add test infrastructure as a Python module (commit), and companion helpers.py |
| Source URL | https://git.sanchayanmaity.net/sanchayanmaity/gem5/commit/f385adc8af744e7f6b78ff9adafd9c3ecf65ce68 |
| Source publisher / author | gem5 project (computer architecture simulator) |
| Source type | repository (commit + source file) |
| Source date (published) | Unknown — not stated |
| Date researched | 2026-10-09 |
| Researched by | tai (agent), model: Claude Sonnet 5, on behalf of retoor |
| Research method | web search synthesis |
| Confidence | High |
| Status | Active |
## Summary
A commit adding Python test infrastructure to the gem5 simulator project, together with its companion `tests/testing/helpers.py`. The helper uses a `threading.Timer` to enforce a timeout on a running subprocess: the timer's callback terminates the child process, then the surrounding code raises a dedicated exception carrying both the captured exit status and the process's output.
## Key findings
- Timeout enforcement pattern: `Timer(timeout, on_timeout_handler)` started before `communicate()`-ing with the process, cancelled afterward if the process finished in time.
- On timeout, the handler terminates the child and a dedicated exception type is raised carrying the captured status and output together — the caller doesn't have to separately go fetch output after catching a generic timeout error.
- gem5's newer test framework (noted in the same research pass) further splits each test into a "run" stage and a "verify" stage, where verify units are automatically skipped if their corresponding run stage didn't execute.
## Pros / strengths
- The "exception carries the captured output" design is directly actionable and immediately reusable — it solves the exact problem of "how do you debug a timed-out test" by attaching the evidence to the failure itself rather than requiring separate log inspection.
- The run/verify stage split is a clean idea for keeping a test's "did it crash" question separate from "did it produce the right result."
## Cons / limitations / caveats
- Uses `threading.Timer`, a synchronous/thread-based mechanism, not `asyncio.wait_for` — `tai_test.py` adapted the *idea* (typed exception carrying output) to an asyncio-native mechanism (`asyncio.wait_for` plus try/except) rather than reusing gem5's thread-based implementation directly.
- Reviewed via commit metadata and the helper file's described behavior, not gem5's full test suite or its actual usage patterns in practice.
## Relevance to tai
The direct model for `tai_test.py`'s exception hierarchy: `TestTimeout`, `TestCrashed`, and `TestAssertionFailed` all subclass `TaiTestError`, which carries a `transcript` list — so a failing test's exception *is* the debugging evidence, exactly matching gem5's "exception carries status and output" pattern, just built on `asyncio.wait_for`/try-except instead of `threading.Timer`.
## Changelog
| Date | Change |
|---|---|
| 2026-10-09 | Initial dossier created. |