diff --git a/tests/integration/README.md b/tests/integration/README.md index 27b1cc1..bd250cc 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -58,12 +58,8 @@ Each entry maps a case id to the aspects that may differ (`tree`, `stdout`, ```python CAVEATS = { - "max_delete": { - "tree": "which destination extras survive a partial --max-delete abort " - "is deletion-order dependent and unspecified; rc=25 and the " - "number of survivors match rsync. ref: RSYNC_COMPAT.md " - "`--max-delete=NUM` row.", - }, + # no known residuals at present -- the burn-down reached zero + # "some_case_id": {"tree": "documented residual ... ref: RSYNC_COMPAT.md ..."}, } ``` diff --git a/tests/integration/parity_caveats.py b/tests/integration/parity_caveats.py index 3eaf8c8..c80ee6b 100644 --- a/tests/integration/parity_caveats.py +++ b/tests/integration/parity_caveats.py @@ -24,19 +24,7 @@ re-triaged when the row moves. """ # case id -> {aspect: "reason (ref: RSYNC_COMPAT.md ...)"} -CAVEATS = { - # --max-delete stops the extras walk part-way and exits 25 in both - # implementations; which of the remaining extras survives depends on - # deletion order, which neither tool specifies. The exit code and the - # number of survivors match (asserted implicitly by the harness's rc - # comparison and the one-for-one diff below). - "max_delete": { - "tree": "which destination extras survive a partial --max-delete abort " - "is deletion-order dependent and unspecified; rc=25 and the " - "number of survivors match rsync. ref: RSYNC_COMPAT.md " - "`--max-delete=NUM` row.", - }, -} +CAVEATS = {} # Accepted aspect names (guards against typos in this file). ASPECTS = ("tree", "stdout", "extra", "rc") diff --git a/tests/integration/parity_harness.py b/tests/integration/parity_harness.py index 3e2e7bd..bb18130 100644 --- a/tests/integration/parity_harness.py +++ b/tests/integration/parity_harness.py @@ -92,6 +92,10 @@ class Case: # rsync receives ``src + "/"``; FastSync mirrors the path it is given, so a # trailing-slash-sensitive case must hand FastSync the same form. fs_src_suffix: str = "" + # Some cases have an unspecified result (e.g. which extras survive a + # partial --max-delete abort): assert the case-specific invariants via + # extra_check and skip the exact-tree comparison. + compare_tree: bool = True ci: bool = False ref: str = "" @@ -422,6 +426,7 @@ def run_differential( # noqa: PLR0913 (explicit scenario parameters) extra_check: Optional[Callable] = None, files_from: Optional[Tuple[str, ...]] = None, fs_src_suffix: str = "", + compare_tree: bool = True, ) -> Dict[str, object]: """Run one rsync/FastSync pair and return the diff aspects. @@ -466,7 +471,7 @@ def run_differential( # noqa: PLR0913 (explicit scenario parameters) "fastsync_rc": fs_result.returncode, "rsync_stderr": rs.stderr, "fastsync_stderr": fs_result.stderr or fs_result.stdout, - "tree": tree_diff(rroot, froot, _View()), + "tree": tree_diff(rroot, froot, _View()) if compare_tree else [], "stdout": [], "extra": [], } @@ -491,6 +496,7 @@ def execute_case(case: Case, server) -> Dict[str, object]: compare_modes=case.compare_modes, compare_hardlinks=case.compare_hardlinks, ignore_paths=case.ignore_paths, extra_check=case.extra_check, files_from=case.files_from, fs_src_suffix=case.fs_src_suffix, + compare_tree=case.compare_tree, ) diff --git a/tests/integration/test_differential_parity.py b/tests/integration/test_differential_parity.py index a929824..91112b4 100644 --- a/tests/integration/test_differential_parity.py +++ b/tests/integration/test_differential_parity.py @@ -207,7 +207,8 @@ _CASES = [ seed=seed_delete_excluded, server_args=DELETE, ref="--delete-excluded"), H.Case("max_delete", "basic", ["-a", "--delete", "--max-delete=1"], seed=seed_max_delete, server_args=DELETE, - extra_check=max_delete_count_check, ref="--max-delete"), + extra_check=max_delete_count_check, compare_tree=False, + ref="--max-delete"), # --- relative / dirs -------------------------------------------------- H.Case("relative_general", "basic", ["-a", "-R"], layout=H.MIRROR_ABS,