param( # Unit/Render/UI 可单独执行;NonUI 跳过界面操作;All 是完整回归。 [ValidateSet('Unit', 'Render', 'UI', 'NonUI', 'All', 'CI')] [string]$Suite = 'Unit', [ValidateSet('Debug', 'Release')] [string]$Configuration = 'Debug', [ValidateSet('x64', 'Win32')] [string]$Platform = 'x64' ) # 统一测试入口:负责构建指定矩阵,并把所有诊断结果集中到 TestResults。 $ErrorActionPreference = 'Stop' # 暂时清空再恢复 PATH,避免 MSBuild/VSTest 被其他工具链中的同名程序劫持。 $savedPath = $env:Path [Environment]::SetEnvironmentVariable('PATH', $null, [EnvironmentVariableTarget]::Process) [Environment]::SetEnvironmentVariable('Path', $savedPath, [EnvironmentVariableTarget]::Process) $root = Split-Path -Parent $PSScriptRoot $msbuild = if ($env:STELLARX_MSBUILD) { $env:STELLARX_MSBUILD } else { 'D:\vs2022\MSBuild\Current\Bin\MSBuild.exe' } $vstest = if ($env:STELLARX_VSTEST) { $env:STELLARX_VSTEST } else { 'D:\vs2022\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe' } $results = Join-Path $root 'TestResults' # 测试输出目录允许未跟踪生成 TRX、JSON、日志和截图,不写入源码目录。 New-Item -ItemType Directory -Force -Path $results | Out-Null if (-not (Test-Path -LiteralPath $msbuild)) { throw "MSBuild not found: $msbuild" } if (-not (Test-Path -LiteralPath $vstest)) { throw "VSTest not found: $vstest" } function Build-Project([string]$project, [string]$config, [string]$arch, [bool]$asan = $false) { # ASan 使用 Rebuild,确保运行库和插桩设置不会沿用上一种构建配置。 $asanValue = if ($asan) { 'true' } else { 'false' } $target = if ($asan) { 'Rebuild' } else { 'Build' } & $msbuild $project /m /t:$target /p:Configuration=$config /p:Platform=$arch /p:EnableAsan=$asanValue /v:minimal if ($LASTEXITCODE -ne 0) { throw "Build failed: $project ($config|$arch)" } } function Run-Unit([string]$config, [string]$arch, [bool]$asan = $false) { # Native Unit Test 在隔离进程中运行,单个 UAF 回归不会直接拖垮 VSTest 宿主。 $project = Join-Path $root 'tests\StellarX.Tests.vcxproj' Build-Project $project $config $arch $asan $outputConfig = if ($asan) { "$config-asan" } else { $config } $dll = Join-Path $root "build\$arch\$outputConfig\StellarX.Tests.dll" $trxName = "unit-$arch-$config" + $(if ($asan) { '-asan' } else { '' }) + '.trx' $savedAsanOptions = $env:ASAN_OPTIONS try { # 只对 ASan 用例启用遇错即停;退出后恢复调用者原有环境变量。 if ($asan) { $env:ASAN_OPTIONS = 'halt_on_error=1:detect_leaks=0' } & $vstest $dll /InIsolation /Logger:"trx;LogFileName=$trxName" /ResultsDirectory:$results if ($LASTEXITCODE -ne 0) { throw "Unit tests failed: $dll" } } finally { $env:ASAN_OPTIONS = $savedAsanOptions } } function Run-UI([int]$repeat = 1) { # EasyX 依赖交互式桌面,UI fixture 始终固定使用 Debug x64 并串行运行。 Build-Project (Join-Path $root 'tests\StellarX.UiFixture.vcxproj') 'Debug' 'x64' & (Join-Path $PSScriptRoot 'run-ui-tests.ps1') -Repeat $repeat if ($LASTEXITCODE -ne 0) { throw 'UI tests failed' } } function Build-KeyScenarios { # KEY1-KEY6 是应用现有主路径的编译/链接冒烟,不在这里模拟鼠标交互。 $project = Join-Path $root 'imGui-easyX.vcxproj' foreach ($key in 1..6) { & $msbuild $project /m /t:Build /p:Configuration=Debug /p:Platform=x64 /p:KeyScenario=$key /p:EnableAsan=false /v:minimal if ($LASTEXITCODE -ne 0) { throw "KEY$key build failed" } } } function Run-NonUI { # 提交前非交互矩阵:覆盖内存安全、多架构、Release 和现有 KEY 编译场景。 Run-Unit 'Debug' 'x64' Run-Unit 'Debug' 'x64' $true Run-Unit 'Release' 'x64' Run-Unit 'Debug' 'Win32' Build-KeyScenarios } switch ($Suite) { # Render 当前复用真实 UI fixture 的像素检查;All 在 NonUI 基础上追加三轮 UI。 'Unit' { Run-Unit $Configuration $Platform } 'Render' { Run-UI 1 } 'UI' { Run-UI 1 } 'NonUI' { Run-NonUI } 'All' { Run-NonUI; Run-UI 3 } 'CI' { Run-Unit 'Debug' 'x64' Run-Unit 'Release' 'x64' Run-Unit 'Debug' 'Win32' if ($env:STELLARX_UI_TESTS -eq '1') { Run-UI 1 } } }