[pve-devel] [PATCH qemu-server v2 20/32] test: add tests for PCI reservations
Fiona Ebner
f.ebner at proxmox.com
Wed Jun 18 15:01:57 CEST 2025
This is currently tested as part of the config-to-command tests, but
the plan is to make command generation for 'qm showcmd' not actually
reserve anything. The reserve_pci_usage() function also serves as
checking what already is reserved by other VMs at the same time.
Thus, the config-to-command test will not be able to test whether
reservations are actually respected after the above-mentioned change.
Add a dedicated test for this.
Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
---
New in v2.
src/PVE/QemuServer/PCI.pm | 2 +-
src/test/Makefile | 5 +-
src/test/run_pci_reservation_tests.pl | 175 ++++++++++++++++++++++++++
3 files changed, 180 insertions(+), 2 deletions(-)
create mode 100755 src/test/run_pci_reservation_tests.pl
diff --git a/src/PVE/QemuServer/PCI.pm b/src/PVE/QemuServer/PCI.pm
index 751f8a84..9b343115 100644
--- a/src/PVE/QemuServer/PCI.pm
+++ b/src/PVE/QemuServer/PCI.pm
@@ -576,7 +576,7 @@ my sub create_nvidia_device {
#
# mdev devices must be chosen later when we actually allocate it, but we
# flatten the inner list since there can only be one device per alternative anyway
-my sub choose_hostpci_devices {
+sub choose_hostpci_devices {
my ($devices, $vmid) = @_;
# if the vm is running, we must be in 'showcmd', so don't actually reserve or create anything
diff --git a/src/test/Makefile b/src/test/Makefile
index f7372e2e..2ef9073a 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,6 +1,6 @@
all: test
-test: test_snapshot test_cfg_to_cmd test_pci_addr_conflicts test_qemu_img_convert test_migration test_restore_config test_parse_config
+test: test_snapshot test_cfg_to_cmd test_pci_addr_conflicts test_pci_reservation test_qemu_img_convert test_migration test_restore_config test_parse_config
test_snapshot: run_snapshot_tests.pl
./run_snapshot_tests.pl
@@ -15,6 +15,9 @@ test_qemu_img_convert: run_qemu_img_convert_tests.pl
test_pci_addr_conflicts: run_pci_addr_checks.pl
./run_pci_addr_checks.pl
+test_pci_reservation: run_pci_reservation_tests.pl
+ ./run_pci_reservation_tests.pl
+
MIGRATION_TEST_TARGETS := $(addprefix test_migration_,$(shell perl -ne 'print "$$1 " if /^\s*name\s*=>\s*["'\'']([^\s"'\'']+)["'\'']\s*,\s*$$/; END { print "\n" }' run_qemu_migrate_tests.pl))
test_migration: run_qemu_migrate_tests.pl MigrationTest/*.pm $(MIGRATION_TEST_TARGETS)
diff --git a/src/test/run_pci_reservation_tests.pl b/src/test/run_pci_reservation_tests.pl
new file mode 100755
index 00000000..bd428a80
--- /dev/null
+++ b/src/test/run_pci_reservation_tests.pl
@@ -0,0 +1,175 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+
+my $vmid = 8006;
+
+use Test::MockModule;
+use Test::More;
+
+use PVE::Mapping::PCI;
+
+use PVE::QemuServer::PCI;
+
+my $pci_devs = [
+ "0000:00:43.1",
+ "0000:00:f4.0",
+ "0000:00:ff.1",
+ "0000:0f:f2.0",
+ "0000:d0:13.0",
+ "0000:d0:15.1",
+ "0000:d0:15.2",
+ "0000:d0:17.0",
+ "0000:f0:42.0",
+ "0000:f0:43.0",
+ "0000:f0:43.1",
+ "1234:f0:43.1",
+ "0000:01:00.4",
+ "0000:01:00.5",
+ "0000:01:00.6",
+ "0000:07:10.0",
+ "0000:07:10.1",
+ "0000:07:10.4",
+];
+
+my $pci_map_config = {
+ ids => {
+ someGpu => {
+ type => 'pci',
+ mdev => 1,
+ map => [
+ 'node=localhost,path=0000:01:00.4,id=10de:2231,iommugroup=1',
+ 'node=localhost,path=0000:01:00.5,id=10de:2231,iommugroup=1',
+ 'node=localhost,path=0000:01:00.6,id=10de:2231,iommugroup=1',
+ ],
+ },
+ someNic => {
+ type => 'pci',
+ map => [
+ 'node=localhost,path=0000:07:10.0,id=8086:1520,iommugroup=2',
+ 'node=localhost,path=0000:07:10.1,id=8086:1520,iommugroup=2',
+ 'node=localhost,path=0000:07:10.4,id=8086:1520,iommugroup=2',
+ ],
+ },
+ },
+};
+
+my $tests = [
+ {
+ name => 'reservation-is-respected',
+ conf => {
+ hostpci0 => 'mapping=someNic',
+ hostpci1 => 'mapping=someGpu,mdev=some-model',
+ hostpci2 => 'mapping=someNic',
+ },
+ expected => {
+ hostpci0 => { ids => [{ id => '0000:07:10.0' }] },
+ hostpci1 => {
+ ids => [
+ { id => '0000:01:00.4' }, { id => '0000:01:00.5' },
+ { id => '0000:01:00.6' },
+ ],
+ mdev => 'some-model',
+ },
+ hostpci2 => { ids => [{ id => '0000:07:10.4' }] },
+ },
+ },
+];
+
+plan tests => scalar($tests->@*);
+
+my $pve_common_inotify;
+$pve_common_inotify = Test::MockModule->new('PVE::INotify');
+$pve_common_inotify->mock(
+ nodename => sub {
+ return 'localhost';
+ },
+);
+
+my $pve_common_sysfstools;
+$pve_common_sysfstools = Test::MockModule->new('PVE::SysFSTools');
+$pve_common_sysfstools->mock(
+ lspci => sub {
+ my ($filter, $verbose) = @_;
+
+ return [
+ map { { id => $_ } }
+ grep {
+ !defined($filter)
+ || (!ref($filter) && $_ =~ m/^(0000:)?\Q$filter\E/)
+ || (ref($filter) eq 'CODE' && $filter->({ id => $_ }))
+ } sort @$pci_devs
+ ];
+ },
+ pci_device_info => sub {
+ my ($path, $noerr) = @_;
+
+ if ($path =~ m/^0000:01:00/) {
+ return {
+ mdev => 1,
+ iommugroup => 1,
+ mdev => 1,
+ vendor => "0x10de",
+ device => "0x2231",
+ };
+ } elsif ($path =~ m/^0000:07:10/) {
+ return {
+ iommugroup => 2,
+ vendor => "0x8086",
+ device => "0x1520",
+ };
+ } else {
+ return {};
+ }
+ },
+);
+
+my $mapping_pci_module = Test::MockModule->new("PVE::Mapping::PCI");
+$mapping_pci_module->mock(
+ config => sub {
+ return $pci_map_config;
+ },
+);
+
+my $pci_module = Test::MockModule->new("PVE::QemuServer::PCI");
+$pci_module->mock(
+ reserve_pci_usage => sub {
+ my ($ids, $vmid, $timeout, $pid, $dryrun) = @_;
+
+ $ids = [$ids] if !ref($ids);
+
+ for my $id (@$ids) {
+ if ($id eq "0000:07:10.1") {
+ die "reserved";
+ }
+ }
+
+ return undef;
+ },
+ create_nvidia_device => sub {
+ return 1;
+ },
+);
+
+for my $test ($tests->@*) {
+ my ($name, $conf, $expected) = $test->@{qw(name conf expected)};
+ my $pci_devices;
+ eval {
+ my $devices = PVE::QemuServer::PCI::parse_hostpci_devices($conf);
+ use JSON;
+ $pci_devices = PVE::QemuServer::PCI::choose_hostpci_devices($devices, $vmid);
+ };
+ if (my $err = $@) {
+ is($err, $expected, $name);
+ } elsif ($pci_devices) {
+ is_deeply($pci_devices, $expected, $name);
+ } else {
+ fail($name);
+ note("no result");
+ }
+}
+
+done_testing();
--
2.39.5
More information about the pve-devel
mailing list