Skip to content

[Feature]: move tests/ into domain directories and shard the macOS CI leg #3497

Closed

Description

@lidge-jun

Area

Multiple areas

What are you trying to accomplish?

Make the test suite navigable and CI faster without touching a single assertion.

tests/ holds 1061 *.test.ts files, 1045 of them flat at the root. 102 exceed 800 lines; the largest (codex-catalog.test.ts) is 6807. Ownership is by filename prefix only, so "the server tests" or "the Cursor adapter tests" are a grep, not a directory. Contributors touching one subsystem cannot see which tests own it, and reviewers cannot tell from a PR file list which area a moved test belongs to.

On CI the unsharded macOS job is the critical path on 10 of the last 10 green dev pushes (mean 14.9 min against a 4.7 min Linux shard maximum), so every PR waits ~15 minutes for one job.

What prevents this today?

  • Bun discovery already recurses (bunfig.toml root = "tests"; tests/images/, tests/videos/, tests/e2e-style/ are nested today), so the blocker is not the runner. It is the ~238 path literals in 104 files that name tests/<file> (ci.yml isolated-job lists, scripts/ci/run-bun-test-batches.sh root-anchored exclusions, scripts/test.ts serial lanes, scripts/release.ts, source-oracle tests that read import.meta.dir + "/../src", 15 child-process helpers located by join(import.meta.dir, "helpers", ...), and the CI contract tests that pin all of the above).
  • bun run test:changed follows only Bun's module graph, so a move that breaks a read-as-text or child-spawn path is invisible to it.
  • macOS has no shard because it was deliberately kept as the "whole-pool control"; the comment justifying it as cheapest (5m23s) is stale.

What should OpenCodex do?

  1. Place tests in tests/<domain>/ directories that mirror src/ (providers, codex-integration, server, adapters, responses, lab, cli, routing, gui, oauth, claude-integration, ci-workflows, usage, lib, clients, service, windows, storage, vision, config, web-search, update, plus the existing images/videos/e2e-style), two levels deep at most. Helpers and fixtures stay where they are.
  2. Provide the move as tooling, not a hand edit: a committed scripts/test-layout/layout.json map, a mover that git mvs one domain slice per PR and rewrites relative imports, dynamic imports, new URL forms and child-helper joins by depth, and a tests/test-layout.test.ts guard that fails when a file lands outside its domain. Source-oracle tests resolve the repository through a tests/helpers/repo-root.ts helper instead of import.meta.dir + "/..".
  3. Keep bun run test, bun run test:changed, scripts/ci/run-bun-test-batches.sh and every ci.yml job behaving as today (same files, same isolation groups). Nothing is deleted and no assertion changes.
  4. Shard the macOS CI job 2-way and keep the unsharded whole-pool run behind workflow_dispatch (lane=macos-control). Linux stays at 4 shards; measured, going to 6 or 8 saves zero wall minutes while macOS is unsharded. The Windows leg stays dispatch-only and is not touched.

Example usage or interface

Before:

bun test tests/cursor-adapter.test.ts tests/cursor-blob.test.ts   # find them by prefix first

After:

bun test tests/providers/cursor            # everything that owns src/adapters/cursor
bun scripts/test-layout/plan.ts --domain server   # what still needs moving

CI: a dev push today finishes in ~15.4 min (macos 14.9); after the 2-way shard, ~7.7 min with both macos 1/2 and macos 2/2 green and macos control available on dispatch.

Alternatives or workarounds

  • Sharding by directory instead of by file: rejected, one fat domain (providers, 201 files) would dominate a shard; file-level --shard stays.
  • Moving tests/helpers/remove-tree (405 importers) into each domain: rejected, it would touch every test in every PR for no gain.
  • Linux 6/8 shards: measured to save nothing while macOS is the critical path.
  • macOS 4-way: only ~3 more minutes than 2-way for two more 10x-billed jobs.

Additional context

