setup and mock fixes
This commit is contained in:
@@ -55,6 +55,65 @@ function Test-Command([string]$cmd) {
|
||||
return [bool](Get-Command $cmd -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
function Get-ComposeServices([string]$composeFile) {
|
||||
$services = @()
|
||||
if (-not (Test-Path $composeFile)) {
|
||||
return $services
|
||||
}
|
||||
|
||||
$ps = docker compose -f $composeFile ps --format json 2>$null
|
||||
if (-not $ps) {
|
||||
return $services
|
||||
}
|
||||
|
||||
foreach ($line in $ps -split "`n") {
|
||||
$line = $line.Trim()
|
||||
if (-not $line) { continue }
|
||||
try {
|
||||
$services += ($line | ConvertFrom-Json)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return $services
|
||||
}
|
||||
|
||||
function Get-ComposeExpectedServices([string]$composeFile) {
|
||||
$services = @()
|
||||
if (-not (Test-Path $composeFile)) {
|
||||
return $services
|
||||
}
|
||||
|
||||
$configured = docker compose -f $composeFile config --services 2>$null
|
||||
if (-not $configured) {
|
||||
return $services
|
||||
}
|
||||
|
||||
foreach ($line in ($configured -split "`n")) {
|
||||
$name = $line.Trim()
|
||||
if ($name) {
|
||||
$services += $name
|
||||
}
|
||||
}
|
||||
|
||||
return $services
|
||||
}
|
||||
|
||||
function Get-RunningContainerByService([string]$serviceName) {
|
||||
$names = docker ps --filter "label=com.docker.compose.service=$serviceName" --format "{{.Names}}" 2>$null
|
||||
if (-not $names) {
|
||||
return $null
|
||||
}
|
||||
|
||||
foreach ($name in ($names -split "`n")) {
|
||||
$trimmed = $name.Trim()
|
||||
if ($trimmed) {
|
||||
return $trimmed
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
# ─── 1. Check prerequisites ────────────────────────────────────────────────
|
||||
|
||||
function Test-Prerequisites {
|
||||
@@ -230,19 +289,31 @@ function Start-Infrastructure {
|
||||
$maxWait = 120
|
||||
$elapsed = 0
|
||||
while ($elapsed -lt $maxWait) {
|
||||
$ps = docker compose -f docker-compose.dev.yml ps --format json 2>$null
|
||||
if ($ps) {
|
||||
$expectedServices = Get-ComposeExpectedServices 'docker-compose.dev.yml'
|
||||
$services = Get-ComposeServices 'docker-compose.dev.yml'
|
||||
if ($expectedServices.Count -gt 0) {
|
||||
$allowed = @{}
|
||||
foreach ($name in $expectedServices) {
|
||||
$allowed[$name.ToLowerInvariant()] = $true
|
||||
}
|
||||
|
||||
$services = $services | Where-Object {
|
||||
$service = "$($_.Service)".ToLowerInvariant()
|
||||
$service -and $allowed.ContainsKey($service)
|
||||
}
|
||||
}
|
||||
if ($services.Count -gt 0) {
|
||||
$allHealthy = $true
|
||||
# docker compose ps --format json outputs one JSON object per line
|
||||
foreach ($line in $ps -split "`n") {
|
||||
$line = $line.Trim()
|
||||
if (-not $line) { continue }
|
||||
try {
|
||||
$svc = $line | ConvertFrom-Json
|
||||
if ($svc.Health -and $svc.Health -ne 'healthy') {
|
||||
$allHealthy = $false
|
||||
}
|
||||
} catch {}
|
||||
foreach ($svc in $services) {
|
||||
$state = "$($svc.State)".ToLowerInvariant()
|
||||
$health = "$($svc.Health)".ToLowerInvariant()
|
||||
if ($state -ne 'running') {
|
||||
$allHealthy = $false
|
||||
continue
|
||||
}
|
||||
if ($health -and $health -ne 'healthy') {
|
||||
$allHealthy = $false
|
||||
}
|
||||
}
|
||||
if ($allHealthy -and $elapsed -gt 5) {
|
||||
Write-Ok 'All infrastructure containers healthy'
|
||||
@@ -315,58 +386,116 @@ function Start-Platform {
|
||||
|
||||
function Test-Smoke {
|
||||
Write-Step 'Running smoke tests'
|
||||
$hasBlockingFailures = $false
|
||||
|
||||
# Infrastructure checks
|
||||
$endpoints = @(
|
||||
@{ Name = 'PostgreSQL'; Cmd = { docker exec stellaops-dev-postgres pg_isready -U stellaops 2>$null; $LASTEXITCODE -eq 0 } },
|
||||
@{ Name = 'Valkey'; Cmd = { $r = docker exec stellaops-dev-valkey valkey-cli ping 2>$null; $r -eq 'PONG' } }
|
||||
)
|
||||
|
||||
foreach ($ep in $endpoints) {
|
||||
try {
|
||||
$ok = & $ep.Cmd
|
||||
if ($ok) { Write-Ok $ep.Name } else { Write-Warn "$($ep.Name) not responding" }
|
||||
} catch {
|
||||
Write-Warn "$($ep.Name) check failed: $_"
|
||||
$postgresContainer = Get-RunningContainerByService 'postgres'
|
||||
if ($postgresContainer) {
|
||||
docker exec $postgresContainer pg_isready -U stellaops 2>$null | Out-Null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Ok "PostgreSQL ($postgresContainer)"
|
||||
} else {
|
||||
Write-Fail "PostgreSQL not responding ($postgresContainer)"
|
||||
$hasBlockingFailures = $true
|
||||
}
|
||||
} else {
|
||||
Write-Fail 'PostgreSQL container not found'
|
||||
$hasBlockingFailures = $true
|
||||
}
|
||||
|
||||
$valkeyContainer = Get-RunningContainerByService 'valkey'
|
||||
if ($valkeyContainer) {
|
||||
$valkeyResponse = (docker exec $valkeyContainer valkey-cli ping 2>$null)
|
||||
if ($valkeyResponse -and $valkeyResponse.Trim() -eq 'PONG') {
|
||||
Write-Ok "Valkey ($valkeyContainer)"
|
||||
} else {
|
||||
Write-Fail "Valkey not responding ($valkeyContainer)"
|
||||
$hasBlockingFailures = $true
|
||||
}
|
||||
} else {
|
||||
Write-Fail 'Valkey container not found'
|
||||
$hasBlockingFailures = $true
|
||||
}
|
||||
|
||||
# Platform container health summary
|
||||
Write-Step 'Container health summary'
|
||||
Push-Location $ComposeDir
|
||||
try {
|
||||
$composeFiles = @('docker-compose.dev.yml', 'docker-compose.stella-ops.yml')
|
||||
$composeFiles = if ($InfraOnly) {
|
||||
@('docker-compose.dev.yml')
|
||||
} else {
|
||||
@('docker-compose.stella-ops.yml')
|
||||
}
|
||||
|
||||
if (-not ($composeFiles | Where-Object { Test-Path $_ })) {
|
||||
$composeFiles = @('docker-compose.dev.yml', 'docker-compose.stella-ops.yml')
|
||||
}
|
||||
|
||||
$totalContainers = 0
|
||||
$healthyContainers = 0
|
||||
$unhealthyNames = @()
|
||||
$warningNames = @()
|
||||
$blockingNames = @()
|
||||
$seenContainers = @{}
|
||||
|
||||
foreach ($cf in $composeFiles) {
|
||||
if (-not (Test-Path $cf)) { continue }
|
||||
$ps = docker compose -f $cf ps --format json 2>$null
|
||||
if (-not $ps) { continue }
|
||||
foreach ($line in $ps -split "`n") {
|
||||
$line = $line.Trim()
|
||||
if (-not $line) { continue }
|
||||
try {
|
||||
$svc = $line | ConvertFrom-Json
|
||||
$totalContainers++
|
||||
if (-not $svc.Health -or $svc.Health -eq 'healthy') {
|
||||
$healthyContainers++
|
||||
} else {
|
||||
$unhealthyNames += $svc.Name
|
||||
}
|
||||
} catch {}
|
||||
$expectedServices = Get-ComposeExpectedServices $cf
|
||||
$services = Get-ComposeServices $cf
|
||||
if ($expectedServices.Count -gt 0) {
|
||||
$allowed = @{}
|
||||
foreach ($name in $expectedServices) {
|
||||
$allowed[$name.ToLowerInvariant()] = $true
|
||||
}
|
||||
|
||||
$services = $services | Where-Object {
|
||||
$service = "$($_.Service)".ToLowerInvariant()
|
||||
$service -and $allowed.ContainsKey($service)
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($svc in $services) {
|
||||
$name = "$($svc.Name)"
|
||||
if (-not $name -or $seenContainers.ContainsKey($name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
$seenContainers[$name] = $true
|
||||
$totalContainers++
|
||||
|
||||
$state = "$($svc.State)".ToLowerInvariant()
|
||||
$health = "$($svc.Health)".ToLowerInvariant()
|
||||
|
||||
if ($state -ne 'running') {
|
||||
$blockingNames += "$name (state=$state)"
|
||||
continue
|
||||
}
|
||||
|
||||
if (-not $health -or $health -eq 'healthy') {
|
||||
$healthyContainers++
|
||||
} elseif ($health -eq 'starting') {
|
||||
$warningNames += "$name (health=starting)"
|
||||
} else {
|
||||
$blockingNames += "$name (health=$health)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalContainers -gt 0) {
|
||||
if ($healthyContainers -eq $totalContainers) {
|
||||
if ($blockingNames.Count -eq 0 -and $warningNames.Count -eq 0) {
|
||||
Write-Ok "$healthyContainers/$totalContainers containers healthy"
|
||||
} else {
|
||||
Write-Warn "$healthyContainers/$totalContainers containers healthy"
|
||||
foreach ($name in $unhealthyNames) {
|
||||
Write-Warn " Unhealthy: $name"
|
||||
} elseif ($blockingNames.Count -eq 0) {
|
||||
Write-Warn "$healthyContainers/$totalContainers containers healthy ($($warningNames.Count) still starting)"
|
||||
foreach ($name in $warningNames) {
|
||||
Write-Warn " Advisory: $name"
|
||||
}
|
||||
} else {
|
||||
Write-Fail "$healthyContainers/$totalContainers containers healthy ($($blockingNames.Count) blocking issue(s))"
|
||||
foreach ($name in $blockingNames) {
|
||||
Write-Fail " Blocking: $name"
|
||||
}
|
||||
foreach ($name in $warningNames) {
|
||||
Write-Warn " Advisory: $name"
|
||||
}
|
||||
$hasBlockingFailures = $true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,6 +512,8 @@ function Test-Smoke {
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
return $hasBlockingFailures
|
||||
}
|
||||
|
||||
# ─── Main ───────────────────────────────────────────────────────────────────
|
||||
@@ -401,10 +532,13 @@ if ($ImagesOnly) {
|
||||
}
|
||||
|
||||
Initialize-EnvFile
|
||||
Start-Infrastructure
|
||||
|
||||
if ($InfraOnly) {
|
||||
Test-Smoke
|
||||
Start-Infrastructure
|
||||
$infraSmokeFailed = Test-Smoke
|
||||
if ($infraSmokeFailed) {
|
||||
Write-Warn 'Infrastructure started with blocking smoke failures. Review output and docker compose logs.'
|
||||
}
|
||||
Write-Host "`nDone (infra only). Infrastructure is running." -ForegroundColor Green
|
||||
exit 0
|
||||
}
|
||||
@@ -418,7 +552,10 @@ if (-not $SkipImages) {
|
||||
}
|
||||
|
||||
Start-Platform
|
||||
Test-Smoke
|
||||
$platformSmokeFailed = Test-Smoke
|
||||
if ($platformSmokeFailed) {
|
||||
Write-Warn 'Setup completed with blocking smoke failures. Review output and docker compose logs.'
|
||||
}
|
||||
|
||||
Write-Host "`n=============================================" -ForegroundColor Green
|
||||
Write-Host ' Setup complete!' -ForegroundColor Green
|
||||
|
||||
Reference in New Issue
Block a user