param([string]$OutputDirectory='.tmp-initial-memory') $ErrorActionPreference='Stop' $PSNativeCommandUseErrorActionPreference=$true $taskRoot=Split-Path -Parent $PSScriptRoot Set-Location -LiteralPath $taskRoot $taskSuffix=[guid]::NewGuid().ToString('N').Substring(0,12) $taskNetwork="codex-initial-memory-$taskSuffix" $taskPostgres="codex-initial-memory-pg-$taskSuffix" $taskRedis="codex-initial-memory-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/initial_memory_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=initial_memory_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 initial_memory_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 @('up') *> (Join-Path $taskOutput 'migrate.log') docker cp test/fixtures/local_seed.sql "${taskPostgres}:/tmp/local_seed.sql" docker exec $taskPostgres psql -U voice -d initial_memory_template -v ON_ERROR_STOP=1 -f /tmp/local_seed.sql *> (Join-Path $taskOutput 'seed.log') $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 @('saas','onboarding','httpapi')){ $taskDatabase="initial_memory_test_$taskPackage" docker exec $taskPostgres psql -U voice -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE $taskDatabase TEMPLATE initial_memory_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"} } $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 }