Files
dosh/scripts/test-install-windows.ps1
DuProcess 7f8d5711ea
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
Unify release selection across clients
2026-07-17 18:58:58 -04:00

169 lines
6.8 KiB
PowerShell

$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$version = "9.8.7-rc3"
$root = Join-Path ([System.IO.Path]::GetTempPath()) ("dosh-installer-test-" + [guid]::NewGuid())
$webRoot = Join-Path $root "web"
$repoRoot = Join-Path $webRoot "repo"
$releaseRoot = Join-Path $repoRoot "releases\download\v$version"
$rawRoot = Join-Path $repoRoot "raw\branch\main"
$stageRoot = Join-Path $root "stage\dosh"
$requestLog = Join-Path $root "requests.log"
$prefix = Join-Path $root "prefix"
$home = Join-Path $root "home"
$unrelated = Join-Path $root "unrelated"
$job = $null
$savedBinaryVersion = $env:DOSH_BINARY_VERSION
$savedBinaryExact = $env:DOSH_BINARY_EXACT
function Invoke-TestInstaller($HomePath, $WorkingDirectory, $InstallPrefix, $Repository) {
$savedHome = $env:HOME
$savedUserProfile = $env:USERPROFILE
try {
$env:HOME = $HomePath
$env:USERPROFILE = $HomePath
Push-Location $WorkingDirectory
try {
$powershell = (Get-Process -Id $PID).Path
& $powershell -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "..\install.ps1") -Role client -Repo $Repository -Prefix $InstallPrefix -BinaryRequired
if ($LASTEXITCODE -ne 0) {
throw "Windows installer exited with status $LASTEXITCODE"
}
}
finally {
Pop-Location
}
}
finally {
$env:HOME = $savedHome
$env:USERPROFILE = $savedUserProfile
}
}
try {
New-Item -ItemType Directory -Force -Path $releaseRoot, $rawRoot, (Join-Path $stageRoot "bin"), $home, $unrelated | Out-Null
@"
[package]
name = "dosh"
version = "$version"
"@ | Set-Content -Encoding ascii -NoNewline (Join-Path $rawRoot "Cargo.toml")
@"
[package]
name = "not-dosh"
version = "99.0.0"
"@ | Set-Content -Encoding ascii -NoNewline (Join-Path $unrelated "Cargo.toml")
"$version`n" | Set-Content -Encoding ascii -NoNewline (Join-Path $stageRoot "VERSION")
"fixture" | Set-Content -Encoding ascii -NoNewline (Join-Path $stageRoot "bin\dosh-client.exe")
$archive = Join-Path $releaseRoot "dosh-windows-x86_64.zip"
Compress-Archive -Force -Path $stageRoot -DestinationPath $archive
$digest = (Get-FileHash -Algorithm SHA256 $archive).Hash.ToLowerInvariant()
"$digest dosh-windows-x86_64.zip`n" | Set-Content -Encoding ascii -NoNewline "$archive.sha256"
$probe = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback, 0)
$probe.Start()
$port = ([System.Net.IPEndPoint]$probe.LocalEndpoint).Port
$probe.Stop()
$listenPrefix = "http://127.0.0.1:$port/"
$job = Start-Job -ArgumentList $webRoot, $listenPrefix, $requestLog -ScriptBlock {
param($Root, $Prefix, $Log)
$listener = [System.Net.HttpListener]::new()
$listener.Prefixes.Add($Prefix)
$listener.Start()
try {
while ($listener.IsListening) {
$context = $listener.GetContext()
$path = [System.Uri]::UnescapeDataString($context.Request.Url.AbsolutePath.TrimStart('/'))
Add-Content -Encoding ascii -Path $Log -Value $context.Request.Url.AbsolutePath
$file = Join-Path $Root ($path.Replace('/', [System.IO.Path]::DirectorySeparatorChar))
if (Test-Path -LiteralPath $file -PathType Leaf) {
$bytes = [System.IO.File]::ReadAllBytes($file)
$context.Response.StatusCode = 200
$context.Response.ContentLength64 = $bytes.Length
if ($context.Request.HttpMethod -ne "HEAD") {
$context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
}
} else {
$context.Response.StatusCode = 404
}
$context.Response.Close()
}
}
finally {
$listener.Stop()
}
}
$ready = $false
for ($attempt = 0; $attempt -lt 50; $attempt++) {
try {
Invoke-WebRequest -UseBasicParsing -Uri "${listenPrefix}repo/raw/branch/main/Cargo.toml" | Out-Null
$ready = $true
break
}
catch {
Start-Sleep -Milliseconds 100
}
}
if (-not $ready) {
throw "installer fixture HTTP server did not start"
}
$env:DOSH_BINARY_VERSION = "v0.1.17"
Remove-Item Env:DOSH_BINARY_EXACT -ErrorAction SilentlyContinue
Invoke-TestInstaller $home $unrelated $prefix "${listenPrefix}repo.git"
if (-not (Test-Path (Join-Path $prefix "bin\dosh-client.exe"))) {
throw "Windows installer did not install dosh-client.exe"
}
$requests = Get-Content $requestLog -Raw
if ($requests -notmatch "/repo/raw/branch/main/Cargo.toml") {
throw "Windows installer did not read the repository release version"
}
if ($requests -notmatch "/repo/releases/download/v$([regex]::Escape($version))/dosh-windows-x86_64.zip") {
throw "Windows installer did not request the repository-declared release artifact"
}
if ($requests -match "/releases/latest" -or $requests -match "99.0.0") {
throw "Windows installer used a stable redirect or unrelated Cargo.toml"
}
"fixture-v2" | Set-Content -Encoding ascii -NoNewline (Join-Path $stageRoot "bin\dosh-client.exe")
Compress-Archive -Force -Path $stageRoot -DestinationPath $archive
$digest = (Get-FileHash -Algorithm SHA256 $archive).Hash.ToLowerInvariant()
"$digest dosh-windows-x86_64.zip`n" | Set-Content -Encoding ascii -NoNewline "$archive.sha256"
$installedAlias = Join-Path $prefix "bin\dosh.exe"
$lock = [System.IO.File]::Open($installedAlias, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::None)
try {
Invoke-TestInstaller $home $unrelated $prefix "${listenPrefix}repo.git"
$pending = @(Get-ChildItem (Join-Path $prefix "bin") -Filter "dosh.exe.pending.*")
if ($pending.Count -ne 1) {
throw "locked Windows executable was not staged exactly once"
}
}
finally {
$lock.Dispose()
}
$replaced = $false
for ($attempt = 0; $attempt -lt 100; $attempt++) {
if ((Get-Content $installedAlias -Raw) -eq "fixture-v2" -and -not (Get-ChildItem (Join-Path $prefix "bin") -Filter "dosh.exe.pending.*")) {
$replaced = $true
break
}
Start-Sleep -Milliseconds 100
}
if (-not $replaced) {
throw "staged Windows executable was not applied after its lock was released"
}
Write-Host "Windows installer runtime test passed"
}
finally {
$env:DOSH_BINARY_VERSION = $savedBinaryVersion
$env:DOSH_BINARY_EXACT = $savedBinaryExact
if ($job) {
Stop-Job $job -ErrorAction SilentlyContinue
Remove-Job $job -Force -ErrorAction SilentlyContinue
}
Remove-Item -Recurse -Force $root -ErrorAction SilentlyContinue
}