From 531deafdb7757aa7d5bb93541f6d7a278603b8d5 Mon Sep 17 00:00:00 2001 From: Clint Branham Date: Fri, 20 Mar 2026 14:35:53 -0500 Subject: [PATCH] fix(test): fix integration test failures for SDN, containers, OVA, suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SDN: zone ID cannot contain hyphens — rename 'pester-zone' to 'pesterz' - SDN: subnet removal uses original CIDR, not transformed ID - Containers: New-PveContainer now auto-assigns VM ID via /cluster/nextid when -VmId is omitted (was missing, unlike New-PveVm) - OVA: enable 'images' content type on local storage for import-from - Suspend: add delay before status check, use Should -Not -Throw pattern Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Containers/NewPveContainerCmdlet.cs | 12 ++++++++++ .../Integration/Integration.Tests.ps1 | 24 ++++++++++--------- .../scripts/prepare-test-environment.sh | 2 +- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs index 30274db..c586338 100644 --- a/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Management.Automation; using System.Net; using System.Runtime.InteropServices; +using Newtonsoft.Json.Linq; +using PSProxmoxVE.Core.Client; using PSProxmoxVE.Core.Models.Vms; using PSProxmoxVE.Core.Services; @@ -133,7 +135,17 @@ namespace PSProxmoxVE.Cmdlets.Containers var config = new Dictionary(); if (VmId.HasValue) + { config["vmid"] = VmId.Value.ToString(); + } + else + { + // Auto-allocate the next available ID from the cluster. + using var allocClient = new PveHttpClient(session); + var nextIdJson = allocClient.GetAsync("cluster/nextid").GetAwaiter().GetResult(); + var nextIdData = JObject.Parse(nextIdJson)["data"]; + config["vmid"] = int.Parse(nextIdData!.ToString()); + } if (!string.IsNullOrEmpty(Hostname)) config["hostname"] = Hostname!; if (Memory.HasValue) diff --git a/tests/PSProxmoxVE.Tests/Integration/Integration.Tests.ps1 b/tests/PSProxmoxVE.Tests/Integration/Integration.Tests.ps1 index 0c1beee..5208717 100644 --- a/tests/PSProxmoxVE.Tests/Integration/Integration.Tests.ps1 +++ b/tests/PSProxmoxVE.Tests/Integration/Integration.Tests.ps1 @@ -464,17 +464,19 @@ Describe 'Integration Tests' -Tag 'Integration' { # Start the VM Start-PveVm -Node $script:Node -VmId $script:TestVmId -Wait | Out-Null - # Suspend - $suspendTask = Suspend-PveVm -Node $script:Node -VmId $script:TestVmId -Wait - $suspendTask | Should -Not -BeNullOrEmpty + # Suspend — sends QMP stop to QEMU + { Suspend-PveVm -Node $script:Node -VmId $script:TestVmId -Wait -ErrorAction Stop } | + Should -Not -Throw + Start-Sleep -Seconds 3 $vm = Get-PveVm -Node $script:Node | Where-Object { $_.VmId -eq $script:TestVmId } $vm.Status | Should -Be 'paused' - # Resume - $resumeTask = Resume-PveVm -Node $script:Node -VmId $script:TestVmId -Wait - $resumeTask | Should -Not -BeNullOrEmpty + # Resume — sends QMP cont to QEMU + { Resume-PveVm -Node $script:Node -VmId $script:TestVmId -Wait -ErrorAction Stop } | + Should -Not -Throw + Start-Sleep -Seconds 2 $vm = Get-PveVm -Node $script:Node | Where-Object { $_.VmId -eq $script:TestVmId } $vm.Status | Should -Be 'running' @@ -742,7 +744,7 @@ Describe 'Integration Tests' -Tag 'Integration' { if (Skip-IfNoTarget) { return } if ($script:SkipSdn) { Set-ItResult -Skipped -Because $script:SkipSdn; return } - { New-PveSdnZone -Zone 'pester-zone' -Type 'simple' -ErrorAction Stop } | + { New-PveSdnZone -Zone 'pesterz' -Type 'simple' -ErrorAction Stop } | Should -Not -Throw } @@ -752,7 +754,7 @@ Describe 'Integration Tests' -Tag 'Integration' { $zones = Get-PveSdnZone $zones | Should -Not -BeNullOrEmpty - $zones | Where-Object { $_.Zone -eq 'pester-zone' } | + $zones | Where-Object { $_.Zone -eq 'pesterz' } | Should -Not -BeNullOrEmpty } @@ -760,7 +762,7 @@ Describe 'Integration Tests' -Tag 'Integration' { if (Skip-IfNoTarget) { return } if ($script:SkipSdn) { Set-ItResult -Skipped -Because $script:SkipSdn; return } - { New-PveSdnVnet -Vnet 'pestervn' -Zone 'pester-zone' -ErrorAction Stop } | + { New-PveSdnVnet -Vnet 'pestervn' -Zone 'pesterz' -ErrorAction Stop } | Should -Not -Throw } @@ -794,7 +796,7 @@ Describe 'Integration Tests' -Tag 'Integration' { if (Skip-IfNoTarget) { return } if ($script:SkipSdn) { Set-ItResult -Skipped -Because $script:SkipSdn; return } - { Remove-PveSdnSubnet -Vnet 'pestervn' -Subnet 'pestervn-10.99.0.0-24' ` + { Remove-PveSdnSubnet -Vnet 'pestervn' -Subnet '10.99.0.0/24' ` -Confirm:$false -ErrorAction Stop } | Should -Not -Throw } @@ -810,7 +812,7 @@ Describe 'Integration Tests' -Tag 'Integration' { if (Skip-IfNoTarget) { return } if ($script:SkipSdn) { Set-ItResult -Skipped -Because $script:SkipSdn; return } - { Remove-PveSdnZone -Zone 'pester-zone' -Confirm:$false -ErrorAction Stop } | + { Remove-PveSdnZone -Zone 'pesterz' -Confirm:$false -ErrorAction Stop } | Should -Not -Throw } } diff --git a/tests/infrastructure/scripts/prepare-test-environment.sh b/tests/infrastructure/scripts/prepare-test-environment.sh index 014c21d..9eb2cb7 100755 --- a/tests/infrastructure/scripts/prepare-test-environment.sh +++ b/tests/infrastructure/scripts/prepare-test-environment.sh @@ -30,7 +30,7 @@ echo "=== Preparing test environment on ${NESTED_IP} ===" # Enable snippets and import content types on local storage echo "Configuring local storage content types..." -${SSH_CMD} "mkdir -p /var/lib/vz/snippets && pvesm set local --content iso,vztmpl,snippets,import" +${SSH_CMD} "mkdir -p /var/lib/vz/snippets && pvesm set local --content images,iso,vztmpl,snippets,import" # Upload cloud-init user-data snippet (no API for snippet upload) echo "Uploading cloud-init user-data snippet..."