mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-01 07:44:01 +08:00
test(cli): neutralize ambient client home overrides in the C runner
The CLI resolves each client's config home from its own environment variable before falling back to $HOME — cbm_codex_config_dir() honours $CODEX_HOME and ignores the home_dir it is handed. A test that redirects only HOME therefore does not isolate those clients: it resolves, reads and WRITES the developer's real configuration. On a machine with $CODEX_HOME exported (any Codex or Orca user) 27 of 269 cli tests failed for that reason alone. Every one of them asserted a successful rc while the CLI was reporting genuine failures against the ambient config: an unbalanced managed marker left in the real config.toml, an AGENTS.md that is a symlink and is refused by the O_NOFOLLOW writer, and user-modified agent profiles that are correctly preserved. The behaviour under test passed in all of them; only the rc was poisoned. Worse than the red: the suite mutated that real config, installing and removing SKILL.md under the user's Codex home. The individual tests that already neutralize CODEX_HOME are exactly the ones that pass, and the file carries a comment admitting one suite was "green only via env leaked from earlier suites". Rather than extend those ad-hoc per-test lists again, neutralize the whole inventory once in the runner, and reuse the inventory the shell fixtures are already required to satisfy. tests/test_smoke_fixture_contract.sh grows one check so the two cannot drift: a client isolated in the smoke scripts but forgotten in the C runner now fails the contract. Verified on macOS arm64 with $CODEX_HOME and $OPENCODE_CONFIG_DIR exported: cli went from 241 passed / 28 failed to 268 passed / 0 failed, with no change outside tests/. Signed-off-by: Gabriel Gonzalez Pineda <64bits@gmail.com>
This commit is contained in:
+38
-4
@@ -54,8 +54,7 @@ static bool tf_invoked_as_windows_git_module(void) {
|
||||
* Inspect the actual loaded module so the copied git.exe probe cannot fall
|
||||
* through into the ordinary test runner when argv[0] is merely "git". */
|
||||
wchar_t image[32768];
|
||||
DWORD image_length =
|
||||
GetModuleFileNameW(NULL, image, (DWORD)(sizeof(image) / sizeof(image[0])));
|
||||
DWORD image_length = GetModuleFileNameW(NULL, image, (DWORD)(sizeof(image) / sizeof(image[0])));
|
||||
if (image_length == 0 || image_length >= (DWORD)(sizeof(image) / sizeof(image[0]))) {
|
||||
return false;
|
||||
}
|
||||
@@ -86,8 +85,7 @@ static bool tf_invoked_as_blocking_git(const char *argv0) {
|
||||
base = cursor + 1;
|
||||
}
|
||||
}
|
||||
return strcmp(base, "git") == 0 || strcmp(base, "git.exe") == 0 ||
|
||||
strcmp(base, "GIT.EXE") == 0;
|
||||
return strcmp(base, "git") == 0 || strcmp(base, "git.exe") == 0 || strcmp(base, "GIT.EXE") == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -165,6 +163,38 @@ static void tf_cleanup_cache_sentinel(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Client home overrides the CLI honours BEFORE $HOME, so redirecting HOME alone
|
||||
* does not isolate them: cbm_codex_config_dir() and its siblings return the
|
||||
* ambient path and the suite resolves against the developer's real config —
|
||||
* reading its state and writing to it. Same inventory the shell fixtures are
|
||||
* already required to neutralize (tests/test_smoke_fixture_contract.sh), kept
|
||||
* in one place so a new client cannot be isolated in the smoke scripts and
|
||||
* forgotten here. A test that exercises one of these sets it after setup. */
|
||||
static const char *const tf_client_home_overrides[] = {
|
||||
"CLAUDE_CONFIG_DIR",
|
||||
"CODEX_HOME",
|
||||
"KIRO_HOME",
|
||||
"HERMES_HOME",
|
||||
"QWEN_HOME",
|
||||
"CLINE_DATA_DIR",
|
||||
"OPENCLAW_HOME",
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_PROFILE",
|
||||
"OPENCLAW_CONFIG_PATH",
|
||||
"OPENCLAW_WORKSPACE_DIR",
|
||||
"OPENCODE_CONFIG",
|
||||
"OPENCODE_CONFIG_DIR",
|
||||
"COPILOT_HOME",
|
||||
"CRUSH_GLOBAL_CONFIG",
|
||||
"VIBE_HOME",
|
||||
"GLAB_CONFIG_DIR",
|
||||
"KIMI_CODE_HOME",
|
||||
"CBM_CONTINUE_CONFIG_PATH",
|
||||
"CBM_TRAE_CONFIG_PATH",
|
||||
"CBM_ROO_CONFIG_PATH",
|
||||
"CBM_CODY_CONFIG_PATH",
|
||||
};
|
||||
|
||||
static bool tf_setup_cache_sentinel(void) {
|
||||
snprintf(tf_home_sentinel, sizeof(tf_home_sentinel), "/tmp/cbm-test-home-XXXXXX");
|
||||
if (!cbm_mkdtemp(tf_home_sentinel)) {
|
||||
@@ -175,6 +205,10 @@ static bool tf_setup_cache_sentinel(void) {
|
||||
* override keeps both conventions pointed at the same isolated tree. */
|
||||
cbm_setenv("HOME", tf_home_sentinel, 1);
|
||||
cbm_unsetenv("CBM_CACHE_DIR");
|
||||
for (size_t i = 0U; i < sizeof(tf_client_home_overrides) / sizeof(tf_client_home_overrides[0]);
|
||||
i++) {
|
||||
cbm_unsetenv(tf_client_home_overrides[i]);
|
||||
}
|
||||
atexit(tf_cleanup_cache_sentinel);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,44 @@ require(
|
||||
"smoke-local.sh must not reserve/release a port or launch a separate http.server",
|
||||
)
|
||||
|
||||
# Every environment variable the CLI honours ahead of $HOME. A fixture that
|
||||
# redirects only HOME still resolves these to the developer's real config, so
|
||||
# both the shell fixtures and the C runner must neutralize the whole set.
|
||||
CLIENT_HOME_OVERRIDES = (
|
||||
"CLAUDE_CONFIG_DIR",
|
||||
"CODEX_HOME",
|
||||
"KIRO_HOME",
|
||||
"HERMES_HOME",
|
||||
"QWEN_HOME",
|
||||
"CLINE_DATA_DIR",
|
||||
"OPENCLAW_HOME",
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_PROFILE",
|
||||
"OPENCLAW_CONFIG_PATH",
|
||||
"OPENCLAW_WORKSPACE_DIR",
|
||||
"OPENCODE_CONFIG",
|
||||
"OPENCODE_CONFIG_DIR",
|
||||
"COPILOT_HOME",
|
||||
"CRUSH_GLOBAL_CONFIG",
|
||||
"VIBE_HOME",
|
||||
"GLAB_CONFIG_DIR",
|
||||
"KIMI_CODE_HOME",
|
||||
"CBM_CONTINUE_CONFIG_PATH",
|
||||
"CBM_TRAE_CONFIG_PATH",
|
||||
"CBM_ROO_CONFIG_PATH",
|
||||
"CBM_CODY_CONFIG_PATH",
|
||||
)
|
||||
|
||||
# The C suite exercises the same install/uninstall paths as the shell fixtures,
|
||||
# so it needs the same neutralization — otherwise a green run on a developer
|
||||
# machine only proves the ambient config happened to be writable.
|
||||
test_main = read("tests/test_main.c")
|
||||
for variable in CLIENT_HOME_OVERRIDES:
|
||||
require(
|
||||
f'"{variable}"' in test_main,
|
||||
f"tests/test_main.c must neutralize ambient {variable}",
|
||||
)
|
||||
|
||||
for relative, source in (
|
||||
("scripts/smoke-local.sh", smoke_local),
|
||||
("test-infrastructure/vm/vm-smoke.sh", vm_smoke),
|
||||
@@ -89,31 +127,7 @@ for relative, source in (
|
||||
'wait "$SERVER_PID"' in source,
|
||||
f"{relative} cleanup must reap the fixture-server process",
|
||||
)
|
||||
for variable in (
|
||||
"CLAUDE_CONFIG_DIR",
|
||||
"CODEX_HOME",
|
||||
"KIRO_HOME",
|
||||
"HERMES_HOME",
|
||||
"QWEN_HOME",
|
||||
"CLINE_DATA_DIR",
|
||||
"OPENCLAW_HOME",
|
||||
"OPENCLAW_STATE_DIR",
|
||||
"OPENCLAW_PROFILE",
|
||||
"OPENCLAW_CONFIG_PATH",
|
||||
"OPENCLAW_WORKSPACE_DIR",
|
||||
"OPENCODE_CONFIG",
|
||||
"OPENCODE_CONFIG_DIR",
|
||||
"COPILOT_HOME",
|
||||
"CRUSH_GLOBAL_CONFIG",
|
||||
"VIBE_HOME",
|
||||
"GLAB_CONFIG_DIR",
|
||||
"KIMI_CODE_HOME",
|
||||
"CBM_CONTINUE_CONFIG_PATH",
|
||||
"CBM_TRAE_CONFIG_PATH",
|
||||
"CBM_ROO_CONFIG_PATH",
|
||||
"CBM_CODY_CONFIG_PATH",
|
||||
"CBM_TEST_WINDOWS_USER_PATH_RUN_ID",
|
||||
):
|
||||
for variable in CLIENT_HOME_OVERRIDES + ("CBM_TEST_WINDOWS_USER_PATH_RUN_ID",):
|
||||
require(
|
||||
f"-u {variable}" in source,
|
||||
f"{relative} must neutralize ambient {variable}",
|
||||
|
||||
Reference in New Issue
Block a user