Skip to content

test(chain-storage): exercise the EXDEV fallback in movePath for real - #3363

Open
Crypto2099 wants to merge 1 commit into
masterfrom
test/chain-storage-cross-device-move
Open

test(chain-storage): exercise the EXDEV fallback in movePath for real#3363
Crypto2099 wants to merge 1 commit into
masterfrom
test/chain-storage-cross-device-move

Conversation

@Crypto2099

Copy link
Copy Markdown
Collaborator

movePath falls back to copy-then-remove when fs.move fails with EXDEV
what happens when a user relocates chain storage to another disk.

Every migration spec stubs it out with jest.spyOn(manager, '_movePath'), so
that branch had never executed in a test, despite being the code that moves a
user's entire chain directory.

The obstacle was not what it looked like

Testing EXDEV was assumed to need loopback mounts and therefore root.
/dev/shm is a tmpfs on a different device, present and writable on a developer
machine and inside the Nix build sandbox:

build dir: dev=2096
/dev/shm:  dev=84, writable: yes

So a genuine cross-device move needs no privileges and no setup.

Coverage

Case Covers
same-device move fs.move succeeds by rename
cross-device move the EXDEV fallback
non-EXDEV error rethrow, target not created

Two deliberate choices

The cross-device test asserts its own preconditions — that the two roots
differ by st_dev, and that a bare renameSync between them really raises
EXDEV. Without those, fs.move could succeed by rename and the test would pass
green while exercising nothing.

It fails loudly rather than skipping when no cross-device pair is available.
A silent skip on the only test covering this path would report coverage that does
not exist.

Verification

Run inside the sandbox with nix build .#checks.x86_64-linux.jest, not only on
the host, because the whole question was whether /dev/shm is available there:
67 suites, 781 tests. Lint, compile, stylelint and treefmt also pass.

movePath falls back to copy-then-remove when fs.move fails with EXDEV, which
is what happens when chain storage is relocated to another disk. Every
migration spec stubs the function out with jest.spyOn(manager, '_movePath'),
so that branch had never executed in a test — despite being the code that
moves a user's entire chain directory, potentially tens of gigabytes.

The obstacle was assumed to be privileges: loopback mounts need root. It is
not. /dev/shm is a tmpfs on a different device, present and writable both on
a developer machine and inside the Nix build sandbox, so a genuine
cross-device move is testable with no special setup.

Adds chainStorageManagerShared.realfs.spec.ts covering the same-device move,
the cross-device move through the EXDEV fallback, and the rethrow of any
other error.

The cross-device test asserts its own preconditions — that the two roots
differ by st_dev, and that a bare renameSync between them really raises
EXDEV — because otherwise fs.move would succeed by rename and the test would
pass without exercising the fallback. It fails loudly rather than skipping
when no cross-device pair is available, since a silent skip on the only test
covering this path would report coverage that does not exist.

Verified inside the sandbox with nix build .#checks.x86_64-linux.jest, not
only on the host: 67 suites, 781 tests.
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