Skip to content

fix(test): test delete Windows registry accidently - #4918

Open
baka-gourd wants to merge 4 commits into
rust-lang:mainfrom
baka-gourd:windows-registry-per-test-uuid
Open

fix(test): test delete Windows registry accidently#4918
baka-gourd wants to merge 4 commits into
rust-lang:mainfrom
baka-gourd:windows-registry-per-test-uuid

Conversation

@baka-gourd

Copy link
Copy Markdown

fix #4915

This PR is intended to fix the issue mentioned in the ticket regarding the accidental deletion of existing registry entries. However, while investigating the problem, we also discovered a concurrency issue in RegistryGuard, so the scope of the fix is quite extensive.

  • Add per-test Windows registry isolation using a unique test UUID.
  • Route Windows registry helpers through test-specific registry subkeys when a UUID is present.
  • Update RegistryGuard to support multiple registry values and clean up the per-test registry subtree.
  • Forward the registry UUID through the test Config and CliTestContext.
  • Update Windows unit and integration tests to use UUID-scoped registry guards.
  • Keep PATH registry checks and Programs entry checks isolated in tests.
  • Treat missing registry keys or values as non-fatal during registry cleanup.
  • No new UUID dependency is introduced; UUIDs are generated from rand.

@baka-gourd
baka-gourd force-pushed the windows-registry-per-test-uuid branch from a758fde to c4635ae Compare June 21, 2026 13:53
Comment thread src/cli/self_update/windows.rs Outdated
static REGISTRY_LOCK: Mutex<()> = Mutex::new(());
impl Drop for RegistryGuard {
fn drop(&mut self) {
for (id, prev) in self.saved.iter().rev() {

@Cloud0310 Cloud0310 Jun 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess since we're trying to remove the whole test subtree all together, no need for settting them empty again here?

View changes since the review

@Cloud0310

Copy link
Copy Markdown
Contributor

Another thing here is, can we make code format coming along with commits instead of doing formatting in the end commit here.

@rustbot

This comment has been minimized.

@baka-gourd
baka-gourd force-pushed the windows-registry-per-test-uuid branch from 9be4399 to 360e048 Compare July 2, 2026 12:21
@rustbot

This comment has been minimized.

@baka-gourd
baka-gourd requested a review from Cloud0310 July 2, 2026 12:54
@rami3l rami3l self-assigned this Jul 3, 2026
@rustbot

This comment has been minimized.

@rami3l
rami3l requested review from rami3l and removed request for Cloud0310 August 3, 2026 14:31
Comment thread src/cli/self_update/windows.rs Outdated
@baka-gourd
baka-gourd force-pushed the windows-registry-per-test-uuid branch from 360e048 to dcd1d78 Compare August 5, 2026 11:20
@rustbot

rustbot commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Comment thread src/cli/self_update.rs
}
Ok(()) if !no_modify_path => {
info!("removing cargo bin directory `{cargo_bin_display}` from $PATH");
do_remove_from_path(process)?;

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Moving do_remove_from_programs() out of this match{} is a separate change and has nothing to do with this refactoring commit.

Consider spitting this into a refactoring commit (that puts do_remove_from_programs() directly below this line) first, and a breaking change commit (moving the above call out of the match{} block) after that.

View changes since the review

Comment thread src/cli/self_update.rs
}

#[cfg(windows)]
do_add_to_programs(cfg.process)?;

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment thread src/cli/self_update/windows.rs Outdated
id,
prev: id.get()?,
})
fn registry_sub_key_path(sub_key: &str, process: &Process) -> String {

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: This should be converted into a Windows-only method of the Process type.

View changes since the review

Comment thread src/cli/self_update/windows.rs Outdated

#[cfg(not(any(test, feature = "test")))]
fn registry_sub_key_path(sub_key: &str, _process: &Process) -> String {
sub_key.to_owned()

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There doesn't seem to be a need for this function.

View changes since the review

Comment thread src/cli/self_update/windows.rs Outdated
impl RegistryValueId {
pub fn get(&self) -> Result<Option<Value>> {
let sub_key = CURRENT_USER.create(self.sub_key)?;
fn resolved_sub_key(&self, uuid: Option<&str>) -> windows_registry::Result<Key> {

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggest inlining this function.

View changes since the review

Comment thread src/cli/self_update/windows.rs Outdated
impl RegistryValueId {
pub fn get(&self) -> Result<Option<Value>> {
let sub_key = CURRENT_USER.create(self.sub_key)?;
fn resolved_sub_key(&self, uuid: Option<&str>) -> windows_registry::Result<Key> {

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems that in every test case involving registry access, a UUID is needed anyways, if that is indeed true, I don't see a reason to pass Option<> here.

View changes since the review

Comment thread src/cli/self_update/windows.rs Outdated
pub struct RegistryGuard {
uuid: String,
saved: Vec<(&'static RegistryValueId, Option<Value>)>,
}

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the analysis in d303f39#r3721131249 is correct, then we don't need a registry guard at all.

View changes since the review

Comment thread src/cli/self_update/windows.rs Outdated
id,
prev: id.get()?,
})
fn registry_sub_key_path(sub_key: &str, process: &Process) -> String {

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When we are running tests, new registry keys and all its children should be created as volatile, so that we won't leave unintended garbage entries in the developer's machine (thanks, @Cloud0310).

View changes since the review

Comment thread src/test/clitools.rs Outdated
test_root_dir: PathBuf,
/// Per-test Windows registry UUID.
#[cfg(windows)]
pub test_registry_uuid: Option<String>,

@rami3l rami3l Aug 5, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It feels like this (01182b7) should be squashed into one of the previous commits; your goal should be that each commit would still be able to pass all the tests.

View changes since the review

@rami3l rami3l left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@baka-gourd I think this looks quite interesting but would require more work before it can be merged.

Three general principles of our committing style:

  1. Each commit should do one single thing, whether that is refactoring, introducing a breaking change, or adding a new feature.
  2. Each commit should ensure that all test cases are passing. If running all tests is not practical in your local environment, you should have run at least all related tests and have made sure that they are passing.
  3. When a commit indicates a behavioral change that might cause some tests to fail, you should update those influenced tests in the same commit so that they pass again.

View changes since this review

@baka-gourd
baka-gourd force-pushed the windows-registry-per-test-uuid branch from 6366e7f to 78a2fde Compare August 5, 2026 15:06
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.

Current tests run on Windows will accidently clears installed registry values by normal installation of rustup

4 participants