Files
ai-media-hub/scripts/selftest.ps1
T
GHStaK 139e8f8781
build-push / docker (push) Successful in 4m7s
Add Windows PowerShell dev workflow
2026-03-17 15:47:01 +09:00

159 lines
5.6 KiB
PowerShell

param(
[int]$MockPort = 18080,
[int]$AppPort = 18081,
[switch]$SkipGoFmt
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "dev-tools.ps1")
Use-LocalTooling
$repoRoot = Get-RepoRoot
$tmpRoot = Join-Path (Get-LocalRoot) ("selftest-" + [guid]::NewGuid().ToString("N"))
Ensure-Directory -Path $tmpRoot
$mockProcess = $null
$appProcess = $null
$appStdoutTask = $null
$appStderrTask = $null
function Stop-TrackedProcess {
param($Process)
if ($null -ne $Process -and -not $Process.HasExited) {
Stop-Process -Id $Process.Id -Force
$Process.WaitForExit()
}
}
try {
if (-not $SkipGoFmt) {
Write-Step "gofmt"
Invoke-CheckedCommand -FilePath "gofmt" -Arguments @(
"-w",
(Join-Path $repoRoot "backend\main.go"),
(Join-Path $repoRoot "backend\handlers\api.go"),
(Join-Path $repoRoot "backend\models\db.go"),
(Join-Path $repoRoot "backend\services\cse.go"),
(Join-Path $repoRoot "backend\services\cse_test.go"),
(Join-Path $repoRoot "backend\services\search_collectors.go"),
(Join-Path $repoRoot "backend\services\ranker.go"),
(Join-Path $repoRoot "backend\services\gemini.go"),
(Join-Path $repoRoot "backend\services\gemini_test.go")
)
}
Write-Step "python syntax"
Invoke-CheckedCommand -FilePath (Resolve-VenvPythonExe) -Arguments @(
"-m",
"py_compile",
(Join-Path $repoRoot "worker\downloader.py"),
(Join-Path $repoRoot "scripts\mock_searxng.py")
)
Write-Step "go test"
Invoke-CheckedCommand -FilePath "go" -Arguments @("test", "./...")
Write-Step "frontend syntax"
Invoke-CheckedCommand -FilePath "node" -Arguments @("--check", (Join-Path $repoRoot "frontend\app.js"))
Write-Step "go build"
$binaryPath = Join-Path $tmpRoot "ai-media-hub.exe"
Invoke-CheckedCommand -FilePath "go" -Arguments @("build", "-o", $binaryPath, "./backend")
Write-Step "start mock searxng"
$mockLog = Join-Path $tmpRoot "mock-searxng.stdout.log"
$mockErrLog = Join-Path $tmpRoot "mock-searxng.stderr.log"
$mockProcess = Start-Process -FilePath (Resolve-VenvPythonExe) `
-ArgumentList @((Join-Path $repoRoot "scripts\mock_searxng.py"), "--port", $MockPort) `
-RedirectStandardOutput $mockLog `
-RedirectStandardError $mockErrLog `
-PassThru `
-WindowStyle Hidden
Write-Step "start app"
$downloadsDir = Join-Path $tmpRoot "downloads"
Ensure-Directory -Path $downloadsDir
$appLog = Join-Path $tmpRoot "app.log"
$envMap = Get-AppEnvironment `
-WorkspaceRoot $repoRoot `
-DownloadsDir $downloadsDir `
-SqlitePath (Join-Path $tmpRoot "media.db") `
-AppAddr ("127.0.0.1:{0}" -f $AppPort) `
-SearxUrl ("http://127.0.0.1:{0}" -f $MockPort)
$appStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$appStartInfo.FileName = $binaryPath
$appStartInfo.WorkingDirectory = $repoRoot
$appStartInfo.UseShellExecute = $false
$appStartInfo.RedirectStandardOutput = $true
$appStartInfo.RedirectStandardError = $true
foreach ($entry in $envMap.GetEnumerator()) {
$appStartInfo.Environment[$entry.Key] = [string]$entry.Value
}
$appProcess = New-Object System.Diagnostics.Process
$appProcess.StartInfo = $appStartInfo
$null = $appProcess.Start()
$appStdoutTask = $appProcess.StandardOutput.ReadToEndAsync()
$appStderrTask = $appProcess.StandardError.ReadToEndAsync()
$healthUrl = "http://127.0.0.1:$AppPort/healthz"
$healthy = $false
for ($i = 0; $i -lt 30; $i++) {
try {
$health = Invoke-RestMethod -Uri $healthUrl -TimeoutSec 2
if ($health.status -eq "ok") {
$healthy = $true
break
}
} catch {
Start-Sleep -Seconds 1
}
}
if (-not $healthy) {
throw "/healthz 확인 실패"
}
Write-Step "verify search"
$searchPayload = @{
query = "city rain"
platforms = @("envato", "artgrid", "google video")
} | ConvertTo-Json
$search = Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:$AppPort/api/search" -ContentType "application/json" -Body $searchPayload
$searchResults = @($search.results)
if ($null -eq $search.results -or $searchResults.Count -lt 2) {
throw "검색 결과가 너무 적습니다."
}
if (@($searchResults | Where-Object { -not $_.link }).Count -gt 0) {
throw "검색 결과에 link가 비어 있습니다."
}
Write-Step "verify upload"
$sampleFile = Join-Path $tmpRoot "sample.txt"
Set-Content -LiteralPath $sampleFile -Value "selftest upload" -Encoding UTF8
$form = @{
file = Get-Item -LiteralPath $sampleFile
}
$upload = Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:$AppPort/api/upload" -Form $form
if (-not $upload.filename) {
throw "업로드 응답에 filename이 없습니다."
}
$uploadedPath = Join-Path $downloadsDir $upload.filename
if (-not (Test-Path -LiteralPath $uploadedPath)) {
throw "업로드된 파일이 downloads에 존재하지 않습니다."
}
Write-Step "selftest ok"
} finally {
Stop-TrackedProcess -Process $appProcess
Stop-TrackedProcess -Process $mockProcess
if ($appStdoutTask) {
$appStdoutTask.Wait()
$appStdoutTask.Result | Set-Content -LiteralPath (Join-Path $tmpRoot "app.log") -Encoding UTF8
}
if ($appStderrTask) {
$appStderrTask.Wait()
$appStderrTask.Result | Add-Content -LiteralPath (Join-Path $tmpRoot "app.log") -Encoding UTF8
}
}