hermes-agent/scripts/tests/test-install-ps1-gitbash-compatibility.ps1

120 lines
4.3 KiB
PowerShell

# Unit tests for install.ps1's Git Bash compatibility and Mandatory-ASLR
# guidance helpers. The installer itself is never executed: functions are
# extracted through the PowerShell AST to avoid downloads, PATH changes, or
# user-environment writes.
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path))
$installScript = Join-Path $repoRoot "scripts\install.ps1"
$failures = 0
function Assert-Equal {
param($Expected, $Actual, [string]$Label)
if ($Expected -ne $Actual) {
Write-Host "FAIL: $Label" -ForegroundColor Red
Write-Host " expected: $Expected"
Write-Host " actual: $Actual"
$script:failures++
} else {
Write-Host "OK: $Label" -ForegroundColor Green
}
}
function Assert-True {
param($Condition, [string]$Label)
if (-not $Condition) {
Write-Host "FAIL: $Label" -ForegroundColor Red
$script:failures++
} else {
Write-Host "OK: $Label" -ForegroundColor Green
}
}
$tokens = $null
$parseErrors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
$installScript, [ref]$tokens, [ref]$parseErrors
)
if ($parseErrors.Count -gt 0) {
throw "install.ps1 has parse errors: $($parseErrors -join '; ')"
}
foreach ($name in @(
"Test-GitBashCompatibility",
"Test-MandatoryAslrEnabled",
"Get-GitRootFromBashPath",
"New-GitBashAslrFailureReason",
"Stage-Git"
)) {
$fnAst = $ast.FindAll(
{
param($node)
$node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and
$node.Name -eq $name
}, $true
) | Select-Object -First 1
if (-not $fnAst) { throw "$name not found in install.ps1" }
. ([scriptblock]::Create($fnAst.Extent.Text))
}
Write-Host ""
Write-Host "-- Git root resolution --"
Assert-Equal "C:\Program Files\Git" `
(Get-GitRootFromBashPath "C:\Program Files\Git\bin\bash.exe") `
"PortableGit/full Git bin layout"
Assert-Equal "C:\Program Files\Git" `
(Get-GitRootFromBashPath "C:\Program Files\Git\usr\bin\bash.exe") `
"usr/bin layout"
Write-Host ""
Write-Host "-- Mandatory ASLR detection --"
function Get-ProcessMitigation {
param([switch]$System)
[pscustomobject]@{ Aslr = [pscustomobject]@{ ForceRelocateImages = "ON" } }
}
Assert-Equal $true (Test-MandatoryAslrEnabled) "ForceRelocateImages ON is detected"
function Get-ProcessMitigation {
param([switch]$System)
[pscustomobject]@{ Aslr = [pscustomobject]@{ ForceRelocateImages = "NOTSET" } }
}
Assert-Equal $false (Test-MandatoryAslrEnabled) "ForceRelocateImages NOTSET is not diagnosed"
Write-Host ""
Write-Host "-- Actionable remediation --"
$reason = New-GitBashAslrFailureReason "C:\Program Files\Git\bin\bash.exe"
Assert-True ($reason -match "Mandatory ASLR") "reason identifies Mandatory ASLR"
Assert-True ($reason -match "Reinstalling Git will not change") "reason rejects ineffective reinstall"
Assert-True ($reason -match [regex]::Escape("C:\Program Files\Git")) "reason uses selected Git root"
Assert-True ($reason -match "Set-ProcessMitigation") "reason includes targeted mitigation command"
Write-Host ""
Write-Host "-- External-program probe --"
$gitCommand = Get-Command git -ErrorAction SilentlyContinue
$gitBash = $null
if ($gitCommand -and $gitCommand.Source) {
$gitRoot = Split-Path (Split-Path $gitCommand.Source -Parent) -Parent
foreach ($candidate in @("$gitRoot\bin\bash.exe", "$gitRoot\usr\bin\bash.exe")) {
if (Test-Path -LiteralPath $candidate) { $gitBash = $candidate; break }
}
}
if ($gitBash) {
Assert-Equal $true (Test-GitBashCompatibility $gitBash) `
"installed Git Bash launches external MSYS programs"
} else {
Write-Host "SKIP: no Git Bash found next to git.exe" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "-- Stage failure propagation --"
function Install-Git { return $false }
$script:GitInstallFailureReason = "specific Git Bash failure"
$stageError = $null
try { Stage-Git } catch { $stageError = $_.Exception.Message }
Assert-Equal "specific Git Bash failure" $stageError "Git stage preserves actionable reason"
Write-Host ""
if ($failures -gt 0) {
Write-Host "FAILED: $failures assertion(s) failed" -ForegroundColor Red
exit 1
}
Write-Host "All Git Bash compatibility tests passed." -ForegroundColor Green
exit 0