www_site/services/api/tests/README.md
flym 8657f447a1 fix(api): make quota adjustment consistent with concurrent freeze/settlement
Admin quota adjustment now takes the per-user advisory lock and a FOR UPDATE
row lock on the quota account before projecting the balance, so the check
covers both used and reserved amounts and stays transactionally consistent
with task freeze and settlement. Settlement and lease-recovery paths also
lock the quota row explicitly.

Add the isolated Phase 5 exception-matrix harness (fault injection against a
dedicated DB + fake upstream) covering last-quota contention, concurrent
admin reduce, freeze/reduce stress, bad/oversized/timeout upstream, storage
failure, cross-period settlement and queued/running restart recovery.
Add test-only deps, provisioning helper (secrets via env) and test README.
2026-09-10 04:38:47 +08:00

75 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# services/api 测试
可靠性 / 异常矩阵测试在**隔离环境**运行:独立 Postgres 库、独立音频目录、本地伪造
上游fake TTS。绝不连接真实 TTS 提供者,也不改动生产 `kaotings` 库。
## 依赖
运行时依赖见 `../requirements.txt`,测试额外依赖见 `requirements-test.txt`
已验证版本(隔离环境实测):
| 组件 | 版本 |
| --- | --- |
| Python | 3.12.3 |
| fastapi | 0.115.14 |
| uvicorn[standard] | 0.34.3 |
| psycopg[binary] | 3.2.9 |
| httpx | 0.28.1 |
| argon2-cffi | 25.1.0 |
| pydantic | 2.11.7 |
安装(在独立 venv
```
python3 -m venv /path/venv
/path/venv/bin/pip install -r requirements.txt -r requirements-test.txt
```
## 1. 准备隔离库
`provision_isolated_env.sh` 会删除并重建隔离库、应用迁移并种子化 plan/voice。
秘密只通过环境变量注入,不写入仓库:
```
export SUDO_PASSWORD='<sudo 密码>'
export P5_DB_PASSWORD='<隔离库密码>' # 任意强口令,仅隔离库使用
bash services/api/tests/provision_isolated_env.sh
```
## 2. 运行异常矩阵
`phase5_exception_matrix.py` 会启动一个隔离 APIuvicorn+ 本地伪造上游,逐项执行
异常场景并输出结果表与不变式判定:
| 场景 | 覆盖 |
| --- | --- |
| S1 | 成功基线(写入、结算、回放、下载) |
| S2 | 最后额度并发争用(仅一个冻结成功) |
| S3 | 管理员并发调减额度(不变式:总额度 >= 已用+冻结) |
| S4 | 冻结与调减并发压测(终态不变式) |
| S5 | 上游 非音频 / 损坏 / 超大 / HTTP 5xx |
| S6 | 跨周期结算(结算落到任务创建时所属周期账户) |
| S7 | 存储失败(音频目录不可写) |
| S8 | 上游超时 |
| S9 | 重启恢复 - queued未决任务重启后被领取结算 |
| S10 | 重启恢复 - running 租约过期(释放冻结) |
```
export P5_DATABASE_URL='postgresql://kaotings_p5:<P5_DB_PASSWORD>@127.0.0.1:5432/kaotings_p5'
export P5_API_DIR="$(pwd)/services/api" # 被测代码目录
export P5_AUDIO_DIR="/tmp/kaotings-p5-audio"
/path/venv/bin/python services/api/tests/phase5_exception_matrix.py
echo "exit=$?" # 0 = 全部不变式通过
```
退出码 0 表示所有场景的额度不变式与状态断言通过;非 0 表示存在失败项。
`P5_REPORT_PATH` 可指定把结果表写成 markdown 留档。
## 3. 其它测试
- `phase3_reliability.py`:最小成功 / 负向 / 超时 / 存储失败(旧版,使用共享测试库)。
- `phase4_admin.py` / `phase4_browser.py`:管理后台 API 与浏览器验收。
> 浏览器测试Playwright需 `PLAYWRIGHT_BROWSERS_PATH` 指向已下载浏览器缓存;
> 浏览器二进制不入库,见 `docs/phase-4-report.md`。