Files
planet/scripts/harness/test_windows_launcher.ps1
rayd1o a2025dbfe0
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
release / images (push) Has been cancelled
ci / delivery (push) Has been cancelled
release: bump version to 0.75.2
2026-09-25 02:03:53 +08:00

128 lines
7.3 KiB
PowerShell

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot '..\windows\planet-launcher.ps1')
function Assert-Equal($Expected, $Actual, $Label) {
if ($Expected -cne $Actual) { throw "$Label expected [$Expected], got [$Actual]" }
}
foreach ($prefix in @('\\wsl$\', '\\wsl.localhost\')) {
$target = Get-PlanetTarget ($prefix + 'Ubuntu-24.04\home\alice\planet app')
Assert-Equal 'Ubuntu-24.04' $target.Distro 'UNC distribution'
Assert-Equal '/home/alice/planet app' $target.LinuxProjectRoot 'UNC Linux path'
}
$specialRoot = '/home/alice/planet ' + [char]0x5730 + [char]0x7403 + " ' & % ! `$ (demo)"
$target = Get-PlanetTarget ('\\wsl$\Debian' + $specialRoot.Replace('/', '\'))
Assert-Equal $specialRoot $target.LinuxProjectRoot 'Special characters'
function Invoke-WslText {
param([string[]]$Arguments)
if ($Arguments[1] -eq 'printenv') { return 'Ubuntu' }
Assert-Equal 'C:\Projects\Planet Space' $Arguments[-1] 'Windows path remains one argument'
return '/mnt/c/Projects/Planet Space'
}
$driveTarget = Get-PlanetTarget 'C:\Projects\Planet Space'
Assert-Equal 'Ubuntu' $driveTarget.Distro 'Default distribution'
Assert-Equal '/mnt/c/Projects/Planet Space' $driveTarget.LinuxProjectRoot 'Mounted drive'
foreach ($elevated in @($false, $true)) {
$bootstrap = Get-PlanetBootstrap $target -RunElevated:$elevated
$tokens = $null; $errors = $null
[void][Management.Automation.Language.Parser]::ParseInput($bootstrap, [ref]$tokens, [ref]$errors)
if ($errors.Count) { throw ($errors | Out-String) }
$encoded = ConvertTo-PlanetEncodedCommand $bootstrap
Assert-Equal $bootstrap ([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($encoded))) 'Encoded command roundtrip'
if ($bootstrap.Contains($specialRoot)) { throw 'Project path must remain encoded data' }
$match = [regex]::Match($bootstrap, "FromBase64String\('([A-Za-z0-9+/=]+)'\)")
$decoded = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($match.Groups[1].Value)) | ConvertFrom-Json
Assert-Equal $specialRoot $decoded.LinuxProjectRoot 'Bound target roundtrip'
}
function Test-PlanetAdministrator { return $true }
function wsl.exe {
$script:CapturedWslArguments = $args
$global:LASTEXITCODE = 17
Write-Output 'live-wsl-output'
}
$liveOutput = Start-PlanetRestart $target -AlreadyElevated
Assert-Equal 'live-wsl-output' $liveOutput 'WSL output is streamed, not returned as an exit-code array'
Assert-Equal 17 $script:PlanetLauncherExitCode 'WSL exit status preserved'
Assert-Equal $specialRoot $script:CapturedWslArguments[3] 'Working directory is one native argument'
Assert-Equal ($specialRoot + '/scripts/windows/restart.zsh') $script:CapturedWslArguments[8] 'Bridge path is one native argument'
$testDirectory = Join-Path ([IO.Path]::GetTempPath()) ('planet-launcher-tests-' + [guid]::NewGuid().ToString('N'))
[void][IO.Directory]::CreateDirectory($testDirectory)
try {
$launcher = Install-PlanetDesktopLauncher $target -Desktop $testDirectory
Assert-Equal 'Planet.cmd' ([IO.Path]::GetFileName($launcher)) 'First install'
$content = [IO.File]::ReadAllText($launcher)
if ($content -notmatch 'DisableDelayedExpansion' -or $content -notmatch '--install-only') {
throw 'Generated launcher lacks safe CMD mode or install-only option'
}
Assert-Equal $launcher (Install-PlanetDesktopLauncher $target -Desktop $testDirectory) 'Repeat install'
$other = Install-PlanetDesktopLauncher $driveTarget -Desktop $testDirectory
if ($other -eq $launcher) { throw 'Different projects must not overwrite each other' }
Assert-Equal $content ([IO.File]::ReadAllText($launcher)) 'Original target preserved'
[IO.File]::WriteAllText($launcher, 'unrelated user file')
$alternate = Install-PlanetDesktopLauncher $target -Desktop $testDirectory
if ($alternate -eq $launcher) { throw 'Unrelated file overwritten' }
Assert-Equal 'unrelated user file' ([IO.File]::ReadAllText($launcher)) 'User file preserved'
$missing = @{ Distro = 'Ubuntu'; LinuxProjectRoot = '/missing/planet-launcher-test-' + [guid]::NewGuid() }
try { Assert-PlanetTarget $missing; throw 'Missing project accepted' }
catch { if ($_.Exception.Message -notmatch 'P_WINDOWS_LAUNCHER_TARGET_MISSING') { throw } }
Write-Host 'PASS: UNC aliases, drive mapping, special paths, encoding, repeat installation, collisions, missing project'
} finally {
$resolved = [IO.Path]::GetFullPath($testDirectory)
$tempRoot = [IO.Path]::GetFullPath([IO.Path]::GetTempPath())
if (-not $resolved.StartsWith($tempRoot, [StringComparison]::OrdinalIgnoreCase) -or
[IO.Path]::GetFileName($resolved) -notlike 'planet-launcher-tests-*') { throw 'Unsafe cleanup path' }
Remove-Item -LiteralPath $resolved -Recurse -Force
}
function Get-Command {
param([string]$Name, [string]$CommandType, [string]$ErrorAction)
if ($script:AvailableLaunchCommands.ContainsKey($Name)) {
return [pscustomobject]@{ Source = $script:AvailableLaunchCommands[$Name] }
}
}
$pwshPath = 'C:\Program Files\PowerShell\7\pwsh.exe'
$terminalPath = 'C:\Users\Test\AppData\Local\Microsoft\WindowsApps\wt.exe'
$legacyPath = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
foreach ($hasTerminal in @($true, $false)) {
foreach ($hasPwsh in @($true, $false)) {
$script:AvailableLaunchCommands = @{ 'powershell.exe' = $legacyPath }
if ($hasTerminal) { $script:AvailableLaunchCommands['wt.exe'] = $terminalPath }
if ($hasPwsh) { $script:AvailableLaunchCommands['pwsh.exe'] = $pwshPath }
$launch = Get-PlanetTerminalLaunch 'TESTPAYLOAD'
$expectedShell = if ($hasPwsh) { $pwshPath } else { $legacyPath }
$expectedExecutable = if ($hasTerminal) { $terminalPath } else { $expectedShell }
Assert-Equal $expectedExecutable $launch.FilePath 'Terminal/shell priority'
if ($hasTerminal -and -not $launch.ArgumentList.Contains('"' + $expectedShell + '"')) {
throw 'Terminal shell path must be quoted, including Program Files paths'
}
if ($launch.ArgumentList -notmatch '-EncodedCommand TESTPAYLOAD$') {
throw 'Encoded bootstrap was not preserved'
}
}
}
function Test-PlanetAdministrator { return $script:IsTestAdministrator }
function Start-Process {
param($FilePath, $ArgumentList, $WindowStyle, $Verb)
$script:CapturedLaunch = @{ FilePath = $FilePath; ArgumentList = $ArgumentList; Verb = $Verb }
$script:LaunchCount++
}
$script:AvailableLaunchCommands = @{ 'pwsh.exe' = $pwshPath; 'wt.exe' = $terminalPath }
$script:LaunchCount = 0
foreach ($isAdmin in @($false, $true)) {
$script:IsTestAdministrator = $isAdmin
Start-PlanetRestart $target
Assert-Equal $terminalPath $script:CapturedLaunch.FilePath 'Admin and ordinary entry both use Terminal'
if ($isAdmin -and $script:CapturedLaunch.Verb) { throw 'Already elevated entry must not request UAC again' }
if (-not $isAdmin) { Assert-Equal 'RunAs' $script:CapturedLaunch.Verb 'Ordinary entry requires elevation' }
}
$script:IsTestAdministrator = $false
try { Start-PlanetRestart $target -AlreadyElevated; throw 'Unelevated child accepted' }
catch { if ($_.Exception.Message -ne 'Administrator elevation was not granted.') { throw } }
Assert-Equal 2 $script:LaunchCount 'Child must not recursively launch more windows'
Write-Host 'PASS: Terminal/PowerShell priority, quoted paths, elevation and no recursive dispatch'