Pre-existing test_startup_logs_warning_when_running_as_root fails under ASGITransport #655

Open
opened 2026-05-21 17:11:03 +02:00 by marcel · 0 comments
Owner

Symptom

ocr-service/test_main.py::test_startup_logs_warning_when_running_as_root
AssertionError: assert 'Running as root' in ''
 +  where '' = <_pytest.logging.LogCaptureFixture object at 0x...>.text

Reproduces on main as well — predates PR #653 and #652.

Root cause

The test uses AsyncClient(transport=ASGITransport(app=app), ...) and
expects the FastAPI lifespan to fire, which would emit the
Running as root — CIS Docker §4.1 violation warning. httpx's
ASGITransport does not run the lifespan by default — it only proxies
HTTP scope requests. So the lifespan startup code never executes, caplog
captures nothing, and the assertion fails.

The metrics suite already hit the same wall and routes around it with:

# ocr-service/test_metrics.py
async with app.router.lifespan_context(app):
    # lifespan startup is now active for the duration of this block

(see test_ocr_models_ready_gauge_is_one_after_lifespan_startup).

Proposed fix

Migrate test_startup_logs_warning_when_running_as_root and its sibling
test_startup_does_not_warn_when_running_as_non_root to drive the
lifespan directly via app.router.lifespan_context(app) (same pattern as
test_metrics.py). The runtime mock of os.getuid() stays as-is.

Alternative: use httpx.ASGITransport(app=app, lifespan="on"), but only
recent httpx versions accept that argument — check the pinned version
before relying on it.

Acceptance criteria

  • test_startup_logs_warning_when_running_as_root passes.
  • test_startup_does_not_warn_when_running_as_non_root still passes.
  • No additional warnings introduced in pytest output.
  • CLAUDE.md / CODESTYLE.md note this pattern alongside the existing
    ASGITransport examples (only if a future grep would benefit).
  • PR #653 (mentioned the failure in the test plan, did not fix it)
  • ocr-service/test_metrics.py::test_ocr_models_ready_gauge_is_one_after_lifespan_startup
## Symptom ``` ocr-service/test_main.py::test_startup_logs_warning_when_running_as_root AssertionError: assert 'Running as root' in '' + where '' = <_pytest.logging.LogCaptureFixture object at 0x...>.text ``` Reproduces on `main` as well — predates PR #653 and #652. ## Root cause The test uses `AsyncClient(transport=ASGITransport(app=app), ...)` and expects the FastAPI `lifespan` to fire, which would emit the `Running as root — CIS Docker §4.1 violation` warning. `httpx`'s `ASGITransport` **does not run the lifespan by default** — it only proxies HTTP scope requests. So the lifespan startup code never executes, caplog captures nothing, and the assertion fails. The metrics suite already hit the same wall and routes around it with: ```python # ocr-service/test_metrics.py async with app.router.lifespan_context(app): # lifespan startup is now active for the duration of this block ``` (see `test_ocr_models_ready_gauge_is_one_after_lifespan_startup`). ## Proposed fix Migrate `test_startup_logs_warning_when_running_as_root` and its sibling `test_startup_does_not_warn_when_running_as_non_root` to drive the lifespan directly via `app.router.lifespan_context(app)` (same pattern as `test_metrics.py`). The runtime mock of `os.getuid()` stays as-is. Alternative: use `httpx.ASGITransport(app=app, lifespan="on")`, but only recent httpx versions accept that argument — check the pinned version before relying on it. ## Acceptance criteria - [ ] `test_startup_logs_warning_when_running_as_root` passes. - [ ] `test_startup_does_not_warn_when_running_as_non_root` still passes. - [ ] No additional warnings introduced in pytest output. - [ ] CLAUDE.md / CODESTYLE.md note this pattern alongside the existing `ASGITransport` examples (only if a future grep would benefit). ## Related - PR #653 (mentioned the failure in the test plan, did not fix it) - `ocr-service/test_metrics.py::test_ocr_models_ready_gauge_is_one_after_lifespan_startup`
marcel added the bugdevops labels 2026-05-21 17:11:08 +02:00
Sign in to join this conversation.
No Label bug devops
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#655