Design and measurements: devlog/_plan/260905_test_modularization_and_windows/ (001 inventory, 002 codex-rs / hermes reference layouts, 003 CI timing baseline, 030 tooling design, 040 migration slices and the macOS shard). Landing as one tooling PR, six move PRs (one per domain group, git mv so history survives), and one CI PR, each linked here as it opens.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. added
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    platformOS/service/tray/ACL (Windows-heavy, not Windows-only)
    toolstool_calls, MCP, web-search / sidecar tools
    on Sep 4, 2026
  2. lidge-jun commented on Sep 4, 2026

    @lidge-jun
    OwnerAuthor

    리뷰 · 우선순위 72 / 80

    이 이슈는 tests/ 루트에 평평하게 쌓인 약 1045개 Bun 테스트 파일을 tests/<domain>/ 구조로 옮기고, CI에서 병목인 macOS 잡을 2-way로 쪼개자는 추적 티켓이다. 지금 dev HEAD(3e65218ba)는 #3496 로컬 대시보드 admin-token UX 쪽을 보고 있지만, 그와 직교하는 저장소 운영/CI 속도 과제다. Bun은 이미 tests/ 아래를 재귀로 찾는다. 진짜 막히는 지점은 경로를 글자로 박아 둔 곳들이다. ci.yml 격리 잡 목록, scripts/ci/run-bun-test-batches.sh의 루트 고정 제외, scripts/test.ts 시리얼 레인, 소스 오라클이 import.meta.dir + "/.."로 저장소를 짚는 방식, join(import.meta.dir, "helpers", …)로 헬퍼를 찾는 자식 프로세스, 그리고 그 문자열을 고정하는 CI 계약 테스트들이다. 파일을 손으로 옮기면 bun run test:changed가 모듈 그래프만 따라가서, 텍스트로 읽거나 spawn으로 여는 경로 깨짐을 놓친다.

    그래서 제안 순서가 맞다. (1) 도메인 지도와 이동기·검증기·repo-root 헬퍼를 먼저 넣고, (2) 도메인 슬라이스마다 git mv PR을 기계적으로 열고, (3) 마지막에 macOS 2-way shard와 lane=macos-control dispatch를 붙인다. 방금 그 (1)이 #3500으로 열렸다. #3500은 파일을 한 개도 안 옮기고 scripts/test-layout/ 공구, tests/helpers/repo-root.ts, 레이아웃 가드/툴링 테스트, CI 제외 basename 앵커, 시리얼 레인 basename 키잉, AGENTS 문단만 넣는다. 이 이슈 본문의 "한 공구 PR + 여섯 move PR + 한 CI PR" 계획과 정확히 맞물린다. Linux를 6/8 shard로 늘리거나 helpers를 도메인마다 복사하는 대안을 버린 이유도 측량과 임포터 수(remove-tree 405)로 설명되어 있어, 메인테이너가 다시 논쟁할 필요는 거의 없다.

    라벨은 자동 부착으로 보인다. enhancement는 맞지만 account-pool / platform / tools는 이 이슈의 본문(테스트 레이아웃·macOS CI)과 거리가 있다. 기여자가 "platform 스택만" 같은 트리아지 뷰에서 이 티켓을 만나면 헷갈린다. chore 또는 CI/테스트 성격 라벨로 정리하는 편이 낫다. Preview 배포나 types/config 분할과는 무관하다. 중복 이슈로 닫을 대상도 아니고, #3500이 공구를 랜딩하면 이 이슈는 열린 채로 move/CI 체크리스트를 받는 허브로 쓰면 된다.

    이슈 본문의 "macOS가 최근 10번 green dev push에서 critical path, 평균 14.9분" 숫자는 003 CI timing baseline에 근거한다고 되어 있다. 공구(#3500)만 머지해도 그 wall time은 안 줄어든다. 체감 이득은 move 이후 탐색성 + 마지막 CI PR의 macOS shard에서 난다. 그래서 이 이슈의 우선순위는 "지금 당장 유저 버그를 고친다"가 아니라 "저장소가 커질수록 리뷰·CI 비용이 선형으로 커지는 구조를 끊는 열차"로 74에 가까운 72로 둔다. #3500이 초록이면 공구부터 머지하고, 이 이슈 체크리스트에 PR 링크를 쌓아 가면 된다.

    이슈 라벨 account-pool / platform / tools - 본문은 테스트 디렉터리 이동과 macOS CI shard인데, 계정 풀·플랫폼 ACL·툴콜 라벨이 붙어 있다. 트리아지 뷰를 오염시킨다.
    이슈 본문 · 체크리스트 - 공구/move/CI PR을 링크할 자리가 본문에는 서술만 있고 체크 항목으로 고정되어 있지 않다. #3500을 첫 줄에 체크 가능하게 박아 두면 진행률이 보인다.
    macOS shard 효과 - 공구 PR만으로는 14.9분 병목이 안 줄어든다. 기대치를 "탐색성 먼저, wall time은 CI PR 이후"로 이슈에 한 줄 적어 두면 기여자 오해가 줄어든다.
    devlog/_plan/260905_test_modularization_and_windows/ - 설계는 여기로 모아 두었고 #3500이 030을 구현한다. 이 이슈가 허브라면 000/040 요약을 본문 Additional context에 짧은 목차로 남겨도 좋다.

    메인테이너의 판단이 필요한 지점

    • 라벨을 chore/CI 쪽으로 정리할지, 자동 라벨러를 이 제목에 맞게 고칠지.
    • move 슬라이스 순서(040)를 이 이슈 체크리스트에 고정할지, 각 move PR 제목에만 맡길지.
    • macOS 2-way shard CI PR을 move 전부 끝난 뒤에 둘지, 공구 직후 병렬로 열지(본문은 파일 샤드라 디렉터리 이동과 독립 가능해 보인다).

    너의 추천
    이 이슈는 열린 추적 허브로 유지한다. #3500 CI가 초록이면 공구부터 머지하고, 이 이슈 첫 댓글/본문에 #3500을 체크 항목으로 연결한 뒤 040 순서의 move PR을 이어서 연다. 라벨은 account-pool/platform/tools를 떼고 chore(또는 테스트/CI)로 맞추자. 닫지 않는다.

    이 댓글은 grok-bot이 작성했습니다

  3. Ingwannu commented on Sep 4, 2026

    @Ingwannu
    Owner

    Post-merge safety follow-up from #3500 (now dev commit 5df664cda): the first three-domain slice can be reviewed independently, but the general mover still has three boundaries that must not be lost before larger/all-domain runs.

    • filesNamingAny sends every moved path as -e arguments to one git grep, and runMove sends the full write set to one git status. The supported repeated/all-domain input can exceed the Windows CreateProcess command-line limit. Both calls need deterministic batching and result deduplication.
    • A mid-move failure leaves a partial staged rename/rewrite set, while the current documented recovery uses repository-wide restore/checkout even though the preflight explicitly permits unrelated dirty files outside the write set. Recovery must be scoped to computed source + destination + rewritten paths.
    • layout.json is still truncated and rewritten in place even though it is the migration authority. Persist through a sibling temporary file and atomic rename with cleanup.

    #3509 moves only 49 files across three domains, so its exact resulting diff and CI can still be valid; it does not prove the full-input command boundary. Please keep #3497 open and carry these items as a focused tooling follow-up before broader slices.

  4. 8 remaining items

  5. lidge-jun commented on Sep 4, 2026

    @lidge-jun
    OwnerAuthor

    Landed on dev:

    PR merge subject
    #3500 5df664c layout map, mover/verifier tooling, tests/helpers/repo-root.ts, basename-anchored CI exclusions
    #3501 4cacdfb macOS 2-way shard; unsharded control on workflow_dispatch (lane=macos-control)
    #3509 8f02f24 windows, service, update
    #3510 3aab264 lib, config, clients, usage, vision, web-search
    #3511 5424ad4 cli, oauth, routing, claude-integration
    #3513 b20af66 adapters (+google/anthropic/openai), responses, lab, gui
    #3516 8b6e454 providers (+cursor/kiro/xai/ollama/github-copilot), codex-integration
    #3518 79e0364 server, storage, ci-workflows
    #3534 (closeout, in review) AGENTS.md / structure / docs-site wording, devlog to _fin

    Every merge followed a green ci on the exact PR head; tests/ root now holds only the two layout guards and 1045 files moved with git mv into 25 domain directories. No test was deleted and no assertion changed.

    CI: the macOS shard job is ~7.6 min per half (was 14.9 unsharded); an unqueued run finishes in ~9.4 min wall (was 15.4). Linux stays at 4 shards (measured: no wall gain while macOS was the critical path). platform-windows is unchanged apart from the lane skip condition. Measurements and the per-PR CI table: devlog/_fin/260905_test_modularization_and_windows/041, 090.

    Adding a test now: put it in its domain directory and add the basename to scripts/test-layout/layout.json explicit and tests/fixtures/test-layout-expected.json; tests/test-layout-tooling.test.ts names the missing entry, and the regex seeds place a conventionally named file until then.

  6. lidge-jun commented on Sep 4, 2026

    @lidge-jun
    OwnerAuthor

    Closed by #3534 (6d96391). Full table and measurements in the comment above and in devlog/_fin/260905_test_modularization_and_windows/090_outcome.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansenhancementNew feature or requestplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)toolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions