87 lines
4.3 KiB
PowerShell
87 lines
4.3 KiB
PowerShell
param(
|
|
[string]$SourceRoot = (Split-Path -Parent $MyInvocation.MyCommand.Path),
|
|
[string]$WorkRoot = (Join-Path $env:TEMP ("agent99-synthetic-" + (Get-Date -Format "yyyyMMdd-HHmmss")))
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$checks = @()
|
|
|
|
function Add-SyntheticCheck {
|
|
param([string]$Name, [bool]$Ok, [string]$Detail)
|
|
$script:checks += [pscustomobject]@{ name = $Name; ok = $Ok; detail = $Detail }
|
|
}
|
|
|
|
Remove-Item -Recurse -Force $WorkRoot -ErrorAction SilentlyContinue
|
|
New-Item -ItemType Directory -Force -Path $WorkRoot | Out-Null
|
|
|
|
$inbox = Join-Path $SourceRoot "agent99-sre-alert-inbox.ps1"
|
|
$routingOutput = @(& $inbox -AgentRoot $WorkRoot -SelfTest 2>&1) -join "`n"
|
|
$routingExitCode = $LASTEXITCODE
|
|
try {
|
|
$routing = $routingOutput | ConvertFrom-Json
|
|
Add-SyntheticCheck "routing:self_test" ($routingExitCode -eq 0 -and $routing.ok -eq $true) "passed=$($routing.passedCount)/$($routing.caseCount) exit=$routingExitCode"
|
|
Add-SyntheticCheck "routing:provider_freshness" (@($routing.results | Where-Object { $_.alertId -eq "selftest-provider-freshness" -and $_.mode -eq "ProviderFreshness" }).Count -eq 1) "provider freshness structured route"
|
|
Add-SyntheticCheck "routing:reboot_slo" (@($routing.results | Where-Object { $_.alertId -eq "selftest-reboot-slo" -and $_.mode -eq "Recover" -and $_.routeSource -eq "suggestedMode" }).Count -eq 1) "reboot SLO has priority over contaminated text"
|
|
} catch {
|
|
Add-SyntheticCheck "routing:self_test" $false "invalid self-test JSON: $($_.Exception.Message)"
|
|
}
|
|
|
|
$tokens = $null
|
|
$errors = $null
|
|
$controlPath = Join-Path $SourceRoot "agent99-control-plane.ps1"
|
|
$controlSource = [IO.File]::ReadAllText($controlPath, [Text.Encoding]::UTF8)
|
|
$ast = [System.Management.Automation.Language.Parser]::ParseInput($controlSource, [ref]$tokens, [ref]$errors)
|
|
$formatFunctions = @{}
|
|
foreach ($functionName in @("Get-AgentObjectValue", "Limit-AgentTextLine", "Format-AgentMetricForCard", "Format-AgentTelegramText")) {
|
|
$definition = $ast.Find({
|
|
param($node)
|
|
$node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq $functionName
|
|
}, $true)
|
|
if ($definition) {
|
|
Invoke-Expression $definition.Extent.Text
|
|
$formatFunctions[$functionName] = $true
|
|
}
|
|
}
|
|
if ($formatFunctions.ContainsKey("Format-AgentTelegramText")) {
|
|
$perfCard = Format-AgentTelegramText "warning" "performance_warning" "test" ([pscustomobject]@{
|
|
host = "192.168.0.120"
|
|
reasons = @("perf_readback_failed")
|
|
loadPerCore = $null
|
|
memAvailablePercent = $null
|
|
diskUsedPercent = $null
|
|
})
|
|
$providerCard = Format-AgentTelegramText "warning" "provider_freshness_triage" "test" ([pscustomobject]@{
|
|
candidateId = "pf-test"
|
|
target = "provider_freshness_signal"
|
|
hitCount = 2
|
|
missingFields = @("lastSeen")
|
|
status = "handled_blocked_by_trust_gate"
|
|
candidatePath = "C:\Wooo\Agent99\state\pf-test.json"
|
|
})
|
|
$cards = "$perfCard`n$providerCard"
|
|
Add-SyntheticCheck "telegram:localized" ([regex]::IsMatch($cards, "[^\x00-\x7F]")) "localized card is present"
|
|
Add-SyntheticCheck "telegram:no_blank_metrics" (-not $perfCard.Contains("load/core=, ")) "failed readback renders unavailable values"
|
|
Add-SyntheticCheck "telegram:provider_handled" ($providerCard.Contains("handled_blocked_by_trust_gate") -and $providerCard.Contains("Agent99")) "handled state and agent are visible"
|
|
Add-SyntheticCheck "telegram:no_raw_python" (-not $cards.Contains("urllib.request")) "relay source is absent from user-facing card"
|
|
} else {
|
|
Add-SyntheticCheck "telegram:formatter" $false "Format-AgentTelegramText not found"
|
|
}
|
|
|
|
$control = $controlSource
|
|
Add-SyntheticCheck "recovery:single_flight_queue" ($control.Contains("recovery_already_queued") -and $control.Contains("recovery_trigger_cooldown") -and $control.Contains('mode = "Recover"')) "automatic recovery is queued and deduplicated"
|
|
Add-SyntheticCheck "transport:identity_jump" ($control.Contains("IdentitiesOnly=yes") -and $control.Contains("preferJumpHost") -and $control.Contains("directHosts")) "dedicated identity and bounded routes are present"
|
|
|
|
$failures = @($checks | Where-Object { -not $_.ok })
|
|
$result = [pscustomobject]@{
|
|
timestamp = (Get-Date -Format o)
|
|
ok = [bool]($failures.Count -eq 0)
|
|
workRoot = $WorkRoot
|
|
checkCount = $checks.Count
|
|
failureCount = $failures.Count
|
|
checks = $checks
|
|
failures = $failures
|
|
}
|
|
$result | ConvertTo-Json -Depth 8
|
|
if (-not $result.ok) { exit 1 }
|
|
exit 0
|