From 8a940481b003f64c9915b0292cf1b14c797fc559 Mon Sep 17 00:00:00 2001 From: Anand Aiyer Date: Fri, 17 Jul 2026 20:35:41 +0530 Subject: [PATCH] fix(tests): isolate Codex home from user state Signed-off-by: Anand Aiyer --- tests/test_cli.c | 22 +++++++++++++++++++++- tests/test_main.c | 20 +++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/tests/test_cli.c b/tests/test_cli.c index bb8a94b6f..395625325 100644 --- a/tests/test_cli.c +++ b/tests/test_cli.c @@ -226,6 +226,19 @@ static void restore_test_env(const char *name, char *saved) { } } +TEST(cli_runner_uses_private_codex_home) { + const char *home = getenv("HOME"); + const char *codex_home = getenv("CODEX_HOME"); + ASSERT_NOT_NULL(home); + ASSERT_NOT_NULL(codex_home); + + char expected[1024]; + int expected_len = snprintf(expected, sizeof(expected), "%s/.codex", home); + ASSERT(expected_len >= 0 && (size_t)expected_len < sizeof(expected)); + ASSERT_STR_EQ(codex_home, expected); + PASS(); +} + /* Helper: mkdirp */ static int test_mkdirp(const char *path) { char tmp[1024]; @@ -2354,10 +2367,13 @@ TEST(cli_detect_agents_finds_codex) { snprintf(dir, sizeof(dir), "%s/.codex", tmpdir); test_mkdirp(dir); + char *saved_codex = save_test_env("CODEX_HOME"); + cbm_unsetenv("CODEX_HOME"); cbm_detected_agents_t agents = cbm_detect_agents(tmpdir); - ASSERT_TRUE(agents.codex); + restore_test_env("CODEX_HOME", saved_codex); test_rmdir_r(tmpdir); + ASSERT_TRUE(agents.codex); PASS(); } @@ -2395,7 +2411,10 @@ TEST(cli_install_plan_receipt_no_mutation_issue388) { snprintf(dir, sizeof(dir), "%s/.codex", tmpdir); test_mkdirp(dir); + char *saved_codex = save_test_env("CODEX_HOME"); + cbm_unsetenv("CODEX_HOME"); char *json = cbm_build_install_plan_json(tmpdir, "/usr/local/bin/codebase-memory-mcp"); + restore_test_env("CODEX_HOME", saved_codex); ASSERT_NOT_NULL(json); ASSERT(strstr(json, "agent.install.plan.v1") != NULL); ASSERT(strstr(json, "writes_started") != NULL); @@ -9643,6 +9662,7 @@ TEST(cli_sha256_file_matches_known_vector) { * ═══════════════════════════════════════════════════════════════════ */ SUITE(cli) { + RUN_TEST(cli_runner_uses_private_codex_home); RUN_TEST(cli_sha256_file_matches_known_vector); /* Version (2 tests — selfupdate_test.go) */ RUN_TEST(cli_compare_versions); diff --git a/tests/test_main.c b/tests/test_main.c index ffbb1fb5c..18cc70a9c 100644 --- a/tests/test_main.c +++ b/tests/test_main.c @@ -25,10 +25,10 @@ int tf_skip_count = 0; #include /* #798 follow-up: socket-isolation re-exec probe */ #endif -/* Test handlers that exercise the production index_repository flow must never - * inherit the user's real cache. Individual tests may temporarily override - * this sentinel and restore it; atexit removes anything left behind by an - * assertion that returns before fixture cleanup. */ +/* Test handlers that exercise production indexing or agent installation must + * never inherit the user's real cache or Codex configuration. Individual tests + * may temporarily override this sentinel and restore it; atexit removes + * anything left behind by an assertion that returns before fixture cleanup. */ static char tf_home_sentinel[512]; static void tf_cleanup_cache_sentinel(void) { @@ -45,8 +45,14 @@ static bool tf_setup_cache_sentinel(void) { /* Legacy integration fixtures derive DB paths from HOME, while production * cache_dir() prefers CBM_CACHE_DIR. A private HOME plus no inherited cache * override keeps both conventions pointed at the same isolated tree. */ - cbm_setenv("HOME", tf_home_sentinel, 1); - cbm_unsetenv("CBM_CACHE_DIR"); + char codex_home[sizeof(tf_home_sentinel) + sizeof("/.codex")]; + int codex_home_len = snprintf(codex_home, sizeof(codex_home), "%s/.codex", tf_home_sentinel); + if (codex_home_len < 0 || (size_t)codex_home_len >= sizeof(codex_home) || + cbm_setenv("HOME", tf_home_sentinel, 1) != 0 || + cbm_setenv("CODEX_HOME", codex_home, 1) != 0 || cbm_unsetenv("CBM_CACHE_DIR") != 0) { + tf_cleanup_cache_sentinel(); + return false; + } atexit(tf_cleanup_cache_sentinel); return true; } @@ -304,7 +310,7 @@ int main(int argc, char **argv) { * A test that exercises the supervisor must explicitly re-enable it. */ cbm_setenv("CBM_INDEX_SUPERVISOR", "0", 1); if (!tf_setup_cache_sentinel()) { - fprintf(stderr, "failed to create isolated test cache\n"); + fprintf(stderr, "failed to create isolated test home\n"); return 2; }