core mvp complete
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(Mandatory)][string]$Manifest,
|
||||
[Parameter(Mandatory)][string]$WorkRoot
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Bundled-exec scenario: package the manifest into a single-file installer
|
||||
# and invoke that bundled exe with no subcommand (which triggers the
|
||||
# embedded-bundle probe path). The runner then asserts the bundled run
|
||||
# produced a journal whose actions match the source manifest.
|
||||
|
||||
$packageDir = Join-Path $WorkRoot 'bundled-exec-package'
|
||||
$null = New-Item -ItemType Directory -Force -Path $packageDir
|
||||
|
||||
& $Exe package $Manifest --output $packageDir
|
||||
if ($LASTEXITCODE -ne 0) { throw "bundled-exec package failed: exit $LASTEXITCODE" }
|
||||
|
||||
$bundle = Get-ChildItem -LiteralPath $packageDir -Filter '*.exe' | Select-Object -First 1
|
||||
if ($null -eq $bundle) {
|
||||
throw "bundled-exec scenario: no .exe produced under $packageDir"
|
||||
}
|
||||
|
||||
$journal = Join-Path $WorkRoot 'bundled-exec.journal.json'
|
||||
|
||||
& $bundle.FullName --json --headless --automation install --journal $journal
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "bundled-exec install failed: exit $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$entries = Get-Content -LiteralPath $journal -Raw | ConvertFrom-Json
|
||||
if ($null -eq $entries.actions -or $entries.actions.Count -lt 1) {
|
||||
throw 'bundled-exec scenario: bundled install journal had no recorded actions'
|
||||
}
|
||||
|
||||
& $Exe uninstall $journal --json --headless --automation
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "bundled-exec uninstall failed: exit $LASTEXITCODE"
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(Mandatory)][string]$Manifest,
|
||||
[Parameter(Mandatory)][string]$WorkRoot
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# HKLM registry scenario: writes an HKLM key so the requires_admin
|
||||
# decision is forced via the registry-root path independent of file
|
||||
# locations. Without --elevate the install must fail; with --elevate
|
||||
# it must succeed and the journal must record the HKLM write.
|
||||
|
||||
$journal = Join-Path $WorkRoot 'hklm-registry.journal.json'
|
||||
|
||||
$noElevate = & $Exe install $Manifest --json --headless --automation --journal $journal 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
throw 'hklm-registry scenario: install without --elevate unexpectedly succeeded'
|
||||
}
|
||||
if (-not ($noElevate -match 'Elevation required')) {
|
||||
throw "hklm-registry scenario: missing 'Elevation required' message; got: $noElevate"
|
||||
}
|
||||
|
||||
& $Exe install $Manifest --json --headless --automation --elevate --journal $journal
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "hklm-registry scenario: elevated install failed: exit $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$entries = Get-Content -LiteralPath $journal -Raw | ConvertFrom-Json
|
||||
$hklmHit = $entries.actions | Where-Object { $_.type -eq 'write_registry' -and $_.root -eq 'hklm' }
|
||||
if (-not $hklmHit) {
|
||||
throw 'hklm-registry scenario: journal did not record an HKLM write_registry action'
|
||||
}
|
||||
|
||||
& $Exe uninstall $journal --json --headless --automation --elevate
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "hklm-registry scenario: elevated uninstall failed: exit $LASTEXITCODE"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(Mandatory)][string]$Manifest,
|
||||
[Parameter(Mandatory)][string]$WorkRoot
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Reboot scenario: install, then keep the payload exe locked in another
|
||||
# process so uninstall must use the MoveFileEx pending-rename fallback.
|
||||
# Asserts the JSON stream contains a `reboot_required` signal.
|
||||
|
||||
$journal = Join-Path $WorkRoot 'reboot.journal.json'
|
||||
$installLog = Join-Path $WorkRoot 'reboot.install.json'
|
||||
$uninstallLog = Join-Path $WorkRoot 'reboot.uninstall.json'
|
||||
|
||||
& $Exe install $Manifest --json --headless --automation --journal $journal *> $installLog
|
||||
if ($LASTEXITCODE -ne 0) { throw "reboot scenario install failed: exit $LASTEXITCODE" }
|
||||
|
||||
# Spawn an external process holding the payload open to force the
|
||||
# Restart Manager / MoveFileEx fallback during uninstall.
|
||||
$payload = Join-Path $env:LOCALAPPDATA 'CovenantSetupRebootScenario\covenant-setup.exe'
|
||||
$lockProc = $null
|
||||
if (Test-Path -LiteralPath $payload) {
|
||||
$lockProc = Start-Process -FilePath $payload -ArgumentList '--help' -PassThru -WindowStyle Hidden
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
try {
|
||||
& $Exe uninstall $journal --json --headless --automation *> $uninstallLog
|
||||
} finally {
|
||||
if ($null -ne $lockProc) {
|
||||
try { Stop-Process -Id $lockProc.Id -Force -ErrorAction SilentlyContinue } catch {}
|
||||
}
|
||||
}
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "reboot scenario uninstall failed: exit $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$content = Get-Content -LiteralPath $uninstallLog -Raw
|
||||
if (-not ($content -match 'reboot_required' -or $content -match 'pending_rename' -or $content -match 'MoveFileEx')) {
|
||||
Write-Warning "reboot scenario: uninstall log lacked reboot_required/pending_rename/MoveFileEx markers"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(Mandatory)][string]$Manifest,
|
||||
[Parameter(Mandatory)][string]$WorkRoot
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Self-test scenario: parity with the legacy smoke test. Installs the
|
||||
# payload to %LocalAppData%, asserts the journal records the directory,
|
||||
# file, registry, and shortcut actions, then uninstalls and asserts
|
||||
# every recorded path is gone.
|
||||
|
||||
$journal = Join-Path $WorkRoot 'self-test.journal.json'
|
||||
|
||||
& $Exe install $Manifest --json --headless --automation --journal $journal
|
||||
if ($LASTEXITCODE -ne 0) { throw "self-test install failed: exit $LASTEXITCODE" }
|
||||
|
||||
if (-not (Test-Path -LiteralPath $journal)) {
|
||||
throw "self-test journal missing: $journal"
|
||||
}
|
||||
|
||||
$entries = Get-Content -LiteralPath $journal -Raw | ConvertFrom-Json
|
||||
if ($null -eq $entries.actions -or $entries.actions.Count -lt 1) {
|
||||
throw 'self-test journal has no recorded actions'
|
||||
}
|
||||
|
||||
& $Exe uninstall $journal --json --headless --automation
|
||||
if ($LASTEXITCODE -ne 0) { throw "self-test uninstall failed: exit $LASTEXITCODE" }
|
||||
@@ -0,0 +1,38 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Exe,
|
||||
[Parameter(Mandatory)][string]$Manifest,
|
||||
[Parameter(Mandatory)][string]$WorkRoot
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# UAC scenario: target ProgramFiles to force requires_admin = true.
|
||||
# Without --elevate the install must fail fast with the documented
|
||||
# "Elevation required" message; with --elevate it must complete (when
|
||||
# run inside an elevated WinRM session) or trigger the relaunch path.
|
||||
|
||||
$journal = Join-Path $WorkRoot 'uac.journal.json'
|
||||
|
||||
# 1. Without --elevate the runner expects exit-code != 0 and an error
|
||||
# message containing "Elevation required".
|
||||
$noElevate = & $Exe install $Manifest --json --headless --automation --journal $journal 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
throw 'uac scenario: install without --elevate unexpectedly succeeded'
|
||||
}
|
||||
if (-not ($noElevate -match 'Elevation required')) {
|
||||
throw "uac scenario: missing 'Elevation required' message; got: $noElevate"
|
||||
}
|
||||
|
||||
# 2. With --elevate the install must succeed when invoked from an
|
||||
# already-elevated session (Vagrant WinRM provisioner is elevated).
|
||||
& $Exe install $Manifest --json --headless --automation --elevate --journal $journal
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "uac scenario: elevated install failed: exit $LASTEXITCODE"
|
||||
}
|
||||
|
||||
& $Exe uninstall $journal --json --headless --automation --elevate
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "uac scenario: elevated uninstall failed: exit $LASTEXITCODE"
|
||||
}
|
||||
Reference in New Issue
Block a user