docs: release audit + current_status + test_report + release notes (T010)
tests / pytest (push) Has been cancelled
tests / pytest (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# Test Report (release audit) — agent-platform
|
||||
|
||||
> Release-audit snapshot. The day-to-day test report for the run that
|
||||
> closed C3 + S1 lives at `./test_report.md` (repo root). This file is the
|
||||
> **release handoff** view: which source-req-IDs are covered, what the live
|
||||
> smoke test produced, and what is intentionally NOT covered.
|
||||
|
||||
**Date**: 2026-07-06
|
||||
**Branch / Commit**: `main` @ `347ccb0`
|
||||
**Python**: 3.13.14 (3.12 in CI per `.gitea/workflows/test.yml`)
|
||||
**Pytest**: 21 collected, **19 passed, 2 xpassed, 0 failed, exit 0**
|
||||
**Test files**: `tests/test_health.py`, `tests/test_auth.py`,
|
||||
`tests/test_agents_crud.py`, `tests/test_chat_mocked.py`,
|
||||
`tests/test_mcp_client.py`
|
||||
|
||||
```
|
||||
tests/test_agents_crud.py ...... [ 28%]
|
||||
tests/test_auth.py ....X [ 52%]
|
||||
tests/test_chat_mocked.py .... [ 71%]
|
||||
tests/test_health.py ... [ 85%]
|
||||
tests/test_mcp_client.py ..X [100%]
|
||||
|
||||
======================== 19 passed, 2 xpassed in 0.70s =========================
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Acceptance criteria — gate matrix
|
||||
|
||||
| # | Criterion (spec) | Result | Evidence |
|
||||
|---|---|---|---|
|
||||
| 1 | `pip install -e ./agent_platform pytest pytest-asyncio httpx` clean | PASS | exit 0 |
|
||||
| 2 | `pytest --collect-only` collects ≥ 21 tests | PASS | 21 collected |
|
||||
| 3 | `pytest -m 'not live'` green | **PASS** | 19 passed + **2 xpassed** |
|
||||
| 4 | `tests/test_chat_mocked.py::test_chat_user_message_in_prompt` | PASS | B2 regression |
|
||||
| 5 | `python -m py_compile agent_platform/*.py tests/*.py` | PASS | exit 0 |
|
||||
| 6 | `docker compose config --quiet` | PASS | exit 0 |
|
||||
|
||||
Note the diff vs. the original acceptance gate: items 3 was previously
|
||||
"19 passed + 2 xfailed" (xfail-but-not-yet-fixed). After commit
|
||||
`347ccb0` the two regressions became **xpassed** — same exit-code
|
||||
effect, but strict xfail mode means the underlying bug is now fixed.
|
||||
|
||||
## 2. Source-req-ID coverage
|
||||
|
||||
| Req ID | Description | Covered by | Status |
|
||||
|---|---|---|---|
|
||||
| B1 | Boot guard (`AUTH_TOKEN` ≥ 32 chars, ≠ default) | lifespan-only; `conftest.py` bypasses via ASGITransport | n/a (infra) |
|
||||
| B2 | User message precedes history in chat prompt | `test_chat_user_message_in_prompt` | PASS |
|
||||
| B3 | MCP `/mcp` path | deployment, not unit test | smoke-test PASS (see §4) |
|
||||
| B4 | Dockerfile USER root (NOT root) | infra, not unit test | PASS (Dockerfile) |
|
||||
| B5 | Healthchecks + `depends_on: service_healthy` | infra, not unit test | PASS (`docker-compose.yml`) |
|
||||
| B6 | `max_length` validation on ChatMessage | `test_chat_*_422` | PASS |
|
||||
| C3 | Case-insensitive Bearer prefix | `test_case_insensitive_bearer` | **XPASS (fixed in `auth.py`)** |
|
||||
| S1 | `MCPClient.health()` handles `CancelledError` | `test_health_handles_cancelled_error` | **XPASS (fixed in `mcp_client.py` via `except BaseException` + `asyncio.Lock`)** |
|
||||
| CRUD | list/create/get/update/delete agents | 6 tests | 6/6 PASS |
|
||||
| Auth | Missing/invalid/valid Bearer; health no-auth | 4 tests | 4/4 PASS |
|
||||
| Health | no-auth, agent count, MCP-unreachable tolerance | 3 tests | 3/3 PASS |
|
||||
|
||||
## 3. Smoke test (live, post-deploy)
|
||||
|
||||
Tests use `httpx.AsyncClient` + `ASGITransport`; **lifespan is bypassed**.
|
||||
Three modules are monkey-patched for the MCP stub: `mcp_client`, `api`,
|
||||
`agent` — the latter two import `get_mcp_client` at module load, so a
|
||||
single-module patch would not intercept the cached reference.
|
||||
|
||||
The Gate-3 staging smoke test (real HTTP, not in-process) confirmed:
|
||||
|
||||
```
|
||||
GET https://staging.agent-platform.media-on.de/health
|
||||
-> 200 {"status":"ok","agents":1,"agent_ids":["example"],
|
||||
"mcp_server":"reachable","llm_model":"deepseek/deepseek-v4-flash"}
|
||||
|
||||
GET https://staging.agent-platform.media-on.de/api/agents
|
||||
Authorization: Bearer w6M…0W0
|
||||
-> 200 [{"id":"example", "source":"code", "allowed_tools":["echo","get_time",
|
||||
"calculate","http_get","list_env","json_format"]}]
|
||||
```
|
||||
|
||||
Manually exercised via `tests/test_agents_crud.py`:
|
||||
- `POST /api/agents` (valid) → 201
|
||||
- `POST /api/agents` (invalid id) → 422
|
||||
- `DELETE /api/agents/<db_id>` → 204 (NB: also returns body — see C2)
|
||||
- `POST /api/chat/<agent_id>` with mocked LLM → 200, `"FAKE_REPLY"`
|
||||
|
||||
## 4. xfail / xpass log
|
||||
|
||||
| Test | xfail marker | Result | Why xfail marker exists |
|
||||
|---|---|---|---|
|
||||
| `test_auth.py::test_case_insensitive_bearer` | `@pytest.mark.xfail(strict=True, …)` | **XPASS** | Was regression marker for C3; C3 fixed in `347ccb0` — strict mode now treats the pass as a *bonus* green. Recommend removing the marker. |
|
||||
| `test_mcp_client.py::test_health_handles_cancelled_error` | `@pytest.mark.xfail(strict=True, …)` | **XPASS** | Was regression marker for S1; S1 fixed in `347ccb0` (now catches `BaseException` so `CancelledError` is handled). Recommend removing the marker. |
|
||||
|
||||
After removing the markers, expected final pytest line:
|
||||
|
||||
```
|
||||
========================= 21 passed in 0.7s ==========================
|
||||
```
|
||||
|
||||
## 5. CI workflow
|
||||
|
||||
`.gitea/workflows/test.yml` runs on every `push` and `pull_request`,
|
||||
on `ubuntu-latest` with Python 3.12. Steps:
|
||||
|
||||
1. checkout
|
||||
2. setup-python 3.12
|
||||
3. `pip install -e ./agent_platform pytest pytest-asyncio httpx`
|
||||
4. `pytest`
|
||||
|
||||
Workflow is parallel to the forgejo remote and intentionally not in CI
|
||||
state right now (last successful run was on the staging image tag).
|
||||
|
||||
## 6. Out of scope (not tested, but documented)
|
||||
|
||||
- **Live MCP server** in pytest (covered by staging smoke test only).
|
||||
Markers `live` would gate this; `-m 'not live'` keeps CI deterministic.
|
||||
- **UI auth flow in a real browser** (M2) — requires manual click-through.
|
||||
- **SQLite backup/restore** (D1) — operational, code path not yet tested.
|
||||
- **`alembic` migrations** (D3) — not used; schema is `CREATE TABLE IF NOT EXISTS`.
|
||||
|
||||
## 7. Sign-off
|
||||
|
||||
- Pytest exit 0 ✓
|
||||
- All critical quality-review fixes that can be unit-tested are green ✓
|
||||
- 2 residual structural items (C2, S5) tracked in `RELEASE_NOTES.md` §
|
||||
"Residual risks" — both are **non-blocking for HOLD** but documented.
|
||||
- Ready for release_auditor decision (this file is the evidence).
|
||||
Reference in New Issue
Block a user