Files
dbtool-cli-v1/QA_RUNTIME_ENVIRONMENT.md
Paperclip CTO d5f69462b0
Some checks failed
release-smoke / macos-13 / x86_64-apple-darwin (push) Has been cancelled
release-smoke / ubuntu-latest / x86_64-unknown-linux-gnu (push) Has been cancelled
release-smoke / windows-latest / x86_64-pc-windows-msvc (push) Has been cancelled
feat(usable): integrate current dbtool implementation snapshot
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-02 08:26:18 +00:00

251 lines
9.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.

# PostgreSQL / MySQL Runtime Smoke 环境建议
## 结论
当前阶段的目标推荐方案是:**让 QA agent 直接在升级后的 `local-db-codex` 容器内执行 smoke并通过挂载宿主机 Docker daemon、Docker 配置、Cargo 与 Rustup 目录来复用宿主能力**。
- 继续复用现有 `docker-compose.demo.yml`、bootstrap 脚本和 SQL fixtures
- 不依赖长期运行的宿主机 PostgreSQL / MySQL
- 不再要求 QA 手动切回宿主机执行
- 将 Docker、Rust、Cargo mirror、Docker registry mirror 的能力统一沉淀到容器运行时
在该部署升级完成前,宿主机执行仍然是可用 fallback但后续默认路径应转向容器内 agent 自行完成 smoke。
2026-03-26 的 [CMP-17](/CMP/issues/CMP-17#comment-0cd53e93-25a5-456b-8dba-31ea098c2aa8) 已证明该路径可以成立:宿主机 PostgreSQL / MySQL smoke 已执行完成,因此“当前 QA runner 无 Docker”只代表本 agent 本地限制,不再代表方案无效。
## 三种方案对比
### 方案 A宿主机长期运行 PostgreSQL / MySQL
优点:
- 首次接入快
- QA 不需要每次拉起容器
缺点:
- 状态容易漂移,重复执行时很难保证数据库干净
- 需要长期维护端口、用户、权限和版本
- 一旦多人共用宿主机,测试数据会互相污染
- 更适合共享开发环境,不适合作为 release smoke 证据来源
结论:**可作为临时兜底,不作为推荐主路径。**
### 方案 B为 `local-db-codex` 部署增加 Docker runtime 能力
优点:
- 从 agent 视角最方便,理论上可以把 smoke 也放回当前容器体系
- 后续若多个项目都依赖容器型集成测试,长期上限更高
缺点:
- 这是平台/安全/运维改造,不是当前仓库内的小改动
- 会引入容器嵌套、权限边界、镜像缓存、资源隔离等额外复杂度
- 当前项目的真实瓶颈是缺可执行宿主,不是缺应用层代码
结论:**不适合作为本阶段 unblock 手段,只在未来多个项目都提出同类需求时再立项。**
### 方案 CQA runner 在宿主机执行,数据库通过 Docker Compose 临时拉起
优点:
- 直接复用现有仓库资产,落地最快
- 每次 `up` / `down -v` 都是干净环境,可重复性最好
- 不要求改 `local-db-codex` 平台
- 后续可平滑迁移到自托管 runner 或专用 QA 主机
缺点:
- 需要一台具备 Docker / `docker compose` 的宿主机
- 宿主机上仍需准备 Rust toolchain 或 release binary
结论:**作为 fallback 可用,但不再是长期目标路径。**
### 方案 D升级 `local-db-codex`,让 agent 在容器内复用宿主机 Docker 和 Rust
优点:
- agent 可直接在容器内执行 PostgreSQL / MySQL Docker-backed smoke
- 后续每个功能实现后的测试路径一致,不需要在人和 agent 之间切换执行环境
- 继续复用宿主机 Docker daemon 的镜像缓存、registry mirror 和权限体系
- 继续复用宿主机 Rust toolchain、Cargo 配置和 crates mirror 配置
缺点:
- 需要维护容器与宿主机之间的挂载关系
- Docker socket 暴露会提升容器能力边界,需明确接受该风险
- 宿主机 Docker / Rust 环境本身出问题时,容器内 agent 会继承同样问题
结论:**这是后续迭代的目标方案。**
## 推荐执行方式
### 容器化 QA runner 要求
- `deploy/local-db-codex` 已升级,挂载:
- 宿主机 Docker socket
- 宿主机 Docker config
- 宿主机 Cargo home
- 宿主机 Rustup home
- 容器内可直接运行:
- `docker`
- `cargo`
- `rustc`
- 宿主机 Docker daemon 已配置好 registry mirror如有
- 宿主机 Cargo / Rustup mirror 配置已就绪(如有)
### 使用步骤
1. 启动升级后的 `local-db-codex` 部署
2. 进入 agent 所在容器运行环境,确认 `docker``cargo``rustc` 可用
3. 在工作区准备 CLI
- 开发验证:`cargo build`
- 或使用已生成的 `target/debug/dbtool` / `target/release/dbtool`
4. 导出密码环境变量:
```bash
export DBTOOL_PASSWORD=dbtool
export DBTOOL_POSTGRES_ADMIN_PASSWORD=dbtoolroot
```
5. 拉起 PostgreSQL / MySQL
```bash
docker compose -f docker-compose.demo.yml up -d postgres mysql
```
6. 导入 demo 数据:
```bash
./examples/scripts/bootstrap-postgres.sh
./examples/scripts/bootstrap-mysql.sh
```
如果本机 PostgreSQL demo 容器早于本轮权限修正创建,先清旧卷再重建:
```bash
docker compose -f docker-compose.demo.yml down -v
docker compose -f docker-compose.demo.yml up -d postgres mysql
./examples/scripts/bootstrap-postgres.sh
./examples/scripts/bootstrap-mysql.sh
```
PostgreSQL demo 当前权限边界:
- `postgres` / `dbtoolroot`:只用于 seed、restricted probe 建立与清理
- `dbtool` / `dbtool`QA 与 TUI/CLI live 路径使用的非超级用户
可先验证 `dbtool` 不再是超级用户:
```bash
PGPASSWORD="$DBTOOL_POSTGRES_ADMIN_PASSWORD" \
psql -h 127.0.0.1 -p 55432 -U postgres -d dbtool_demo \
-c "select rolname, rolsuper, rolcreaterole, rolcreatedb from pg_roles where rolname='dbtool';"
```
PostgreSQL restricted-schema 最小复验步骤:
```bash
PGPASSWORD="$DBTOOL_POSTGRES_ADMIN_PASSWORD" \
psql -h 127.0.0.1 -p 55432 -U postgres -d dbtool_demo <<'SQL'
drop schema if exists restricted_probe cascade;
create schema restricted_probe;
create table restricted_probe.audit_log (
id bigint primary key,
note text not null
);
insert into restricted_probe.audit_log values (1, 'hidden from dbtool');
revoke all on schema restricted_probe from public;
revoke all on all tables in schema restricted_probe from public;
revoke all on schema restricted_probe from dbtool;
revoke all on all tables in schema restricted_probe from dbtool;
SQL
export DBTOOL_PASSWORD=dbtool
cargo run -p dbtool-cli -- inspect --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD
cargo run -p dbtool-cli -- inspect --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --schema restricted_probe
```
预期:
- root inspect 出现 `restricted_probe [restricted]`
- 显式 `--schema restricted_probe` 返回 restricted inspect error而不是 empty tables
清理:
```bash
PGPASSWORD="$DBTOOL_POSTGRES_ADMIN_PASSWORD" \
psql -h 127.0.0.1 -p 55432 -U postgres -d dbtool_demo \
-c "drop schema if exists restricted_probe cascade;"
```
7.`SMOKE_RUNBOOK.md` 执行 PostgreSQL / MySQL 的 happy-path`HOST_FAILURE_PATH_CHECKLIST.md` 执行 failure-path
8. 将结果回填到 `ACCEPTANCE_CHECKLIST.md``TEST_STRATEGY.md``PRE_RELEASE_CHECKLIST.md`
9. 清理环境:
```bash
docker compose -f docker-compose.demo.yml down -v
```
## Failure-path 执行入口
- PostgreSQL / MySQL happy-path 继续使用 `SMOKE_RUNBOOK.md`
- PostgreSQL / MySQL failure-path 统一使用 `HOST_FAILURE_PATH_CHECKLIST.md`
- 证据记录格式继续以 `FAILURE_PATH_EVIDENCE_TEMPLATE.md` 为准
- 在发起宿主机或 sidecar live 执行前,先跑离线夹具收敛 helper / wrapper 契约:
```bash
scripts/qa/test-failure-path-fixtures.sh
```
- 若只想检查单一路径,可改跑:
```bash
scripts/qa/test-failure-path-fixtures.sh format
scripts/qa/test-failure-path-fixtures.sh sidecar
```
## 2026-03-28 当前容器化 runner 观察
- QA runner 已可访问 Docker daemon但当前仍缺 `docker compose` 子命令。
- QA runner 不能直接访问 `127.0.0.1:55432/53306`,也不能直接访问 demo 数据库容器 IP。
- 当前有效补充路径是:
1. 复用已运行的 `dbtool-cli-v1-postgres-1` / `dbtool-cli-v1-mysql-1`
2.`docker exec` 直接导入 PostgreSQL / MySQL demo 数据
3. 创建 sidecar container 并加入 `dbtool-cli-v1_default` 网络
4. 在 sidecar container 内执行 `dbtool`,默认主机名跟随 `QA_POSTGRES_CONTAINER` / `QA_MYSQL_CONTAINER`(当前默认是 `dbtool-cli-v1-postgres-1` / `dbtool-cli-v1-mysql-1`
这条 sidecar network execution 路径在 2026-03-28 当前 heartbeat 已被直接验证,可用于继续补 PostgreSQL / MySQL failure-path 证据。
为减少重复手工步骤,当前仓库已提供:
```bash
scripts/qa/run-failure-path-evidence-sidecar.sh ./target/release/dbtool ./tmp/failure-path-evidence
```
这条脚本化路径会自动完成:
- PostgreSQL / MySQL demo 数据重导入
- sidecar container 创建与清理
- sidecar 内 failure-path helper 执行
- 证据文件回传到本地输出目录
- 当前 PostgreSQL sidecar 重导入默认使用 `postgres` / `dbtoolroot`;若宿主机 demo 管理员身份被改写,可改传 `QA_POSTGRES_ADMIN_USER` / `QA_POSTGRES_ADMIN_PASSWORD`
## 团队职责
- 后端:维护 `docker-compose.demo.yml`、bootstrap 脚本、fixtures、命令契约和容器内 smoke 兼容性
- QA优先在容器内 agent 运行环境执行 smoke沉淀证据和失败复现记录
- 前端:当前继续 gated不参与此轮 runtime smoke
- CTO维持方案边界并确保 `local-db-codex` 能长期承载容器内 smoke
## 风险与维护成本
- Docker socket 暴露:容器获得了较强的宿主机控制能力,必须明确接受这一安全边界。
- 宿主机 Docker / Rust 环境漂移:容器会继承宿主机配置,出现问题时必须同时排查宿主机。
- 二进制与文档漂移QA 执行时必须绑定具体 commit 或 release artifact。
- 端口冲突:必要时继续参数化 compose 端口。
- 当前已知结论:宿主机 patched-run 已确认 MySQL 中文与 emoji 输出正常,问题根因收敛到 bootstrap/import 字符集路径;后续需要把这类验证稳定迁入容器内 smoke 路径。
总体维护成本可控,因为主路径继续复用仓库现有 smoke 资产,只是把执行宿主从人工宿主机切换成可复用宿主能力的 Paperclip 容器。