跳转至

scripts\smoke-pages.ps1

源码路径:scripts\smoke-pages.ps1 · 124 行

# 逐页冒烟测试:把功能树上的**每一页**都开一遍,确认真的开对了页。
#
# 用法:
#   .\scripts\smoke-pages.ps1                 # 用已有的 target\release\nfarms.exe
#   .\scripts\smoke-pages.ps1 -Build          # 先编再测
#   .\scripts\smoke-pages.ps1 -Only "weather,topo"
#   .\scripts\smoke-pages.ps1 -SettleMs 2500  # 慢机器上多等一会儿
#
# 为什么不是「开起来就算过」:进程活着只能说明窗口建起来了,**不能说明开对了页**。
# 所以判据是日志里那一行 `界面启动,首页=<id>` —— 那是界面自己写下来的。
#
# 页面清单也不是脚本里写死的:`--list-pages` 问程序要。页面从「常量数组」
# 变成「插件注册表的产物」之后,脚本自己拼一份清单只会越来越快地过期。

[CmdletBinding()]
param(
    [switch]$Build,
    [string]$Only = '',
    [int]$SettleMs = 1800,
    [string]$Exe = 'target\release\nfarms.exe'
)

$ErrorActionPreference = 'Continue'
$ws = Split-Path -Parent $PSScriptRoot

if ($Build) {
    & (Join-Path $PSScriptRoot 'build-release.ps1')
    if (-not (Test-Path (Join-Path $ws 'target\release\nfarms.exe'))) { throw '编译失败' }
}

$exe = if ([System.IO.Path]::IsPathRooted($Exe)) { $Exe } else { Join-Path $ws $Exe }
if (-not (Test-Path $exe)) { throw "找不到 $exe —— 先跑 .\scripts\build-release.ps1 或加 -Build" }
$exeDir = Split-Path -Parent $exe

# ---------------------------------------------------------------- 页面清单
# 本程序是 Windows(GUI)子系统:PowerShell 直接 `&` 调用既不等待也拿不到输出,
# 必须用 cmd 重定向到文件再读(这条坑原版 README 里记过)。
function Invoke-Cli([string[]]$CliArgs) {
    $probe = Join-Path $env:TEMP ("nfarms-smoke-" + [guid]::NewGuid().ToString('N').Substring(0, 8) + ".txt")
    $cmd = '"{0}" {1} > "{2}" 2>&1' -f $exe, ($CliArgs -join ' '), $probe
    cmd /c $cmd | Out-Null
    $text = if (Test-Path $probe) { Get-Content $probe -Encoding UTF8 -Raw } else { '' }
    Remove-Item $probe -Force -ErrorAction SilentlyContinue
    return $text
}

$listed = Invoke-Cli @('--list-pages')
if (-not $listed) { throw '--list-pages 没有输出' }

$pages = @()
foreach ($line in ($listed -split "`r?`n")) {
    if (-not $line -or $line.StartsWith('#')) { continue }
    $pages += ($line -split "`t")[0]
}
if ($pages.Count -eq 0) { throw '页面清单是空的' }
if ($Only) {
    $want = $Only.Split(',') | ForEach-Object { $_.Trim() } | Where-Object { $_ }
    $pages = $pages | Where-Object { $want -contains $_ }
    if ($pages.Count -eq 0) { throw "-Only 指定的页一页都不在清单里:$Only" }
}

# ---------------------------------------------------------------- 日志位置
# **别自己拼 `<exe 目录>\logs`**:布局已经扁平化,exe 就在程序根,
# 而程序根上溯到了 `bin\` 的上一层 —— 日志在 `<安装目录>\logs`,不在 bin 下面。
# 这个差别让「装的版本冒烟全挂、编译目录里却全过」,查起来很费劲。
# 所以直接问程序:--logs 的第一行就是它自己在用的日志文件。
$logsOut = Invoke-Cli @('--logs')
$logFile = $null
$m = [regex]::Match($logsOut, '(?m)^主日志\s*:\s*(.+?)\s*$')
if ($m.Success) { $logFile = $m.Groups[1].Value }
if (-not $logFile) {
    # 老版本没这行输出时的兜底
    $logFile = Join-Path (Join-Path $exeDir 'logs') 'nfarms-hub.log'
}
$logDir = Split-Path -Parent $logFile
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Force -Path $logDir | Out-Null }
Write-Host "日志:$logFile" -ForegroundColor DarkGray

Write-Host ("逐页冒烟:{0} 页,每页等 {1} ms" -f $pages.Count, $SettleMs) -ForegroundColor Cyan
Write-Host ""

$fail = @()
$i = 0
foreach ($id in $pages) {
    $i++
    $before = if (Test-Path $logFile) { (Get-Item $logFile).Length } else { 0 }

    Start-Process -FilePath $exe -ArgumentList @('--page', $id) | Out-Null
    Start-Sleep -Milliseconds $SettleMs
    # 界面是 GUI 子系统,没有「跑完就退出」这回事 —— 只能到点收工
    Get-Process -Name 'nfarms' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
    Start-Sleep -Milliseconds 150

    $after = if (Test-Path $logFile) { (Get-Item $logFile).Length } else { 0 }
    $grew = $after -gt $before

    # 判据一:界面自己写下「首页=<id>」
    $tail = if ($grew) { Get-Content $logFile -Encoding UTF8 | Select-Object -Last 40 } else { @() }
    $started = $tail | Where-Object { $_ -match '\[gui\].*界面启动,首页=' } | Select-Object -Last 1
    $ok = $started -and $started.EndsWith("首页=$id")
    # 判据二:没有「本平台没装载这一页」这种退回
    $fellBack = ($tail | Where-Object { $_ -match '没有装载页面' }).Count -gt 0

    if ($ok -and -not $fellBack) {
        Write-Host ("  [{0,2}/{1}] {2,-18} OK" -f $i, $pages.Count, $id) -ForegroundColor DarkGreen
    } else {
        $why = if (-not $grew) { '日志没长 —— 进程大概没起来' }
               elseif (-not $started) { '日志里没有「界面启动」这一行' }
               elseif ($fellBack) { '界面报告该页没装载,退回了别的页' }
               else { "开的是别的页:$started" }
        Write-Host ("  [{0,2}/{1}] {2,-18} 失败 —— {3}" -f $i, $pages.Count, $id, $why) -ForegroundColor Red
        $fail += $id
    }
}

Write-Host ""
if ($fail.Count -eq 0) {
    Write-Host ("[OK] {0} 页全部开对" -f $pages.Count) -ForegroundColor Green
    exit 0
} else {
    Write-Host ("[x] {0} / {1} 页没过:{2}" -f $fail.Count, $pages.Count, ($fail -join ', ')) -ForegroundColor Red
    exit 1
}