Skip to content

test(migrate): cover execute()/verify() flow with isolated fake engines - #23

Merged
tzzs merged 3 commits into
masterfrom
test/migrate-flow-coverage
Sep 14, 2026
Merged

tzzs merged 3 commits into
masterfrom
test/migrate-flow-coverage

Conversation

@tzzs

@tzzs tzzs commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Closes the remaining coverage gap flagged in the Socket-audit triage (#22): migrate.execute() had only the dest==source guard tests, and migrate.verify() had none at all (tests/integration/test_cli_smoke.py explicitly deferred migrate e2e coverage).

Stacked on #22 — the first commit is the guard fix; this PR's own change is the second commit only.

What's covered

execute() — driven through the real rules engine (custom rules dir marks the source as migratable FakeApp data, so identify_path + assert_not_critical + the migratable re-validation all run for real) against fake copy/link engines (platform_pkg.get_copy_engine/get_link_engine/get_work_dir monkeypatched, per the platform Protocols):

  • succeeded via link method (source removed, link created, result file written) and via manual Method (hint recorded, no link)
  • verification-failed (copy engine silently drops a file) leaves the original untouched
  • copy-ok-source-not-removed when shutil.rmtree raises OSError
  • dry-run (confirm=False) copies nothing and writes no result file
  • RequiresAppClosed blocks until --app-closed is attested
  • stale-plan gates: vanished source, non-empty destination

verify() — hand-crafted result files: passing report appends LastVerification back into the result JSON; missing destination / drifted file count / broken link each fail their own check; missing result file raises FileNotFoundError.

Verification

  • New tests: 13 (8 execute flow + 5 verify), all passing.
  • Full suite: 156 passed, 39 skipped — skip count matches the known Windows baseline (39).

plan() refuses dest==src, but execute() re-reads the plan JSON from disk,
so a hand-edited plan file can still pair a directory with itself: an
empty source dir slips past the non-empty-destination check, the copy
trivially verifies (0==0), and rmtree then deletes it as its own
destination. The guard compares resolve_path()+normcase() on both sides,
so trailing separators and Windows case variants are covered too.

Surfaced by a Socket supply-chain audit anomaly (LOW) on core/migrate.py.
…POSIX

CI caught the guard's blind spot: os.path.normcase lowercases on Windows
but returns POSIX paths unchanged, while macOS's default APFS volumes are
case-insensitive. A tampered plan pairing '/Users/me/models' with an
upper-cased spelling slipped past the guard on macOS and ran the self-
migration flow. Compare resolved paths, fold case additionally on darwin;
on Linux the comparison stays exact (case-sensitive filesystems keep
distinct Foo/foo as distinct directories).
execute() was only covered by the dest==source guard tests; its whole
status matrix ran untested. Drive it through the real rules engine (a
custom rules dir marks the source as migratable FakeApp data) against
fake copy/link engines and get_work_dir pointed at tmp_path:

- succeeded via link method and via manual method (hint recorded, no
  link created)
- verification-failed leaves the original untouched
- copy-ok-source-not-removed when rmtree raises OSError
- dry-run copies nothing and writes no result file
- RequiresAppClosed blocks until --app-closed is attested
- stale-plan gates: vanished source, non-empty destination

verify() had no coverage at all: passing report writes LastVerification
back into the result file, missing destination / drifted file counts /
broken link each fail their own check, and a missing result file raises
FileNotFoundError.

Full suite: 156 passed, 39 skipped -- skip count matches the known
Windows baseline (39). Stacked on #22.
@tzzs
tzzs force-pushed the test/migrate-flow-coverage branch from 7e22477 to 565d8b5 Compare September 13, 2026 18:51
@tzzs
tzzs merged commit 2a7cf11 into master Sep 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant