Per-mutant timeout budget is parallelism-blind — full-core runs convert contention into spurious timeout verdicts
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 38/100
- issue の種類
- バグ
- 明瞭さ
- 説明が足りない
- 活発さ
- 静か
調査の方向性
mutmut run で使用されるミュータントごとのタイムアウト計算から始め、(estimated_time_of_tests + 1) * 15 / * 30 の予算と --max-children の処理を含めて確認します。次に、mutants/ にあるキャッシュ済み結果の再開動作を調査し、子プロセス数を変えたコールドランでスコアの差を再現します。完了の定義は、並列性に関連するタイムアウト判定を防ぐこと、または互換性のないキャッシュ済み判定を明確に処理することとします。
索引モデルが issue の本文から書いたものです。
説明
[boxed/mutmut] Per-mutant timeout budget is parallelism-blind — full-core runs convert contention into spurious ⏰ verdicts
Summary
The per-mutant wall/CPU budget ((estimated_time_of_tests + 1) * 15 / * 30) is computed from a solo-run estimate, but mutmut run defaults to forking one child per core, all hammering the same test database and CPUs. Under that contention each child's covering set runs several times slower than the estimate assumes, so the fixed deadline converts scheduler contention into timeout verdicts.
Measurements (6-core runner, DB-bound Django suite)
- Default parallelism, cold cache: run "finishes" in ~20 min with 616 ⏰ at ~1 s per "timeout" — the verdicts are contention artifacts, not scores.
- Same tree,
mutmut run --max-children 2, cold cache: 708 🎉 / 24 🙁 / 366 ⏰ in ~83 min (~96.7 % of scored mutants killed) — the residual ⏰ being the fixed-budget issue reported separately (missingcall.whenfilter starves the estimate).
So the same code and tests score wildly differently depending only on child count — and nothing warns about it.
Compounding trap: cached ⏰ verdicts replay as final
Resume-from-cache replays previously recorded ⏰ verdicts across config generations: after changing the covering set's cost (or --max-children), a "resumed" run still reports the old timeouts. A meaningful re-score requires a cold mutants/ — worth documenting, or invalidating cached ⏰ (only ⏰) on config change.
Suggested fixes (any of)
- Scale the deadline by the number of concurrent children (estimate × children is a cheap upper bound for a shared-resource suite).
- Re-measure the baseline estimate AT the configured parallelism before scoring.
- Expose the multiplier/constant as config (the ask in closed #492) so operators can compensate explicitly.
- At minimum: document that DB-bound suites need
--max-childrenwell below core count, and that ⏰ verdicts from a differently-parallel run must not be resumed.
Environment
- mutmut 3.x, pytest 8.x, Django + Postgres suite, 6-core Linux runner
- Related: #492 (closed — configurable multiplier), #518 (wrong est-lookup key), and our separate report on the
call.whenrecording bug.
- 主要言語
- Python
- スター
- 1.5k
- フォーク
- 185
- 平均マージ
- 1日 11時間
- マージ済み PR(30日)
- 8
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
boxed/mutmut のほかの issue
-
Removing `not` from a parenthesized multi-line expression drops the parentheses (InvalidGeneratedSyntaxException, 3.8.0)対応中かも @jihtsan が 11 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
`run` with a `name__mutmut_*` pattern runs the whole test suite in the clean-test check対応中かも @Ishaan400 が 22 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
Invalid unary plus generated in match statement対応中かも @GhostCoder6969 が 31 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
vllm-project/vllm#64845 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
dekobon/big-code-analysis#1729 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
pydantic/pydantic-ai#12091 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100