From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id A56481FF13B for ; Wed, 11 Feb 2026 10:26:17 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 809C316400; Wed, 11 Feb 2026 10:27:00 +0100 (CET) From: Dominik Csapak To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server v4 1/4] ovmf: introduce helpers that can be mocked for tests Date: Wed, 11 Feb 2026 10:04:01 +0100 Message-ID: <20260211092624.1318345-2-d.csapak@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260211092624.1318345-1-d.csapak@proxmox.com> References: <20260211092624.1318345-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.031 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. 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: V2E6UXBZVLQUXF7C7L6ZX245ZDM4WTGK X-Message-ID-Hash: V2E6UXBZVLQUXF7C7L6ZX245ZDM4WTGK X-MailFrom: d.csapak@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: This makes it easy for us to mock these in tests, so there is no need for the files to actually exist during package build. Makes the edk2-firmware build dependency unnecessary. Signed-off-by: Dominik Csapak --- new in v4 alternatively, we could look into using 'Test::MockFile', which can mock all file accesses, but this would probably be a more intrusive change for the tests, since it will by default mock every file access. src/PVE/QemuServer/OVMF.pm | 35 +++++++++++++++++++--------- src/test/run_config2command_tests.pl | 19 +++++++++++++++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/PVE/QemuServer/OVMF.pm b/src/PVE/QemuServer/OVMF.pm index 01b037ef..689d290a 100644 --- a/src/PVE/QemuServer/OVMF.pm +++ b/src/PVE/QemuServer/OVMF.pm @@ -54,6 +54,18 @@ my $OVMF = { }, }; +# easier to mock for testing that '-f'. +sub file_exists { + my ($path) = @_; + return -f $path; +} + +# easier to mock for testing that '-s'. +sub get_file_size { + my ($path) = @_; + return -s $path; +} + my sub get_ovmf_files($$$$) { my ($arch, $efidisk, $smm, $cvm_type) = @_; @@ -65,14 +77,14 @@ my sub get_ovmf_files($$$$) { if ($cvm_type && $cvm_type eq 'snp') { $type = "4m-snp"; my ($ovmf) = $types->{$type}->@*; - die "EFI base image '$ovmf' not found\n" if !-f $ovmf; + die "EFI base image '$ovmf' not found\n" if !file_exists($ovmf); return ($ovmf); } elsif ($cvm_type && ($cvm_type eq 'std' || $cvm_type eq 'es')) { $type = "4m-sev"; } elsif ($cvm_type && $cvm_type eq 'tdx') { $type = "4m-tdx"; my ($ovmf) = $types->{$type}->@*; - die "EFI base image '$ovmf' not found\n" if !-f $ovmf; + die "EFI base image '$ovmf' not found\n" if !file_exists($ovmf); return ($ovmf); } elsif (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') { $type = $smm ? "4m" : "4m-no-smm"; @@ -83,8 +95,8 @@ my sub get_ovmf_files($$$$) { } my ($ovmf_code, $ovmf_vars) = $types->{$type}->@*; - die "EFI base image '$ovmf_code' not found\n" if !-f $ovmf_code; - die "EFI vars image '$ovmf_vars' not found\n" if !-f $ovmf_vars; + die "EFI base image '$ovmf_code' not found\n" if !file_exists($ovmf_code); + die "EFI vars image '$ovmf_vars' not found\n" if !file_exists($ovmf_vars); return ($ovmf_code, $ovmf_vars); } @@ -103,6 +115,7 @@ my sub print_ovmf_drive_commandlines { if $cvm_type && $cvm_type eq 'tdx'; my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35, $cvm_type); + my $ovmf_vars_size = get_file_size($ovmf_vars); my $var_drive_str = "if=pflash,unit=1,id=drive-efidisk0"; if ($d) { @@ -121,15 +134,15 @@ my sub print_ovmf_drive_commandlines { } $var_drive_str .= ",format=$format,file=$path"; - $var_drive_str .= ",size=" . (-s $ovmf_vars) + $var_drive_str .= ",size=" . $ovmf_vars_size if $format eq 'raw' && $version_guard->(4, 1, 2); $var_drive_str .= ',readonly=on' if $readonly; } else { log_warn("no efidisk configured! Using temporary efivars disk."); my $path = "/tmp/$vmid-ovmf.fd"; - PVE::Tools::file_copy($ovmf_vars, $path, -s $ovmf_vars); + PVE::Tools::file_copy($ovmf_vars, $path, $ovmf_vars_size); $var_drive_str .= ",format=raw,file=$path"; - $var_drive_str .= ",size=" . (-s $ovmf_vars) if $version_guard->(4, 1, 2); + $var_drive_str .= ",size=" . $ovmf_vars_size if $version_guard->(4, 1, 2); } return ("if=pflash,unit=0,format=raw,readonly=on,file=$ovmf_code", $var_drive_str); @@ -139,7 +152,7 @@ sub get_efivars_size { my ($arch, $efidisk, $smm, $cvm_type) = @_; my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $cvm_type); - return -s $ovmf_vars; + return get_file_size($ovmf_vars); } my sub is_ms_2023_cert_enrolled { @@ -171,7 +184,7 @@ sub create_efidisk($$$$$$$$) { my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $cvm_type); - my $vars_size_b = -s $ovmf_vars; + my $vars_size_b = get_file_size($ovmf_vars); my $vars_size = PVE::Tools::convert_size($vars_size_b, 'b' => 'kb'); my $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, $vars_size); PVE::Storage::activate_volumes($storecfg, [$volid]); @@ -219,7 +232,7 @@ my sub generate_ovmf_blockdev { } else { log_warn("no efidisk configured! Using temporary efivars disk."); my $path = "/tmp/$vmid-ovmf.fd"; - PVE::Tools::file_copy($ovmf_vars, $path, -s $ovmf_vars); + PVE::Tools::file_copy($ovmf_vars, $path, get_file_size($ovmf_vars)); $drive = { file => $path, interface => 'efidisk', index => 0 }; $format = 'raw'; } @@ -231,7 +244,7 @@ my sub generate_ovmf_blockdev { my $extra_blockdev_options = {}; $extra_blockdev_options->{'read-only'} = 1 if $readonly; - $extra_blockdev_options->{size} = -s $ovmf_vars if $format eq 'raw'; + $extra_blockdev_options->{size} = get_file_size($ovmf_vars) if $format eq 'raw'; my $throttle_group = PVE::QemuServer::Blockdev::generate_throttle_group($drive); diff --git a/src/test/run_config2command_tests.pl b/src/test/run_config2command_tests.pl index 4c872d1c..d272bbc6 100755 --- a/src/test/run_config2command_tests.pl +++ b/src/test/run_config2command_tests.pl @@ -19,6 +19,7 @@ use PVE::QemuServer; use PVE::QemuServer::Drive; use PVE::QemuServer::Helpers; use PVE::QemuServer::Monitor; +use PVE::QemuServer::OVMF; use PVE::QemuServer::QMPHelpers; use PVE::QemuServer::CPUConfig; use PVE::Storage; @@ -264,6 +265,24 @@ $qemu_server_module->mock( }, ); +my $qemu_server_ovmf_module = Test::MockModule->new("PVE::QemuServer::OVMF"); +$qemu_server_ovmf_module->mock( + file_exists => sub { + my ($path) = @_; + return 1; + }, + get_file_size => sub { + my ($path) = @_; + if ($path =~ m/VARS_4M/i) { + return 528 * 1024; + } elsif ($path =~ m/VARS/) { + return 128 * 1024; + } else { + return 0; + } + }, +); + my $storage_module = Test::MockModule->new("PVE::Storage"); $storage_module->mock( activate_volumes => sub { -- 2.47.3