Files
codex/codex-rs/windows-sandbox-rs/src/setup_refresh_tests.rs
T
Tamir Duberstein b06b7d2f77 Upgrade Windows bindings to windows-sys 0.61.2 (#50058)
## What changed

- Centralize `windows-sys` at version `0.61.2` in the workspace and migrate dependent crates to it.
- Adapt Windows API calls to the updated handle, boolean, and type definitions. Replace custom handle owners with `OwnedHandle` and use `BorrowedHandle` where ownership stays with the caller.
- Add explicit wrappers for non-owning Windows handles passed between threads.

## Testing

Enable the MCP refresh cleanup test on Windows. Retain process handles to verify that a superseded MCP server stays alive during an in-flight call, exits after cancellation, and leaves the replacement running until shutdown.

GitOrigin-RevId: 86f53d9b300d13edff7154f4a7c32e34dacd2919
2026-10-01 18:05:05 +00:00

65 lines
2.4 KiB
Rust

//! Verifies refresh helpers stay console-free when launched by a detached daemon.
use std::fs;
use std::os::windows::process::CommandExt;
use std::path::PathBuf;
use std::process::Command;
use anyhow::Result;
use pretty_assertions::assert_eq;
use windows_sys::Win32::System::Console::GetConsoleWindow;
use windows_sys::Win32::System::Threading::DETACHED_PROCESS;
use super::run_setup_refresh_payload;
const DETACHED_TEST: &str = "setup::refresh_tests::refresh_helper_has_no_console";
const HELPER_TEST: &str = "setup::refresh_tests::refresh_console_probe";
const HOME_ENV: &str = "CODEX_TEST_REFRESH_CONSOLE_HOME";
#[test]
fn refresh_helper_has_no_console() -> Result<()> {
if let Some(home) = std::env::var_os(HOME_ENV).map(PathBuf::from) {
assert!(unsafe { GetConsoleWindow() }.is_null());
run_setup_refresh_payload(HELPER_TEST, &home)?;
assert_eq!(fs::read(home.join("probe"))?, b"no console");
return Ok(());
}
// Re-execute detached with a disposable fake setup helper beside it. This
// exercises the production refresh launch without provisioning sandbox users.
let temporary = tempfile::tempdir()?;
let executable = std::env::current_exe()?;
let detached = temporary.path().join("detached.exe");
codex_utils_cargo_bin::copy_executable(&executable, &detached)?;
codex_utils_cargo_bin::copy_executable(
&executable,
&temporary.path().join("codex-windows-sandbox-setup.exe"),
)?;
let output = Command::new(detached)
.args(["--exact", DETACHED_TEST, "--nocapture"])
.env(HOME_ENV, temporary.path())
.creation_flags(DETACHED_PROCESS)
.output()?;
assert!(
output.status.success(),
"detached refresh probe failed:\n{}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
assert_eq!(fs::read(temporary.path().join("probe"))?, b"no console");
Ok(())
}
#[test]
fn refresh_console_probe() -> Result<()> {
// The setup launcher supplies this test name as its single payload argument.
// Ordinary test runs must not require their own parent to be console-free.
if std::env::args().nth(1).as_deref() != Some(HELPER_TEST) {
return Ok(());
}
let home = PathBuf::from(std::env::var_os(HOME_ENV).expect("detached probe home"));
assert!(unsafe { GetConsoleWindow() }.is_null());
fs::write(home.join("probe"), b"no console")?;
Ok(())
}