mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
fix(test): strip the instance-selection env vars in test/setup.ts
`test/setup.ts` gives every test file a temp HOME so the suite cannot touch the real Codeman tree, and strips the env vars that would leak past it — but the list only covered auth and the gesture flag. The three vars `src/config/instance.ts` derives the data dir and tmux socket from were missing, and they reach past the temp HOME: - **`CODEMAN_DATA_DIR` is the one that matters.** It is an ABSOLUTE override read in `getDataDir()`, so it bypasses HOME entirely: a developer who exports it — or a shell left over from `codeman web -d` — has the suite reading and WRITING their real `state.json`, `users.json`, `intents.json` and `hook-secret`. - **`CODEMAN_INSTANCE`** moves the data dir to `~/.codeman-<name>` and the socket to `codeman-<name>`. Inside the temp HOME that is not data loss, but it silently changes the paths tests assert on — and `scripts/run-beta.sh` exports it, so any shell that has run a beta carries it. - **`CODEMAN_TMUX_SOCKET`** renames the socket `resolveTmuxSocketName()` returns. `TmuxManager` no-ops its shell commands under vitest, so this is assertion drift rather than a stray `tmux -L` against prod — same class of leak, same one-line fix. They are deleted in the setup file rather than in a hook because `CODEMAN_INSTANCE` is captured into a module-level const the first time `config/instance.ts` is imported; a `beforeEach` would already be too late. `test/test-env-isolation.test.ts` pins the whole list in two halves, because the obvious half is not enough: asserting the vars are unset passes trivially on a machine that never set them, so a removed `delete` line would sail through on almost every box and on CI. The static half reads `setup.ts` and asserts each name is deleted there, which fails everywhere. An anti-drift check catches the other direction — a var stripped in `setup.ts` but never given a reason in the list — and is scoped to the strip section so the teardown's restores are not mistaken for strips. Verified by demonstrating the leak: with the `CODEMAN_DATA_DIR` line removed and the var exported, the runtime assertion fails; with the line restored it passes. Full suite: no new failures against an upstream/master baseline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQkoi1cNegqVwZHgzx5SbJ
This commit is contained in:
+32
-2
@@ -5,8 +5,11 @@
|
||||
* mode before application modules load. Tests therefore cannot touch the real
|
||||
* Codeman state/cases tree or launch external tmux-backed agent sessions.
|
||||
*
|
||||
* This setup file strips shell-level auth configuration that can leak from a
|
||||
* running Codeman instance, then handles mock/timer cleanup between tests.
|
||||
* This setup file strips shell-level configuration that can leak from a running
|
||||
* Codeman instance — auth (`CODEMAN_PASSWORD`/`CODEMAN_USERNAME`), the gesture
|
||||
* flag, and the three INSTANCE-selection vars that would otherwise point the
|
||||
* suite at a real data dir or tmux socket — then handles mock/timer cleanup
|
||||
* between tests.
|
||||
*/
|
||||
|
||||
import { mkdtempSync, rmSync } from 'node:fs';
|
||||
@@ -39,6 +42,33 @@ delete process.env.CODEMAN_USERNAME;
|
||||
// (test/server-index-title.test.ts) when the shell exports CODEMAN_GESTURE=1.
|
||||
delete process.env.CODEMAN_GESTURE;
|
||||
|
||||
// Instance selection is PROCESS-WIDE and is what `src/config/instance.ts` derives
|
||||
// both the data dir and the tmux socket from, so a shell that exports any of these
|
||||
// three reaches straight past the temp HOME above and undoes the isolation this
|
||||
// file exists to provide:
|
||||
//
|
||||
// - CODEMAN_DATA_DIR is the dangerous one. It is an ABSOLUTE override read in
|
||||
// `getDataDir()`, so it bypasses HOME entirely: a developer who exports it
|
||||
// (or a shell left over from `codeman web -d`) has the suite reading and
|
||||
// WRITING their real `state.json`, `users.json`, `intents.json` and
|
||||
// `hook-secret` instead of a throwaway tree.
|
||||
// - CODEMAN_INSTANCE moves the data dir to `~/.codeman-<name>` and the socket to
|
||||
// `codeman-<name>`. Inside the temp HOME that is not a data-loss risk, but it
|
||||
// silently changes the paths tests assert on — and `scripts/run-beta.sh`
|
||||
// exports it, so any shell that has run a beta carries it.
|
||||
// - CODEMAN_TMUX_SOCKET renames the socket `resolveTmuxSocketName()` returns.
|
||||
// `TmuxManager` no-ops its shell commands under vitest, so this is assertion
|
||||
// drift rather than a stray `tmux -L` against prod — but it is the same class
|
||||
// of leak and the same one-line fix.
|
||||
//
|
||||
// ⚠️ These must be deleted HERE rather than in a test, because `CODEMAN_INSTANCE`
|
||||
// is captured into a module-level const the first time `config/instance.ts` is
|
||||
// imported. A setup file runs before any application module loads; a beforeEach
|
||||
// would already be too late.
|
||||
delete process.env.CODEMAN_INSTANCE;
|
||||
delete process.env.CODEMAN_DATA_DIR;
|
||||
delete process.env.CODEMAN_TMUX_SOCKET;
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.useRealTimers();
|
||||
|
||||
Reference in New Issue
Block a user