Files
deepseek-harness/apps/desktop/tests/windows-runner-network.ps1
T

118 lines
6.8 KiB
PowerShell

# Isolated proxy fixture; no external requests, runner registration or signing hardware.
param([switch]$CheckStartup)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot '../scripts/windows-runner-network.ps1')
$root = Join-Path ([IO.Path]::GetTempPath()) ('dsh-network-' + [guid]::NewGuid().ToString('N'))
$null = New-Item -ItemType Directory -Path $root
$null = New-Item -ItemType Directory -Path (Join-Path $root 'tools')
$pwshLink = Join-Path $root 'tools/pwsh-7.6.6'
if ($CheckStartup) { $null = New-Item -ItemType Junction -Path $pwshLink -Target $PSHOME }
$server = $null
$saved = @{}
foreach ($name in @('HTTP_PROXY','HTTPS_PROXY','NO_PROXY','NODE_USE_ENV_PROXY')) { $saved[$name] = [Environment]::GetEnvironmentVariable($name,'Process') }
try {
if ($null -ne (Read-RunnerNetwork $root)) { throw 'Absent configuration changed behavior.' }
$fixture = Join-Path $root 'proxy.cjs'
@'
const http = require('node:http');
const fs = require('node:fs');
const path = require('node:path');
const root = process.argv[2];
const server = http.createServer((req, res) => {
fs.appendFileSync(path.join(root, 'requests'), req.method + ' ' + req.url + '\n');
if (req.url.includes('/hang')) return;
res.writeHead(req.url.includes('/fail') ? 503 : 200);
res.end();
});
server.on('connect', (req, socket) => {
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
server.emit('connection', socket);
});
server.listen(0, '127.0.0.1', () => fs.writeFileSync(path.join(root, 'port'), String(server.address().port)));
'@ | Set-Content -LiteralPath $fixture
$info = [Diagnostics.ProcessStartInfo]::new((Get-Command node).Source)
$info.UseShellExecute = $false
$info.CreateNoWindow = $true
$info.ArgumentList.Add($fixture)
$info.ArgumentList.Add($root)
$server = [Diagnostics.Process]::Start($info)
$deadline = [DateTime]::UtcNow.AddSeconds(30)
while (-not (Test-Path (Join-Path $root 'port'))) {
if ($server.HasExited -or [DateTime]::UtcNow -gt $deadline) { throw 'Proxy fixture did not become ready.' }
Start-Sleep -Milliseconds 50
}
$port = Get-Content (Join-Path $root 'port') -Raw
$config = @{proxyUrl="http://127.0.0.1:$port";noProxy='';serviceName='';probeUrl='http://runner-probe.invalid/ready';attempts=2;timeoutSeconds=2;retrySeconds=1}
function Write-Config { $config | ConvertTo-Json | Set-Content (Join-Path $root 'runner-network.json') }
Write-Config
$parsed = Read-RunnerNetwork $root
Set-RunnerNetwork $parsed
Wait-RunnerNetwork $parsed
if ($env:NODE_USE_ENV_PROXY -ne '1' -or $env:HTTP_PROXY -ne $config.proxyUrl -or $env:HTTPS_PROXY -ne $config.proxyUrl) { throw 'Proxy environment was not applied.' }
# Full startup requires the operator's installed packaging toolchain and persistent PATH.
if ($CheckStartup) {
$output = & (Join-Path $PSHOME 'pwsh.exe') -NoProfile -File (Join-Path $PSScriptRoot '../scripts/start-windows-packaging-runner.ps1') -RunnerRoot $root -ConfigRoot $root -CheckOnly 2>&1 | Out-String
if ($LASTEXITCODE -ne 0 -or -not $output.Contains('Runner network dependency ready')) { throw "Startup integration failed: $output" }
if ((Get-Content (Join-Path $root 'requests')).Count -ne 2) { throw 'Startup did not reach the configured proxy.' }
Clear-Content (Join-Path $root 'requests')
Wait-RunnerNetwork $parsed
}
$config.probeUrl = 'http://runner-probe.invalid/fail'
Write-Config
$failed = $false
try { Wait-RunnerNetwork (Read-RunnerNetwork $root) } catch { $failed = $_.Exception.Message.StartsWith('Runner network dependency unavailable;') }
if (-not $failed -or (Get-Content (Join-Path $root 'requests')).Count -ne 3) { throw 'Failed readiness did not stop at its budget.' }
$config.serviceName = 'fixture-service'
$config.probeUrl = 'http://runner-probe.invalid/ready'
$script:serviceChecks = 0
function Get-Service {
param($Name)
$script:serviceChecks++
[pscustomobject]@{ Status = if ($script:serviceChecks -eq 1) { 'Stopped' } else { 'Running' } }
}
try {
Wait-RunnerNetwork $config
if ($script:serviceChecks -ne 2 -or (Get-Content (Join-Path $root 'requests')).Count -ne 4) { throw 'Service readiness did not contain probes.' }
function Get-Service { throw 'fake-secret' }
$failure = $null
try { Wait-RunnerNetwork $config } catch { $failure = $_ }
if (-not $failure -or $failure.ToString().Contains('fake-secret') -or (Get-Content (Join-Path $root 'requests')).Count -ne 4) { throw 'Missing service was not contained.' }
} finally { Remove-Item Function:Get-Service }
$config.serviceName = ''
$config.proxyUrl = 'http://127.0.0.1:1'
$config.noProxy = '127.0.0.1'
$config.probeUrl = "http://127.0.0.1:$port/ready"
Set-RunnerNetwork $config
Wait-RunnerNetwork $config
if ((Get-Content (Join-Path $root 'requests')).Count -ne 5) { throw 'NO_PROXY did not bypass the unavailable proxy.' }
$config.probeUrl = "http://127.0.0.1:$port/hang"
$config.attempts = 1
$config.timeoutSeconds = 1
$failure = $null
try { Wait-RunnerNetwork $config } catch { $failure = $_ }
if (-not $failure -or (Get-Content (Join-Path $root 'requests')).Count -ne 6) { throw 'Unresponsive endpoint did not terminate its probe.' }
foreach ($invalid in @('extra','credential','budget','type','wildcard','malformed')) {
$bad = $config.Clone()
switch ($invalid) {
'extra' { $bad.unknown = 'invalid' }
'credential' { $bad.proxyUrl = 'http://fake-secret:fake-secret@localhost:1' }
'budget' { $bad.attempts = 0 }
'type' { $bad.retrySeconds = '2' }
'wildcard' { $bad.serviceName = '*' }
}
$json = if ($invalid -eq 'malformed') { '{fake-secret' } else { $bad | ConvertTo-Json }
$json | Set-Content (Join-Path $root 'runner-network.json')
$failure = $null
try { $null = Read-RunnerNetwork $root } catch { $failure = $_ }
if (-not $failure -or $failure.ToString().Contains('fake-secret')) { throw 'Invalid configuration accepted or disclosed.' }
}
Write-Output "PASS: absent config, proxy routing, Node proxy opt-in, service readiness, bounded failure and redacted invalid config; startup integration=$CheckStartup."
} finally {
foreach ($name in $saved.Keys) { [Environment]::SetEnvironmentVariable($name,$saved[$name],'Process') }
if ($server) { if (-not $server.HasExited) { $server.Kill($true); $server.WaitForExit() }; $server.Dispose() }
if ($CheckStartup) { [IO.Directory]::Delete($pwshLink) }
if ([IO.Path]::GetDirectoryName([IO.Path]::GetFullPath($root)).TrimEnd('\') -ne [IO.Path]::GetTempPath().TrimEnd('\')) { throw 'Fixture cleanup escaped the temporary directory.' }
Remove-Item -LiteralPath $root -Recurse -Force
}
exit 0