From 429eca85a9ed92eaf57f335cd5c9ee03f802bebe Mon Sep 17 00:00:00 2001 From: abraunegg Date: Fri, 13 Mar 2026 10:06:45 +1100 Subject: [PATCH] Expand 'sync_list' testing scenarios Add Scenario SL-0022: exact root-file include Add Scenario SL-0023: sync_root_files = true with rooted 'Projects' include Add Scenario SL-0024: cleanup regression with 'sync_root_files = true' Add Scenario SL-0025: prefix-collision safety for 'Projects/Code' Add Scenario SL-0026: mixed rooted subtree include plus exact root-file include --- .../testcases/tc0002_sync_list_validation.py | 143 ++++++++++++++++++ docs/end_to_end_testing.md | 2 +- 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/ci/e2e/testcases/tc0002_sync_list_validation.py b/ci/e2e/testcases/tc0002_sync_list_validation.py index b0ecbb7c..73221139 100644 --- a/ci/e2e/testcases/tc0002_sync_list_validation.py +++ b/ci/e2e/testcases/tc0002_sync_list_validation.py @@ -858,6 +858,9 @@ class TestCase0002SyncListValidation(E2ETestCase): f"{FIXTURE_ROOT_NAME}/Projects/Video", f"{FIXTURE_ROOT_NAME}/Projects/Video/Renders", f"{FIXTURE_ROOT_NAME}/Projects/Code", + f"{FIXTURE_ROOT_NAME}/Projects/Code-Archive", + f"{FIXTURE_ROOT_NAME}/Projects/Codecs", + f"{FIXTURE_ROOT_NAME}/Projects/Coder", f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ", f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports", f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source", @@ -945,6 +948,11 @@ class TestCase0002SyncListValidation(E2ETestCase): f"{FIXTURE_ROOT_NAME}/Projects/Video/Renders/render.mov": "render\n", f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav": "export wav\n", f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt": "source\n", + f"{FIXTURE_ROOT_NAME}/Projects/Code-Archive/archive.txt": "archived code\n", + f"{FIXTURE_ROOT_NAME}/Projects/Codecs/readme.txt": "codecs info\n", + f"{FIXTURE_ROOT_NAME}/Projects/Coder/profile.txt": "coder profile\n", + f"{FIXTURE_ROOT_NAME}/README.txt": "fixture readme\n", + f"{FIXTURE_ROOT_NAME}/loose.bin": "fixture loose data\n", f"{FIXTURE_ROOT_NAME}/Programming/Projects/Android/App1/build/output.apk": "android app1 build\n", f"{FIXTURE_ROOT_NAME}/Programming/Projects/Android/App1/build/intermediates/classes.dex": "classes dex\n", f"{FIXTURE_ROOT_NAME}/Programming/Projects/Android/App1/.cxx/tmp/native.o": "native object\n", @@ -1436,6 +1444,141 @@ class TestCase0002SyncListValidation(E2ETestCase): f"{FIXTURE_ROOT_NAME}/Secret_data", ], ), + SyncListScenario( + scenario_id="SL-0022", + description="root file exact include only", + sync_list=[f"{FIXTURE_ROOT_NAME}/README.txt"], + allowed_exact=[f"{FIXTURE_ROOT_NAME}/README.txt"], + required_processed=[f"{FIXTURE_ROOT_NAME}/README.txt"], + required_skipped=[ + f"{FIXTURE_ROOT_NAME}/Backup", + f"{FIXTURE_ROOT_NAME}/Documents", + ], + ), + SyncListScenario( + scenario_id="SL-0023", + description="sync_root_files true with rooted Projects include and root file processing", + sync_list=[ + f"!/{FIXTURE_ROOT_NAME}/Projects/Audio", + f"!/{FIXTURE_ROOT_NAME}/Projects/Video", + f"/{FIXTURE_ROOT_NAME}/Projects", + ], + allowed_exact=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + ], + allowed_prefixes=[f"{FIXTURE_ROOT_NAME}/Projects"], + forbidden_prefixes=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + ], + required_processed=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt", + ], + required_skipped=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + f"{FIXTURE_ROOT_NAME}/Backup", + ], + phase2_config_overrides=['sync_root_files = "true"'], + ), + SyncListScenario( + scenario_id="SL-0024", + description="cleanup regression with sync_root_files true retains root files while pruning excluded Projects subtrees", + execution_mode="cleanup_regression", + sync_list=[ + f"!/{FIXTURE_ROOT_NAME}/Projects/Audio", + f"!/{FIXTURE_ROOT_NAME}/Projects/Video", + f"/{FIXTURE_ROOT_NAME}/Projects", + ], + allowed_exact=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + ], + allowed_prefixes=[f"{FIXTURE_ROOT_NAME}/Projects"], + forbidden_prefixes=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + ], + required_processed=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt", + ], + required_skipped=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + ], + phase1_config_overrides=[ + 'download_only = "false"', + 'cleanup_local_files = "false"', + 'sync_root_files = "true"', + ], + phase2_config_overrides=[ + 'download_only = "true"', + 'cleanup_local_files = "true"', + 'sync_root_files = "true"', + ], + expected_present_after=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt", + ], + expected_absent_after=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + ], + required_removed=[ + f"{FIXTURE_ROOT_NAME}/Projects/Audio", + f"{FIXTURE_ROOT_NAME}/Projects/Video", + ], + forbidden_removed=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/loose.bin", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + ], + ), + SyncListScenario( + scenario_id="SL-0025", + description="prefix collision safety for Projects Code versus similarly named siblings", + sync_list=[f"/{FIXTURE_ROOT_NAME}/Projects/Code"], + allowed_prefixes=[f"{FIXTURE_ROOT_NAME}/Projects/Code"], + required_processed=[ + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt", + ], + required_skipped=[ + f"{FIXTURE_ROOT_NAME}/Projects/Code-Archive", + f"{FIXTURE_ROOT_NAME}/Projects/Codecs", + f"{FIXTURE_ROOT_NAME}/Projects/Coder", + ], + ), + SyncListScenario( + scenario_id="SL-0026", + description="mixed rooted subtree include plus exact root file include", + sync_list=[ + f"/{FIXTURE_ROOT_NAME}/Projects", + f"{FIXTURE_ROOT_NAME}/README.txt", + ], + allowed_exact=[f"{FIXTURE_ROOT_NAME}/README.txt"], + allowed_prefixes=[f"{FIXTURE_ROOT_NAME}/Projects"], + required_processed=[ + f"{FIXTURE_ROOT_NAME}/README.txt", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Exports/file.wav", + f"{FIXTURE_ROOT_NAME}/Projects/Code/JOBXYZ/Source/main.txt", + ], + required_skipped=[ + f"{FIXTURE_ROOT_NAME}/Backup", + f"{FIXTURE_ROOT_NAME}/Documents", + ], + ), SyncListScenario( scenario_id="SL-0018", description="Issue #3655 exact trailing slash configuration with cleanup validation", diff --git a/docs/end_to_end_testing.md b/docs/end_to_end_testing.md index 18b68c79..d1771265 100644 --- a/docs/end_to_end_testing.md +++ b/docs/end_to_end_testing.md @@ -5,4 +5,4 @@ Placeholder document that will detail all test cases and coverage | Test Case | Description | Details | |:---|:---|:---| | 0001 | Basic Resync | - validate that the E2E framework can invoke the client
- validate that the configured environment is sufficient to run a basic sync
- provide a simple baseline smoke test before more advanced E2E scenarios | -| 0002 | 'sync_list' Validation | This validates sync_list as a policy-conformance test.

The test is considered successful when all observed sync operations involving the fixture tree match the active sync_list rules.

This test covers exclusions, inclusions, wildcard and globbing for paths and files. Specific 'sync_list' test coverage is as follows:
- Scenario SL-0001: root directory include with trailing slash
- Scenario SL-0002: root include without trailing slash
- Scenario SL-0003: non-root include by name
- Scenario SL-0004: include tree with nested exclusion
- Scenario SL-0005: included tree with hidden directory excluded
- Scenario SL-0006: file-specific include inside named directory
- Scenario SL-0007: rooted include of Programming tree
- Scenario SL-0008: exclude Android recursive build output and include Programming
- Scenario SL-0009: exclude Android recursive .cxx content and include Programming
- Scenario SL-0010: exclude Web recursive build output and include Programming
- Scenario SL-0011: exclude .gradle anywhere and include Programming
- Scenario SL-0012: exclude build/kotlin anywhere and include Programming
- Scenario SL-0013: exclude .venv and venv anywhere and include Programming
- Scenario SL-0014: exclude common cache and vendor directories and include Programming
- Scenario SL-0015: complex style Programming ruleset
- Scenario SL-0016: massive mixed rule set across Programming Documents and Work
- Scenario SL-0017: stress test kitchen sink rule set with broad include and targeted file include
- Scenario SL-0018: exact trailing slash configuration with cleanup validation
- Scenario SL-0019: no trailing slash workaround with cleanup validation
- Scenario SL-0020: focused trailing slash Projects regression for sibling path survival
- Scenario SL-0021: focused no trailing slash Projects regression for sibling path survival
| \ No newline at end of file +| 0002 | 'sync_list' Validation | This validates sync_list as a policy-conformance test.

The test is considered successful when all observed sync operations involving the fixture tree match the active sync_list rules.

This test covers exclusions, inclusions, wildcard and globbing for paths and files. Specific 'sync_list' test coverage is as follows:
- Scenario SL-0001: root directory include with trailing slash
- Scenario SL-0002: root include without trailing slash
- Scenario SL-0003: non-root include by name
- Scenario SL-0004: include tree with nested exclusion
- Scenario SL-0005: included tree with hidden directory excluded
- Scenario SL-0006: file-specific include inside named directory
- Scenario SL-0007: rooted include of Programming tree
- Scenario SL-0008: exclude Android recursive build output and include Programming
- Scenario SL-0009: exclude Android recursive .cxx content and include Programming
- Scenario SL-0010: exclude Web recursive build output and include Programming
- Scenario SL-0011: exclude .gradle anywhere and include Programming
- Scenario SL-0012: exclude build/kotlin anywhere and include Programming
- Scenario SL-0013: exclude .venv and venv anywhere and include Programming
- Scenario SL-0014: exclude common cache and vendor directories and include Programming
- Scenario SL-0015: complex style Programming ruleset
- Scenario SL-0016: massive mixed rule set across Programming Documents and Work
- Scenario SL-0017: stress test kitchen sink rule set with broad include and targeted file include
- Scenario SL-0018: exact trailing slash configuration with cleanup validation
- Scenario SL-0019: no trailing slash workaround with cleanup validation
- Scenario SL-0020: focused trailing slash Projects regression for sibling path survival
- Scenario SL-0021: focused no trailing slash Projects regression for sibling path survival
- Scenario SL-0022: exact root-file include
- Scenario SL-0023: sync_root_files = true with rooted 'Projects' include
- Scenario SL-0024: cleanup regression with 'sync_root_files = true'
- Scenario SL-0025: prefix-collision safety for 'Projects/Code'
- Scenario SL-0026: mixed rooted subtree include plus exact root-file include
| \ No newline at end of file