Files
ITWorx-Pulse-Public/scripts/wallboard-soak.ps1
T
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

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
}