parent
6312f067cd
commit
ac2cf1dbd1
|
|
@ -0,0 +1,88 @@
|
|||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const { execFileMock, execFileAsyncMock } = vi.hoisted(() => ({
|
||||
execFileMock: vi.fn(),
|
||||
execFileAsyncMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('child_process', () => {
|
||||
const execFileWithPromisify = Object.assign(execFileMock, {
|
||||
[Symbol.for('nodejs.util.promisify.custom')]: execFileAsyncMock
|
||||
})
|
||||
return {
|
||||
execFile: execFileWithPromisify,
|
||||
spawn: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
import { detectWslCommandsOnPath } from './preflight-wsl-agent-detection'
|
||||
|
||||
function lastShCommandPayload(): string {
|
||||
const call = execFileAsyncMock.mock.calls.at(-1)
|
||||
expect(call).toBeDefined()
|
||||
const [file, args] = call as [string, string[]]
|
||||
expect(file).toBe('wsl.exe')
|
||||
// args: [...distroArgs, '--', 'sh', '-c', <payload>]
|
||||
return args.at(-1) as string
|
||||
}
|
||||
|
||||
describe('detectWslCommandsOnPath', () => {
|
||||
beforeEach(() => {
|
||||
execFileAsyncMock.mockReset()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('builds a probe script with no `fi done` (zsh parse error) sequence', async () => {
|
||||
execFileAsyncMock.mockResolvedValue({ stdout: '', stderr: '' })
|
||||
|
||||
await detectWslCommandsOnPath({ distro: 'Ubuntu' }, ['claude'])
|
||||
|
||||
const payload = lastShCommandPayload()
|
||||
// Why: zsh aborts on `fi done` — the loop body and `done` must be separated
|
||||
// by a newline. Regression guard for issue #5325.
|
||||
expect(payload).not.toContain('fi done')
|
||||
expect(payload).toContain('fi\ndone')
|
||||
})
|
||||
|
||||
it('parses detected commands from prefixed stdout', async () => {
|
||||
execFileAsyncMock.mockResolvedValue({
|
||||
stdout:
|
||||
'__ORCA_AGENT_PATH__claude\t/usr/bin/claude\n' +
|
||||
'__ORCA_AGENT_PATH__codex\t/home/user/.local/bin/codex\n',
|
||||
stderr: ''
|
||||
})
|
||||
|
||||
const found = await detectWslCommandsOnPath({ distro: 'Ubuntu' }, ['claude', 'codex'])
|
||||
|
||||
expect(found).toEqual(new Set(['claude', 'codex']))
|
||||
})
|
||||
|
||||
it('ignores commands whose resolved path is not absolute', async () => {
|
||||
execFileAsyncMock.mockResolvedValue({
|
||||
stdout: '__ORCA_AGENT_PATH__claude\tclaude\n',
|
||||
stderr: ''
|
||||
})
|
||||
|
||||
const found = await detectWslCommandsOnPath({ distro: 'Ubuntu' }, ['claude'])
|
||||
|
||||
expect(found).toEqual(new Set())
|
||||
})
|
||||
|
||||
it('returns an empty set when the probe fails (e.g. shell parse error)', async () => {
|
||||
execFileAsyncMock.mockRejectedValue(new Error("zsh:1: parse error near `done'"))
|
||||
|
||||
const found = await detectWslCommandsOnPath({ distro: 'Ubuntu' }, ['claude'])
|
||||
|
||||
expect(found).toEqual(new Set())
|
||||
})
|
||||
|
||||
it('skips the probe entirely when no commands are requested', async () => {
|
||||
const found = await detectWslCommandsOnPath({ distro: 'Ubuntu' }, [])
|
||||
|
||||
expect(found).toEqual(new Set())
|
||||
expect(execFileAsyncMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
|
@ -24,13 +24,17 @@ export async function detectWslCommandsOnPath(
|
|||
}
|
||||
|
||||
const commandList = uniqueCommands.map(shellQuote).join(' ')
|
||||
// Why: join with newlines, not spaces. zsh treats `fi done` as a parse error
|
||||
// (it needs a separator before `done`); the login shell may be zsh, so a
|
||||
// space-joined script silently fails for every agent. Newlines are valid
|
||||
// statement separators in every POSIX shell and zsh.
|
||||
const script = [
|
||||
`for cmd in ${commandList}; do`,
|
||||
'if resolved=$(command -v "$cmd" 2>/dev/null); then',
|
||||
`printf '${WSL_AGENT_DETECTION_PREFIX}%s\\t%s\\n' "$cmd" "$resolved";`,
|
||||
'fi',
|
||||
'done'
|
||||
].join(' ')
|
||||
].join('\n')
|
||||
|
||||
try {
|
||||
// Why: WSL cold-start plus many parallel wsl.exe probes can timeout and
|
||||
|
|
|
|||
Loading…
Reference in New Issue