Skip to content

test(shelfundo): keep the stranger's inode distinct from the move's - #184

Merged
thisisgm merged 1 commit into
thisisgm:mainfrom
felixzsh:fix/shelfundo-stranger-inode
Sep 23, 2026
Merged

thisisgm merged 1 commit into
thisisgm:mainfrom
felixzsh:fix/shelfundo-stranger-inode

Conversation

@felixzsh

@felixzsh felixzsh commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

shelfundo::tests::undo_refuses_to_walk_a_stranger_back removes the landed file, writes
a replacement at the same name, and expects the recorded dev/ino/kind to refuse it.
On a filesystem that hands the just-freed inode to the replacement -- ext4 does, and the
Omarchy package builder's /tmp did -- the stranger carries the move's own identity,
put_back does not refuse, and it falls through to move_back with the source directory
absent, failing with "could not go back (file or folder not found)".

That one failure aborted check() and kept flea 0.3.0/0.3.1 from publishing. Omarchy
worked around it in the package by running the shelfundo suite with TMPDIR on
/dev/shm (tmpfs, which allocates inode numbers from a counter and never reuses one),
which is exactly the allocator behaviour this test was silently assuming. This makes the
test independent of that assumption, so it holds on ext4, tmpfs and anywhere else.

Hold the landed file open across the unlink, so its inode stays allocated and the
replacement is provably a different item. dev+ino+kind remains the identity: ctime
is deliberately not part of it because permission repair changes it (see
backend/opsreq.rs), so the test has to make the two items differ rather than trust the
allocator.

Verified: the shelfundo suite is 8 passed on btrfs and tmpfs; the original failure does
not reproduce here (this box's filesystems do not recycle the inode), which is why it only
showed on the builder.

Fixes #180.

Summary by CodeRabbit

  • Tests
    • Improved reliability of undo behavior tests when a destination file is deleted and recreated.
    • Ensured the test distinguishes the recreated file from the original file by keeping the destination open during deletion.

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: dfdde390-a7ca-4113-aada-0ae066aa246d

📥 Commits

Reviewing files that changed from the base of the PR and between 3ba2eaf and 72b0497.

📒 Files selected for processing (1)
  • src/shelfundo_tests.rs

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

The test now keeps the destination file open before deletion and recreation. This prevents inode reuse from making the replacement appear to be the original file.

Changes

Shelf undo test

Layer / File(s) Summary
Hold the original inode during replacement
src/shelfundo_tests.rs
undo_refuses_to_walk_a_stranger_back opens the destination file and retains the handle through removal and recreation.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Other · Severity of issue fixed: Medium

Suggested reviewers: thisisgm

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the test change that keeps the stranger's inode distinct from the moved item.
Linked Issues check ✅ Passed The change addresses issue #180. The test keeps the landed file open across unlinking, so the replacement receives a distinct inode. The test still validates replacement identity with dev, ino, an…
Out of Scope Changes check ✅ Passed The pull request changes only undo_refuses_to_walk_a_stranger_back. The file handle directly supports the issue objective by preventing inode reuse. No unrelated production behavior or unrelated tes…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@felixzsh
felixzsh force-pushed the fix/shelfundo-stranger-inode branch from 3ddc1a2 to 3ba2eaf Compare September 21, 2026 15:27
undo_refuses_to_walk_a_stranger_back removed the landed file and wrote a
replacement at the same name, expecting the recorded dev/ino/kind to refuse it.
On a filesystem that hands the just-freed inode to the replacement -- tmpfs and
ext4 both do, and the Omarchy builder did -- the stranger carried the move's own
identity, put_back did not refuse, and it fell through to move_back with the
source directory absent, failing with "could not go back (file or folder not
found)".

Hold the landed file open across the unlink so its inode stays allocated and the
replacement is provably a different item. dev+ino+kind stays the identity: ctime
is deliberately not part of it, because permission repair changes it (see
backend/opsreq.rs), so the test has to make the two items differ rather than
trust the allocator.

This is the one failure that aborts Omarchy's check() for flea 0.3.0 and 0.3.1.
@felixzsh
felixzsh force-pushed the fix/shelfundo-stranger-inode branch from 3ba2eaf to 72b0497 Compare September 21, 2026 15:31
@thisisgm
thisisgm merged commit 3bc9ba0 into thisisgm:main Sep 23, 2026
1 check passed
@thisisgm

Copy link
Copy Markdown
Owner

Shipped in v0.3.3. Thanks @felixzsh! https://github.com/thisisgm/flea/releases/tag/v0.3.3

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.

shelfundo: undo_refuses_to_walk_a_stranger_back fails when the filesystem reuses the inode

2 participants