From 18873d88d7b61e02c4b4fce5fafa9172a6e2dee0 Mon Sep 17 00:00:00 2001 From: Pascal Scholz Date: Wed, 25 Mar 2026 18:34:53 +0100 Subject: [PATCH] tests: Add an integration test for PCI device ID allocation errors Adds a test that checks the correct error is returned on allocation of an invalid device ID (one that is not in the range 0-31) and when trying to allocate a reserved ID (such as that of the root bridge). Signed-off-by: Pascal Scholz On-behalf-of: SAP pascal.scholz@sap.com Signed-off-by: Rob Bradford --- cloud-hypervisor/tests/integration.rs | 80 +++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/cloud-hypervisor/tests/integration.rs b/cloud-hypervisor/tests/integration.rs index 51d4b06e8..8657edc3b 100644 --- a/cloud-hypervisor/tests/integration.rs +++ b/cloud-hypervisor/tests/integration.rs @@ -5915,6 +5915,86 @@ mod common_parallel { handle_child_output(r, &output); } + + #[test] + // Test that requesting an invalid device ID fails. + fn test_invalid_pci_device_id() { + let disk_config = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string()); + let guest = Guest::new(Box::new(disk_config)); + + #[cfg(target_arch = "x86_64")] + let kernel_path = direct_kernel_boot_path(); + #[cfg(target_arch = "aarch64")] + let kernel_path = edk2_path(); + + let api_socket = temp_api_path(&guest.tmp_dir); + + // Boot without network + let mut cmd = GuestCommand::new(&guest); + + cmd.args(["--api-socket", &api_socket]) + .default_cpus() + .default_memory() + .args(["--kernel", kernel_path.to_str().unwrap()]) + .args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE]) + .default_net() + .default_disks() + .capture_output(); + + let mut child = cmd.spawn().unwrap(); + + guest.wait_vm_boot().unwrap(); + + let r = std::panic::catch_unwind(|| { + // Invalid API call because the PCI device ID is out of range + let (cmd_success, _, cmd_stderr) = remote_command_w_output( + &api_socket, + "add-net", + Some( + format!( + "id=test0,tap=,mac={},ip={},mask=255.255.255.128,pci_device_id=188", + guest.network.guest_mac1, guest.network.host_ip1, + ) + .as_str(), + ), + ); + // Check for fail + assert!(!cmd_success); + // Check that the error message contains the expected error + let std_err_str = String::from_utf8(cmd_stderr).unwrap(); + assert!( + std_err_str + .contains("Given PCI device ID (188) is out of the supported range of 0..32"), + "Command return was: {std_err_str}", + ); + + // Use the reserved device ID 0 (root device) + let (cmd_success, _, cmd_stderr) = remote_command_w_output( + &api_socket, + "add-net", + Some( + format!( + "id=test0,tap=,mac={},ip={},mask=255.255.255.128,pci_device_id=0", + guest.network.guest_mac1, guest.network.host_ip1, + ) + .as_str(), + ), + ); + // Check for fail + assert!(!cmd_success); + // Check that the error message contains the expected error + let std_err_str = String::from_utf8(cmd_stderr).unwrap(); + assert!( + std_err_str.contains("Given PCI device ID (0) is reserved"), + "Command return was: {std_err_str}" + ); + }); + + kill_child(&mut child); + let output = child.wait_with_output().unwrap(); + + handle_child_output(r, &output); + } } mod dbus_api {