Skip to content

test(archive-props): keep shifted symlinks pointing where they did - #660

Merged
rominf merged 1 commit into
mainfrom
test/archive-props-precision
Oct 14, 2026
Merged

rominf merged 1 commit into
mainfrom
test/archive-props-precision

Conversation

@rominf

@rominf rominf commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator

Follows up #559 (jussielo-amd's notes).

  • Shifted symlinks: moving ComfyUI entries one level down, under a/, used to pull their relative symlink targets one level back inside the install. A new moved_one_level_down helper adds a compensating ../, so ../outside still escapes. moving_an_entry_down_keeps_its_symlink_target_in_place checks that the resolved target is the same before and after the move, and fails without the fix.
  • ESCAPES_ONLY: now defined once, in archive_props.rs.
  • The CaseOutcome.tree doc: now says shared_inodes is always empty there, because those entries are moved into escapes.
  • running_as_root() not reused: archive_props.rs is #[path]-included into three crates, and crate::openmpi doesn't resolve outside rocm-core. The umask still has to be read from /proc anyway.

Verified locally:

  • fmt
  • tests for rocm --bin rocm (1096), rocm-core (622) and e2e-cucumber lib, plus feature_naming
  • both clippy invocations, on Linux and for x86_64-pc-windows-gnu

This is test-only, so no scenario.

`entries_without_top_level_symlink` moves every relative ComfyUI entry under
`a/`, but left the generator's relative link targets as they were, so
`../outside` written one level deeper resolved to `dest/outside` and no longer
escaped. A moved symlink's relative target now gains a `../`, keeping the
"link, then write through it" escape the property is meant to exercise, and a
unit test checks the resolved target is unchanged by the move.

Also share one `ESCAPES_ONLY` between the uv and ComfyUI properties, and say
on `CaseOutcome::tree` that its `shared_inodes` is always empty because
`run_case` reports those as escapes.

Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
@rominf
rominf requested a review from a team as a code owner October 13, 2026 18:12
@rominf
rominf requested a review from r0x0r October 13, 2026 18:12

@jussielo-amd jussielo-amd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. No correctness bugs found — I traced moved_one_level_down's relative-symlink-target compensation against lexical path-resolution semantics and cross-checked it against the tar crate's actual resolution behavior (symlink targets resolve relative to the link's own directory; hardlink targets resolve relative to the destination root, so correctly leaving them untouched is also correct). Moving an entry under a/ increases its containing directory's depth by exactly one regardless of original nesting, so the single ../ compensation holds in all cases.

Ran the full test suite locally, including the new moving_an_entry_down_keeps_its_symlink_target_in_place test and the entries_without_top_level_symlink-driven property test (512 cases, hardlink shapes reached ~11% of the time) — all passing.

Two minor, non-blocking cleanup notes left as inline comments below.

Comment thread apps/rocm/src/comfyui.rs
let moved: Vec<Entry> = entries.into_iter().map(moved_one_level_down).collect();
for entry in &moved {
if matches!(entry.kind, Kind::Symlink(_))
&& !entry.name.starts_with(b"/")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this absolute/re-rooted guard (!name.starts_with(b"/") && !name.starts_with(b"@")) is now duplicated between moved_one_level_down (around line 3142) and this symlink-filter loop. If the re-rooting convention ever changes (e.g. a new sentinel prefix), it'd be easy to update one copy and miss the other. Might be worth factoring into a shared helper.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The absolute/re-rooted guard should live in one place. I will move it into a shared helper in a follow-up PR rather than re-spin this approved one.

Comment thread apps/rocm/src/comfyui.rs
b"a",
] {
let moved = moved_one_level_down(Entry {
name: b"l".to_vec(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: this test only exercises a top-level link name (l -> a/l), never one already nested in a subdirectory (e.g. sub/l). So it can't by itself prove the doc comment's "exactly one ../, regardless of original nesting depth" claim — only the probabilistic property test would catch a depth-dependent regression here, and only non-deterministically. A second case with a pre-nested name would pin that down.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. Only the property test reaches a nested link today. The follow-up will add a direct sub/l case, so the "exactly one ../ whatever the depth" claim has a deterministic test.

@rominf
rominf added this pull request to the merge queue Oct 14, 2026

@juhovainio juhovainio left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed this (test-only follow-up to #559) with a full fan-out correctness pass plus a separate Standards/Spec pass. No blocking findings on either.

Independently traced the ../-compensation math across all 6 relative-target cases and confirmed it correctly restores the original resolved location in every one. Cross-checked impact across the other crates that use archive_props.rs (uv.rs, therock.rs, lemonade's install.rs) and confirmed none of them share this shifted-symlink pattern, so this is correctly scoped to comfyui.rs alone. The ESCAPES_ONLY dedup is clean. Also checked this against #559's own review thread: 3 of the 4 follow-up items are fully implemented here, and the 4th (reusing running_as_root()) is explicitly declined with cross-crate #[path]-inclusion reasoning that I verified is actually correct by grep, not a shortcut.

One non-blocking tightening worth doing at some point, not blocking this PR: moving_an_entry_down_keeps_its_symlink_target_in_place only pins one branch of each of the two absolute-name/absolute-target guard conditions explicitly. The missing branches are still exercised probabilistically by the existing 512-case property sweeps, so actual regression risk is low, but two more one-line assertions would make the dedicated unit test deterministic instead of relying on that backup coverage.

Approving - nothing here blocks merge.

@rominf

rominf commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks. Agreed: the follow-up already promised for jussielo's notes (sharing the guard, adding a nested sub/l case) will also add the two missing guard branches to moving_an_entry_down_keeps_its_symlink_target_in_place. That way the unit test pins all four cases without relying on the property sweep.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 14, 2026
@rominf
rominf added this pull request to the merge queue Oct 14, 2026
@rominf

rominf commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

The merge queue ejected this on chat-06 (chat-tool-definitions-accepted), main's harness timeout from #661, which this change does not touch. I re-queued it behind #662, which fixes that timeout, so its merge group now includes the fix.

Merged via the queue into main with commit dfe1df3 Oct 14, 2026
30 checks passed
@rominf
rominf deleted the test/archive-props-precision branch October 14, 2026 10:26
@rominf

rominf commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up is in #684, with a correction. The nested sub/l case showed that "one ../ keeps the target in place at any depth" is only true for top-level links and for targets that escape the root. A nested link whose target stays inside the root still stays inside, but not always at the same path: sub/l -> . resolves to sub before the move and to a after it. The escape properties depend only on what does hold. #684 corrects the doc comments and pins that. It also shares the guard and covers all four guard branches.

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.

3 participants