From 4c335c91332042b1024802fa619522eac107e244 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sun, 16 Aug 2026 15:23:42 -0700 Subject: [PATCH] =?UTF-8?q?fix(test):=20first=20cross-platform=20run=20of?= =?UTF-8?q?=20the=20wave's=20tests=20=E2=80=94=20Linux=20tmp=20portability?= =?UTF-8?q?=20+=20Windows-lane=20truthfulness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four platform holes from the lanes' first full run over the v1.67 tests: - uninstall neutral-root fallback hardcoded /private/tmp (macOS-only) and ENOENT'd on Linux CI, where the shard TMPDIR is the gstack-containing path that forces the fallback — now realpath'd literal /tmp. - uninstall's kept-and-listed assertion demanded a backslash path on Windows while the bash uninstall prints POSIX paths — now separator-insensitive. - setup-rerun's IS_WINDOWS=0 sub-case and the iron rule's force-restart consent path are Unix-shaped by construction (Git Bash ln -snf copies without Developer Mode; the consent path boots a real replacement daemon the browserless Windows lane cannot host) — gated off win32 with the reasons in place; the Windows-relevant halves still run there. - codex-under-codex-detection drives rendered bash under a hardcoded POSIX PATH, so every case saw empty output on Windows — moved to KNOWN_WINDOWS_INCOMPATIBLE with the run receipt. Co-Authored-By: Claude Fable 5 --- browse/test/busy-daemon-iron-rule.test.ts | 6 ++++++ scripts/test-free-shards.ts | 4 ++++ test/setup-windows-rerun-refresh.test.ts | 5 +++++ test/uninstall-windows-copies.test.ts | 10 ++++++++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/browse/test/busy-daemon-iron-rule.test.ts b/browse/test/busy-daemon-iron-rule.test.ts index e34acbac8..53149cb31 100644 --- a/browse/test/busy-daemon-iron-rule.test.ts +++ b/browse/test/busy-daemon-iron-rule.test.ts @@ -177,6 +177,12 @@ describe('#2219 iron rule (CLI integration)', () => { }, 45_000); test('wedged-alive daemon + --force-restart IS killed (explicit consent path)', async () => { + // Unix lanes only: the consent path must boot a REAL replacement daemon + // to answer the command, which the secretless/browserless Windows lane + // cannot do (no Chromium install), and the teardown relies on setsid + // process-group semantics Windows lacks. The Windows-relevant half of + // the iron rule — busy → refusal, never an implicit kill — runs above. + if (process.platform === 'win32') return; const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'browse-iron-')); const stateFile = path.join(tmpDir, 'browse.json'); const daemon = await startWedgedDaemon(); diff --git a/scripts/test-free-shards.ts b/scripts/test-free-shards.ts index dbc9186a5..140eac361 100755 --- a/scripts/test-free-shards.ts +++ b/scripts/test-free-shards.ts @@ -169,6 +169,10 @@ export const KNOWN_WINDOWS_INCOMPATIBLE: Array<{ file: string; reason: string }> // seven POSIX-bound files the content patterns cannot see (their // POSIX-ness is what they TEST, or arrives via a variable). Receipts: // PR #2593 windows-free-tests run 31918591602. + { + file: 'test/codex-under-codex-detection.test.ts', + reason: 'drives the rendered preflight bash under a hardcoded POSIX PATH (/usr/bin:/bin) — bash is unreachable through that PATH on Windows, so every case sees empty output (v1.67 windows lane run 95234224148)', + }, { file: 'test/regression-pr1169-build-app-sed.test.ts', reason: 'tests sed escape sequences in build-app.sh — sed/bash are the subject under test', diff --git a/test/setup-windows-rerun-refresh.test.ts b/test/setup-windows-rerun-refresh.test.ts index 60158f729..6c60ad47c 100644 --- a/test/setup-windows-rerun-refresh.test.ts +++ b/test/setup-windows-rerun-refresh.test.ts @@ -274,6 +274,11 @@ describe('setup: Windows re-run refresh — behavior fixture (#2444)', () => { // On Unix the asset is a SYMLINK into the working tree; pruning through // it would delete real build output from the repo. The prune is gated on // the Windows real-copy shape ([ -d ] && [ ! -L ]). + // Not runnable ON Windows: this sub-case models the UNIX shape, but Git + // Bash's `ln -snf` produces a real copy there (no Developer Mode on CI), + // so the symlink assertion is false by platform, not by regression. The + // Unix lanes (macOS dev boxes + Linux CI) own this case. + if (process.platform === 'win32') return; const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-rerun-prune-unix-')); try { const src = path.join(tmp, 'skill-src'); diff --git a/test/uninstall-windows-copies.test.ts b/test/uninstall-windows-copies.test.ts index 056511bf6..3e2caa699 100644 --- a/test/uninstall-windows-copies.test.ts +++ b/test/uninstall-windows-copies.test.ts @@ -111,7 +111,9 @@ describe('gstack-uninstall removes Windows real-dir copies (#2563)', () => { expect(r.status).toBe(0); expect(fs.existsSync(usersOwn)).toBe(true); expect(fs.readFileSync(path.join(usersOwn, 'SKILL.md'), 'utf-8')).toContain('name: ship'); - expect(r.stderr).toContain(path.join('skills', 'ship')); + // Separator-insensitive: the bash uninstall prints POSIX paths even on + // Windows (Git Bash), where path.join would demand a backslash. + expect(r.stderr.replace(/\\/g, '/')).toContain('skills/ship'); }); test('real dir without any SKILL.md is untouched and unlisted', () => { @@ -206,7 +208,11 @@ describe.skipIf(process.platform === 'win32')( // the test's own expectations). Fall back to a fixed neutral root and // ASSERT neutrality so the precondition can never silently rot. let neutralRoot = os.tmpdir(); - if (neutralRoot.includes('gstack')) neutralRoot = '/private' + path.sep + 'tmp'; + // realpath'd literal /tmp: /private/tmp on macOS, /tmp on Linux. The + // hardcoded '/private/tmp' fallback ENOENT'd on Linux CI, where the + // shard runner's TMPDIR is the gstack-containing path that forces this + // branch. (Never taken on Windows — its TMPDIR carries no 'gstack'.) + if (neutralRoot.includes('gstack')) neutralRoot = fs.realpathSync('/tmp'); const neutral = fs.mkdtempSync(path.join(neutralRoot, 'other-skill-src-')); expect(neutral.includes('gstack')).toBe(false); const elsewhere = path.join(neutral, 'elsewhere.md');