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
169 lines
6.8 KiB
PowerShell
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
|
|
}
|