[CmdletBinding()] param( [string]$RepoRoot = (Split-Path -Parent $PSScriptRoot), [string]$BuildDir = "", [string]$Config = "Debug", [switch]$SkipBuild, [switch]$IncludeSmoke, [switch]$SkipCtestEnumerate ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" function Resolve-NormalizedPath { param( [Parameter(Mandatory = $true)] [string]$Path ) if (Test-Path -LiteralPath $Path) { return (Resolve-Path -LiteralPath $Path).Path } return [System.IO.Path]::GetFullPath($Path) } function Join-NormalizedPath { param( [Parameter(Mandatory = $true)] [string[]]$Parts ) return [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($Parts)) } function Assert-PathExists { param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [string]$Label ) if (-not (Test-Path -LiteralPath $Path)) { throw "$Label not found: $Path" } } function Invoke-NativeStep { param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$FilePath, [string[]]$Arguments = @() ) Write-Host "==> $Name" -ForegroundColor Cyan & $FilePath @Arguments $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { throw "$Name failed with exit code $exitCode." } } function Invoke-CtestEnumeration { param( [Parameter(Mandatory = $true)] [string]$BuildDir, [Parameter(Mandatory = $true)] [string]$Config ) Write-Host "==> Enumerate CTest registry" -ForegroundColor Cyan $output = & ctest --test-dir $BuildDir -N -C $Config 2>&1 $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { $output | ForEach-Object { Write-Host $_ } throw "Enumerate CTest registry failed with exit code $exitCode." } $lines = $output | ForEach-Object { $_.ToString() } $registeredCount = ($lines | Where-Object { $_ -match '^\s*Test\s+#\d+:' }).Count $notBuiltCount = ($lines | Where-Object { $_ -match '_NOT_BUILT' }).Count $totalLine = $lines | Where-Object { $_ -match '^Total Tests:\s+\d+' } | Select-Object -Last 1 if ($null -ne $totalLine) { Write-Host ("{0}; NOT_BUILT placeholders: {1}" -f $totalLine.Trim(), $notBuiltCount) ` -ForegroundColor DarkGray } else { Write-Host ("CTest enumeration completed; registered tests: {0}; NOT_BUILT placeholders: {1}" ` -f $registeredCount, $notBuiltCount) -ForegroundColor DarkGray } } $RepoRoot = Resolve-NormalizedPath -Path $RepoRoot if ([string]::IsNullOrWhiteSpace($BuildDir)) { $BuildDir = Join-NormalizedPath -Parts @($RepoRoot, "build") } else { $BuildDir = Resolve-NormalizedPath -Path $BuildDir } $ctestRoot = Join-NormalizedPath -Parts @($BuildDir, "CTestTestfile.cmake") Assert-PathExists -Path $ctestRoot -Label "CTest root" $scriptingExe = Join-NormalizedPath -Parts @( $BuildDir, "tests", "Scripting", $Config, "scripting_tests.exe") $windowingExe = Join-NormalizedPath -Parts @( $BuildDir, "tests", "UI", "Editor", "unit", $Config, "editor_windowing_phase1_tests.exe") $srpValidationTests = @( "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeRuntimeExposesDefaultNativeBackendPolicy", "MonoScriptRuntimeTest.ScriptCoreUniversalRenderPipelineAssetExposesDefaultNativeBackendPolicy", "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeUsesDefaultRendererSelectionForNativeBackendPolicy", "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeUsesCameraRendererOverrideAcrossPlanningAndExecution", "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeRebuildsRendererAfterRendererDataInvalidation", "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeReleasesPersistentRendererFeatureAcrossRendererInvalidationAndAssetRuntimeRelease", "MonoScriptRuntimeTest.ManagedRenderPipelineBridgeRebuildsPipelineAfterAssetInvalidation", "MonoScriptRuntimeTest.ManagedRenderPipelineAssetPlansFullscreenStagesFromPipelineStageSupport", "MonoScriptRuntimeTest.ManagedRendererFeatureConfiguresCameraFramePlanThroughPlanningContext", "ProjectScriptAssemblyTest.ProjectManagedBridgeRebuildsRendererAfterProjectRendererDataInvalidation", "ProjectScriptAssemblyTest.ProjectManagedBridgeReleasesProjectRendererCachesAcrossInvalidationAndAssetRuntimeRelease", "ProjectScriptAssemblyTest.ProjectManagedBridgeRebuildsPipelineAfterProjectAssetInvalidation" ) $srpValidationFilter = [string]::Join(":", $srpValidationTests) Push-Location $RepoRoot try { if (-not $SkipBuild) { $buildTargets = @( "scripting_tests", "editor_windowing_phase1_tests" ) if ($IncludeSmoke) { $buildTargets += "editor_ui_smoke_targets" } $buildArguments = @( "--build", $BuildDir, "--config", $Config, "--target" ) + $buildTargets Invoke-NativeStep ` -Name "Build renderer phase regression targets ($Config)" ` -FilePath "cmake" ` -Arguments $buildArguments } Assert-PathExists -Path $scriptingExe -Label "scripting_tests.exe" Assert-PathExists -Path $windowingExe -Label "editor_windowing_phase1_tests.exe" if (-not $SkipCtestEnumerate) { Write-Host "ctest enumeration may still print *_NOT_BUILT placeholders for targets that were not built." ` -ForegroundColor DarkGray Invoke-CtestEnumeration -BuildDir $BuildDir -Config $Config } Invoke-NativeStep ` -Name "Run managed SRP validation batch (12 tests)" ` -FilePath $scriptingExe ` -Arguments @("--gtest_filter=$srpValidationFilter") Invoke-NativeStep ` -Name "Run editor windowing phase1 tests" ` -FilePath $windowingExe if ($IncludeSmoke) { Invoke-NativeStep ` -Name "Run XCUI editor smoke" ` -FilePath "ctest" ` -Arguments @( "--test-dir", $BuildDir, "-C", $Config, "-R", "^xcui_editor_app_smoke$", "--output-on-failure" ) } Write-Host "Renderer phase regression passed." -ForegroundColor Green } finally { Pop-Location }