chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
param(
|
||||
[ValidateSet('smoke','acceptance')][string]$Profile='smoke',
|
||||
[string]$Duration='',
|
||||
[int]$Rate=0,
|
||||
[int]$DuplicateWindow=0,
|
||||
[int]$ConversationPool=50
|
||||
)
|
||||
$ErrorActionPreference='Stop'
|
||||
$PSNativeCommandUseErrorActionPreference=$true
|
||||
$root=Split-Path -Parent $PSScriptRoot
|
||||
Set-Location -LiteralPath $root
|
||||
$run=[Guid]::NewGuid().ToString('N')
|
||||
$model="load-callback-$run"
|
||||
$prefix="load-callback-$run-"
|
||||
$tenant='10000000-0000-0000-0000-000000000001'
|
||||
$fixtures=$null
|
||||
if($ConversationPool-lt1-or$ConversationPool-gt500){throw 'ConversationPool must be between 1 and 500'}
|
||||
|
||||
function Sql([string]$statement){
|
||||
$result=$statement|docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -q -t -A
|
||||
if($LASTEXITCODE-ne0){throw 'Provider callback load SQL failed'}
|
||||
return ($result|Out-String).Trim()
|
||||
}
|
||||
|
||||
try{
|
||||
$setup=@"
|
||||
BEGIN;
|
||||
WITH selected AS (
|
||||
SELECT household_id,id subject_id,tenant_id,profile_version FROM subject_profile WHERE tenant_id='$tenant'::uuid AND status='active' ORDER BY created_at LIMIT 1
|
||||
), consent AS (
|
||||
INSERT INTO consent_snapshot(tenant_id,subject_id,snapshot_version,effective_consents,source_consent_ids)
|
||||
SELECT tenant_id,subject_id,profile_version,'{}'::jsonb,jsonb_build_array('$model') FROM selected RETURNING id,tenant_id,subject_id
|
||||
), context AS (
|
||||
INSERT INTO context_snapshot(tenant_id,subject_id,profile_version,consent_snapshot_id,memory_versions,prompt_bundle_version,engine_mode,content_digest,sanitized_summary)
|
||||
SELECT c.tenant_id,c.subject_id,s.profile_version,c.id,'[]'::jsonb,'$model','s2s_hybrid',encode(digest('$model','sha256'),'hex'),'供应商通知负载夹具' FROM consent c JOIN selected s ON s.subject_id=c.subject_id RETURNING id,tenant_id,subject_id,consent_snapshot_id
|
||||
), device_rows AS (
|
||||
INSERT INTO device(tenant_id,serial_digest,model,hardware_revision,credential_ref,minimum_security_version)
|
||||
SELECT '$tenant'::uuid,encode(digest('$run-device-'||g,'sha256'),'hex'),'$model','load','load://callback/'||g,'load' FROM generate_series(1,$ConversationPool) g RETURNING id
|
||||
), numbered_devices AS (
|
||||
SELECT id,row_number() OVER(ORDER BY id) n FROM device_rows
|
||||
), conversation_row AS (
|
||||
INSERT INTO conversation(tenant_id,household_id,subject_id,device_id,consent_snapshot_id,context_snapshot_id,provider_task_ref,engine_mode,retention_mode,status,allocation_expires_at,lease_expires_at,started_at)
|
||||
SELECT '$tenant'::uuid,s.household_id,s.subject_id,d.id,c.consent_snapshot_id,c.id,'$prefix'||d.n,'s2s_hybrid','none','ACTIVE',now()+interval '15 minutes',now()+interval '15 minutes',now()
|
||||
FROM selected s CROSS JOIN context c CROSS JOIN numbered_devices d RETURNING id,public_id,provider_task_ref
|
||||
), task AS (
|
||||
INSERT INTO rtc_task(conversation_id,provider,provider_task_ref,room_id,device_rtc_user_id,agent_rtc_user_id,status,lease_expires_at)
|
||||
SELECT id,'mock',provider_task_ref,'room-'||provider_task_ref,'device-'||provider_task_ref,'agent-'||provider_task_ref,'ACTIVE',now()+interval '15 minutes' FROM conversation_row
|
||||
)
|
||||
SELECT string_agg(public_id::text||'|'||provider_task_ref,',' ORDER BY provider_task_ref) FROM conversation_row;
|
||||
COMMIT;
|
||||
"@
|
||||
$fixtures=((Sql $setup)-split"`n"|Select-Object -Last 1).Trim()
|
||||
if(($fixtures-split',').Count-ne$ConversationPool-or$fixtures-notmatch'^[A-Za-z0-9|,\-]+$'){throw "Invalid provider load fixture pool"}
|
||||
$fixedOccurredAt=[DateTime]::UtcNow.ToString('o')
|
||||
$arguments=@('run','--rm','-v',"${PWD}/test/load:/scripts:ro",'grafana/k6','run','-e','CALLBACK_URL=http://host.docker.internal:58081','-e',"PROFILE=$Profile",'-e',"PROVIDER_CALLBACK_SECRET=local-provider-callback-secret-32-bytes-minimum",'-e',"PROVIDER_FIXTURES=$fixtures",'-e',"OCCURRED_AT=$fixedOccurredAt")
|
||||
if($Duration){$arguments+=@('-e',"DURATION=$Duration")}
|
||||
if($Rate-gt0){$arguments+=@('-e',"RATE=$Rate")}
|
||||
if($DuplicateWindow-gt0){$arguments+=@('-e',"DUPLICATE_WINDOW=$DuplicateWindow")}
|
||||
$arguments+='/scripts/provider-callbacks.js'
|
||||
docker @arguments
|
||||
if($LASTEXITCODE-ne0){throw 'Provider callback k6 thresholds failed'}
|
||||
$minimumUnique=if($DuplicateWindow-gt0){$DuplicateWindow}elseif($Profile-eq'smoke'){100}else{300000}
|
||||
$evidence=Sql "SELECT count(*)||'|'||count(*) FILTER(WHERE processing_status IN('processed','ignored'))||'|'||(SELECT count(*) FROM conversation WHERE provider_task_ref LIKE '$prefix%' AND status='ACTIVE')||'|'||(SELECT count(*) FROM rtc_task rt JOIN conversation c ON c.id=rt.conversation_id WHERE c.provider_task_ref LIKE '$prefix%' AND rt.status='ACTIVE') FROM provider_event WHERE conversation_id IN(SELECT id FROM conversation WHERE provider_task_ref LIKE '$prefix%');"
|
||||
$parts=$evidence-split'\|'
|
||||
if($parts.Count-ne4-or[int]$parts[0]-lt$minimumUnique-or$parts[0]-ne$parts[1]-or[int]$parts[2]-ne$ConversationPool-or[int]$parts[3]-ne$ConversationPool){throw "Provider callback persistence mismatch: $evidence"}
|
||||
Write-Host "Provider callback load passed: profile=$Profile, conversations=$ConversationPool, unique_events=$($parts[0]), all_processed_or_ignored=true, conversation_tasks_active=$($parts[3])"
|
||||
}finally{
|
||||
if($fixtures){
|
||||
$cleanup=@"
|
||||
BEGIN;
|
||||
CREATE TEMP TABLE load_conversation ON COMMIT DROP AS SELECT id,public_id,context_snapshot_id,consent_snapshot_id,device_id FROM conversation WHERE provider_task_ref LIKE '$prefix%';
|
||||
DELETE FROM alert_incident WHERE resource_type='conversation' AND resource_public_id IN(SELECT public_id FROM load_conversation);
|
||||
DELETE FROM web_event WHERE resource_type='conversation' AND resource_public_id IN(SELECT public_id FROM load_conversation);
|
||||
DELETE FROM audit_event WHERE resource_id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM outbox_event WHERE aggregate_id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM alert_incident
|
||||
WHERE tenant_id='$tenant'::uuid AND fingerprint='outbox-dead'
|
||||
AND NOT EXISTS(SELECT 1 FROM outbox_event WHERE tenant_id='$tenant'::uuid AND status='dead');
|
||||
DELETE FROM conversation_state_history WHERE conversation_id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM provider_event WHERE conversation_id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM rtc_task WHERE conversation_id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM conversation WHERE id IN(SELECT id FROM load_conversation);
|
||||
DELETE FROM device WHERE id IN(SELECT device_id FROM load_conversation);
|
||||
DELETE FROM context_snapshot WHERE id IN(SELECT context_snapshot_id FROM load_conversation);
|
||||
DELETE FROM consent_snapshot WHERE id IN(SELECT consent_snapshot_id FROM load_conversation);
|
||||
COMMIT;
|
||||
"@
|
||||
try{Sql $cleanup|Out-Null}catch{Write-Warning $_}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user