Public source validation / validate (push) Failing after 3m8s
72 lines
4.4 KiB
PowerShell
72 lines
4.4 KiB
PowerShell
param(
|
|
[ValidateRange(0.01, 168)] [double]$DurationHours = 24,
|
|
[ValidateRange(5, 3600)] [int]$SampleSeconds = 60,
|
|
[ValidateRange(30, 86400)] [int]$ReconnectSeconds = 3600,
|
|
[string]$OutputDirectory = 'artifacts/evidence/M10-14/raw'
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$PSNativeCommandUseErrorActionPreference = $true
|
|
Set-Location (Split-Path -Parent $PSScriptRoot)
|
|
|
|
function Get-FreeLoopbackPort {
|
|
$listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback, 0)
|
|
$listener.Start()
|
|
try { return ([System.Net.IPEndPoint]$listener.LocalEndpoint).Port } finally { $listener.Stop() }
|
|
}
|
|
|
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) { throw 'Docker is required for the isolated wallboard soak.' }
|
|
if (-not (Get-Command node -ErrorAction SilentlyContinue)) { throw 'Node.js is required for the wallboard soak runner.' }
|
|
$goBin = Join-Path $env:LOCALAPPDATA 'ITWorx-Pulse\toolchains\go1.26.6\bin'
|
|
if (-not (Get-Command go -ErrorAction SilentlyContinue) -and (Test-Path (Join-Path $goBin 'go.exe'))) { $env:PATH = $goBin + ';' + $env:PATH }
|
|
|
|
$project = 'itworx-pulse-soak-' + $PID
|
|
$webPort = Get-FreeLoopbackPort
|
|
$apiPort = Get-FreeLoopbackPort
|
|
$dbPort = Get-FreeLoopbackPort
|
|
$baseURL = "http://127.0.0.1:$webPort"
|
|
$compose = @('-p', $project, '-f', 'deploy/compose.yaml', '-f', 'deploy/compose.dev.yaml', '-f', 'deploy/compose.smoke.yaml')
|
|
$resolvedOutput = [System.IO.Path]::GetFullPath((Join-Path (Get-Location) $OutputDirectory))
|
|
if (Test-Path -LiteralPath $resolvedOutput) {
|
|
$existingArtifact = Get-ChildItem -LiteralPath $resolvedOutput -Force | Select-Object -First 1
|
|
if ($existingArtifact) { throw "Refusing to mix soak evidence in non-empty output directory: $resolvedOutput" }
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $resolvedOutput | Out-Null
|
|
$sourceCommit = (git rev-parse HEAD).Trim()
|
|
$sourceDirty = [bool](git status --porcelain)
|
|
|
|
$env:PULSE_POSTGRES_PASSWORD = 'soak-process-only'
|
|
$env:PULSE_DATABASE_URL = 'postgres://pulse:soak-process-only@pulse-postgres:5432/pulse?sslmode=disable'
|
|
$env:PULSE_ENV = 'development'
|
|
$env:PULSE_AUTH_MODE = 'mock'
|
|
$env:PULSE_DEV_WEB_PORT = [string]$webPort
|
|
$env:PULSE_DEV_API_PORT = [string]$apiPort
|
|
$env:PULSE_DEV_DB_PORT = [string]$dbPort
|
|
$env:PULSE_SMOKE_WEBHOOK_TOKEN = 'soak-runtime-only'
|
|
$env:PULSE_SOAK_BASE_URL = $baseURL
|
|
$env:PULSE_SOAK_OUTPUT_DIR = $resolvedOutput
|
|
$env:PULSE_SOAK_DURATION_HOURS = [string]$DurationHours
|
|
$env:PULSE_SOAK_SAMPLE_SECONDS = [string]$SampleSeconds
|
|
$env:PULSE_SOAK_RECONNECT_SECONDS = [string]$ReconnectSeconds
|
|
|
|
try {
|
|
Write-Host "== isolated 24-hour wallboard deployment ($project) ==" -ForegroundColor Cyan
|
|
docker compose @compose config --quiet
|
|
docker compose @compose build --quiet
|
|
docker compose @compose up -d --wait --wait-timeout 240
|
|
docker compose @compose images --format json | Set-Content -Path (Join-Path $resolvedOutput 'launch-images.jsonl') -Encoding utf8
|
|
@{ project = $project; baseURL = $baseURL; startedAt = (Get-Date).ToUniversalTime().ToString('o'); durationHours = $DurationHours; sampleSeconds = $SampleSeconds; reconnectSeconds = $ReconnectSeconds; sourceCommit = $sourceCommit; sourceDirty = $sourceDirty } | ConvertTo-Json | Set-Content -Path (Join-Path $resolvedOutput 'stack.json') -Encoding utf8
|
|
node tools/wallboard-soak.mjs
|
|
if ($LASTEXITCODE -ne 0) { throw 'wallboard soak runner failed' }
|
|
docker compose @compose ps --format json | Set-Content -Path (Join-Path $resolvedOutput 'final-compose-ps.jsonl') -Encoding utf8
|
|
docker compose @compose logs --no-color --timestamps | Set-Content -Path (Join-Path $resolvedOutput 'final-compose.log') -Encoding utf8
|
|
Write-Host 'WALLBOARD SOAK: PASS' -ForegroundColor Green
|
|
} finally {
|
|
if (-not (Test-Path (Join-Path $resolvedOutput 'final-compose.log'))) {
|
|
docker compose @compose ps --format json 2>$null | Set-Content -Path (Join-Path $resolvedOutput 'failure-compose-ps.jsonl') -Encoding utf8
|
|
docker compose @compose logs --no-color --timestamps 2>$null | Set-Content -Path (Join-Path $resolvedOutput 'failure-compose.log') -Encoding utf8
|
|
}
|
|
docker compose @compose down --volumes --remove-orphans 2>$null
|
|
Remove-Item Env:PULSE_POSTGRES_PASSWORD,Env:PULSE_DATABASE_URL,Env:PULSE_ENV,Env:PULSE_AUTH_MODE,Env:PULSE_DEV_WEB_PORT,Env:PULSE_DEV_API_PORT,Env:PULSE_DEV_DB_PORT,Env:PULSE_SMOKE_WEBHOOK_TOKEN,Env:PULSE_SOAK_BASE_URL,Env:PULSE_SOAK_OUTPUT_DIR,Env:PULSE_SOAK_DURATION_HOURS,Env:PULSE_SOAK_SAMPLE_SECONDS,Env:PULSE_SOAK_RECONNECT_SECONDS -ErrorAction SilentlyContinue
|
|
}
|