Legacy backup recovery overwrites newer source and deletes the backup without conflict detection
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- Mezza giornata
- Idoneità per principianti
- 35/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- python
- Ambito
- testing-qa
Direzione di ricerca
Start with restore_backups in src/mutator/engine.py (around lines 17-31), which writes and unlinks files under target/mutator-backup. Run the reproduction probe from the issue to see the overwrite and deletion. The call site is in src/mutator/cli.py (around lines 486-488), and tests/test_engine.py has the existing backup test. Done means newer source survives, both versions are kept, a conflict is reported, and a separate test covers a verified interrupted mutant.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
restore_backups treats every target/mutator-backup file as authoritative. A stale backup overwrites legitimate newer source without comparison or confirmation, then the backup is deleted. Non-scan CLI runs invoke this recovery automatically when source files are selected.
Verified on main at 830ec7e9c39664d753f8699015bc796df67727b9 with Python 3.14.8. No package installation is required for this reproduction.
Minimal reproduction
Run with Python 3.11+ and Git. This uses only disposable fixture files and does not install or invoke the mutator launcher.
work=$(mktemp -d)
git clone https://github.com/unclebob/mutator.git "$work/mutator"
cd "$work/mutator"
git checkout 830ec7e9c39664d753f8699015bc796df67727b9
python3 -B - <<'PY'
"""Run from a mutator checkout using Python 3.11+; standard library only."""
import ast
import tempfile
from pathlib import Path
path = Path('src/mutator/engine.py')
tree = ast.parse(path.read_text())
module = ast.parse('from __future__ import annotations')
module.body += [n for n in tree.body if isinstance(n, ast.FunctionDef) and n.name == 'restore_backups']
g = {'Path': Path}
exec(compile(module, str(path), 'exec'), g)
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
source = root / 'calc.py'
backup = root / 'target' / 'mutator-backup' / 'calc.py'
backup.parent.mkdir(parents=True)
backup.write_bytes(b'def answer():\n return 1\n')
# New legitimate code, not an in-place mutant left by an interrupted run.
source.write_bytes(b'def answer():\n return 42\n\ndef added():\n return 7\n')
newer = source.read_bytes()
restored = g['restore_backups'](root)
assert restored == [source]
assert source.read_bytes() != newer
assert source.read_bytes() == b'def answer():\n return 1\n'
assert not backup.exists()
print('newer source overwritten with stale backup; backup deleted; no conflict reported')
PY
This standard-library probe executes the actual restore_backups function extracted with ast. All files are disposable fixtures inside TemporaryDirectory. It calls the recovery function directly rather than launching the CLI.
Observed output
newer source overwritten with stale backup; backup deleted; no conflict reported
Expected behavior
Do not overwrite legitimate newer source automatically. Preserve both versions on an ambiguous recovery and report a conflict, or require an explicit recovery decision backed by enough state to identify the interrupted mutant.
Actual behavior
A source file with a newer function and an added function is replaced with the stale backup; the added function disappears. The backup is unlinked and no conflict is reported.
Regression test
Place stale original bytes in target/mutator-backup and legitimate newer code at the corresponding source path. Invoke recovery and assert the newer source survives, both versions remain available, and the conflict is reported. Retain a separate test for an explicitly verified interrupted mutant.
The reproduction asserts the currently observed defect. A regression test should invert the defective-behavior assertions to enforce the expected behavior.
Source
- Unconditional backup write and deletion
- CLI automatic recovery
- Non-scan invocation
- Existing backup test
Related #20 concerns final cleanup after current worker execution. This defect occurs before mutation execution in legacy restore_backups, so removing _restore_if_dirty does not fix it. No genuine duplicate found.
- Lingua principale
- Python
- Stelle
- 112
- Fork
- 53
- 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à 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 2 giorni
-
test_git_status_keeps_real_names_and_fails_closed fails when git output is translatedForse già presa @bennibyx l’ha presa 14 giorni fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 83/100
unclebob/mutator#24 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 2 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 17 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di unclebob/mutator
Issue simili
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
splunk/security_content#4418 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug / Enhancement]: Improve teleop_robot CLI with configurable timeout, robust input validation, and clean ROS shutdownForse già presa @muskan-creates352 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 3 giorni
-
bug(pipelines): shortcode stripping deletes text between a {{< >}} shortcode and the next {{% %}}Forse già presa @Ashborne-lab l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
kubeflow/docs-agent#293 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
Imbad0202/academic-research-skills#1093 ·
I maintainer di solito rispondono entro 1 giorno
-
Input: placeholder drawn in the text colour when the empty Input is focused but not yet editedAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pierreaubert/gpui-toolkit#114 ·
I maintainer di solito rispondono entro 1 giorno