Skip to content

chore(compose-test-setup): 補上範本預期的 compose.yaml 與 test 服務,讓需要 DB/MQ 的後端測試(含驗收)能以 docker compose --env-file .env -f .worktrees/<id>/compose.yaml run --rm test 在本機跑 - #97

Merged
Marcus778899 merged 2 commits into
developfrom
chore/compose-test-setup
Oct 21, 2026

Conversation

@Marcus778899

Copy link
Copy Markdown
Owner

Closes #96

派工單:tasks/compose-test-setup.md(負責:architect)

Worker 自驗:docker compose --env-file .env -f .worktrees/compose-test-setup/compose.yaml run --rm test ; docker compose --env-file .env -f .worktrees/compose-test-setup/compose.yaml ps -a ; make check ; make check CONTAINER_TESTS=skip → exit 0

變更檔案:

  • compose.yaml
  • docker-compose.yml
  • Makefile
  • .github/workflows/ci.yml
  • api/pom.xml
  • docs/design/INIT-01.md

…n sandbox

- compose.yaml: test service runs mvnw verify with Testcontainers via host socket
- Makefile: make test falls back to -Punit-only when engine unreachable (CI runs all)
- api/pom.xml: unit-only profile excludes acceptance/ and *IntegrationTest
- INIT-01: verification section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0134QMUz6NTfqU8Yrh3BJekj
@Marcus778899

Copy link
Copy Markdown
Owner Author

QA:PASS(commit 07b8431)

PASS 07b8431

