podman-client-dotnet/src/e2e-tests/Test-PodmanE2E.ps1
2026-07-28 22:30:11 +02:00

173 lines
5.5 KiB
PowerShell

#Requires -Version 7
<#
.SYNOPSIS
End-to-end tests against a running Podman API via MaksIT.PodmanClientDotNet.PowerShell.
.DESCRIPTION
Builds the module, connects with PODMAN_TEST_URL, then runs scenarios from scenarios\Scenario-*.ps1.
Filter:
pwsh -File .\src\e2e-tests\Test-PodmanE2E.ps1 -Scenario 'System'
pwsh -File .\src\e2e-tests\Test-PodmanE2E.ps1 -Scenario '*Image*','*Container*'
.EXAMPLE
$env:PODMAN_TEST_URL = 'http://192.168.2.128:8080'
pwsh -File .\src\e2e-tests\Test-PodmanE2E.ps1
#>
param(
[string[]] $Scenario = @('*')
)
# Allow comma-separated values from cmd.exe / single-arg callers: -Scenario System,Images
$Scenario = @(
$Scenario |
ForEach-Object { $_ -split ',' } |
ForEach-Object { $_.Trim().Trim("'").Trim('"') } |
Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
)
if ($Scenario.Count -eq 0) {
$Scenario = @('*')
}
$e2eRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
. (Join-Path $e2eRoot 'Podman.E2E.Common.ps1')
if ($PSVersionTable.PSVersion.Major -lt 7) {
throw 'This script is pwsh-only.'
}
$runtimeFx = [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription
if ($runtimeFx -notmatch '\.NET 10\.') {
throw (
"The Podman module is net10.0; this pwsh is hosted on: $runtimeFx" + [Environment]::NewLine +
'Install PowerShell 7 with .NET 10 from https://github.com/PowerShell/PowerShell/releases'
)
}
$envName = 'PODMAN_TEST_URL'
$url = [Environment]::GetEnvironmentVariable($envName, 'Process')
if ([string]::IsNullOrWhiteSpace($url)) {
$url = [Environment]::GetEnvironmentVariable($envName, 'User')
}
if ([string]::IsNullOrWhiteSpace($url)) {
$url = [Environment]::GetEnvironmentVariable($envName, 'Machine')
}
if ([string]::IsNullOrWhiteSpace($url)) {
throw @"
PODMAN_TEST_URL is not set (Process, User, or Machine).
Example:
`$env:PODMAN_TEST_URL = 'http://192.168.2.128:8080'
# must be an absolute http(s) URL (include the scheme)
"@
}
$url = $url.Trim().TrimEnd('/')
if ($url -notmatch '^https?://') {
throw "PODMAN_TEST_URL must be an absolute http(s) URL. Got: $url"
}
$repoRoot = Resolve-Path (Join-Path $e2eRoot '..\..')
$moduleTfm = 'net10.0'
$relModuleProject = 'src\PodmanClient.PowerShell\PodmanClient.PowerShell.csproj'
$relModuleManifest = "src\PodmanClient.PowerShell\bin\Debug\$moduleTfm\MaksIT.PodmanClientDotNet.PowerShell.psd1"
Write-E2eLog -Kind Step -Message "Build: $relModuleProject"
Push-Location $repoRoot
try {
$buildOutput = dotnet build $relModuleProject 2>&1
if ($LASTEXITCODE -ne 0) {
$buildOutput | ForEach-Object { Write-Host $_ }
throw "Build failed: $relModuleProject"
}
if (-not (Test-Path -LiteralPath $relModuleManifest)) {
throw "Module manifest not found: $relModuleManifest"
}
$moduleManifest = (Resolve-Path -LiteralPath $relModuleManifest).Path
}
finally {
Pop-Location
}
Write-E2eLog -Kind Ok -Message "Importing module: $moduleManifest"
Import-Module $moduleManifest -Force
$exported = @(Get-Command -Module MaksIT.PodmanClientDotNet.PowerShell | Select-Object -ExpandProperty Name)
Clear-PodmanE2eScenarioRegistry
$scenarioDir = Join-Path $e2eRoot 'scenarios'
if (-not (Test-Path -LiteralPath $scenarioDir)) {
throw "Scenarios directory missing: $scenarioDir"
}
Get-ChildItem -LiteralPath $scenarioDir -Filter 'Scenario-*.ps1' | Sort-Object Name | ForEach-Object {
Write-E2eLog -Message "Load scenarios: $($_.Name)"
. $_.FullName
}
Write-E2eLog -Kind Step -Message "Connect-Podman (base URL: $url, ApiVersion: v5.4.0)"
Connect-Podman -BaseAddress $url -ApiVersion 'v5.4.0'
Use-PodmanE2eCmdlet Connect-Podman
Write-E2eLog -Kind Ok -Message 'Connect-Podman: session ready'
try {
$ver = Get-PodmanVersion
$engine = $ver.Version
if (-not $engine) { $engine = $ver.Components | Where-Object { $_.Name -eq 'Podman Engine' } | Select-Object -ExpandProperty Version -First 1 }
Write-E2eLog -Message "Server Podman version: $engine (E2E baseline: 5.4.0)"
if ($engine -and ("$engine" -notlike '5.4*')) {
Write-E2eLog -Kind Warn "Server is $engine; this suite is validated against Podman 5.4.0"
}
}
catch {
Write-E2eLog -Kind Warn "Could not read Get-PodmanVersion: $($_.Exception.Message)"
}
$ErrorActionPreference = 'Stop'
$ran = 0
try {
foreach ($entry in $script:PodmanE2eScenarioRegistry) {
$include = $false
foreach ($p in $Scenario) {
if ($entry.Id -like $p) {
$include = $true
break
}
}
if (-not $include) {
Write-E2eLog -Kind Warn "Skip (filter): $($entry.Id)"
continue
}
Write-E2eLog -Kind Step -Message "========== Scenario: $($entry.Id) =========="
Write-E2eLog -Message $entry.Description
try {
& $entry.ScriptBlock
$ran++
}
catch {
Write-E2eLog -Kind Warn "Scenario '$($entry.Id)' FAILED: $($_.Exception.Message)"
throw
}
}
if ($ran -eq 0) {
$registered = ($script:PodmanE2eScenarioRegistry | ForEach-Object { $_.Id }) -join ', '
throw "No scenarios matched -Scenario patterns: $($Scenario -join ', '). Registered: $registered"
}
Use-PodmanE2eCmdlet Disconnect-Podman
$missing = @($exported | Where-Object { -not $script:PodmanE2eCmdletHits.Contains($_) })
if ($missing.Count -gt 0 -and ($Scenario.Count -eq 1 -and $Scenario[0] -eq '*')) {
Write-E2eLog -Kind Warn -Message ("Cmdlets not marked Use-PodmanE2eCmdlet in scenarios: " + ($missing -join ', '))
throw "E2E completeness gate failed: $($missing.Count) cmdlet(s) not exercised."
}
Write-E2eLog -Kind Ok -Message "All selected scenarios passed ($ran run)."
}
finally {
Disconnect-Podman
Write-E2eLog -Message 'Disconnect-Podman'
}