mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 02:27:43 +00:00
* test: preserve ready PR guards under draft admission policy * test: use activation tab contract in mirror overlap proof * test: replace copied IPC inventories with registration lifecycle proof * fix: combine duplicate host imports to restore lint gate * test: remove preflight filter duplicate with stronger resolver proof --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
281 lines
11 KiB
TypeScript
281 lines
11 KiB
TypeScript
import { mkdir, mkdtemp, readFile, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import path from 'node:path'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { removeTree } from '../../shared/windows-transient-lock-removal'
|
|
import {
|
|
execLocalPreflightCommandOrThrow,
|
|
findRunnableLocalCommand,
|
|
isCommandAvailable,
|
|
isCommandOnPath,
|
|
shellQuote
|
|
} from './preflight-command-exec'
|
|
|
|
const COMMAND = 'orca-22975-gh'
|
|
const BROKEN_SHIM = 'echo broken-shim >&2\nexit 126\n'
|
|
let root = ''
|
|
|
|
async function cliInDirectory(label: string, body = 'echo gh-version-fixture\n'): Promise<string> {
|
|
const dir = path.join(root, label)
|
|
await mkdir(dir, { recursive: true })
|
|
await writeFile(
|
|
path.join(dir, COMMAND),
|
|
`#!/bin/sh\nprintf '%s\\n' "$@" >> ${shellQuote(path.join(dir, 'argv.txt'))}\n${body}`,
|
|
{ mode: 0o755 }
|
|
)
|
|
return dir
|
|
}
|
|
|
|
async function probedArgs(dir: string): Promise<string[]> {
|
|
try {
|
|
return (await readFile(path.join(dir, 'argv.txt'), 'utf8')).split('\n').filter(Boolean)
|
|
} catch (error) {
|
|
if (typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') {
|
|
return []
|
|
}
|
|
throw error
|
|
}
|
|
}
|
|
|
|
describe.skipIf(process.platform === 'win32')(
|
|
'local CLI version probes with real processes',
|
|
() => {
|
|
beforeEach(async () => {
|
|
root = await mkdtemp(path.join(tmpdir(), 'orca-22975-case-'))
|
|
vi.stubEnv('HOME', root)
|
|
})
|
|
|
|
afterEach(async () => {
|
|
vi.unstubAllEnvs()
|
|
await removeTree(root)
|
|
})
|
|
|
|
it('detects a runnable copy behind an executable shim that exits 126', async () => {
|
|
const shim = await cliInDirectory('shim', BROKEN_SHIM)
|
|
const good = await cliInDirectory('good')
|
|
vi.stubEnv('PATH', [shim, good].join(path.delimiter))
|
|
|
|
await expect(isCommandOnPath(COMMAND)).resolves.toBe(true)
|
|
await expect(
|
|
execLocalPreflightCommandOrThrow(path.join(shim, COMMAND), ['--version'])
|
|
).rejects.toMatchObject({ code: 126, stderr: 'broken-shim\n' })
|
|
await expect(
|
|
execLocalPreflightCommandOrThrow(path.join(good, COMMAND), ['--version'])
|
|
).resolves.toMatchObject({ stdout: 'gh-version-fixture\n' })
|
|
await expect(isCommandAvailable(COMMAND)).resolves.toBe(true)
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(good, COMMAND)
|
|
})
|
|
})
|
|
|
|
it('keeps PATH order and leaves later copies unprobed when the first works', async () => {
|
|
const first = await cliInDirectory('first')
|
|
const second = await cliInDirectory('second')
|
|
vi.stubEnv('PATH', [first, second].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(first, COMMAND)
|
|
})
|
|
expect(await probedArgs(first)).toEqual(['--version'])
|
|
expect(await probedArgs(second)).toEqual([])
|
|
})
|
|
|
|
it('keeps the full timeout for a healthy first copy when other copies exist', async () => {
|
|
const first = await cliInDirectory('slow-first', '/bin/sleep 2\necho gh-version-fixture\n')
|
|
const second = await cliInDirectory('broken-second', BROKEN_SHIM)
|
|
const third = await cliInDirectory('broken-third', BROKEN_SHIM)
|
|
vi.stubEnv('PATH', [first, second, third].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(first, COMMAND)
|
|
})
|
|
expect(await probedArgs(second)).toEqual([])
|
|
expect(await probedArgs(third)).toEqual([])
|
|
})
|
|
|
|
it('distinguishes exhausted failing copies from an absent command', async () => {
|
|
const first = await cliInDirectory('first', BROKEN_SHIM)
|
|
const second = await cliInDirectory('second', BROKEN_SHIM)
|
|
vi.stubEnv('PATH', [first, second].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'exec_failed',
|
|
binary: path.join(second, COMMAND)
|
|
})
|
|
await expect(findRunnableLocalCommand('orca-22975-absent-cli')).resolves.toEqual({
|
|
status: 'absent'
|
|
})
|
|
expect(await probedArgs(first)).toEqual(['--version'])
|
|
expect(await probedArgs(second)).toEqual(['--version'])
|
|
})
|
|
|
|
it('never substitutes another binary for an explicit failing path', async () => {
|
|
const shim = await cliInDirectory('shim', BROKEN_SHIM)
|
|
const good = await cliInDirectory('good')
|
|
vi.stubEnv('PATH', good)
|
|
const selected = path.join(shim, COMMAND)
|
|
|
|
await expect(findRunnableLocalCommand(selected)).resolves.toEqual({
|
|
status: 'exec_failed',
|
|
binary: selected
|
|
})
|
|
expect(await probedArgs(good)).toEqual([])
|
|
})
|
|
|
|
it('executes relative explicit paths and reports an explicit missing path', async () => {
|
|
const good = await cliInDirectory('good')
|
|
const selected = path.relative(process.cwd(), path.join(good, COMMAND))
|
|
vi.stubEnv('PATH', '')
|
|
|
|
await expect(findRunnableLocalCommand(selected)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: selected
|
|
})
|
|
await expect(findRunnableLocalCommand(path.join(root, 'missing', COMMAND))).resolves.toEqual({
|
|
status: 'absent'
|
|
})
|
|
})
|
|
|
|
it.each([true, false])(
|
|
'preserves relative PATH order with shim first: %s',
|
|
async (shimFirst) => {
|
|
const good = await cliInDirectory('good')
|
|
const shim = await cliInDirectory('shim', BROKEN_SHIM)
|
|
const relative = path.relative(process.cwd(), good)
|
|
vi.stubEnv('PATH', (shimFirst ? [shim, relative] : [relative, shim]).join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(good, COMMAND)
|
|
})
|
|
expect(await probedArgs(good)).toEqual(['--version'])
|
|
expect(await probedArgs(shim)).toEqual(shimFirst ? ['--version'] : [])
|
|
}
|
|
)
|
|
|
|
it('deduplicates PATH entries before spending the probe limit', async () => {
|
|
const shim = await cliInDirectory('shim', BROKEN_SHIM)
|
|
const good = await cliInDirectory('good')
|
|
vi.stubEnv('PATH', [shim, shim, shim, shim, good].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(good, COMMAND)
|
|
})
|
|
expect(await probedArgs(shim)).toEqual(['--version'])
|
|
})
|
|
|
|
it('caps execution at four distinct candidates and reports the limit', async () => {
|
|
const doomed: string[] = []
|
|
for (const index of [0, 1, 2, 3]) {
|
|
doomed.push(await cliInDirectory(`doomed-${index}`, BROKEN_SHIM))
|
|
}
|
|
const good = await cliInDirectory('past-cap')
|
|
vi.stubEnv('PATH', [...doomed, good].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'limit_reached',
|
|
binary: path.join(doomed[3], COMMAND)
|
|
})
|
|
for (const dir of doomed) {
|
|
expect(await probedArgs(dir)).toEqual(['--version'])
|
|
}
|
|
expect(await probedArgs(good)).toEqual([])
|
|
})
|
|
|
|
it('recovers a working copy after a real launcher timeout', async () => {
|
|
const marker = path.join(root, 'descendant-terminated')
|
|
const childScript = `trap ${shellQuote(`printf terminated > ${shellQuote(marker)}; exit 0`)} TERM\n/bin/sleep 30 &\nwait\n`
|
|
const hung = await cliInDirectory('hung', `/bin/sh -c ${shellQuote(childScript)} &\nwait\n`)
|
|
const good = await cliInDirectory('good')
|
|
vi.stubEnv('PATH', [hung, good].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(good, COMMAND)
|
|
})
|
|
expect(await probedArgs(hung)).toEqual(['--version'])
|
|
expect(await probedArgs(good)).toEqual(['--version'])
|
|
expect(await readFile(marker, 'utf8')).toBe('terminated')
|
|
}, 15_000)
|
|
|
|
it('uses the known Nix install directory after PATH copies fail', async () => {
|
|
const shim = await cliInDirectory('shim', BROKEN_SHIM)
|
|
const profile = await cliInDirectory(path.join('.nix-profile', 'bin'))
|
|
vi.stubEnv('PATH', shim)
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.join(profile, COMMAND)
|
|
})
|
|
})
|
|
}
|
|
)
|
|
|
|
describe.runIf(process.platform === 'win32')('Windows preflight batch shims', () => {
|
|
beforeEach(async () => {
|
|
root = await mkdtemp(path.join(tmpdir(), 'orca-22975-cmd-'))
|
|
})
|
|
|
|
afterEach(async () => {
|
|
vi.unstubAllEnvs()
|
|
await removeTree(root)
|
|
})
|
|
|
|
it('runs the next cmd shim after an earlier copy exits 126', async () => {
|
|
const first = path.join(root, 'first')
|
|
const second = path.join(root, 'second')
|
|
for (const dir of [first, second]) {
|
|
await mkdir(dir)
|
|
}
|
|
const name = `${COMMAND}.CMD`
|
|
await writeFile(path.join(first, name), '@echo off\r\nexit /b 126\r\n')
|
|
await writeFile(
|
|
path.join(second, name),
|
|
'@echo off\r\necho gh-version-fixture\r\nexit /b 0\r\n'
|
|
)
|
|
vi.stubEnv('PATH', [first, second].join(path.delimiter))
|
|
vi.stubEnv('Path', [first, second].join(path.delimiter))
|
|
|
|
const result = await findRunnableLocalCommand(COMMAND)
|
|
|
|
expect(result).toEqual({ status: 'available', binary: path.posix.join(second, name) })
|
|
if (result.status === 'available') {
|
|
await expect(
|
|
execLocalPreflightCommandOrThrow(result.binary, ['auth', 'status'])
|
|
).resolves.toMatchObject({ stdout: expect.stringContaining('gh-version-fixture') })
|
|
}
|
|
})
|
|
|
|
// Include the probe, tree-cleanup deadline, and recovery probe on a busy Windows runner.
|
|
it('recovers after a hung batch launcher and terminates its Node child', async () => {
|
|
const first = path.join(root, 'hung')
|
|
const second = path.join(root, 'working')
|
|
await mkdir(first)
|
|
await mkdir(second)
|
|
const name = `${COMMAND}.CMD`
|
|
await writeFile(
|
|
path.join(first, 'hang.js'),
|
|
`require('node:fs').writeFileSync(require('node:path').join(__dirname, 'child.pid'), String(process.pid)); setTimeout(function () {}, 60000);`
|
|
)
|
|
await writeFile(path.join(first, name), `@echo off\r\n"${process.execPath}" "%~dp0hang.js"\r\n`)
|
|
await writeFile(
|
|
path.join(second, name),
|
|
'@echo off\r\necho gh-version-fixture\r\nexit /b 0\r\n'
|
|
)
|
|
vi.stubEnv('PATH', [first, second].join(path.delimiter))
|
|
vi.stubEnv('Path', [first, second].join(path.delimiter))
|
|
|
|
await expect(findRunnableLocalCommand(COMMAND)).resolves.toEqual({
|
|
status: 'available',
|
|
binary: path.posix.join(second, name)
|
|
})
|
|
const childPid = Number(await readFile(path.join(first, 'child.pid'), 'utf8'))
|
|
expect(Number.isSafeInteger(childPid) && childPid > 0).toBe(true)
|
|
expect(() => process.kill(childPid, 0)).toThrow()
|
|
}, 30_000)
|
|
})
|