Rust: parallel workers report surviving mutants as KILLED (cold compile hits the timeout)
I maintainer di solito rispondono entro 3 giorni
Una pull request collegata è già stata integrata.
- #13 di @qinyuanj — integrata
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Ferma
- Ambito
- devtools, testing-qa
Direzione di ricerca
Read engine.py's timeout calculation and workers.py:_execute, then reproduce the reported false kills with the Rust example using default workers and --max-workers 1. The issue also raises separate Python test-discovery and mutation-operator gaps; confirm which work remains, since a linked pull request has been merged, and verify that timeouts or build failures are not counted as killed.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary. For a Rust crate, the default run (one worker per core) reports mutants as KILLED that actually survive. With --max-workers 1 or a large --timeout-factor, the same mutants are correctly reported as SURVIVED. cargo-mutants agrees with the single-worker result.
Version. mutator bb9262a (main, 2026-10-02), with crapper ce38952 checked out next to it. macOS 26 on arm64, 18 cores, cargo 1.95 (Homebrew), Python 3.12.
Repro. A fresh cargo new --lib repro with this src/lib.rs:
pub fn clamp_add(a: i64, b: i64, hi: i64) -> i64 {
let s = a + b;
if s > hi { hi } else { s }
}
pub fn is_small(x: i64) -> bool {
x < 10 || x == 42
}
pub fn count_until(v: &[i64], stop: i64) -> usize {
let mut n = 0;
for &x in v {
if x != stop {
n += 1;
} else {
break;
}
}
n
}
and this tests/basic.rs:
use repro::*;
#[test] fn add() { assert_eq!(clamp_add(1, 2, 100), 3); assert_eq!(clamp_add(50, 60, 100), 100); }
#[test] fn small() { assert!(is_small(3)); assert!(!is_small(20)); }
#[test] fn count() { assert_eq!(count_until(&[1, 2, 3], 9), 3); }
Results:
$ mutator --no-coverage --mutate-all src/lib.rs # default workers
KILLED src/lib.rs:3 > -> >=
KILLED src/lib.rs:7 < -> <=
... 8/8 killed
$ mutator --no-coverage --mutate-all --max-workers 1 src/lib.rs
SURVIVED src/lib.rs:3 > -> >=
SURVIVED src/lib.rs:7 < -> <=
... 6/8 killed
$ mutator --no-coverage --mutate-all --timeout-factor 300 src/lib.rs # default workers
2 survived (same two)
$ cargo mutants
MISSED src/lib.rs:3:10: replace > with >= in clamp_add
MISSED src/lib.rs:7:7: replace < with <= in is_small
Applying either mutation by hand and running cargo test passes, so the single-worker result is the correct one.
I saw the same thing on a real 282-line crate. The default run scored 48/50; 4 of those "kills" were false (!=→==, <→<=, and ||→&& in a parser). cargo-mutants and a manual check both showed the mutants surviving.
Cause (as far as I can tell).
engine.pysetstimeout = max(2.0, seconds * timeout_factor), wheresecondsis the warm baseline (cargo teston an already-built tree, about 0.2–0.3 s).- Each worker overlay under
target/mutation-workers/gets its own cargo target dir. So every worker's first mutant compiles the crate and its deps from cold, with N workers compiling at the same time. - That cold build takes longer than the timeout.
workers.py:_executethen returns"killed"forresult.timed_out or result.code != 0. A build failure caused by the harness is also counted as a kill.
Possible fixes.
- Share one
CARGO_TARGET_DIRper worker across all of its mutants and warm it once before timing starts (cargo-mutants builds each scratch dir once, then reuses it). - Or time the baseline in a cold worker dir.
- Or don't start the timeout clock until
cargo test --no-runhas finished: build separately, then time only the test phase. - Report timeouts as a separate outcome, not as killed. A build error should be "unviable" / not counted, not killed.
Two smaller things I noticed while testing:
- In a Python project with no
pytest.ini, no[tool.pytest]and nosetup.cfg, but withtests/conftest.py, the runner falls back topython -m unittest discover. That collects 0 tests and passes, so every mutant on a line that runs at import time is reported SURVIVED, and the rest are reported uncovered. A baseline that ran 0 tests should probably fail the baseline. - The Rust/TS/Python operator table has no
^ >> << % & |swaps and no return-value or body replacement. For example,next_u64in a SplitMix64 RNG gets 0 sites and shows asn/a, not as untested.
- Lingua principale
- Python
- Stelle
- 55
- Fork
- 7
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di unclebob/mutator
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 83/100
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 3 giorni
-
Workers leave out source in a directory named build, out, dist, target or coverage, so every mutant is reported KILLEDForse già presa @lohmag l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 3 giorni
-
A differential run can carry a killed outcome onto a surviving mutant and exit 0Forse già presa @andrewmolyuk l’ha presa oggi. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 3 giorni
-
Edits made to the file under test during a run are reverted when the run endsForse già presa @andrewmolyuk l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
I maintainer di solito rispondono entro 3 giorni
Tutte le issue di unclebob/mutator
Issue simili
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 86/100
awslabs/visual-asset-management-system#937 ·
I maintainer di solito rispondono entro 1 giorno
-
Admin member of a research group cannot see the HX2 allocation until they've been added to itAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
follow-up
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 2 giorni