param( [string]$ApiBaseUrl = "http://192.168.200.61:18121/api/v1", [string]$ClusterID = "cfc0743d-d960-49fb-9de8-96e063d5e4aa", [string]$ActorUserID = "f67d943f-5397-4b3a-a229-695fe67ad700", [string]$NodeName = "test-1", [string]$ResultPath = "artifacts\c19a-service-workload-supervision-smoke-result.json" ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).ProviderPath $runId = "c19a-" + (Get-Date -Format "yyyyMMdd-HHmmss") function Invoke-Api { param( [string]$Method, [string]$Path, [object]$Body = $null ) $uri = "$ApiBaseUrl$Path" try { if ($null -eq $Body) { return Invoke-RestMethod -Method $Method -Uri $uri -TimeoutSec 30 } return Invoke-RestMethod -Method $Method -Uri $uri -ContentType "application/json" -Body ($Body | ConvertTo-Json -Depth 40) -TimeoutSec 30 } catch { $statusCode = $null if ($_.Exception.Response) { $statusCode = [int]$_.Exception.Response.StatusCode } $details = $_.ErrorDetails.Message if (-not $details) { $details = $_.Exception.Message } throw "$Method $Path failed with HTTP $statusCode`: $details" } } function Get-NodeByName { param([string]$Name) $nodes = (Invoke-Api -Method GET -Path "/clusters/$ClusterID/nodes?actor_user_id=$ActorUserID").nodes $node = @($nodes | Where-Object { $_.name -eq $Name }) | Select-Object -First 1 if ($null -eq $node) { throw "Node '$Name' was not found in cluster $ClusterID" } return $node } function Wait-ForWorkloadStates { param( [string]$NodeID, [hashtable]$Expected, [int]$TimeoutSeconds = 90 ) $deadline = (Get-Date).AddSeconds($TimeoutSeconds) $last = @() while ((Get-Date) -lt $deadline) { Start-Sleep -Seconds 5 $statuses = (Invoke-Api -Method GET -Path "/clusters/$ClusterID/nodes/$NodeID/workloads/status?actor_user_id=$ActorUserID").workload_statuses $last = @($statuses | Where-Object { $Expected.ContainsKey([string]$_.service_type) }) $ok = $true foreach ($key in $Expected.Keys) { $item = @($last | Where-Object { $_.service_type -eq $key } | Select-Object -First 1) if ($null -eq $item -or [string]$item.reported_state -ne [string]$Expected[$key]) { $ok = $false break } } if ($ok) { return $last } } throw "Timed out waiting for workload states. Last observed: $($last | ConvertTo-Json -Depth 20)" } $node = Get-NodeByName -Name $NodeName Invoke-Api -Method PUT -Path "/clusters/$ClusterID/nodes/$($node.id)/workloads/synthetic.echo/desired" -Body @{ actor_user_id = $ActorUserID desired_state = "enabled" version = "c19a-synthetic-echo-$runId" runtime_mode = "native" artifact_ref = "builtin:synthetic.echo" config = @{ echo = "enabled" scope = "service-supervisor-smoke" run_id = $runId } environment = @{} } | Out-Null $expected = @{ "core-mesh" = "running" "fabric-listener" = "running" "synthetic.echo" = "running" } $statuses = Wait-ForWorkloadStates -NodeID $node.id -Expected $expected $synthetic = @($statuses | Where-Object { $_.service_type -eq "synthetic.echo" } | Select-Object -First 1) $checks = [ordered]@{ core_mesh_running = [bool](@($statuses | Where-Object { $_.service_type -eq "core-mesh" -and $_.reported_state -eq "running" }).Count -gt 0) fabric_listener_running = [bool](@($statuses | Where-Object { $_.service_type -eq "fabric-listener" -and $_.reported_state -eq "running" }).Count -gt 0) synthetic_echo_running = [bool]($null -ne $synthetic -and [string]$synthetic.reported_state -eq "running") synthetic_echo_builtin = [bool]($null -ne $synthetic -and [string]$synthetic.status_payload.execution_mode -eq "builtin") synthetic_echo_test_only = [bool]($null -ne $synthetic -and [string]$synthetic.status_payload.traffic -eq "test_service_only") } $result = [ordered]@{ schema_version = "c19a.service_workload_supervision_smoke.v1" run_id = $runId base_url = $ApiBaseUrl cluster_id = $ClusterID node = [ordered]@{ id = $node.id name = $node.name } statuses = $statuses checks = $checks passed = -not ($checks.Values -contains $false) } $fullResultPath = Join-Path $repoRoot $ResultPath $resultDir = Split-Path -Parent $fullResultPath if ($resultDir) { New-Item -ItemType Directory -Force -Path $resultDir | Out-Null } $result | ConvertTo-Json -Depth 30 | Set-Content -Encoding UTF8 -Path $fullResultPath if (-not $result.passed) { throw "C19A service workload supervision smoke failed. Result: $fullResultPath" } Write-Host "C19A service workload supervision smoke passed. Result: $fullResultPath" $result