mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 05:56:37 +01:00
test(windows): spawn cmd.exe hooks verbatim, use a .invalid UNC host, and match CRLF fixtures and native separators
windows-free-tests reds on 364f0f3, each verified on windows-latest
(46 pass, 1 POSIX-only skip, 0 fail):
- investigate-freeze-path cmd.exe cases: Bun MSVC-quoted the command line
cmd.exe parses, so cmd saw \"bash and failed; Node's shell spawn (what
Claude Code uses) passes it verbatim.
- investigate-freeze-path UNC cases: a single-label host made each
filesystem probe wait on network name resolution (cd 11 s, -L 2.8 s);
a reserved .invalid host fails at once (55-80 ms).
- paid-report-census: the junit fixture is CRLF in a Windows checkout.
- codex-invocation-sites: rendered paths use backslashes on Windows.
This commit is contained in:
1 parent
9d37bb4a4f
commit
dfaf15449c
3 files changed
+11
-6
No files matched your search
@@ -53,7 +53,7 @@ function render(host: string): string[] {
|
||||
}
|
||||
|
||||
describe('every rendered Codex invocation is classified by the shared validator', () => {
|
||||
const rendered = Object.fromEntries(['claude', 'codex'].map(host => [host, render(host).flatMap(f => codexSites(fs.readFileSync(f, 'utf8'), path.relative(TMP, f)))]));
|
||||
const rendered = Object.fromEntries(['claude', 'codex'].map(host => [host, render(host).flatMap(f => codexSites(fs.readFileSync(f, 'utf8'), path.relative(TMP, f).split(path.sep).join('/')))]));
|
||||
|
||||
test('the Claude render has the expected invocation sites', () => {
|
||||
const files = new Set(rendered.claude!.map(s => s.file.replace(/^claude\//, '')));
|
||||
|
||||
@@ -80,9 +80,11 @@ describe('E1: freeze boundary and target share one platform-aware normalization
|
||||
['C:\\dev\\proj\\src\\', 'C:\\dev\\proj\\src-old\\a.py', 'deny'],
|
||||
['C:\\dev\\proj\\src\\', 'D:\\dev\\proj\\src\\a.py', 'deny'],
|
||||
['C:\\dev\\proj\\src\\', 'C:\\dev\\proj\\other\\missing\\a.py', 'deny'],
|
||||
['\\\\server\\share\\proj\\', '\\\\server\\share\\proj\\a.py', 'allow'],
|
||||
['\\\\server\\share\\proj\\', '\\\\server\\other\\proj\\a.py', 'deny'],
|
||||
['\\\\server\\share\\proj\\', '/server/share/proj/a.py', 'deny'],
|
||||
// A reserved .invalid host fails name resolution at once; a single-label
|
||||
// host makes Windows probe the network for ~10 s per filesystem call.
|
||||
['\\\\server.invalid\\share\\proj\\', '\\\\server.invalid\\share\\proj\\a.py', 'allow'],
|
||||
['\\\\server.invalid\\share\\proj\\', '\\\\server.invalid\\other\\proj\\a.py', 'deny'],
|
||||
['\\\\server.invalid\\share\\proj\\', '/server.invalid/share/proj/a.py', 'deny'],
|
||||
])('boundary %s, target %s → %s', (boundary, target, expected) => {
|
||||
expect(freezeDecision(boundary, target)).toBe(expected);
|
||||
});
|
||||
@@ -196,10 +198,13 @@ describe('E1: registered hook commands run under cmd.exe and POSIX sh (#2354)',
|
||||
for (const [label, argv] of shells) {
|
||||
test(`${rel} hook #${i + 1} reaches a decision via ${label}`, () => {
|
||||
withInstalledHome((home) => withState(path.join(home, 'frozen'), (env) => {
|
||||
// Claude Code hands cmd.exe its command line verbatim (Node's shell
|
||||
// spawn); MSVC-quoting it would escape the inner quotes cmd.exe reads.
|
||||
const r = Bun.spawnSync(argv(home), {
|
||||
stdin: Buffer.from(JSON.stringify(input)),
|
||||
env: { ...env, HOME: home },
|
||||
timeout: 15_000,
|
||||
windowsVerbatimArguments: IS_WIN,
|
||||
});
|
||||
expect(r.exitCode, r.stderr.toString()).toBe(0);
|
||||
expect(decision(r.stdout.toString())).toBe(expected);
|
||||
|
||||
@@ -74,8 +74,8 @@ describe('census attribution from the 2026-10-03 artifacts', () => {
|
||||
const qa = junit(dir, 'skill-e2e-qa-workflow');
|
||||
fs.writeFileSync(qa, fs.readFileSync(qa, 'utf8').replace(/(<testcase name="qa-fix-loop"[^>]*?) \/>/, '$1><skipped /></testcase>'));
|
||||
const cso = junit(dir, 'skill-e2e-cso');
|
||||
fs.writeFileSync(cso, fs.readFileSync(cso, 'utf8').replace('</testsuite>\n</testsuites>',
|
||||
'<testcase name="an unlabeled helper" classname="CSO v3" time="1" file="test/skill-e2e-cso.test.ts" line="9" />\n</testsuite>\n</testsuites>'));
|
||||
fs.writeFileSync(cso, fs.readFileSync(cso, 'utf8').replace(/<\/testsuite>(\r?\n)<\/testsuites>/,
|
||||
'<testcase name="an unlabeled helper" classname="CSO v3" time="1" file="test/skill-e2e-cso.test.ts" line="9" />$1</testsuite>$1</testsuites>'));
|
||||
});
|
||||
expect(r.status, r.out).toBe(0);
|
||||
expect(r.out).toContain(' SKIPPED 1 · INFRA 0 · INCOMPLETE 0 · unattributed 1 · ACTION REQUIRED 0');
|
||||
|
||||
Reference in new issue
Block a user