diff --git a/src/datasmith/harbor_adapter/template/tests/lsv_measure.py b/src/datasmith/harbor_adapter/template/tests/lsv_measure.py index c65adc91..8eb1343c 100644 --- a/src/datasmith/harbor_adapter/template/tests/lsv_measure.py +++ b/src/datasmith/harbor_adapter/template/tests/lsv_measure.py @@ -217,6 +217,15 @@ def base_in_place(): os.rename(PARKED, REPO_ROOT) +def rebuild_both_sides(cmd: str, log: Path) -> None: + """test.sh rebuilt only the patched tree; the base copy still holds the image's build. Build the base with the same + command at the same path, then the patched tree again, so the paired timing differs only by the patch.""" + with log.open("a") as out: + with base_in_place(): + subprocess.run(["bash", "-c", cmd], cwd=REPO_ROOT, stdout=out, stderr=subprocess.STDOUT, check=True) + subprocess.run(["bash", "-c", cmd], cwd=REPO_ROOT, stdout=out, stderr=subprocess.STDOUT, check=True) + + TEMP_ROOTS = (Path("/tmp"),) @@ -403,6 +412,9 @@ def main() -> None: if BASE_COPY.is_dir(): print(f"[{_ts()}] [phase] LSV paired measure: {BASE_COPY} vs {REPO_ROOT}, {args.rounds} rounds") try: + if os.environ.get("FC_REBUILD_CMD"): + print(f"[{_ts()}] [lsv_measure] rebuilding the base copy and the patched tree the same way (log: rebuild_both.log)") + rebuild_both_sides(os.environ["FC_REBUILD_CMD"], OUTPUT_DIR / "rebuild_both.log") measure_data = measure_paired(session, changed, args) except Exception as e: # noqa: BLE001 -- a crashed measure still writes results with the error print(f"[{_ts()}] [lsv_measure] ERROR: paired measure raised: {e}") diff --git a/tests/docker/test_lsv_paired_measure.py b/tests/docker/test_lsv_paired_measure.py index 4307f572..1ec4f2b4 100644 --- a/tests/docker/test_lsv_paired_measure.py +++ b/tests/docker/test_lsv_paired_measure.py @@ -61,6 +61,20 @@ def run(): assert not m.PARKED.exists() +def test_rebuild_builds_base_then_patched_at_the_repo_path(m, tmp_path): + m.rebuild_both_sides("cat side >> " + str(tmp_path / "order") + "; echo built >> build", tmp_path / "rebuild.log") + assert (tmp_path / "order").read_text() == "basepatched" + assert (m.REPO_ROOT / "build").read_text() == "built\n" and (m.BASE_COPY / "build").read_text() == "built\n" + assert _side(m) == "patched" + + +def test_failed_base_rebuild_leaves_repo_patched(m, tmp_path): + with pytest.raises(m.subprocess.CalledProcessError): + m.rebuild_both_sides('[ "$(cat side)" = patched ]', tmp_path / "rebuild.log") + assert _side(m) == "patched" and (m.BASE_COPY / "side").read_text() == "base" + assert not m.PARKED.exists() + + def test_paired_stats_median_log_ratio(): m = _load("lsv_measure") rounds = [