syncEngine: tests for restore-deleted-files + fault-isolation fix - #259
Open
philips-clanker wants to merge 3 commits into
Open
philips-clanker wants to merge 3 commits into
philips-clanker wants to merge 3 commits into
Conversation
runDeviceSync had no direct coverage: the file was deliberately thin and relied on deviceSync.ts's unit tests for the decision logic. The pending restore-deleted-files change (PR #258) adds real re-partitioning logic to the orchestration layer, which needs its own tests. Uses an in-memory fake vault plus vi.mock for obsidian (a real TFile class, for the instanceof checks), scanDeviceSupernoteTree, and fetchFromDevice; manifest fixtures are built with the real buildSyncRecord/hashBytes so they stay honest. Covers: - restoring a locally deleted file whose device copy is unchanged (deleted file re-downloaded at the same path, counts, manifest refresh) - restoring into a deleted subfolder (folders recreated) - intact unchanged files left untouched and un-fetched - locally edited unchanged files still flagged as skip-conflict, never clobbered or re-downloaded - a mixed run partitioning each file into exactly one bucket - a failed restore download reported per-file without aborting the run One test is skipped for now: fault isolation when an unchanged vault file can't be read. It encodes the expected per-file degradation, but the re-partition pass calls currentHash() unguarded, so it currently fails with the error escaping runDeviceSync entirely. To be unskipped by the fix in the next commit.
… read The deleted-file restore pass called currentHash() unguarded, so one unreadable vault file (e.g. an IO error on readBinary) threw out of runDeviceSync and aborted the entire sync run — no files synced, no manifest persisted. Both adjacent passes already isolate per-file failures: the toSync loop catches into result.failed, and the drift-check loop catches and logs. Guard the restore pass the same way: on a read error, log it and conservatively keep the listing in the unchanged bucket — never attempt to restore over a file we couldn't inspect — and let the drift-check loop report it on its own guarded pass. Unskips the fault-isolation test from the previous commit, which demonstrated the error escaping runDeviceSync (EIO out of currentHash) before this fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #258 — this branch contains that PR's commit plus two follow-ups. Merge #258 first; until then GitHub shows its commit in the diff here too. Review only the last two commits:
2874004syncEngine: add direct tests for runDeviceSyncf3891f2syncEngine: don't abort the whole sync run when a vault file can't be readWhy
#258 adds real re-partitioning logic to
runDeviceSync, which previously had no direct test coverage (the file was deliberately thin and relied ondeviceSync.ts's unit tests). Reviewing it surfaced one robustness regression, fixed here.Tests (
src/syncEngine.test.ts, new)Uses an in-memory fake vault plus
vi.mockforobsidian(a realTFileclass, for theinstanceofchecks),scanDeviceSupernoteTree, andfetchFromDevice; manifest fixtures are built with the realbuildSyncRecord/hashBytesso they stay honest. Covers:skip-conflict, never clobbered or re-downloadedFix: one unreadable vault file aborted the entire sync run
The #258 restore pass called
currentHash()unguarded, so a singlereadBinaryerror (e.g. IO failure on any unchanged vault file) threw out ofrunDeviceSync— no files synced, no manifest persisted. Both adjacent passes already isolate per-file failures: thetoSyncloop catches intoresult.failed, and the drift-check loop catches and logs. The test demonstrated the error escaping (EIOout ofcurrentHash) before the fix.The fix guards the pass the same way: on a read error, log it and conservatively keep the listing in the
unchangedbucket — never attempt to restore over a file we couldn't inspect — and let the drift-check loop report it on its own guarded pass.Validation
tsc --noEmitclean,npm run lintclean (same single pre-existing warning as main)Follow-up idea, not included here: the restore pass and the drift-check loop each read+hash surviving unchanged files, so they're read twice per run; merging the two passes would halve vault I/O for large vaults.