Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e79718a5fb
|
||
|
|
fbac1003f0 |
+5
-11
@@ -96,16 +96,13 @@ function Install-Octopus {
|
|||||||
try {
|
try {
|
||||||
$null = Invoke-WebRequest -Uri $releaseUrl -Method Head -UseBasicParsing -ErrorAction Stop
|
$null = Invoke-WebRequest -Uri $releaseUrl -Method Head -UseBasicParsing -ErrorAction Stop
|
||||||
} catch {
|
} catch {
|
||||||
Write-Color "Error: Release v$specificVersion not found." "Red"
|
throw "Release v$specificVersion not found. Available releases: $baseUrl/$REPO/releases"
|
||||||
Write-Color "Available releases: $baseUrl/$REPO/releases" "DarkGray"
|
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Write-Color "Fetching latest version..." "DarkGray"
|
Write-Color "Fetching latest version..." "DarkGray"
|
||||||
$specificVersion = Get-LatestVersion
|
$specificVersion = Get-LatestVersion
|
||||||
if (-not $specificVersion) {
|
if (-not $specificVersion) {
|
||||||
Write-Color "Error: Failed to fetch latest version." "Red"
|
throw "Failed to fetch latest version."
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +113,7 @@ function Install-Octopus {
|
|||||||
$installedVersion = & $existing --version 2>$null
|
$installedVersion = & $existing --version 2>$null
|
||||||
if ($installedVersion -eq $specificVersion) {
|
if ($installedVersion -eq $specificVersion) {
|
||||||
Write-Color "Version $specificVersion already installed." "DarkGray"
|
Write-Color "Version $specificVersion already installed." "DarkGray"
|
||||||
exit 0
|
return
|
||||||
} else {
|
} else {
|
||||||
Write-Color "Installed version: $installedVersion" "DarkGray"
|
Write-Color "Installed version: $installedVersion" "DarkGray"
|
||||||
}
|
}
|
||||||
@@ -144,10 +141,8 @@ function Install-Octopus {
|
|||||||
$ProgressPreference = "SilentlyContinue"
|
$ProgressPreference = "SilentlyContinue"
|
||||||
Invoke-WebRequest -Uri $downloadUrl -OutFile $zipPath -UseBasicParsing
|
Invoke-WebRequest -Uri $downloadUrl -OutFile $zipPath -UseBasicParsing
|
||||||
} catch {
|
} catch {
|
||||||
Write-Color "Error: Failed to download $downloadUrl" "Red"
|
|
||||||
Write-Color $_.Exception.Message "Red"
|
|
||||||
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
||||||
exit 1
|
throw "Failed to download $downloadUrl : $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extract
|
# Extract
|
||||||
@@ -157,9 +152,8 @@ function Install-Octopus {
|
|||||||
New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null
|
New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null
|
||||||
$exeSrc = Join-Path $tmpDir "$APP.exe"
|
$exeSrc = Join-Path $tmpDir "$APP.exe"
|
||||||
if (-not (Test-Path $exeSrc)) {
|
if (-not (Test-Path $exeSrc)) {
|
||||||
Write-Color "Error: $APP.exe not found in archive." "Red"
|
|
||||||
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
||||||
exit 1
|
throw "$APP.exe not found in archive."
|
||||||
}
|
}
|
||||||
Copy-Item -Path $exeSrc -Destination (Join-Path $INSTALL_DIR "$APP.exe") -Force
|
Copy-Item -Path $exeSrc -Destination (Join-Path $INSTALL_DIR "$APP.exe") -Force
|
||||||
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#Requires -Version 5.1
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Regression tests for install.ps1.
|
||||||
|
|
||||||
|
.BUG
|
||||||
|
`irm <url> | iex` closed the terminal window. Cause: the script used
|
||||||
|
`exit`, which under Invoke-Expression terminates the entire PowerShell
|
||||||
|
host process (there is no script scope to exit). Fix: use `return`
|
||||||
|
(success) / `throw` (errors) so the host survives.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Host-process termination cannot be observed from inside the dying process,
|
||||||
|
so these tests combine a source-verification guard with a behavioral test
|
||||||
|
run in a child process (`exit` cannot be caught by try/catch and kills the
|
||||||
|
child; `throw` is catchable).
|
||||||
|
#>
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||||
|
$installScript = Join-Path $repoRoot "install.ps1"
|
||||||
|
$failures = [System.Collections.Generic.List[string]]::new()
|
||||||
|
|
||||||
|
function Assert-True([bool]$Cond, [string]$Message) {
|
||||||
|
if (-not $Cond) { $failures.Add($Message) | Out-Null }
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Test 1 (source verification): no host-terminating `exit` ---
|
||||||
|
$content = Get-Content -Path $installScript -Raw
|
||||||
|
$exitCount = ([regex]::Matches($content, '(?m)^\s*exit\b')).Count
|
||||||
|
Assert-True ($exitCount -eq 0) "install.ps1 must not use bare 'exit' (found $exitCount); 'irm | iex' would kill the host. Use return/throw."
|
||||||
|
|
||||||
|
# --- Test 2: parses cleanly ---
|
||||||
|
$parseOk = $true
|
||||||
|
try { [void][scriptblock]::Create($content) } catch { $parseOk = $false }
|
||||||
|
Assert-True $parseOk "install.ps1 must parse without syntax errors."
|
||||||
|
|
||||||
|
# --- Test 3 (behavioral): iex must NOT kill the host ---
|
||||||
|
# Force the version lookup to fail fast against an unreachable address so the
|
||||||
|
# script reaches its early-exit/throw path offline. `exit` terminates the child
|
||||||
|
# (RESULT never emitted); `throw` is caught and RESULT is emitted.
|
||||||
|
$inner = @'
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
$env:OCTOPUS_DOWNLOAD_BASE = "http://127.0.0.1:1"
|
||||||
|
$r = "nothing"
|
||||||
|
try {
|
||||||
|
Invoke-Expression (Get-Content -Raw "__INSTALL__")
|
||||||
|
$r = "completed"
|
||||||
|
} catch {
|
||||||
|
$r = "caught-throw"
|
||||||
|
}
|
||||||
|
Write-Output ("RESULT=$r")
|
||||||
|
'@.Replace("__INSTALL__", $installScript)
|
||||||
|
|
||||||
|
$tmp = Join-Path $env:TEMP ("octopus_iex_test_" + $PID + ".ps1")
|
||||||
|
Set-Content -Path $tmp -Value $inner -Encoding UTF8
|
||||||
|
try {
|
||||||
|
$childOut = (& powershell -NoProfile -File $tmp 2>&1 | Out-String)
|
||||||
|
} finally {
|
||||||
|
Remove-Item $tmp -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
Assert-True ($childOut -match 'RESULT=') "iex must not terminate the host (try/catch must observe a RESULT). Child output:`n$childOut"
|
||||||
|
|
||||||
|
# --- Report ---
|
||||||
|
if ($failures.Count -gt 0) {
|
||||||
|
Write-Host ("FAIL: " + $failures.Count + " test(s)") -ForegroundColor Red
|
||||||
|
foreach ($f in $failures) { Write-Host (" - " + $f) -ForegroundColor Red }
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Host "PASS: all regression tests passed." -ForegroundColor Green
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user