fix(runtimes): keep the rollback target when re-selecting the active runtime - #485
Conversation
…runtime
Activating the runtime already in use recomputed the rollback target from
the runtime being left. There is none in that case, so it cleared the
recorded one -- silently taking away the recovery path the previous
activation had just offered ("if this causes problems, run `rocm runtimes
rollback`"). Nothing the user could see had changed, so nothing signalled
that the undo was gone.
Deriving the target from the current runtime is right only when the user
is actually leaving one. When the requested runtime is already active the
activation is a no-op for the registry pointers, so the recorded target is
now preserved instead of overwritten. The guard that stopped a runtime
being recorded as its own rollback target is kept: in the branch that
records a new target, the current runtime differs from the requested one
by construction.
The shortest command sequence that exposes this is three activations in a
row, which is why none of the seven existing lifecycle scenarios caught
it -- every one- and two-command sequence conforms. Scenario
runtime-lifecycle-08 pins it: it fails before this change and passes
after, and needs no GPU or download, so it runs on the mock lane every PR.
Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
juhovainio
left a comment
There was a problem hiding this comment.
Traced this through activate_runtime, rollback_runtime, and the uninstall path that clears previous_runtime_key. The fix is correct: the rollback target should only ever be re-derived from current when you're actually leaving it, and re-selecting the already-active runtime now leaves the recorded target alone instead of wiping it. I checked the case I was worried about — previous_runtime_key surviving a reselect while pointing at a runtime that's since been uninstalled — and confirmed the uninstall path already clears that field when it matches, so no inconsistent state is reachable through this change.
Test coverage is an e2e-cucumber scenario rather than a unit test, which is the right call here per AGENTS.md §3 ("a unit test asserting the internal helper does NOT discharge this"). The new scenario asserts registry state via rocm runtimes list, not activation wording, matching the PR's own checklist claim. PR body claims (no stale expectations.toml rows, scope) all check out against the repo as it stands.
This is a diff-only read — approving based on that, not a substitute for CI or your own pass.
tests/e2e-cucumber/expectations.tomlfor the fixed ticket ID and removed/narrowed any now-stale xfail rows. — no rows reference the runtimes lifecycle scenarios.docs/architecture.md. — N/A, no new subcommand.rocm runtimes list, not the activation wording.Summary
Re-selecting the ROCm runtime you are already using silently discarded the rollback target, so the recovery path the previous activation had just offered disappeared with no sign it had gone.
Root cause.
activate_runtimederived the rollback target from the runtime being left. When the requested runtime is already the active one there is nothing being left, so the derivation producedNone— and thatNonewas written over the recorded target rather than leaving it alone. Deriving from the current runtime is correct only when the user is actually switching.Fix. When the requested runtime is already active, the registry pointers are left as they are. The guard that prevents a runtime being recorded as its own rollback target is preserved: in the branch that does record a new target, the current runtime differs from the requested one by construction, so the previous
.filter()was redundant there.Risk: low. One function, no API or schema change, no migration. The behaviour change is confined to the previously-destructive no-op path.
Changed user-facing output
On a re-activation of the already-active runtime,
rocm runtimes activatenow reports the preserved rollback target instead of<unset>, and consequently prints the rollback hint:The hint is now truthful — rollback genuinely is available. The
changed_from_label reads a little oddly for a command that changed nothing; it is reporting the rollback target on record. Happy to follow up with a dedicated "already in use" report for that path if reviewers prefer it, but that is a wording decision beyond this fix.Test plan
runtime-lifecycle-08pins the behaviour and fails before this change, passes after — verified both ways against a locally built binary. It plants read-only tarball runtimes in an isolated registry, so it needs no GPU, no Python and no download, and runs on the mock lane on every PR (measured ~21s against that job's 15-minute cap).runtime_lifecyclescenarios pass against the built binary: 35 steps, 0 failures.cargo test --workspace --all-targets,cargo clippy --workspace --all-targets -- -D warnings,cargo clippy -p e2e-cucumber --test e2e -- -D warnings,cargo fmt --all --check, and thefeature_namingguard all pass.Scope
Deliberately not included: a broader conformance check that walks every sequence of
activate/rollback/uninstalland compares the listing against a model of the documented state machine. That is how this defect was found — the shortest sequence exposing it is three activations, which is why none of the seven existing scenarios covered it — but its per-run cost is still being weighed, so only the targeted regression lands here.Fixes #486