Files

77 lines
5.2 KiB
PowerShell
Raw Permalink Normal View History

param([string]$OutputDirectory='.tmp-elder-persona-sync')
$ErrorActionPreference='Stop'
$PSNativeCommandUseErrorActionPreference=$true
$taskRoot=Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $taskRoot
$taskSuffix=[guid]::NewGuid().ToString('N').Substring(0,12)
$taskNetwork="codex-persona-$taskSuffix"
$taskPostgres="codex-persona-pg-$taskSuffix"
$taskRedis="codex-persona-redis-$taskSuffix"
$taskPreviousDatabase=$env:TEST_DATABASE_URL
$taskPreviousRedis=$env:TEST_REDIS_ADDR
$taskOutput=Join-Path $taskRoot $OutputDirectory
New-Item -ItemType Directory -Force -Path $taskOutput | Out-Null
function Run-Migrate([string[]]$MigrationArgs){
docker run --rm --pull=never --network $taskNetwork --mount "type=bind,source=$taskRoot/migrations,target=/migrations,readonly" migrate/migrate:v4.18.3 -path=/migrations "-database=postgres://voice:voice_test_only@$taskPostgres`:5432/persona_template?sslmode=disable" @MigrationArgs
}
try{
docker network create $taskNetwork | Out-Null
docker run -d --pull=never --name $taskPostgres --network $taskNetwork --tmpfs /var/lib/postgresql/data -e POSTGRES_USER=voice -e POSTGRES_PASSWORD=voice_test_only -e POSTGRES_DB=persona_template -p '127.0.0.1::5432' pgvector/pgvector:pg16 | Out-Null
docker run -d --pull=never --name $taskRedis --network $taskNetwork -p '127.0.0.1::6379' redis:7-alpine | Out-Null
$taskReady=$false
$PSNativeCommandUseErrorActionPreference=$false
for($taskAttempt=0;$taskAttempt -lt 40;$taskAttempt++){
docker exec $taskPostgres pg_isready -U voice -d persona_template *> $null
if($LASTEXITCODE -eq 0){$taskReady=$true;break}
Start-Sleep -Milliseconds 250
}
$PSNativeCommandUseErrorActionPreference=$true
if(!$taskReady){throw 'Isolated PostgreSQL did not become ready'}
Run-Migrate @('goto','75') *> (Join-Path $taskOutput 'migrate-75.log')
docker cp test/fixtures/local_seed.sql "${taskPostgres}:/tmp/local_seed.sql"
docker exec $taskPostgres psql -U voice -d persona_template -v ON_ERROR_STOP=1 -f /tmp/local_seed.sql *> (Join-Path $taskOutput 'seed.log')
$taskBackfillSQL=@'
INSERT INTO subject_voice_agent(subject_id,bot_name,bot_id,status,config) VALUES('10000000-0000-0000-0000-000000000401','backfill-test','backfill-test','READY','{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"保留基础角色\n你正在陪伴的长者称呼是测试长者。"}}}}');
'@
$taskBackfillFile=Join-Path $taskOutput 'backfill.sql'
[IO.File]::WriteAllText($taskBackfillFile,$taskBackfillSQL,[Text.UTF8Encoding]::new($false))
docker cp $taskBackfillFile "${taskPostgres}:/tmp/backfill.sql"
docker exec $taskPostgres psql -U voice -d persona_template -v ON_ERROR_STOP=1 -f /tmp/backfill.sql | Out-Null
Run-Migrate @('up') *> (Join-Path $taskOutput 'migrate-76.log')
$taskBackfillResult=docker exec $taskPostgres psql -U voice -d persona_template -At -c "SELECT persona_base_role='保留基础角色' AND persona_sync_state='PENDING' AND persona_synced_revision=0 FROM subject_voice_agent WHERE bot_id='backfill-test';"
if($taskBackfillResult -ne 't'){throw 'Existing Bot migration/backfill failed'}
docker exec $taskPostgres psql -U voice -d persona_template -v ON_ERROR_STOP=1 -c "DELETE FROM subject_voice_agent WHERE bot_id='backfill-test';" | Out-Null
$taskPgBinding=docker port $taskPostgres 5432/tcp
$taskRedisBinding=docker port $taskRedis 6379/tcp
if($taskPgBinding -notmatch '^127\.0\.0\.1:(\d+)$'){throw 'Unexpected test database binding'}
$taskPgPort=$Matches[1]
if($taskRedisBinding -notmatch '^127\.0\.0\.1:(\d+)$'){throw 'Unexpected test Redis binding'}
$taskRedisPort=$Matches[1]
$taskSummary=@()
foreach($taskPackage in @('elderagent','saas','callmemory','httpapi')){
$taskDatabase="persona_test_$taskPackage"
docker exec $taskPostgres psql -U voice -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE $taskDatabase TEMPLATE persona_template;" | Out-Null
$env:TEST_DATABASE_URL="postgres://voice:voice_test_only@127.0.0.1:$taskPgPort/$taskDatabase`?sslmode=disable"
$env:TEST_REDIS_ADDR="127.0.0.1:$taskRedisPort"
$taskLog=Join-Path $taskOutput "integration-$taskPackage.jsonl"
$PSNativeCommandUseErrorActionPreference=$false
go test -count=1 -p 1 -json "./internal/$taskPackage" *> $taskLog
$taskTestExit=$LASTEXITCODE
$PSNativeCommandUseErrorActionPreference=$true
$taskEvents=Get-Content -LiteralPath $taskLog | ForEach-Object {try{$_|ConvertFrom-Json}catch{}}
$taskSummary+=@{package=$taskPackage;passed=@($taskEvents|Where-Object{$_.Action -eq 'pass' -and $_.Test}).Count;skipped=@($taskEvents|Where-Object{$_.Action -eq 'skip' -and $_.Test}).Count;exit_code=$taskTestExit}
if($taskTestExit -ne 0){Get-Content -LiteralPath $taskLog -Tail 90;throw "Integration tests failed: $taskPackage"}
}
Run-Migrate @('down','1') *> (Join-Path $taskOutput 'migration-down.log')
Run-Migrate @('up') *> (Join-Path $taskOutput 'migration-up-again.log')
$taskSummary|ConvertTo-Json|Set-Content -LiteralPath (Join-Path $taskOutput 'results.json')
$taskSummary|ConvertTo-Json
}finally{
$env:TEST_DATABASE_URL=$taskPreviousDatabase
$env:TEST_REDIS_ADDR=$taskPreviousRedis
$PSNativeCommandUseErrorActionPreference=$false
# Names are generated by this invocation; never touch Compose or other services.
docker rm -f $taskPostgres $taskRedis *> $null
docker network rm $taskNetwork *> $null
}