82 lines
6.3 KiB
PowerShell
82 lines
6.3 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|||
|
|
$PSNativeCommandUseErrorActionPreference = $true
|
||
|
|
$root = Split-Path -Parent $PSScriptRoot
|
||
|
|
Set-Location -LiteralPath $root
|
||
|
|
|
||
|
|
$api = 'http://localhost:58080'
|
||
|
|
$tokenUrl = 'http://localhost:58180/realms/voice-local/protocol/openid-connect/token'
|
||
|
|
$tenant = '10000000-0000-0000-0000-000000000010'
|
||
|
|
$device = '10000000-0000-0000-0000-000000000511'
|
||
|
|
$key = 'integration-issue-smoke-' + [Guid]::NewGuid().ToString('N')
|
||
|
|
$requestPrefix = 'integration-issue-smoke-' + [Guid]::NewGuid().ToString('N')
|
||
|
|
$issue = $null
|
||
|
|
|
||
|
|
function Get-Token([string]$name) {
|
||
|
|
(Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType 'application/x-www-form-urlencoded' -Body @{
|
||
|
|
grant_type = 'password'; client_id = 'voice-platform-web'; username = $name; password = 'LocalOnly123!'; scope = 'openid'
|
||
|
|
}).access_token
|
||
|
|
}
|
||
|
|
|
||
|
|
function Invoke-IssuePatch([string]$id, [int]$version, [hashtable]$body, [string]$token, [string]$suffix) {
|
||
|
|
Start-Sleep -Milliseconds 550
|
||
|
|
Invoke-WebRequest -UseBasicParsing -Method Patch -Uri "$api/api/v1/ops/integration-issues/$id" -Headers @{
|
||
|
|
Authorization = "Bearer $token"; 'X-Tenant-Id' = $tenant; 'If-Match' = '"v' + $version + '"'; 'X-Request-Id' = $requestPrefix + '-' + $suffix
|
||
|
|
} -ContentType 'application/json' -Body ($body | ConvertTo-Json -Compress)
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$owner = Get-Token 'owner'
|
||
|
|
$outsider = Get-Token 'outsider'
|
||
|
|
$baselineSummary = ((Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/integration-issues" -Headers @{Authorization = "Bearer $owner"; 'X-Tenant-Id' = $tenant}).Content | ConvertFrom-Json).data.summary
|
||
|
|
$body = @{
|
||
|
|
phenomenon = '模拟设备已入房,但供应商任务未在预期时间进入活动状态'
|
||
|
|
severity = 'HIGH'
|
||
|
|
device_id = $device
|
||
|
|
occurred_at = [DateTime]::UtcNow.AddMinutes(-1).ToString('o')
|
||
|
|
request_id = $requestPrefix + '-source'
|
||
|
|
responsible_party = 'Agent研发组'
|
||
|
|
} | ConvertTo-Json -Compress
|
||
|
|
$headers = @{Authorization = "Bearer $owner"; 'X-Tenant-Id' = $tenant; 'Idempotency-Key' = $key; 'X-Request-Id' = $requestPrefix + '-create'}
|
||
|
|
$createdResponse = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$api/api/v1/ops/integration-issues" -Headers $headers -ContentType 'application/json' -Body $body
|
||
|
|
$issue = ($createdResponse.Content | ConvertFrom-Json).data
|
||
|
|
if ($createdResponse.StatusCode -ne 201 -or $createdResponse.Headers.ETag -ne '"v1"' -or $issue.status -ne 'OPEN' -or $issue.severity -ne 'HIGH') { throw '联调问题创建结果不正确' }
|
||
|
|
|
||
|
|
$replayResponse = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$api/api/v1/ops/integration-issues" -Headers $headers -ContentType 'application/json' -Body $body
|
||
|
|
if ($replayResponse.StatusCode -ne 200 -or $replayResponse.Headers.'Idempotency-Replayed' -ne 'true' -or ($replayResponse.Content | ConvertFrom-Json).data.id -ne $issue.id) { throw '联调问题幂等重放不正确' }
|
||
|
|
|
||
|
|
$listData = ((Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/integration-issues?status=OPEN" -Headers @{Authorization = "Bearer $owner"; 'X-Tenant-Id' = $tenant}).Content | ConvertFrom-Json).data
|
||
|
|
$listed = $listData.items
|
||
|
|
if (@($listed | Where-Object {$_.id -eq $issue.id}).Count -ne 1) { throw '联调问题状态筛选未返回新记录' }
|
||
|
|
if ($listData.summary.release_blocking -ne ($baselineSummary.release_blocking + 1) -or $listData.summary.release_gate_satisfied) { throw '高严重度问题未进入发布阻断汇总' }
|
||
|
|
|
||
|
|
try {
|
||
|
|
Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/integration-issues" -Headers @{Authorization = "Bearer $outsider"; 'X-Tenant-Id' = $tenant} | Out-Null
|
||
|
|
throw '跨客户组织读取不应成功'
|
||
|
|
} catch {
|
||
|
|
if ($null -eq $_.Exception.Response -or [int]$_.Exception.Response.StatusCode -ne 403) { throw }
|
||
|
|
}
|
||
|
|
|
||
|
|
$taken = (Invoke-IssuePatch $issue.id 1 @{status='IN_PROGRESS';responsible_party='Agent研发组'} $owner 'take').Content | ConvertFrom-Json
|
||
|
|
$resolved = (Invoke-IssuePatch $issue.id 2 @{status='RESOLVED';resolution_result='修复供应商回调路由并重启模拟任务';root_cause='回调路由误用了旧供应商事件类型';fixed_version='0.49.0-rc.1+build.36'} $owner 'resolve').Content | ConvertFrom-Json
|
||
|
|
$verified = (Invoke-IssuePatch $issue.id 3 @{status='VERIFIED';regression_conclusion='连续三次模拟通话均进入ACTIVE且无遗留任务';regression_evidence=($requestPrefix + '-regression;脱敏诊断包 artifact-36;重复3次')} $owner 'verify').Content | ConvertFrom-Json
|
||
|
|
$closed = (Invoke-IssuePatch $issue.id 4 @{status='CLOSED'} $owner 'close').Content | ConvertFrom-Json
|
||
|
|
if ($taken.data.version -ne 2 -or $resolved.data.version -ne 3 -or $verified.data.version -ne 4 -or $closed.data.version -ne 5 -or $closed.data.status -ne 'CLOSED' -or -not $verified.data.regression_evidence) { throw '联调问题闭环状态或版本不正确' }
|
||
|
|
|
||
|
|
Start-Sleep -Milliseconds 550
|
||
|
|
$closedSummary = ((Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/integration-issues" -Headers @{Authorization = "Bearer $owner"; 'X-Tenant-Id' = $tenant}).Content | ConvertFrom-Json).data.summary
|
||
|
|
if ($closedSummary.release_blocking -ne $baselineSummary.release_blocking -or $closedSummary.release_gate_satisfied -ne $baselineSummary.release_gate_satisfied) { throw '关闭高严重度问题后发布阻断汇总未恢复' }
|
||
|
|
|
||
|
|
try {
|
||
|
|
Invoke-IssuePatch $issue.id 1 @{status='IN_PROGRESS'} $owner 'stale' | Out-Null
|
||
|
|
throw '旧ETag更新不应成功'
|
||
|
|
} catch {
|
||
|
|
if ($null -eq $_.Exception.Response -or [int]$_.Exception.Response.StatusCode -ne 412) { throw }
|
||
|
|
}
|
||
|
|
Write-Host '联调问题清单烟测通过:严重度阻断、根因、修复版本、回归证据、闭环汇总、租户隔离和旧ETag拒绝均正确。'
|
||
|
|
} finally {
|
||
|
|
if ($null -ne $issue -and $issue.id -match '^[0-9a-fA-F-]{36}$') {
|
||
|
|
docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "BEGIN; CREATE TEMP TABLE issue_cleanup AS SELECT id FROM integration_issue WHERE public_id='$($issue.id)'::uuid; DELETE FROM audit_event WHERE request_id LIKE '$requestPrefix%' OR (resource_type='integration_issue' AND resource_id IN(SELECT id FROM issue_cleanup)); DELETE FROM integration_issue WHERE id IN(SELECT id FROM issue_cleanup); DELETE FROM idempotency_record WHERE idempotency_key='$key'; COMMIT;" | Out-Null
|
||
|
|
}
|
||
|
|
Write-Host '已清理联调问题烟测记录、审计和幂等数据。'
|
||
|
|
}
|