diff --git a/tests/PSProxmoxVE.Tests/Integration/06_VMs.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/06_VMs.Tests.ps1 index 4190347..d719a30 100644 --- a/tests/PSProxmoxVE.Tests/Integration/06_VMs.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/06_VMs.Tests.ps1 @@ -17,8 +17,17 @@ BeforeAll { } AfterAll { - # Do NOT clean up pester-test-vm here — later test files (07_Snapshots, - # 09_CloudInit, 15_Tasks) depend on it. 99_Cleanup handles removal. + if (-not $script:SkipReason -and $script:TestVmId) { + foreach ($vmId in @($script:TestVmId, ($script:TestVmId + 1000))) { + try { + Stop-PveVm -Node $script:Node -VmId $vmId -Wait -Timeout 30 -Confirm:$false -ErrorAction SilentlyContinue | Out-Null + } catch { } + Start-Sleep -Seconds 2 + try { + Remove-PveVm -Node $script:Node -VmId $vmId -Force -Purge -Confirm:$false -ErrorAction SilentlyContinue + } catch { } + } + } Disconnect-TestPve } @@ -49,7 +58,6 @@ Describe 'VMs — Integration' -Tag 'Integration' { $vm | Should -Not -BeNullOrEmpty $script:TestVmId = $vm.VmId - Register-TestResource -Name 'pester-test-vm' -VmId $vm.VmId } It 'Should get and set VM config' { diff --git a/tests/PSProxmoxVE.Tests/Integration/07_Snapshots.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/07_Snapshots.Tests.ps1 index f207400..7af1567 100644 --- a/tests/PSProxmoxVE.Tests/Integration/07_Snapshots.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/07_Snapshots.Tests.ps1 @@ -4,13 +4,12 @@ BeforeAll { . $PSScriptRoot/_IntegrationHelper.ps1 Connect-TestPve - # Find the test VM created by 06_VMs.Tests.ps1 - $script:TestVmId = Find-TestVm + $script:SnapVmId = $null - function script:Skip-IfNoTestVm { + function script:Skip-IfNoSnapVm { if (Skip-IfNoTarget) { return $true } - if ($null -eq $script:TestVmId) { - Set-ItResult -Skipped -Because 'No test VM found (pester-test-vm must exist from 06_VMs)' + if ($null -eq $script:SnapVmId) { + Set-ItResult -Skipped -Because 'Snapshot test VM was not created' return $true } return $false @@ -18,28 +17,49 @@ BeforeAll { } AfterAll { - # Snapshot cleanup is inline (remove within the test). - # No VM cleanup here — 06_VMs owns pester-test-vm. + if (-not $script:SkipReason -and $script:SnapVmId) { + try { + Stop-PveVm -Node $script:Node -VmId $script:SnapVmId -Wait -Timeout 30 -Confirm:$false -ErrorAction SilentlyContinue | Out-Null + } catch { } + Start-Sleep -Seconds 2 + try { + Remove-PveVm -Node $script:Node -VmId $script:SnapVmId -Force -Purge -Confirm:$false -ErrorAction SilentlyContinue + } catch { } + } Disconnect-TestPve } Describe 'Snapshots — Integration' -Tag 'Integration' { + Context 'Setup' { + It 'Should create a VM for snapshot tests' { + if (Skip-IfNoTarget) { return } + + $task = New-PveVm ` + -Node $script:Node ` + -Name 'pester-snap-vm' ` + -Memory 128 ` + -Cores 1 ` + -Wait + + $task | Should -Not -BeNullOrEmpty + + $vm = Get-PveVm -Node $script:Node -Name 'pester-snap-vm' | + Select-Object -First 1 + $vm | Should -Not -BeNullOrEmpty + $script:SnapVmId = $vm.VmId + } + } + Context 'Snapshots' { It 'Should create, list, and remove a snapshot' { - if (Skip-IfNoTestVm) { return } - - # Ensure the VM is stopped for snapshot - $vm = Get-PveVm -Node $script:Node | Where-Object { $_.VmId -eq $script:TestVmId } - if ($vm.Status -eq 'running') { - Stop-PveVm -Node $script:Node -VmId $script:TestVmId -Wait -Timeout 30 -Confirm:$false | Out-Null - } + if (Skip-IfNoSnapVm) { return } $snapName = 'pester-snap' # Create $createTask = New-PveSnapshot ` -Node $script:Node ` - -VmId $script:TestVmId ` + -VmId $script:SnapVmId ` -Name $snapName ` -Description 'Created by Pester integration test' ` -Wait @@ -47,14 +67,14 @@ Describe 'Snapshots — Integration' -Tag 'Integration' { $createTask | Should -Not -BeNullOrEmpty # List and verify - $snapshots = Get-PveSnapshot -Node $script:Node -VmId $script:TestVmId + $snapshots = Get-PveSnapshot -Node $script:Node -VmId $script:SnapVmId $snap = $snapshots | Where-Object { $_.Name -eq $snapName } $snap | Should -Not -BeNullOrEmpty # Restore { Restore-PveSnapshot ` -Node $script:Node ` - -VmId $script:TestVmId ` + -VmId $script:SnapVmId ` -Name $snapName ` -Confirm:$false ` -Wait } | Should -Not -Throw @@ -62,7 +82,7 @@ Describe 'Snapshots — Integration' -Tag 'Integration' { # Remove $removeTask = Remove-PveSnapshot ` -Node $script:Node ` - -VmId $script:TestVmId ` + -VmId $script:SnapVmId ` -Name $snapName ` -Confirm:$false ` -Wait diff --git a/tests/PSProxmoxVE.Tests/Integration/09_CloudInit.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/09_CloudInit.Tests.ps1 index 0ecf8b5..83efd2a 100644 --- a/tests/PSProxmoxVE.Tests/Integration/09_CloudInit.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/09_CloudInit.Tests.ps1 @@ -4,39 +4,81 @@ BeforeAll { . $PSScriptRoot/_IntegrationHelper.ps1 Connect-TestPve - # Find a test VM for cloud-init config read test - $script:TestVmId = Find-TestVm - $script:LinuxVmId = Find-TestVm -Name 'pester-linux-vm' + $script:CiVmId = $null + + function script:Skip-IfNoCiVm { + if (Skip-IfNoTarget) { return $true } + if ($null -eq $script:CiVmId) { + Set-ItResult -Skipped -Because 'Cloud-init test VM was not created' + return $true + } + return $false + } } AfterAll { - # Read-only tests — no cleanup needed + if (-not $script:SkipReason -and $script:CiVmId) { + try { + Stop-PveVm -Node $script:Node -VmId $script:CiVmId -Wait -Timeout 30 -Confirm:$false -ErrorAction SilentlyContinue | Out-Null + } catch { } + Start-Sleep -Seconds 2 + try { + Remove-PveVm -Node $script:Node -VmId $script:CiVmId -Force -Purge -Confirm:$false -ErrorAction SilentlyContinue + } catch { } + } Disconnect-TestPve } Describe 'Cloud-Init — Integration' -Tag 'Integration' { + + Context 'Setup' { + It 'Should create a VM with cloud-init drive' { + if (Skip-IfNoTarget) { return } + + $task = New-PveVm ` + -Node $script:Node ` + -Name 'pester-ci-vm' ` + -Memory 128 ` + -Cores 1 ` + -Wait + + $task | Should -Not -BeNullOrEmpty + + $vm = Get-PveVm -Node $script:Node -Name 'pester-ci-vm' | + Select-Object -First 1 + $vm | Should -Not -BeNullOrEmpty + $script:CiVmId = $vm.VmId + + # Add a cloud-init drive + Set-PveVmConfig -Node $script:Node -VmId $script:CiVmId ` + -AdditionalConfig @{ ide2 = "$($script:Storage):cloudinit" } ` + -ErrorAction Stop + } + } + Context 'Cloud-Init' { It 'Should get cloud-init config' { - if (Skip-IfNoTarget) { return } - if ($null -eq $script:TestVmId) { - Set-ItResult -Skipped -Because 'No test VM found' - return - } + if (Skip-IfNoCiVm) { return } - # Get-PveCloudInitConfig should not throw even if the VM has no cloud-init drive. - { Get-PveCloudInitConfig -Node $script:Node -VmId $script:TestVmId -ErrorAction Stop } | + { Get-PveCloudInitConfig -Node $script:Node -VmId $script:CiVmId -ErrorAction Stop } | Should -Not -Throw } - It 'Should regenerate cloud-init image (Invoke-PveCloudInitRegenerate)' { - if (Skip-IfNoTarget) { return } - if ($null -eq $script:LinuxVmId) { - Set-ItResult -Skipped -Because 'Linux VM was not provisioned (PVETEST_PASSWORD may not be set)' - return - } + It 'Should set cloud-init config' { + if (Skip-IfNoCiVm) { return } - # The Linux VM has a cloud-init drive from provisioning - { Invoke-PveCloudInitRegenerate -Node $script:Node -VmId $script:LinuxVmId -Wait -ErrorAction Stop } | + { Set-PveCloudInitConfig -Node $script:Node -VmId $script:CiVmId ` + -CiUser 'pester-user' -ErrorAction Stop } | + Should -Not -Throw + + $config = Get-PveCloudInitConfig -Node $script:Node -VmId $script:CiVmId -ErrorAction Stop + $config.CiUser | Should -Be 'pester-user' + } + + It 'Should regenerate cloud-init image' { + if (Skip-IfNoCiVm) { return } + + { Invoke-PveCloudInitRegenerate -Node $script:Node -VmId $script:CiVmId -Wait -ErrorAction Stop } | Should -Not -Throw } } diff --git a/tests/PSProxmoxVE.Tests/Integration/11_LinuxVM.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/11_LinuxVM.Tests.ps1 index ecdf2c5..e72d5b4 100644 --- a/tests/PSProxmoxVE.Tests/Integration/11_LinuxVM.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/11_LinuxVM.Tests.ps1 @@ -62,7 +62,6 @@ Describe 'Linux VM — Integration' -Tag 'Integration' { $script:LinuxVmId = $vm.VmId $script:CreatedVmIds.Add($vm.VmId) - Register-TestResource -Name 'pester-linux-vm' -VmId $vm.VmId } It 'Should import cloud image disk (Import-PveVmDisk)' { diff --git a/tests/PSProxmoxVE.Tests/Integration/15_Tasks.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/15_Tasks.Tests.ps1 index 4537753..695cd4f 100644 --- a/tests/PSProxmoxVE.Tests/Integration/15_Tasks.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/15_Tasks.Tests.ps1 @@ -4,27 +4,59 @@ BeforeAll { . $PSScriptRoot/_IntegrationHelper.ps1 Connect-TestPve - # Find an existing test VM to use for task tests - $script:TestVmId = Find-TestVm + $script:TaskVmId = $null + + function script:Skip-IfNoTaskVm { + if (Skip-IfNoTarget) { return $true } + if ($null -eq $script:TaskVmId) { + Set-ItResult -Skipped -Because 'Task test VM was not created' + return $true + } + return $false + } } AfterAll { - # Read-only tests — no cleanup needed + if (-not $script:SkipReason -and $script:TaskVmId) { + try { + Stop-PveVm -Node $script:Node -VmId $script:TaskVmId -Wait -Timeout 30 -Confirm:$false -ErrorAction SilentlyContinue | Out-Null + } catch { } + Start-Sleep -Seconds 2 + try { + Remove-PveVm -Node $script:Node -VmId $script:TaskVmId -Force -Purge -Confirm:$false -ErrorAction SilentlyContinue + } catch { } + } Disconnect-TestPve } Describe 'Tasks — Integration' -Tag 'Integration' { + Context 'Setup' { + It 'Should create a VM for task tests' { + if (Skip-IfNoTarget) { return } + + $task = New-PveVm ` + -Node $script:Node ` + -Name 'pester-task-vm' ` + -Memory 128 ` + -Cores 1 ` + -Wait + + $task | Should -Not -BeNullOrEmpty + + $vm = Get-PveVm -Node $script:Node -Name 'pester-task-vm' | + Select-Object -First 1 + $vm | Should -Not -BeNullOrEmpty + $script:TaskVmId = $vm.VmId + } + } + Context 'Tasks' { It 'Should get a task by UPID and wait for completion' { - if (Skip-IfNoTarget) { return } - if ($null -eq $script:TestVmId) { - Set-ItResult -Skipped -Because 'No test VM was created' - return - } + if (Skip-IfNoTaskVm) { return } # Start the VM to get a task object - $startResult = Start-PveVm -Node $script:Node -VmId $script:TestVmId + $startResult = Start-PveVm -Node $script:Node -VmId $script:TaskVmId $startResult | Should -Not -BeNullOrEmpty $startResult.Upid | Should -Not -BeNullOrEmpty @@ -36,8 +68,12 @@ Describe 'Tasks — Integration' -Tag 'Integration' { $task | Should -Not -BeNullOrEmpty $task.IsSuccessful | Should -BeTrue - # Clean up - Stop-PveVm -Node $script:Node -VmId $script:TestVmId -Wait -Timeout 30 -Confirm:$false | Out-Null + # List tasks + $tasks = Get-PveTaskList -Node $script:Node + $tasks | Should -Not -BeNullOrEmpty + + # Clean up — stop the VM + Stop-PveVm -Node $script:Node -VmId $script:TaskVmId -Wait -Timeout 30 -Confirm:$false | Out-Null } } } diff --git a/tests/PSProxmoxVE.Tests/Integration/_IntegrationHelper.ps1 b/tests/PSProxmoxVE.Tests/Integration/_IntegrationHelper.ps1 index bf4b566..5eca74f 100644 --- a/tests/PSProxmoxVE.Tests/Integration/_IntegrationHelper.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/_IntegrationHelper.ps1 @@ -145,43 +145,3 @@ function script:Disconnect-TestPve { #> try { Disconnect-PveServer -ErrorAction SilentlyContinue } catch { } } - -# ── Resource discovery helpers ─────────────────────────────────────────── -# These allow later test files to find resources created by earlier files -# without sharing script-scoped variables. If the resource doesn't exist, -# the caller gets $null and should skip. - -function script:Find-TestVm { - <# - .SYNOPSIS - Finds the pester-test-vm by checking env state or querying PVE. - #> - param([string]$Name = 'pester-test-vm') - - # Check env var first (set by the file that created it) - $envKey = "PVETEST_STATE_$($Name.Replace('-','_').ToUpper())" - $vmId = [System.Environment]::GetEnvironmentVariable($envKey) - if ($vmId) { return [int]$vmId } - - # Fall back to querying PVE - try { - $vms = Get-PveVm -Node $script:Node -ErrorAction Stop - $match = $vms | Where-Object { $_.Name -eq $Name } | Select-Object -First 1 - if ($match) { return [int]$match.VmId } - } catch { } - - return $null -} - -function script:Register-TestResource { - <# - .SYNOPSIS - Registers a resource VMID in env for cross-file discovery. - #> - param( - [string]$Name, - [int]$VmId - ) - $envKey = "PVETEST_STATE_$($Name.Replace('-','_').ToUpper())" - [System.Environment]::SetEnvironmentVariable($envKey, $VmId.ToString()) -}