114 lines
6.8 KiB
PowerShell
114 lines
6.8 KiB
PowerShell
# Repeatable local acceptance checks. No application deployment or device flashing.
|
|||
|
|
$ErrorActionPreference = 'Stop'
|
||
|
|
$taskRoot = Split-Path -Parent $PSScriptRoot
|
||
|
|
$taskPreviousLocation = Get-Location
|
||
|
|
$taskPreviousPlaywright = $env:PLAYWRIGHT_REQUIRE_FROM
|
||
|
|
$taskPreviousDatabase = $env:TEST_DATABASE_URL
|
||
|
|
$taskPreviousRedis = $env:TEST_REDIS_ADDR
|
||
|
|
$taskReport = Join-Path $taskRoot ('.design-evidence/call-memory-acceptance/' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff'))
|
||
|
|
$taskSteps = [System.Collections.Generic.List[object]]::new()
|
||
|
|
$taskStarted = (Get-Date).ToString('o')
|
||
|
|
$taskFailure = $null
|
||
|
|
$taskPassedCount = 0
|
||
|
|
$taskUnverified = @()
|
||
|
|
|
||
|
|
function Invoke-AcceptanceCheck {
|
||
|
|
param([string]$Name, [string]$Command, [string[]]$Arguments)
|
||
|
|
Write-Host "[$Name] Running..."
|
||
|
|
$taskLog = Join-Path $taskReport "$Name.log"
|
||
|
|
$taskStepStart = Get-Date
|
||
|
|
# Native stderr (e.g. build warnings) is logged; exit status decides success.
|
||
|
|
$taskOldPreference = $ErrorActionPreference
|
||
|
|
try {
|
||
|
|
$ErrorActionPreference = 'Continue'
|
||
|
|
& $Command @Arguments *> $taskLog
|
||
|
|
$taskCode = $LASTEXITCODE
|
||
|
|
} finally { $ErrorActionPreference = $taskOldPreference }
|
||
|
|
$taskSteps.Add([ordered]@{
|
||
|
|
name = $Name; exit_code = $taskCode; log = $taskLog
|
||
|
|
seconds = [math]::Round(((Get-Date) - $taskStepStart).TotalSeconds, 2)
|
||
|
|
})
|
||
|
|
if ($taskCode -ne 0) {
|
||
|
|
Get-Content -LiteralPath $taskLog -Tail 35
|
||
|
|
throw "$Name failed; see $taskLog"
|
||
|
|
}
|
||
|
|
Write-Host "[$Name] PASS"
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
Set-Location -LiteralPath $taskRoot
|
||
|
|
New-Item -ItemType Directory -Force -Path $taskReport | Out-Null
|
||
|
|
foreach ($taskTool in @('git', 'docker', 'go', 'node', 'npm.cmd', 'powershell.exe')) {
|
||
|
|
Get-Command $taskTool -ErrorAction Stop | Out-Null
|
||
|
|
}
|
||
|
|
if (-not (Test-Path 'web/node_modules/vite')) {
|
||
|
|
throw 'Web dependencies missing. Run npm ci --prefix web first.'
|
||
|
|
}
|
||
|
|
if (-not $env:PLAYWRIGHT_REQUIRE_FROM) {
|
||
|
|
$taskBundledPlaywright = Join-Path $env:USERPROFILE '.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/package.json'
|
||
|
|
if (Test-Path -LiteralPath $taskBundledPlaywright) {
|
||
|
|
$env:PLAYWRIGHT_REQUIRE_FROM = $taskBundledPlaywright
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# Record hashes for tracked and untracked source files, including local changes.
|
||
|
|
git rev-parse HEAD | Set-Content (Join-Path $taskReport 'base-commit.txt')
|
||
|
|
git -c core.quotepath=false status --short | Set-Content -Encoding UTF8 (Join-Path $taskReport 'worktree-status.txt')
|
||
|
|
$taskSourceHashes = @(foreach ($taskRelative in (git -c core.quotepath=false ls-files --cached --others --exclude-standard)) {
|
||
|
|
if (Test-Path -LiteralPath $taskRelative -PathType Leaf) {
|
||
|
|
[ordered]@{ path = $taskRelative; sha256 = (Get-FileHash -LiteralPath $taskRelative -Algorithm SHA256).Hash }
|
||
|
|
}
|
||
|
|
})
|
||
|
|
ConvertTo-Json -Depth 4 -InputObject $taskSourceHashes | Set-Content -Encoding UTF8 (Join-Path $taskReport 'source-sha256.json')
|
||
|
|
# Ignore any inherited test DB setting; integration tests create their own databases.
|
||
|
|
$env:TEST_DATABASE_URL = $null
|
||
|
|
$env:TEST_REDIS_ADDR = $null
|
||
|
|
Invoke-AcceptanceCheck 'dependencies' 'docker' @('compose', 'up', '-d', 'postgres', 'redis')
|
||
|
|
Invoke-AcceptanceCheck 'go-tests' 'go' @('test', '-count=1', './...')
|
||
|
|
Invoke-AcceptanceCheck 'go-vet' 'go' @('vet', './...')
|
||
|
|
$taskIntegration = Join-Path $taskRoot 'scripts/test-onboarding-integration.ps1'
|
||
|
|
# A child shell gives thrown integration errors an unambiguous nonzero exit code.
|
||
|
|
$taskQuotedScript = $taskIntegration.Replace("'", "''")
|
||
|
|
$taskQuotedOutput = (Join-Path $taskReport 'database').Replace("'", "''")
|
||
|
|
$taskIntegrationCommand = "& '$taskQuotedScript' -VerboseTests -OutputDirectory '$taskQuotedOutput' -Packages billing,callmemory,onboarding,saas,extraction,retrieval,memorytool,privacy,orchestration,vikingmemory"
|
||
|
|
Invoke-AcceptanceCheck 'database-integration' 'powershell.exe' @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', $taskIntegrationCommand)
|
||
|
|
$taskDbLogs = Get-ChildItem -LiteralPath (Join-Path $taskReport 'database') -Filter 'integration-*.log'
|
||
|
|
$taskPassed = @($taskDbLogs | Select-String -Pattern '^--- PASS:')
|
||
|
|
$taskSkipped = @($taskDbLogs | Select-String -Pattern '^\s*--- SKIP:')
|
||
|
|
$taskPassedCount = $taskPassed.Count
|
||
|
|
$taskUnverified = @($taskSkipped | ForEach-Object { $_.Line })
|
||
|
|
$taskPassed | ForEach-Object { $_.Line } | Set-Content -Encoding UTF8 (Join-Path $taskReport 'database-passed-tests.txt')
|
||
|
|
$taskSkipped | ForEach-Object { $_.Line } | Set-Content -Encoding UTF8 (Join-Path $taskReport 'database-skipped-tests.txt')
|
||
|
|
# This existing optional test needs a separately configured real content model.
|
||
|
|
# Keep it explicitly unverified; all database-required tests must actually run.
|
||
|
|
$taskUnexpectedSkips = @($taskSkipped | Where-Object { $_.Line -notmatch '^--- SKIP: TestLocalModelContentValueDecisions \(' })
|
||
|
|
if ($taskDbLogs.Count -ne 10 -or $taskPassed.Count -eq 0 -or $taskUnexpectedSkips.Count -gt 0) {
|
||
|
|
throw 'Database verification incomplete: a package is missing or a required test was skipped. Inspect database logs.'
|
||
|
|
}
|
||
|
|
foreach ($taskSkippedTest in $taskUnverified) { Write-Host "UNVERIFIED: $taskSkippedTest" }
|
||
|
|
Invoke-AcceptanceCheck 'web-build' 'npm.cmd' @('run', 'build', '--prefix', 'web')
|
||
|
|
Invoke-AcceptanceCheck 'browser-component' 'node' @('test/e2e/memory-workspace.mjs')
|
||
|
|
Copy-Item -LiteralPath (Join-Path $taskRoot '.design-evidence/call-memory') -Destination (Join-Path $taskReport 'browser') -Recurse
|
||
|
|
Invoke-AcceptanceCheck 'firmware-node-tests' 'node' @('--test', 'firmware/echoear-platform-agent/tests/setup-portal.test.cjs', 'firmware/echoear-platform-agent/tests/private-sdk-logs.test.cjs')
|
||
|
|
} catch {
|
||
|
|
$taskFailure = $_.Exception.Message
|
||
|
|
Write-Host "FAILED: $taskFailure"
|
||
|
|
} finally {
|
||
|
|
if (Test-Path -LiteralPath $taskReport) {
|
||
|
|
[ordered]@{
|
||
|
|
status = $(if ($taskFailure) { 'FAILED' } else { 'PASSED_LOCAL_CHECKS' })
|
||
|
|
started_at = $taskStarted; finished_at = (Get-Date).ToString('o')
|
||
|
|
error = $taskFailure; steps = @($taskSteps.ToArray())
|
||
|
|
integration_package_test_passes = $taskPassedCount
|
||
|
|
unverified_tests = $taskUnverified
|
||
|
|
boundary = 'Real isolated PostgreSQL tests; browser uses synthetic APIs. Not hardware/provider/end-to-end acceptance. Firmware compile is not run by this script.'
|
||
|
|
} | ConvertTo-Json -Depth 6 | Set-Content -Encoding UTF8 (Join-Path $taskReport 'summary.json')
|
||
|
|
Write-Host "Evidence: $taskReport"
|
||
|
|
}
|
||
|
|
$env:PLAYWRIGHT_REQUIRE_FROM = $taskPreviousPlaywright
|
||
|
|
$env:TEST_DATABASE_URL = $taskPreviousDatabase
|
||
|
|
$env:TEST_REDIS_ADDR = $taskPreviousRedis
|
||
|
|
Set-Location -LiteralPath $taskPreviousLocation
|
||
|
|
}
|
||
|
|
if ($taskFailure) { exit 1 }
|
||
|
|
Write-Host 'PASSED_LOCAL_CHECKS (not full hardware/provider acceptance)'
|