From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id A6F671FF09F for ; Thu, 17 Sep 2026 18:23:53 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 8683B2156C; Thu, 17 Sep 2026 18:23:48 +0200 (CEST) From: =?UTF-8?q?Michael=20K=C3=B6ppl?= To: pve-devel@lists.proxmox.com Subject: [PATCH e2e-tests 2/6] lib: add function for drawing a random unused VMID Date: Thu, 17 Sep 2026 18:23:20 +0200 Message-ID: <20260917162324.1926056-3-m.koeppl@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260917162324.1926056-1-m.koeppl@proxmox.com> References: <20260917162324.1926056-1-m.koeppl@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1789662222444 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.496 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust RCVD_IN_MSPIKE_H2 0.001 Average reputation (+2) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: OB4LCQP34N47RWFNNTNSJGWDGC7VPKVP X-Message-ID-Hash: OB4LCQP34N47RWFNNTNSJGWDGC7VPKVP X-MailFrom: m.koeppl@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: `random_vmid` covers 2 problems: - selecting a random VMID to avoid cases where /cluster/nextid returns a VMID that is still locked (e.g. from a cleanup process). So this mostly covers same-node runs. - selecting the same VMID on parallel runs on different nodes of the same cluster. Drawing from a range of 9 million makes two runs picking the same VMID vanishingly unlikely. PROXMOX_TEST_VMID_RANGE_START and PROXMOX_TEST_VMID_RANGE_END override the range, so parallel runs can be given disjoint ranges to rule out a collision entirely. Signed-off-by: Michael Köppl --- Proxmox/Test/Util.pm | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/Proxmox/Test/Util.pm b/Proxmox/Test/Util.pm index 9b38924..43efd6b 100644 --- a/Proxmox/Test/Util.pm +++ b/Proxmox/Test/Util.pm @@ -3,12 +3,47 @@ use strict; use warnings FATAL => 'all'; use parent 'Exporter'; -our @EXPORT_OK = - qw(poll_until retry skip_unsupported skip_prerequisite guest_name node_from_upid backup_target); +our @EXPORT_OK = qw(random_vmid + poll_until + retry + skip_unsupported + skip_prerequisite + guest_name + node_from_upid + backup_target); use Time::HiRes qw(time sleep); use Test::More (); +my ($vmid_range_start_default, $vmid_range_end_default) = (1_000_000, 9_999_999); + +# An unused VMID for a test guest, drawn at random from a range above the default next-id range. +# +# The VMID selection is random because there are cases where the freshly freed VMID cannot be used +# right away, e.g. if qmeventd runs `qm cleanup`, holding a lock on the VM config for up to 30 +# seconds, making every guest re-created under the freshly freed VMID run into its own lock timeout. +# This is of course not a strict guarantee that this cannot happen, but makes it highly unlikely. +sub random_vmid { + my ($client) = @_; + + my $vmid_range_start = $ENV{PROXMOX_TEST_VMID_RANGE_START} // $vmid_range_start_default; + my $vmid_range_end = $ENV{PROXMOX_TEST_VMID_RANGE_END} // $vmid_range_end_default; + + my $span = $vmid_range_end - $vmid_range_start + 1; + + for (1 .. 100) { + my $vmid = $vmid_range_start + int(rand($span)); + + if (!eval { $client->get('/cluster/nextid', { vmid => $vmid }) }) { + next; + } + + return $vmid; + } + + die "could not find a free VMID in range [$vmid_range_start, $vmid_range_end]\n"; +} + # Poll $cb until it returns a truthy value or $timeout seconds elapse. # # Returns the truthy value. Dies on timeout. Exceptions thrown by $cb are treated as "not ready -- 2.47.3