Skip to content

テスト: 固定の待ちと重複した競合試験が、全体テストの半分の時間を占める #884

Description

@takemi-ohama

何を見つけたか

全体テストの時間は少数のテストに集中しており、その多くは固定の待ち(1 秒のポーリング・5 秒のロック上限)と、同じ実装への重複した競合試験で占められている。

計測は develop(25da1de1)、--durations=0 で順に実行。全 5337 件・198 秒のうち、**0.5 秒以上の 43 件(0.8%)で 106 秒(53%)**を占める。

原因 対象 所要
打ち切りが猶予を待ち切る cross-refactoring/tests/test_git_facts.py 3 件 21 秒(#883 で本体を直す)
bg-wait.sh の sleep 1 ポーリング cross-review/tests/test_bg_wait.py 21 件(うち 1 秒前後が 10 件、4 秒・3 秒・2 秒が各 1 件) 19 秒
同じ共通実装への競合試験の重複 worktree/tests/test_registry.py の test_many_at_once_never_share_the_critical_section(worktree / workflow × 並列 6 / 12 の 4 通り、各 4 秒)と test_six_registrations_at_once_all_survive、scripts/tests/test_lock_common.py::test_six_at_once_leave_one_owner 23 秒
ロック待ちの上限 5 秒を待ち切る worktree/tests/test_testenv.py の test_test_respects_inuse_lock_and_releases_after_failure(5.0 秒)・test_up_does_not_start_when_the_registry_lock_is_held(4.8 秒)、scripts/tests/test_lock_common.py::test_the_timeout_override_reaches_only_the_stage_state(6.0 秒)、scripts/tests/test_token_guard.py::test_lock_held_passes(3.6 秒) 19 秒
同時記録の繰り返し development-workflow/tests/test_stage_check.py::test_records_at_once_never_skip_a_stage(8 回試行) 2.8 秒
プロセスグループの打ち切り cross-review/tests/test_launch_cli_process_group.py 5.6 秒

競合試験の重複について。 wt_lock_acquire(plugins/ndf/scripts/lib/worktree-common.sh:2366)と wf_lock_acquire(plugins/ndf/skills/development-workflow/scripts/lib/workflow-common.sh:649)はどちらも ndf_lock_acquire を 1 行で呼ぶだけである(#293 で共通化済み)。同じ実装の臨界区間を、2 つの入口 × 2 つの並列数で 4 回、さらに共通ファイルの側で 1 回試している。入口が共通実装へ届くことは test_lock_common.py::test_the_existing_names_take_and_release_the_lock が既に見ている。

追記: CI では同じテストを 2 回回している(2026-09-23)

release/** から出した Pull Request では、Python tests が push と pull_request の 2 契機で同時に起動する。 .github/workflows/pytest.yml の on: が pull_request:(絞り込みなし)と push: branches: [main, develop, "release/**"] の両方を持つためである。

実例 push pull_request
PR #886(release/v10.17.0) run 35821421926(05:11:56 起動) run 35821431945(05:12:05 起動)
PR #881(release/v10.17.0-dev.1) 04:56:23 起動 04:56:41 起動

1 回の実行は直近 8 回で約 5〜6 分で、他の検査(4〜48 秒)より 1 桁長い。2 本は並んで走るため待ち時間は増えないが、runner の時間は 2 倍になる。

直し方の候補: push の branches から "release/**" を外す(Pull Request の側が必ず回るため)。main / develop はマージ後の確認として残す。push 側の絞り込みがマージの可否に関わらないことは冒頭のコメントのとおり。

直さないと何が起きるか

並列実行(#882)にしても、1 worker に遅いテストが偏ると全体の終わりがその worker で決まる。順に回す環境(cross-refactoring の --baseline-test など)では、この 100 秒がそのまま毎回かかる。

直し方の候補

待つこと自体が検出の手段になっているテストは、待ちを削らずに上限を注入する。 検出力を落とさないことを優先する(#390 の階層 3)。

  1. bg-wait.sh のポーリング間隔を環境変数で縮められるようにする(既定の 1 秒は変えない)。または間隔を 0.2 秒にする(背景の待ちは Bash ツールの 600 秒上限の中なので、利用者側の費用はほぼ変わらない)
  2. 競合試験は共通実装に対する 1 通り(並列 12・試行 3 など)へ寄せ、入口ごとの parametrize を外す。臨界区間の試験を test_registry.py と test_lock_common.py のどちらが持つかを決める
  3. ロックの上限 5 秒を待つテストは、上限の値を注入できる入口がある場合はそれを使う。台帳の上限を注入できないのは mkdir による排他の実装が worktree-common.sh と workflow-common.sh の 2 箇所に載る #293 の決定(上書きは控えの側だけ)なので、変えるなら決定の記録を更新する。変えない場合は、上限を待ち切ることを見るテストを 1 件に絞る
  4. test_records_at_once_never_skip_a_stage の試行回数は、完了判定の 60 回と別に置いた値なので、4 回程度へ減らせるかを確かめる

受け入れ条件

  • 順に回した全体テストで、0.5 秒以上のテストの合計が 40 秒以下になる
  • 上の各テストが見ている不具合(臨界区間の重なり・上限を越えた待ち・終了コードの取りこぼし)を、変更後も失敗として検出できる(本体へ不具合を入れて落ちることを 1 度確かめる)

追記: PR #891 で行ったことと残り(2026-09-23)

PR #891(light)はテストと継続的統合の設定だけを直した。 本番のスクリプトの変更を要する残りは、この課題に残す。

候補 状態
2. 競合試験の重複 済み。test_registry.py の 1 通り(wt_lock_acquire・並列 12・試行 3)へ寄せ、test_lock_common.py の A7 を外した
4. test_records_at_once_never_skip_a_stage の試行 済み。8 → 4 回(あわせて test_lock_held_passes を 4 → 3 回)
追記の 2 重実行 済み。push の branches から release/** を外した
1. bg-wait.sh のポーリング間隔 残り(本番のスクリプトの変更。順で 20 秒)
3. ロックの上限 5 秒を待つテスト 残り(上限の注入は #293 の決定の更新が要る。順で約 19 秒)
test_git_facts.py の猶予待ち #883

順に回した全体テストの 0.5 秒以上の合計は 106.5 秒 → 88 秒。受け入れ条件の 40 秒以下には、残りの 3 つが要る。

関連

進行

モード: light / 作業ツリー: .worktrees/test/issue-882-884-test-speedup

  • 要求と受け入れ条件 — 2026-09-23 05:37
  • 作業場所の用意 — 2026-09-23 05:38
  • 設計
  • 素材の収集と出典の確定
  • ドキュメント再構成
  • ドキュメントレビュー
  • 計画
  • 実装 — 2026-09-23 05:40
  • 構造改善
  • 実装レビュー — 2026-09-23 05:59
  • 完了判定 — 2026-09-23 06:13
  • Pull Request — 2026-09-23 05:50
  • 確定仕様化
  • 後片付け — 2026-09-23 06:15
  • 配布 — 2026-09-23 06:16
  • 体裁レビュー
  • リリース後テスト
  • 振り返り

Activity

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

    area: ndf-skillNDF の Skill 本体enhancementNew feature or requestpriority: medium保守性・設計一貫性など、計画的に対応する

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions