From 7207ebf56295a8337cd3bc68db52c2eaf575fa07 Mon Sep 17 00:00:00 2001 From: starr-openai Date: Mon, 11 May 2026 12:47:46 -0700 Subject: [PATCH] Isolate tmp-dependent tests from ambient git Co-authored-by: Codex --- codex-rs/core-skills/src/loader_tests.rs | 40 +++++++++++++++---- codex-rs/secrets/src/lib.rs | 10 ++--- codex-rs/tui/src/chatwidget/tests/helpers.rs | 23 ++++++++++- .../src/chatwidget/tests/status_and_layout.rs | 4 +- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/codex-rs/core-skills/src/loader_tests.rs b/codex-rs/core-skills/src/loader_tests.rs index c80585871e..d574d9d47c 100644 --- a/codex-rs/core-skills/src/loader_tests.rs +++ b/codex-rs/core-skills/src/loader_tests.rs @@ -80,6 +80,22 @@ fn project_layers_for_cwd(cwd: &Path) -> Vec { } async fn make_config_for_cwd(codex_home: &TempDir, cwd: PathBuf) -> TestConfig { + let project_layers = project_layers_for_cwd(&cwd); + make_config_for_cwd_with_system_config_and_project_layers( + codex_home, + cwd, + TomlValue::Table(toml::map::Map::new()), + project_layers, + ) + .await +} + +async fn make_config_for_cwd_with_system_config_and_project_layers( + codex_home: &TempDir, + cwd: PathBuf, + system_config: TomlValue, + project_layers: Vec, +) -> TestConfig { let user_config_path = codex_home.path().join(CONFIG_TOML_FILE); let system_config_path = codex_home.path().join("etc/codex/config.toml"); fs::create_dir_all( @@ -94,7 +110,7 @@ async fn make_config_for_cwd(codex_home: &TempDir, cwd: PathBuf) -> TestConfig { ConfigLayerSource::System { file: config_file(system_config_path), }, - TomlValue::Table(toml::map::Map::new()), + system_config, ), ConfigLayerEntry::new( ConfigLayerSource::User { @@ -103,7 +119,7 @@ async fn make_config_for_cwd(codex_home: &TempDir, cwd: PathBuf) -> TestConfig { TomlValue::Table(toml::map::Map::new()), ), ]; - layers.extend(project_layers_for_cwd(&cwd)); + layers.extend(project_layers); let cwd_abs = cwd.abs(); TestConfig { @@ -1726,16 +1742,26 @@ async fn non_git_repo_skills_search_does_not_walk_parents() { fs::create_dir_all(&nested_dir).unwrap(); write_skill_at( - &outer_dir - .path() - .join(REPO_ROOT_CONFIG_DIR_NAME) - .join(SKILLS_DIR_NAME), + &outer_dir.path().join(AGENTS_DIR_NAME).join(SKILLS_DIR_NAME), "outer", "outer-skill", "from outer", ); - let cfg = make_config_for_cwd(&codex_home, nested_dir).await; + let mut system_config = toml::map::Map::new(); + system_config.insert( + "project_root_markers".to_string(), + TomlValue::Array(vec![TomlValue::String( + "__codex_test_project_root_marker_that_does_not_exist__".to_string(), + )]), + ); + let cfg = make_config_for_cwd_with_system_config_and_project_layers( + &codex_home, + nested_dir, + TomlValue::Table(system_config), + Vec::new(), + ) + .await; let outcome = load_skills_for_test(&cfg).await; assert!( diff --git a/codex-rs/secrets/src/lib.rs b/codex-rs/secrets/src/lib.rs index 280c723d36..650e7dcf8f 100644 --- a/codex-rs/secrets/src/lib.rs +++ b/codex-rs/secrets/src/lib.rs @@ -188,12 +188,12 @@ mod tests { #[test] fn environment_id_fallback_has_cwd_prefix() { - let dir = tempfile::tempdir().expect("tempdir"); - let env_id = environment_id_from_cwd(dir.path()); - let canonical = dir - .path() + let cwd = PathBuf::from(std::path::MAIN_SEPARATOR.to_string()) + .join("codex-secrets-test-missing-cwd"); + let env_id = environment_id_from_cwd(&cwd); + let canonical = cwd .canonicalize() - .expect("tempdir canonical path should exist") + .unwrap_or_else(|_| cwd.clone()) .to_string_lossy() .into_owned(); let mut hasher = Sha256::new(); diff --git a/codex-rs/tui/src/chatwidget/tests/helpers.rs b/codex-rs/tui/src/chatwidget/tests/helpers.rs index f11cd64843..81c9977e3d 100644 --- a/codex-rs/tui/src/chatwidget/tests/helpers.rs +++ b/codex-rs/tui/src/chatwidget/tests/helpers.rs @@ -1,6 +1,7 @@ use super::*; use codex_app_server_protocol::PluginAvailability; use pretty_assertions::assert_eq; +use std::sync::OnceLock; pub(super) async fn test_config() -> Config { // Start from the built-in defaults so tests do not inherit host/system config. @@ -16,7 +17,7 @@ pub(super) async fn test_config() -> Config { config.codex_home = codex_home.abs(); config.sqlite_home = codex_home.clone(); config.log_dir = codex_home.join("log"); - config.cwd = PathBuf::from(test_path_display("/tmp/project")).abs(); + config.cwd = test_project_path().abs(); config.config_layer_stack = ConfigLayerStack::default(); config.startup_warnings.clear(); config.user_instructions = None; @@ -24,7 +25,22 @@ pub(super) async fn test_config() -> Config { } pub(super) fn test_project_path() -> PathBuf { - PathBuf::from(test_path_display("/tmp/project")) + static TEST_PROJECT_PATH: OnceLock = OnceLock::new(); + TEST_PROJECT_PATH + .get_or_init(|| { + let root = isolated_test_tmp_dir("chatwidget-project-").keep(); + let project = root.join("project"); + std::fs::create_dir_all(project.join(".git")).expect("create test project git marker"); + project + }) + .clone() +} + +fn isolated_test_tmp_dir(prefix: &str) -> tempfile::TempDir { + tempfile::Builder::new() + .prefix(prefix) + .tempdir() + .expect("tempdir") } pub(super) fn truncated_path_variants(path: &str) -> Vec { @@ -37,6 +53,9 @@ pub(super) fn truncated_path_variants(path: &str) -> Vec { pub(super) fn normalize_snapshot_paths(text: impl Into) -> String { let mut text = text.into(); + let isolated_project = test_project_path().to_string_lossy().into_owned(); + text = text.replace(&isolated_project, "/tmp/project"); + for unix_path in ["/tmp/project", "/tmp/hooks.json"] { let platform_path = test_path_display(unix_path); if platform_path != unix_path { diff --git a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs index 2f4aa30b3b..c54668df86 100644 --- a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs +++ b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs @@ -1736,7 +1736,7 @@ async fn status_line_model_with_reasoning_includes_fast_for_fast_capable_models( let test_cwd = test_path_display("/tmp/project"); assert_eq!( - status_line_text(&chat), + status_line_text(&chat).map(normalize_snapshot_paths), Some(format!("gpt-5.4 xhigh fast · Context 0% used · {test_cwd}")) ); @@ -1744,7 +1744,7 @@ async fn status_line_model_with_reasoning_includes_fast_for_fast_capable_models( chat.refresh_status_line(); assert_eq!( - status_line_text(&chat), + status_line_text(&chat).map(normalize_snapshot_paths), Some(format!( "gpt-5.3-codex xhigh · Context 0% used · {test_cwd}" ))