param([Parameter(Mandatory = $true)][string]$PackageRoot) Set-StrictMode -Version 3.0 $ErrorActionPreference = 'Stop' $root = [IO.Path]::GetFullPath($PackageRoot) $port = [int]$env:SENSE_PORT $mediaUri = [Uri]$env:SENSE_MEDIAMTX_API $stdout = Join-Path ([IO.Path]::GetTempPath()) ("sense-smoke-$PID.out") $stderr = Join-Path ([IO.Path]::GetTempPath()) ("sense-smoke-$PID.err") $server = $null $succeeded = $false try { & (Join-Path $root 'migrate-sense.bat') if ($LASTEXITCODE -ne 0) { throw 'Package migration entry failed.' } if (-not [IO.Path]::IsPathRooted($env:SENSE_MEDIAMTX_BINARY)) { $env:SENSE_MEDIAMTX_BINARY = [IO.Path]::GetFullPath((Join-Path $root $env:SENSE_MEDIAMTX_BINARY)) } if (-not [IO.Path]::IsPathRooted($env:SENSE_MEDIAMTX_CONFIG)) { $env:SENSE_MEDIAMTX_CONFIG = [IO.Path]::GetFullPath((Join-Path $root $env:SENSE_MEDIAMTX_CONFIG)) } if (-not [IO.Path]::IsPathRooted($env:SENSE_WEB_ROOT)) { $env:SENSE_WEB_ROOT = [IO.Path]::GetFullPath((Join-Path $root $env:SENSE_WEB_ROOT)) } $settings = Join-Path $root 'data\runtime\settings.yml' $server = Start-Process -FilePath (Join-Path $root 'sense.exe') -ArgumentList 'server', '-c', $settings -WorkingDirectory $root -RedirectStandardOutput $stdout -RedirectStandardError $stderr -WindowStyle Hidden -PassThru $response = $null for ($attempt = 0; $attempt -lt 80; $attempt++) { $server.Refresh() if ($server.HasExited) { Get-Content -LiteralPath $stdout -Tail 120 -ErrorAction SilentlyContinue | Out-Host Get-Content -LiteralPath $stderr -Tail 120 -ErrorAction SilentlyContinue | Out-Host throw "Sense exited before HTTP readiness with code $($server.ExitCode)." } try { $response = Invoke-WebRequest -UseBasicParsing -Uri "http://127.0.0.1:$port/" -TimeoutSec 1 if ($response.StatusCode -eq 200 -and $response.Content.Contains('')) { break } } catch {} Start-Sleep -Milliseconds 500 } if (-not $response -or $response.StatusCode -ne 200 -or -not $response.Content.Contains('<title>')) { throw 'Sense package did not serve the GoAdmin UI before the smoke timeout.' } $media = $null for ($attempt = 0; $attempt -lt 20; $attempt++) { try { $media = Invoke-RestMethod -Uri "http://$($mediaUri.Host):$($mediaUri.Port)/v3/config/global/get" -TimeoutSec 1 if ($null -ne $media) { break } } catch {} Start-Sleep -Milliseconds 500 } if ($null -eq $media) { throw 'MediaMTX Control API returned no data.' } Write-Host "Sense package smoke passed: web=200, SPA=true, MediaMTX=true, port=$port." $succeeded = $true } finally { if ($server -and -not $server.HasExited) { & taskkill.exe /PID $server.Id /T /F | Out-Null } Remove-Item -LiteralPath $stdout, $stderr -Force -ErrorAction SilentlyContinue }