packmate/mcp/tests/run-capacity.ps1
2026-10-23 11:42:44 +03:00

66 lines
2.9 KiB
PowerShell

param([switch]$KeepContainers)
$ErrorActionPreference = 'Stop'
$repo = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path
Set-Location -LiteralPath $repo
$composeArgs = @('compose', '-p', 'packmate-mcp-capacity', '-f', 'stress/network/docker-compose.yml',
'-f', 'mcp/tests/compose.yml', '-f', 'mcp/tests/capacity.yml')
$testerName = 'packmate-mcp-capacity-tester'
$reportDir = Join-Path $repo 'build/reports/mcp'
$healthProbe = @'
import sys, urllib.request
try:
urllib.request.urlopen('http://localhost:65002/healthz', timeout=2)
except Exception:
sys.exit(1)
'@
if (!(Test-Path -LiteralPath (Join-Path $repo 'build/libs/packmate-1.0-SNAPSHOT.jar'))) {
throw 'Build the current backend with bootJar first; see docs/MCP.md.'
}
function Invoke-Compose {
& docker @composeArgs @args
if ($LASTEXITCODE -ne 0) { throw "Docker Compose failed: $args" }
}
$existing = & docker ps -aq --filter "name=^/$testerName`$"
if ($existing) { throw "Remove the previous disposable $testerName container before running again." }
New-Item -ItemType Directory -Force -Path $reportDir | Out-Null
foreach ($name in @('restart-request.json', 'restart-done.json', 'capacity.json')) {
$report = Join-Path $reportDir $name
if (Test-Path -LiteralPath $report) { Remove-Item -LiteralPath $report }
}
try {
Invoke-Compose up --no-build -d db target packmate mcp
Invoke-Compose run -d --no-deps --name $testerName tester
$deadline = (Get-Date).AddMinutes(20)
$restarted = $false
while ((Get-Date) -lt $deadline) {
if (!$restarted -and (Test-Path -LiteralPath (Join-Path $reportDir 'restart-request.json'))) {
Invoke-Compose restart mcp
$ready = $false
for ($attempt = 0; $attempt -lt 30; $attempt++) {
& docker @composeArgs exec -T mcp python -c $healthProbe
if ($LASTEXITCODE -eq 0) { $ready = $true; break }
Start-Sleep -Seconds 1
}
if (!$ready) { throw 'MCP did not recover after restart' }
Set-Content -LiteralPath (Join-Path $reportDir 'restart-done.json') -Value '{"restarted":true}' -Encoding ascii
$restarted = $true
}
$state = (& docker inspect --format '{{.State.Status}}' $testerName)
if ($state -eq 'exited') {
& docker logs $testerName
$exitCode = [int](& docker inspect --format '{{.State.ExitCode}}' $testerName)
if ($exitCode -ne 0) { throw "Capacity test failed (exit $exitCode)" }
if (!$restarted) { throw 'Test finished without exercising restart' }
return
}
Start-Sleep -Seconds 1
}
throw 'Capacity test exceeded 20 minutes'
} finally {
if (!$KeepContainers) {
& docker rm -f $testerName
# Only this fixed disposable project and its named volumes are removed.
& docker @composeArgs down -v
}
}