QA compose-test-setup(PR #97,chore)

驗收條件對照

  1. compose 單行跑全部後端測試:PASS
    • 指令(主目錄單獨一行):docker compose --env-file .env -f .worktrees/compose-test-setup/compose.yaml run --rm test
    • 輸出尾端(原始):[INFO] Tests run: 191, Failures: 0, Errors: 0, Skipped: 0 / [INFO] BUILD SUCCESS / Total time: 06:54 min
    • 含 acceptance:DeliveryPipelineAcceptanceTest 12、DeliveryResilienceAcceptanceTest 5(docker pause)、SchemaV5UpgradeAcceptanceTest 3、EnvExampleNoTenantIdAcceptanceTest 1 等,全數 Failures 0 / Errors 0。與 CI 的 make check(後端全跑)一致。
  2. 專案名稱獨立、不留容器:PASS(容器部分)
    • 專案名稱 = compose 檔所在目錄(輸出容器名 compose-test-setup-test-run-…);compose.yaml 未設 name。
    • docker compose --env-file .env -f .worktrees/compose-test-setup/compose.yaml ps -a 輸出:NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS(空)。
    • 專案網路 <worktree>_default 會留下(worker 已說明,compose down 可刪);volume cdp-test-m2 刻意保留作快取。
  3. Testcontainers 做法與安全取捨說明:PASS。docs/design/INIT-01.md「驗證方式」與回報 open_questions 有說明;未改任何測試,docker pause 測試通過。
  4. make check 行為與 CI:PASS
    • make check CONTAINER_TESTS=skip(worktree 內):印 Docker not reachable or CONTAINER_TESTS=skip: skipping container tests (acceptance/, *IntegrationTest). 與 compose 指令提示;後端 Tests run: 48, Failures: 0, Errors: 0;web 135 passed;check passed,exit 0。
    • make check(Docker 可達):跑含 acceptance 的完整測試,exit 0。
    • gh pr checks 97:Check pass 4m25s(head 07b8431 = 驗證的 commit)。
  5. README 建議指令已列在回報 open_questions:PASS。

掛載範圍檢查(compose.yaml)

  • /var/run/docker.sock:必要(Testcontainers 兄弟容器)。socket 本身無法以 :ro 達成有意義的唯讀,等同主機 Docker root 權限;為已知取捨,文件已載明,在本機信任的開發環境可接受。
  • ./api:/src/api:ro:唯讀;容器內以 tar 複製到 /workspace/api(排除 target)後建置,不寫回 host。
  • ./.env.example:/workspace/.env.example:ro:唯讀;EnvExampleNoTenantIdAcceptanceTest 需要。
  • m2:/root/.m2:具名 volume cdp-test-m2(Maven 快取),非 host 路徑。
  • 無 ports(測試 DB 不對外)、無與測試無關的 volume、無寫回 host 的掛載。未寫死 token/密碼;TESTCONTAINERS_HOST_OVERRIDE 為固定主機別名,非機敏設定。
  • 範圍檢查:相對 merge-base 僅動 ci.yml(註解)、Makefile、api/pom.xml(unit-only profile)、compose.yaml、docker-compose.yml(註解)、INIT-01.md,均在負責檔案內;未碰禁區。

未驗證項目(照實列出)

  • Testcontainers/Ryuk 啟動的 PostgreSQL、RabbitMQ 容器跑完是否被清除:未驗證。guard 只允許 docker compose …,docker ps 無法使用,不繞過。compose 的 ps -a 只涵蓋 compose 專案內容器,看不到 Ryuk 管理的容器。建議甲方在主機終端 docker ps -a 確認。
  • 專案網路是否殘留:未用 docker network ls 驗證,依 worker 說明(會殘留,非容器)。

邊界/備註(非 FAIL)

  • 主目錄現同時有 compose.yaml 與 docker-compose.yml,不帶 -f 的 docker compose 會選 compose.yaml;make infra-up/down 皆帶 -f docker-compose.yml,行為不變(Makefile diff 已確認)。
  • 首次執行需下載映像與相依,約 7–10 分鐘。

@Marcus778899

Copy link
Copy Markdown
Owner Author

Code review(architect):APPROVE(commit 07b8431)

APPROVE 07b8431

Review compose-test-setup(PR #97)

檢查範圍

  • gh pr diff 97:6 檔(ci.yml 註解、Makefile test/help、api/pom.xml unit-only profile、compose.yaml 新、docker-compose.yml 註解、INIT-01.md「驗證方式」),都在負責檔案內;沒碰禁區(api/src/main、api/src/test/java、application-test.yml、web/)
  • 沒有寫死 secret、port、網址;TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal 是固定主機別名,不是部署設定
  • 測試 DB 不對外開 port(compose 沒有 ports:;Testcontainers 的隨機 port 與在主機直接跑時相同)

重點項目

項目 判定 理由
掛 docker.sock 是否必要 必要,可接受 禁區不准改測試;現有測試用 Testcontainers 自起 PG/RabbitMQ,DeliveryResilienceAcceptanceTest 還要 docker pause,測試行程本身就得能呼叫 Docker API。更窄的做法評估:(a) compose 內放 db/mq、測試改連固定主機:要改測試(禁區)且 pause 測試仍需 Docker API;(b) docker-socket-proxy 限縮 API:Testcontainers 需要 create/start/exec/pause/pull/network,等於全開,且 proxy 擋不了 create 時的 privileged/bind mount,效益低又多一個映像。權限與「主機上直接跑 Testcontainers」相同,沒有比 CI/開發者主機更大;與測試無關的掛載沒有加(只有 api/:ro、.env.example:ro、具名 volume)
-Punit-only 排除是否可靠 可靠 profile 只覆寫 surefire excludes,保留預設的 **/*$*;排除 com/cdp/acceptance/** 與 **/*IntegrationTest.java
make check 自動略過會不會讓 CI 默默略過 不會 條件第一項 [ -n "$CI" ]:GitHub Actions 一律設 CI=true,CI 一律全跑,Docker 壞了是紅燈不是略過。略過分支只在本機發生,且會印出提示與 compose 指令
新慣例是否寫進文件 有 docs/design/INIT-01.md「新測試慣例」列與 api/pom.xml profile 註解
現有測試是否符合新慣例 符合 grep Testcontainers/@Container/*Container/@SpringBootTest/@ServiceConnection:命中檔案全部在 com/cdp/acceptance/;acceptance 以外 17 個測試(architecture、common、delivery、engine、ingest、journey、persistence、query、security)都沒有容器或 Spring context
違反新慣例時的失敗模式 大聲失敗 放錯位置的容器測試不會被排除,sandbox 的 make check 直接報錯,CI 仍全跑;不會造成靜默漏測
make infra-up/infra-down/demo-seed 行為 不變 COMPOSE 仍帶 -f docker-compose.yml;infra-up、infra-down、demo-seed 配方未改;docker-compose.yml 只改註解
專案隔離與殘留 符合 compose.yaml 不設 name:,專案名 = worktree 目錄;run --rm 不留 test 容器(qa ps -a 為空);原始碼複製進容器建置,不寫回主機,不留 root 擁有的檔案

非阻擋建議(給 manager 排後續,不影響本次合併)

  1. 新慣例目前只在 INIT-01.md 與 pom 註解;worker 寫單元測試時主要讀 .claude/skills/backend-standards/references/java.md,建議另開單把「需要容器的測試只放 acceptance/ 或命名 *IntegrationTest」加進去(非本單負責檔案)
  2. Maven 快取 volume cdp-test-m2 被所有 worktree 共用,平行跑兩個 run --rm test 時可能同時寫本機 repo;目前影響小(多半是下載同一相依),若之後遇到損毀再改成每個 worktree 一個 volume
  3. Ryuk 是否清乾淨 Testcontainers 容器、專案網路殘留,qa 因 sandbox 無法驗證;建議甲方在主機終端 docker ps -a、docker network ls 確認一次
  4. 主目錄同時有 compose.yaml 與 docker-compose.yml,不帶 -f 的 docker compose 會選 compose.yaml;README 更新時(manager)一併提醒手動操作要帶 -f

問題數量

阻擋問題 0;非阻擋建議 4

@Marcus778899

Copy link
Copy Markdown
Owner Author

併入最新 develop(07b8431 → dbd2e63):任務 diff 沒變,沿用 qa、review;等 CI 綠再 merge

@Marcus778899
Marcus778899 merged commit 30aa45a into develop Oct 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant