BLOCKED(L2 全层):apps/api 934 个测试文件被一次 Docker Hub 镜像拉取卡死;WORKSPACEX_REUSE_INFRA 的逃生口只认 compose 容器,实测拒绝一台真在跑的 PostgreSQL
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
> 来自 #3004(AT 验收 B3 + 平台前置)。这是本批多项判 `BLOCKED` 的**唯一共因**,单独立案以便各项引用。
> exact SHA:`938d16bf3a49c4047f42bbc697833cd921d1053e`(detached checkout,工作树 clean)。
> 环境:Claude Code 远程执行容器,出网经 agent proxy(策略允许 npm/PyPI,**不允许 Docker Hub**)。
## 现象
`acceptance-test-plan.md` §2 的 **L2 服务集成**(API + PostgreSQL + Deep Agent)一层,在本环境里**一条用例都跑不到**——不是红,是从来没执行过任何断言。
```console
$ pnpm exec tsx .harness/scripts/with-test-isolation.ts -- \
pnpm --filter @repo/api exec vitest run tests/agent-run/run-control-unit.test.ts
Test Files no tests
Tests no tests
Serialized Error: … Image pgvector/pgvector:pg16 Pulling
failed to copy: httpReadSeeker: failed open: failed to do request:
Get "https://production.cloudfront.docker.com/registry-v2/…": Forbidden
```
agent proxy 侧的对应记录:
```json
{"kind":"connect_rejected",
"detail":"gateway answered 403 to CONNECT (policy denial or upstream failure)",
"host":"production.cloudfront.docker.com:443"}
```
Docker daemon 本身是好的(本会话内起了 `dockerd` 29.3.1,`docker info` 正常,4 CPU / 15.7 GiB)。
**卡的是镜像拉取,不是容器运行时。**
## 逃生口存在,但拦在错误的地方
`apps/api/tests/support/db.ts:106` 有 `WORKSPACEX_REUSE_INFRA=1`,语义是「不要起/重启基础设施,用现成的」。
它先问 `postgresReady()`,而 `postgresReady()`(同文件 `:77`)**只有一种问法**:
```ts
execFileSync("docker", [...COMPOSE, "exec", "-T", "postgres", "pg_isready", "-h", "127.0.0.1", "-U", "postgres"])
```
也就是「compose 项目里那个叫 postgres 的容器答不答话」。没有容器 ⇒ 恒 false ⇒ `WORKSPACEX_REUSE_INFRA=1`
直接抛错。
### 实测:一台真在跑、真能连的 PostgreSQL 被判为 unavailable
本机装了 `postgresql-16` + `postgresql-16-pgvector`(0.6.0),起在 `127.0.0.1:20999`:
```console
$ pg_isready -h 127.0.0.1 -p 20999
127.0.0.1:20999 - accepting connections
$ PGPASSWORD=postgres_dev psql -h 127.0.0.1 -p 20999 -U postgres -c 'select version();'
PostgreSQL 16.13 (Ubuntu 16.13-0ubuntu0.24.04.1) …
```
带齐 `ISOLATION_ENV_KEYS` 十五个变量(`PGHOST=127.0.0.1 PGPORT=20999 WORKSPACEX_DB=… MIGRATION_DB_USER=postgres MIGRATION_DB_PASSWORD=postgres_dev`)后:
```console
$ WORKSPACEX_REUSE_INFRA=1 pnpm exec vitest run tests/agent-run/run-control-unit.test.ts
Test Files no tests
Tests no tests
Error: Existing PostgreSQL is unavailable; WORKSPACEX_REUSE_INFRA forbids starting or restarting infrastructure
```
`pg-config.ts` 读的是 `PGHOST/PGPORT/PGDATABASE`——**测试进程本来就该连到这台库上**,
只是就绪探针不是用这套坐标问的,而是问 docker。逃生口因此永远打不开。
## 影响面(机械计数,同 SHA)
`apps/api/vitest.config.ts:16` 把 `globalSetup: ["tests/support/db-global-setup.ts"]` 挂在**唯一一个** test project 上,
而 `db-global-setup.ts:11` 第一件事就是 `ensureDatabase()`。所以:
| 计数 | 值 |
| --- | --- |
| `apps/api/tests/**/*.test.ts` 总数 | **934** |
| 其中真正 import 了 `support/db` / `ensureDatabase` / `resetOrgs` 的 | **380** |
| 本环境实际可执行的 | **0** |
⇒ 剩下 **554 个不碰数据库的文件**(纯 schema/映射/守卫单测)也一并跑不了。
这不是「集成测试要数据库」,是**整包的准入被一次镜像拉取绑死**。
## 与 #2991 的边界
#2991 说的是方案 §10 那三条 api 命令**写成裸跑**、收集到零个文件。本 issue 说的是:
**把跑法写对、进了隔离外壳之后,照样一条都跑不了**,原因在准入探针而不在命令。两者不重叠。
## 建议修法(本 issue 只报障,不自行动手)
1. `postgresReady()` 增加一条**按连接坐标**的探针:直接用 `pg.Client(migrationConfig())` 连一次
(或 `pg_isready -h $PGHOST -p $PGPORT`),成功即就绪。保留现有 docker 探针作为
「compose 栈自己起的」那条路径——两条**或**关系,不是替换。
⚠ 保留 `docker … exec … pg_isready -h 127.0.0.1` 那条时不要动它的 `-h`:
该文件 `:46` 那段长注释(#1704)说明了为什么不能退回裸 `pg_isready`。
2. `createDatabaseIfMissing()` 同理:`docker compose exec psql` 之外补一条直连 `CREATE DATABASE`
的路径,沿用现有 42P04 容错。
3. `WORKSPACEX_REUSE_INFRA=1` 的错误信息带上**它探测了什么**(探针种类 + 坐标),
现在只说 “unavailable”,看不出它问的根本不是 `PGHOST/PGPORT` 那台。
## 由此判 BLOCKED 的验收项(登记在 #3004)
L2 层缺失直接影响:AT-E006、AT-E008、AT-E009、AT-T040、AT-T041、AT-T042、AT-T020、AT-T021、
AT-T011、AT-T012、AT-T013 的**真库/权限/恢复**那一层。各项的组件层结论与逐条证据见 #3004 的评论。
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with apps/api/tests/support/db.ts, especially postgresReady() and createDatabaseIfMissing(), then inspect apps/api/vitest.config.ts and tests/support/db-global-setup.ts. Run the isolated command for tests/agent-run/run-control-unit.test.ts with WORKSPACEX_REUSE_INFRA=1. Done means both compose-hosted and PGHOST/PGPORT PostgreSQL paths are detected without Docker Hub, database setup still handles existing databases, and the error identifies the probes and coordinates used.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, postgresql, typescript
- Domain
- backend, databases, devops, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100