From f7fadadb74338f13c25e434ac601abb1f0c5bc5c Mon Sep 17 00:00:00 2001 From: 491034170 <142008960+491034170@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:32:09 +0800 Subject: [PATCH 1/2] test(backend): add Windows preflight script --- backend/README.md | 16 +++ backend/test-preflight.ps1 | 196 +++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 backend/test-preflight.ps1 diff --git a/backend/README.md b/backend/README.md index 31be561b56e..72227694da9 100644 --- a/backend/README.md +++ b/backend/README.md @@ -115,6 +115,22 @@ This README provides a quick setup guide for the Omi backend. For a comprehensiv deactivate ``` +## Running Backend Test Preflight + +Before running the full backend test suite, use the preflight script for your shell. It checks the Python test runner, key packages, optional service environment variables, Redis reachability, and `test.sh` file references. + +macOS/Linux: +```bash +bash test-preflight.sh +``` + +Windows PowerShell: +```powershell +.\test-preflight.ps1 +``` + +The preflight script does not replace `test.sh`; it only catches setup issues before running the tests. + ## Additional Resources - [Full Backend Setup Documentation](https://docs.omi.me/developer/backend/Backend_Setup) diff --git a/backend/test-preflight.ps1 b/backend/test-preflight.ps1 new file mode 100644 index 00000000000..b54ff8364e3 --- /dev/null +++ b/backend/test-preflight.ps1 @@ -0,0 +1,196 @@ +param() + +$ErrorActionPreference = "Continue" + +$RootDir = Split-Path -Parent $MyInvocation.MyCommand.Path +Set-Location $RootDir + +$PassCount = 0 +$WarnCount = 0 +$FailCount = 0 +$Script:PythonLauncher = $null + +function Add-Pass { + param([string]$Message) + Write-Host " OK $Message" -ForegroundColor Green + $script:PassCount += 1 +} + +function Add-Warn { + param([string]$Message) + Write-Host " WARN $Message" -ForegroundColor Yellow + $script:WarnCount += 1 +} + +function Add-Fail { + param([string]$Message) + Write-Host " FAIL $Message" -ForegroundColor Red + $script:FailCount += 1 +} + +function Invoke-SelectedPython { + param([string[]]$Arguments) + if ($Script:PythonLauncher -eq "py") { + & py -3 @Arguments + } else { + & $Script:PythonLauncher @Arguments + } +} + +Write-Host "Tools:" + +$pythonCommand = Get-Command python -ErrorAction SilentlyContinue +if ($pythonCommand) { + $Script:PythonLauncher = $pythonCommand.Source + $pythonVersion = (& $Script:PythonLauncher --version 2>&1) + Add-Pass "python $pythonVersion" +} elseif (Get-Command py -ErrorAction SilentlyContinue) { + $Script:PythonLauncher = "py" + $pythonVersion = (& py -3 --version 2>&1) + Add-Pass "python $pythonVersion" +} else { + Add-Fail "python not found" +} + +if ($Script:PythonLauncher) { + $pytestOutput = Invoke-SelectedPython @("-m", "pytest", "--version") 2>$null + if ($LASTEXITCODE -eq 0) { + Add-Pass $pytestOutput + } else { + Add-Fail "pytest not installed (pip install pytest)" + } +} else { + Add-Fail "pytest not checked because python is missing" +} + +if (Get-Command black -ErrorAction SilentlyContinue) { + Add-Pass "black (formatter)" +} else { + Add-Warn "black not installed - pre-commit hook will fail (pip install black)" +} + +Write-Host "" +Write-Host "Python packages:" + +$missingPackages = @() +foreach ($pkg in @("pydantic", "fastapi", "firebase_admin", "google.cloud.firestore", "redis", "deepgram_sdk", "openpipe")) { + if (-not $Script:PythonLauncher) { + $missingPackages += $pkg + Add-Warn "$pkg not checked because python is missing" + continue + } + + Invoke-SelectedPython @("-c", "import $pkg") *> $null + if ($LASTEXITCODE -eq 0) { + Add-Pass $pkg + } else { + $missingPackages += $pkg + Add-Warn "$pkg not importable" + } +} + +if ($missingPackages.Count -gt 0) { + Write-Host " -> Run: pip install -r requirements.txt" -ForegroundColor Yellow +} + +Write-Host "" +Write-Host "Env vars (unit tests):" + +if ($env:ENCRYPTION_SECRET) { + Add-Pass "ENCRYPTION_SECRET (set in env)" +} else { + Add-Pass "ENCRYPTION_SECRET (set by test.sh - no action needed)" +} + +Write-Host "" +Write-Host "Env vars (integration - optional):" + +function Test-OptionalEnv { + param( + [string]$Name, + [string]$Description + ) + if ([Environment]::GetEnvironmentVariable($Name)) { + Add-Pass "$Name ($Description)" + } else { + Add-Warn "$Name not set ($Description)" + } +} + +Test-OptionalEnv "OPENAI_API_KEY" "LLM calls - some integration tests skip without it" +Test-OptionalEnv "DEEPGRAM_API_KEY" "STT streaming and pre-recorded transcription" +Test-OptionalEnv "ADMIN_KEY" "admin endpoint tests" +Test-OptionalEnv "REDIS_DB_HOST" "Redis connection (default: localhost)" +Test-OptionalEnv "REDIS_DB_PASSWORD" "Redis auth" +Test-OptionalEnv "GOOGLE_APPLICATION_CREDENTIALS" "Firebase/Firestore integration tests" + +Write-Host "" +Write-Host "Services:" + +$redisCli = Get-Command redis-cli -ErrorAction SilentlyContinue +if ($redisCli) { + $redisHost = if ($env:REDIS_DB_HOST) { $env:REDIS_DB_HOST } else { "localhost" } + $redisPort = if ($env:REDIS_DB_PORT) { $env:REDIS_DB_PORT } else { "6379" } + $redisArgs = @("-h", $redisHost, "-p", $redisPort) + if ($env:REDIS_DB_PASSWORD) { + $redisArgs += @("-a", $env:REDIS_DB_PASSWORD) + } + $redisArgs += "ping" + + & $redisCli.Source @redisArgs *> $null + if ($LASTEXITCODE -eq 0) { + Add-Pass "Redis ($redisHost`:$redisPort) - connected" + } else { + Add-Warn "Redis ($redisHost`:$redisPort) - not reachable (integration tests may fail)" + } +} else { + Add-Warn "redis-cli not installed - cannot check Redis connectivity" +} + +Write-Host "" +Write-Host "Test files:" + +$unitTests = @(Get-ChildItem -Path "tests/unit" -Filter "test_*.py" -Recurse -ErrorAction SilentlyContinue) +if ($unitTests.Count -gt 0) { + Add-Pass "$($unitTests.Count) unit test files found" +} else { + Add-Fail "No unit test files found in tests/unit/" +} + +$missingTests = @() +if (Test-Path "test.sh") { + foreach ($line in Get-Content "test.sh") { + if ($line -match '^pytest\s+(tests/\S+)') { + $testFile = $Matches[1] + if (-not (Test-Path $testFile)) { + $missingTests += $testFile + } + } + } + + if ($missingTests.Count -gt 0) { + Add-Fail "test.sh references missing files: $($missingTests -join ', ')" + } else { + Add-Pass "All test.sh references resolve to existing files" + } +} else { + Add-Fail "test.sh not found" +} + +Write-Host "" +Write-Host "Summary:" +$total = $PassCount + $WarnCount + $FailCount +Write-Host " $PassCount passed $WarnCount warnings $FailCount failed ($total checks)" + +if ($FailCount -gt 0) { + Write-Host " Fix failures above before running test.sh" -ForegroundColor Red + exit 1 +} + +if ($WarnCount -gt 0) { + Write-Host " Warnings are optional - unit tests should still pass" -ForegroundColor Yellow + exit 0 +} + +Write-Host " All clear - ready to run test.sh" -ForegroundColor Green +exit 0 From ca5f7e8f854ef2f87d74d0b7a9eabc065d3345ab Mon Sep 17 00:00:00 2001 From: 491034170 <142008960+491034170@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:43:14 +0800 Subject: [PATCH 2/2] docs(backend): fix Windows preflight invocation --- backend/README.md | 2 +- backend/test-preflight.ps1 | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/README.md b/backend/README.md index 72227694da9..06f71e24d6b 100644 --- a/backend/README.md +++ b/backend/README.md @@ -126,7 +126,7 @@ bash test-preflight.sh Windows PowerShell: ```powershell -.\test-preflight.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File .\test-preflight.ps1 ``` The preflight script does not replace `test.sh`; it only catches setup issues before running the tests. diff --git a/backend/test-preflight.ps1 b/backend/test-preflight.ps1 index b54ff8364e3..53dd69bcb50 100644 --- a/backend/test-preflight.ps1 +++ b/backend/test-preflight.ps1 @@ -3,7 +3,7 @@ param() $ErrorActionPreference = "Continue" $RootDir = Split-Path -Parent $MyInvocation.MyCommand.Path -Set-Location $RootDir +Push-Location $RootDir $PassCount = 0 $WarnCount = 0 @@ -37,6 +37,8 @@ function Invoke-SelectedPython { } } +try { + Write-Host "Tools:" $pythonCommand = Get-Command python -ErrorAction SilentlyContinue @@ -194,3 +196,7 @@ if ($WarnCount -gt 0) { Write-Host " All clear - ready to run test.sh" -ForegroundColor Green exit 0 + +} finally { + Pop-Location +}