test(setup): cover Windows forward-slash sequencing (#13557)

Co-authored-by: OrcaWin <alpha-eng@stably.ai>
This commit is contained in:
Brennan Benson
2026-08-11 13:28:28 -07:00
committed by GitHub
co-authored by OrcaWin
parent e05c7f1625
commit d35fcc9e1c
2 changed files with 107 additions and 92 deletions
+3 -1
View File
@@ -20,6 +20,7 @@ import {
} from './setup-agent-startup-policy'
const TEMP_DIRS: string[] = []
const WINDOWS_PROCESS_TEST_TIMEOUT_MS = 30_000
afterEach(() => {
for (const dir of TEMP_DIRS.splice(0)) {
@@ -330,7 +331,8 @@ describe('createSequencedSetupAgentCommands', () => {
expect(startupExit.code).toBe(0)
expect(startupExit.stderr).toContain('Waiting for setup to finish before starting agent...')
expect(readFileSync(logPath, 'utf8')).toBe('setup-done\r\nagent-start\r\n')
}
},
WINDOWS_PROCESS_TEST_TIMEOUT_MS
)
it.skipIf(process.platform === 'win32')(
+104 -91
View File
@@ -11,6 +11,7 @@ import {
} from './setup-agent-sequencing'
const TEMP_DIRS: string[] = []
const WINDOWS_PROCESS_TEST_TIMEOUT_MS = 30_000
afterEach(() => {
for (const dir of TEMP_DIRS.splice(0)) {
@@ -20,61 +21,69 @@ afterEach(() => {
describe.skipIf(process.platform !== 'win32')('Windows setup-agent sequencing', () => {
it.each([
'path with spaces',
'ampersand&parentheses(test)',
'caret^percent%bang!',
"apostrophe's directory",
'Unicode-한글-abc'
])('preserves the native runner path in %s', async (directoryName) => {
const tempDir = makeTempDir(directoryName)
const runnerScriptPath = join(tempDir, 'setup runner.cmd')
const startupScriptPath = join(tempDir, 'agent startup.ps1')
const logPath = join(dirname(tempDir), 'sequence.log')
const prompt = 'spaces & pipe | caret ^ percent % bang ! "quotes" Unicode 한글 trailing\\'
['path with spaces', false],
['ampersand&parentheses(test)', false],
['caret^percent%bang!', false],
["apostrophe's directory", false],
['Unicode-한글-abc', false],
['forward-slash Git path', true]
] as const)(
'preserves the native runner path in %s',
async (directoryName, useForwardSlashes) => {
const tempDir = makeTempDir(directoryName)
const nativeRunnerScriptPath = join(tempDir, 'setup runner.cmd')
const runnerScriptPath = useForwardSlashes
? nativeRunnerScriptPath.replaceAll('\\', '/')
: nativeRunnerScriptPath
const startupScriptPath = join(tempDir, 'agent startup.ps1')
const logPath = join(dirname(tempDir), 'sequence.log')
const prompt = 'spaces & pipe | caret ^ percent % bang ! "quotes" Unicode 한글 trailing\\'
writeFileSync(
runnerScriptPath,
['@echo off', `>> "${logPath}" echo setup-done`, 'exit /b 0'].join('\r\n'),
'utf8'
)
writeFileSync(
startupScriptPath,
[
'param([string]$Value)',
'$utf8 = [System.Text.UTF8Encoding]::new($false)',
`[System.IO.File]::AppendAllText('${quotePowerShell(logPath)}', $Value + [Environment]::NewLine, $utf8)`
].join('\r\n'),
'utf8'
)
const commands = createSequencedSetupAgentCommands({
runnerScriptPath,
startupCommand: `& '${quotePowerShell(startupScriptPath)}' '${quotePowerShell(prompt)}'`,
platform: 'windows',
nonce: 'windows-sequence',
waitTimeoutSeconds: 2
})
const setupExit = await waitForExit(
spawnWindowsCommand(dirname(tempDir), 'run setup.cmd', commands.setupCommand)
)
expect(setupExit.code).toBe(0)
expect(readFileSync(`${runnerScriptPath}.windows-sequence.done`, 'utf8')).toBe(
'windows-sequence:0\r\n'
)
const startupExit = await waitForExit(
spawnWindowsCommand(
dirname(tempDir),
'run startup.cmd',
commands.startupCommand,
commands.startupEnv
writeFileSync(
runnerScriptPath,
['@echo off', `>> "${logPath}" echo setup-done`, 'exit /b 0'].join('\r\n'),
'utf8'
)
)
expect(startupExit.code).toBe(0)
expect(startupExit.stderr).toContain('Waiting for setup to finish before starting agent...')
expect(readFileSync(logPath, 'utf8')).toBe(`setup-done\r\n${prompt}\r\n`)
})
writeFileSync(
startupScriptPath,
[
'param([string]$Value)',
'$utf8 = [System.Text.UTF8Encoding]::new($false)',
`[System.IO.File]::AppendAllText('${quotePowerShell(logPath)}', $Value + [Environment]::NewLine, $utf8)`
].join('\r\n'),
'utf8'
)
const commands = createSequencedSetupAgentCommands({
runnerScriptPath,
startupCommand: `& '${quotePowerShell(startupScriptPath)}' '${quotePowerShell(prompt)}'`,
platform: 'windows',
nonce: 'windows-sequence',
waitTimeoutSeconds: 2
})
const setupExit = await waitForExit(
spawnWindowsCommand(dirname(tempDir), 'run setup.cmd', commands.setupCommand)
)
expect(setupExit.code).toBe(0)
expect(readFileSync(`${runnerScriptPath}.windows-sequence.done`, 'utf8')).toBe(
'windows-sequence:0\r\n'
)
const startupExit = await waitForExit(
spawnWindowsCommand(
dirname(tempDir),
'run startup.cmd',
commands.startupCommand,
commands.startupEnv
)
)
expect(startupExit.code).toBe(0)
expect(startupExit.stderr).toContain('Waiting for setup to finish before starting agent...')
expect(readFileSync(logPath, 'utf8')).toBe(`setup-done\r\n${prompt}\r\n`)
},
WINDOWS_PROCESS_TEST_TIMEOUT_MS
)
it('keeps the startup command out of generated cmd.exe source', () => {
const startupCommand = 'agent --prompt "& | ^ % ! 한글 trailing\\"'
@@ -90,46 +99,50 @@ describe.skipIf(process.platform !== 'win32')('Windows setup-agent sequencing',
expect(commands.startupEnv?.[SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]).toBe(startupCommand)
})
it('propagates setup failure without launching the agent', async () => {
const tempDir = makeTempDir('failure path & metacharacters!')
const runnerScriptPath = join(tempDir, 'setup runner.cmd')
const startupScriptPath = join(tempDir, 'agent startup.cmd')
const startupLogPath = join(dirname(tempDir), 'agent-started.log')
it(
'propagates setup failure without launching the agent',
async () => {
const tempDir = makeTempDir('failure path & metacharacters!')
const runnerScriptPath = join(tempDir, 'setup runner.cmd')
const startupScriptPath = join(tempDir, 'agent startup.cmd')
const startupLogPath = join(dirname(tempDir), 'agent-started.log')
writeFileSync(runnerScriptPath, '@echo off\r\nexit /b 37\r\n', 'utf8')
writeFileSync(
startupScriptPath,
`@echo off\r\necho started>"${startupLogPath}"\r\nexit /b 0\r\n`,
'utf8'
)
const commands = createSequencedSetupAgentCommands({
runnerScriptPath,
startupCommand: `cmd.exe /d /c "${startupScriptPath}"`,
platform: 'windows',
nonce: 'failed-windows-sequence',
waitTimeoutSeconds: 2
})
const setupExit = await waitForExit(
spawnWindowsCommand(dirname(tempDir), 'run failed setup.cmd', commands.setupCommand)
)
expect(setupExit.code).toBe(37)
expect(readFileSync(`${runnerScriptPath}.failed-windows-sequence.done`, 'utf8')).toBe(
'failed-windows-sequence:37\r\n'
)
const startupExit = await waitForExit(
spawnWindowsCommand(
dirname(tempDir),
'run blocked startup.cmd',
commands.startupCommand,
commands.startupEnv
writeFileSync(runnerScriptPath, '@echo off\r\nexit /b 37\r\n', 'utf8')
writeFileSync(
startupScriptPath,
`@echo off\r\necho started>"${startupLogPath}"\r\nexit /b 0\r\n`,
'utf8'
)
)
expect(startupExit.code).toBe(37)
expect(startupExit.stderr).toContain('Setup failed; skipping agent startup.')
expect(existsSync(startupLogPath)).toBe(false)
})
const commands = createSequencedSetupAgentCommands({
runnerScriptPath,
startupCommand: `cmd.exe /d /c "${startupScriptPath}"`,
platform: 'windows',
nonce: 'failed-windows-sequence',
waitTimeoutSeconds: 2
})
const setupExit = await waitForExit(
spawnWindowsCommand(dirname(tempDir), 'run failed setup.cmd', commands.setupCommand)
)
expect(setupExit.code).toBe(37)
expect(readFileSync(`${runnerScriptPath}.failed-windows-sequence.done`, 'utf8')).toBe(
'failed-windows-sequence:37\r\n'
)
const startupExit = await waitForExit(
spawnWindowsCommand(
dirname(tempDir),
'run blocked startup.cmd',
commands.startupCommand,
commands.startupEnv
)
)
expect(startupExit.code).toBe(37)
expect(startupExit.stderr).toContain('Setup failed; skipping agent startup.')
expect(existsSync(startupLogPath)).toBe(false)
},
WINDOWS_PROCESS_TEST_TIMEOUT_MS
)
})
function makeTempDir(directoryName: string): string {