Skip to content

Commit

Permalink
Move Windows-only test code into windows module
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Jun 22, 2024
1 parent 2b13b2b commit 78426c9
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 102 deletions.
4 changes: 2 additions & 2 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ use crate::{

#[cfg(unix)]
mod shell;
#[cfg(feature = "test")]
pub(crate) mod test;

#[cfg(unix)]
mod unix;
Expand All @@ -85,6 +83,8 @@ mod windows;
pub use windows::complete_windows_uninstall;
#[cfg(windows)]
use windows::{delete_rustup_and_cargo_home, do_add_to_path, do_remove_from_path};
#[cfg(all(windows, feature = "test"))]
pub use windows::{get_path, RegistryGuard, RegistryValueId, USER_PATH};
#[cfg(windows)]
pub(crate) use windows::{run_update, self_replace};

Expand Down
89 changes: 0 additions & 89 deletions src/cli/self_update/test.rs

This file was deleted.

88 changes: 79 additions & 9 deletions src/cli/self_update/windows.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::env::{consts::EXE_SUFFIX, split_paths};
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::io::Write;
use std::io::{self, Write};
use std::os::windows::ffi::{OsStrExt, OsStringExt};
use std::path::Path;
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::sync::{Arc, LockResult, Mutex, MutexGuard};

use anyhow::{anyhow, Context, Result};
use tracing::{info, warn};
Expand All @@ -20,6 +20,7 @@ use crate::utils::utils;
use crate::utils::Notification;

use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
use winreg::types::{FromRegValue, ToRegValue};
use winreg::{RegKey, RegValue};

pub(crate) fn ensure_prompt(process: &Process) -> Result<()> {
Expand Down Expand Up @@ -807,16 +808,85 @@ pub(crate) fn delete_rustup_and_cargo_home(process: &Process) -> Result<()> {
Ok(())
}

#[cfg(test)]
mod tests {
use std::ffi::OsString;
use std::os::windows::ffi::OsStrExt;
#[cfg(any(test, feature = "test"))]
pub fn get_path() -> io::Result<Option<RegValue>> {
USER_PATH.get()
}

#[cfg(any(test, feature = "test"))]
pub struct RegistryGuard<'a> {
_locked: LockResult<MutexGuard<'a, ()>>,
id: &'static RegistryValueId,
prev: Option<RegValue>,
}

#[cfg(any(test, feature = "test"))]
impl<'a> RegistryGuard<'a> {
pub fn new(id: &'static RegistryValueId) -> io::Result<Self> {
Ok(Self {
_locked: REGISTRY_LOCK.lock(),
id,
prev: id.get()?,
})
}
}

#[cfg(any(test, feature = "test"))]
impl<'a> Drop for RegistryGuard<'a> {
fn drop(&mut self) {
self.id.set(self.prev.as_ref()).unwrap();
}
}

#[cfg(any(test, feature = "test"))]
static REGISTRY_LOCK: Mutex<()> = Mutex::new(());

#[cfg(any(test, feature = "test"))]
pub const USER_PATH: RegistryValueId = RegistryValueId {
sub_key: "Environment",
value_name: "PATH",
};

use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
use winreg::{RegKey, RegValue};
#[cfg(any(test, feature = "test"))]
pub struct RegistryValueId {
pub sub_key: &'static str,
pub value_name: &'static str,
}

#[cfg(any(test, feature = "test"))]
impl RegistryValueId {
pub fn get_value<T: FromRegValue>(&self) -> io::Result<Option<T>> {
self.get()?.map(|v| T::from_reg_value(&v)).transpose()
}

fn get(&self) -> io::Result<Option<RegValue>> {
let sub_key = RegKey::predef(HKEY_CURRENT_USER)
.open_subkey_with_flags(self.sub_key, KEY_READ | KEY_WRITE)?;
match sub_key.get_raw_value(self.value_name) {
Ok(val) => Ok(Some(val)),
Err(ref e) if e.kind() == io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e),
}
}

pub fn set_value(&self, new: Option<impl ToRegValue>) -> io::Result<()> {
self.set(new.map(|s| s.to_reg_value()).as_ref())
}

fn set(&self, new: Option<&RegValue>) -> io::Result<()> {
let sub_key = RegKey::predef(HKEY_CURRENT_USER)
.open_subkey_with_flags(self.sub_key, KEY_READ | KEY_WRITE)?;
match new {
Some(new) => sub_key.set_raw_value(self.value_name, new),
None => sub_key.delete_value(self.value_name),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::currentprocess::TestProcess;
use crate::test::{RegistryGuard, USER_PATH};

fn wide(str: &str) -> Vec<u16> {
OsString::from(str).encode_wide().collect()
Expand Down
2 changes: 1 addition & 1 deletion src/env_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ mod tests {

use super::*;
#[cfg(windows)]
use crate::cli::self_update::test::{RegistryGuard, USER_PATH};
use crate::cli::self_update::{RegistryGuard, USER_PATH};
use crate::currentprocess::TestProcess;
use crate::test::Env;

Expand Down
2 changes: 1 addition & 1 deletion src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::currentprocess::TestProcess;
use crate::dist::TargetTriple;

#[cfg(windows)]
pub use crate::cli::self_update::test::{get_path, RegistryGuard, RegistryValueId, USER_PATH};
pub use crate::cli::self_update::{get_path, RegistryGuard, RegistryValueId, USER_PATH};

// Things that can have environment variables applied to them.
pub trait Env {
Expand Down

0 comments on commit 78426c9

Please sign in to comment.