From a3423a4483762dd9d7743fa19fae67e80cb71540 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Sat, 21 Mar 2026 18:43:39 -0700 Subject: [PATCH] tests: extract _test_tap_from_fd to tests_wrappers Extract test logic from test_tap_from_fd into a shared _test_tap_from_fd wrapper function in tests_wrappers.rs. Update the parent test case to use the basic_regular_guest macro with with_cpu(2). The wrapper uses default_kernel_cmdline() for kernel/cmdline setup. Signed-off-by: Muminul Islam --- .../tests/common/tests_wrappers.rs | 70 ++++++++++++++++++ cloud-hypervisor/tests/integration.rs | 73 +------------------ 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/cloud-hypervisor/tests/common/tests_wrappers.rs b/cloud-hypervisor/tests/common/tests_wrappers.rs index bfc954b25..0b8ffd7fe 100644 --- a/cloud-hypervisor/tests/common/tests_wrappers.rs +++ b/cloud-hypervisor/tests/common/tests_wrappers.rs @@ -4,6 +4,7 @@ use std::ffi::CStr; use std::fs::{self, OpenOptions}; use std::io::{Read, Seek, SeekFrom, Write}; +use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; use std::string::String; use std::sync::mpsc; @@ -3193,3 +3194,72 @@ pub(crate) fn _test_pvpanic(guest: &Guest) { handle_child_output(r, &output); } + +pub(crate) fn _test_tap_from_fd(guest: &Guest) { + // Create a TAP interface with multi-queue enabled + let num_queue_pairs: usize = 2; + + use std::str::FromStr; + let taps = net_util::open_tap( + Some("chtap0"), + Some(std::net::IpAddr::V4( + std::net::Ipv4Addr::from_str(&guest.network.host_ip0).unwrap(), + )), + None, + &mut None, + None, + num_queue_pairs, + Some(libc::O_RDWR | libc::O_NONBLOCK), + ) + .unwrap(); + + let mut child = GuestCommand::new(guest) + .default_cpus() + .default_memory() + .default_kernel_cmdline() + .default_disks() + .args([ + "--net", + &format!( + "fd=[{},{}],mac={},num_queues={}", + taps[0].as_raw_fd(), + taps[1].as_raw_fd(), + guest.network.guest_mac0, + num_queue_pairs * 2 + ), + ]) + .capture_output() + .spawn() + .unwrap(); + + let r = std::panic::catch_unwind(|| { + guest.wait_vm_boot().unwrap(); + + assert_eq!( + guest + .ssh_command("ip -o link | wc -l") + .unwrap() + .trim() + .parse::() + .unwrap_or_default(), + 2 + ); + + guest.reboot_linux(0); + + assert_eq!( + guest + .ssh_command("ip -o link | wc -l") + .unwrap() + .trim() + .parse::() + .unwrap_or_default(), + 2 + ); + }); + + kill_child(&mut child); + let output = child.wait_with_output().unwrap(); + + handle_child_output(r, &output); +} diff --git a/cloud-hypervisor/tests/integration.rs b/cloud-hypervisor/tests/integration.rs index e31c08a40..744986fee 100644 --- a/cloud-hypervisor/tests/integration.rs +++ b/cloud-hypervisor/tests/integration.rs @@ -5111,77 +5111,8 @@ mod common_parallel { #[test] fn test_tap_from_fd() { - let disk_config = UbuntuDiskConfig::new(JAMMY_IMAGE_NAME.to_string()); - let guest = Guest::new(Box::new(disk_config)); - let kernel_path = direct_kernel_boot_path(); - - // Create a TAP interface with multi-queue enabled - let num_queue_pairs: usize = 2; - - use std::str::FromStr; - let taps = net_util::open_tap( - Some("chtap0"), - Some(std::net::IpAddr::V4( - std::net::Ipv4Addr::from_str(&guest.network.host_ip0).unwrap(), - )), - None, - &mut None, - None, - num_queue_pairs, - Some(libc::O_RDWR | libc::O_NONBLOCK), - ) - .unwrap(); - - let mut child = GuestCommand::new(&guest) - .args(["--cpus", &format!("boot={num_queue_pairs}")]) - .default_memory() - .args(["--kernel", kernel_path.to_str().unwrap()]) - .args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE]) - .default_disks() - .args([ - "--net", - &format!( - "fd=[{},{}],mac={},num_queues={}", - taps[0].as_raw_fd(), - taps[1].as_raw_fd(), - guest.network.guest_mac0, - num_queue_pairs * 2 - ), - ]) - .capture_output() - .spawn() - .unwrap(); - - let r = std::panic::catch_unwind(|| { - guest.wait_vm_boot().unwrap(); - - assert_eq!( - guest - .ssh_command("ip -o link | wc -l") - .unwrap() - .trim() - .parse::() - .unwrap_or_default(), - 2 - ); - - guest.reboot_linux(0); - - assert_eq!( - guest - .ssh_command("ip -o link | wc -l") - .unwrap() - .trim() - .parse::() - .unwrap_or_default(), - 2 - ); - }); - - kill_child(&mut child); - let output = child.wait_with_output().unwrap(); - - handle_child_output(r, &output); + let guest = basic_regular_guest!(JAMMY_IMAGE_NAME).with_cpu(2); + _test_tap_from_fd(&guest); } // By design, a guest VM won't be able to connect to the host