From 2a1fc29e84a74ee8e3fb8c48ef4e239a5158cde9 Mon Sep 17 00:00:00 2001 From: Huang Jianan Date: Mon, 24 Apr 2023 17:31:45 +0800 Subject: [PATCH] dragonball: add unit test for vhost-user-fs Add some test cases for vhost-user-fs function. Signed-off-by: Beiyue Signed-off-by: Huang Jianan --- .../src/vhost/vhost_user/fs.rs | 198 ++++++++++++++++++ .../src/vhost/vhost_user/test_utils.rs | 1 - 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/fs.rs b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/fs.rs index c4ed0cd7dc..43b132656e 100644 --- a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/fs.rs +++ b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/fs.rs @@ -773,3 +773,201 @@ where self } } + +#[cfg(test)] +mod tests { + use std::sync::Arc; + use std::thread; + use std::time::Duration; + + use dbs_device::resources::DeviceResources; + use dbs_interrupt::{InterruptManager, InterruptSourceType, MsiNotifier, NoopNotifier}; + use dbs_utils::epoll_manager::EpollManager; + use kvm_ioctls::Kvm; + use vhost_rs::vhost_user::message::{ + VhostUserProtocolFeatures, VhostUserU64, VhostUserVirtioFeatures, + }; + use vhost_rs::vhost_user::Listener; + use virtio_queue::QueueSync; + use vm_memory::{FileOffset, GuestMemoryMmap, GuestRegionMmap}; + use vmm_sys_util::tempfile::TempFile; + + use crate::device::VirtioDevice; + use crate::vhost::vhost_user::fs::VhostUserFs; + use crate::vhost::vhost_user::test_utils::*; + use crate::{GuestAddress, VirtioDeviceConfig, VirtioQueueConfig, TYPE_VIRTIO_FS}; + + pub(crate) const GUEST_PHYS_END: u64 = (1 << 46) - 1; + pub(crate) const GUEST_MEM_START: u64 = 0; + pub(crate) const GUEST_MEM_END: u64 = GUEST_PHYS_END >> 1; + + fn create_vhost_user_fs_slave(slave: &mut Endpoint) { + let (hdr, rfds) = slave.recv_header().unwrap(); + assert_eq!(hdr.get_code(), MasterReq::GET_FEATURES); + assert!(rfds.is_none()); + let vfeatures = 0x15 | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); + let hdr = VhostUserMsgHeader::new(MasterReq::GET_FEATURES, 0x4, 8); + let msg = VhostUserU64::new(vfeatures); + slave.send_message(&hdr, &msg, None).unwrap(); + } + + #[test] + fn test_vhost_user_fs_virtio_device_normal() { + let device_socket = "/var/tmp/vhost.1"; + let tag = "test_fs"; + + let handler = thread::spawn(move || { + let listener = Listener::new(device_socket, true).unwrap(); + let mut slave = Endpoint::::from_stream(listener.accept().unwrap().unwrap()); + create_vhost_user_fs_slave(&mut slave); + }); + + thread::sleep(Duration::from_millis(20)); + + let epoll_mgr = EpollManager::default(); + + let mut dev: VhostUserFs> = VhostUserFs::new( + String::from(device_socket), + String::from(tag), + 2, + 2, + 2, + epoll_mgr, + ) + .unwrap(); + + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::device_type(&dev), + TYPE_VIRTIO_FS + ); + + let queue_size = vec![2, 2, 2]; + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::queue_max_sizes( + &dev + ), + &queue_size[..] + ); + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::get_avail_features(&dev, 0), + dev.device().device_info.get_avail_features(0) + ); + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::get_avail_features(&dev, 1), + dev.device().device_info.get_avail_features(1) + ); + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::get_avail_features(&dev, 2), + dev.device().device_info.get_avail_features(2) + ); + VirtioDevice::>, QueueSync, GuestRegionMmap>::set_acked_features( + &mut dev, 2, 0, + ); + assert_eq!( + VirtioDevice::>, QueueSync, GuestRegionMmap>::get_avail_features(&dev, 2), + 0 + ); + let config: [u8; 8] = [0; 8]; + VirtioDevice::>, QueueSync, GuestRegionMmap>::write_config( + &mut dev, 0, &config, + ); + let mut data: [u8; 8] = [1; 8]; + VirtioDevice::>, QueueSync, GuestRegionMmap>::read_config( + &mut dev, 0, &mut data, + ); + assert_eq!(config, data); + + handler.join().unwrap(); + } + + #[test] + fn test_vhost_user_fs_virtio_device_activate() { + let device_socket = "/var/tmp/vhost.1"; + let tag = "test_fs"; + + let handler = thread::spawn(move || { + let listener = Listener::new(device_socket, true).unwrap(); + let mut slave = Endpoint::::from_stream(listener.accept().unwrap().unwrap()); + create_vhost_user_fs_slave(&mut slave); + + let pfeatures = VhostUserProtocolFeatures::CONFIG; + negotiate_slave(&mut slave, pfeatures, false, 3); + }); + + thread::sleep(Duration::from_millis(20)); + + let epoll_mgr = EpollManager::default(); + let mut dev: VhostUserFs> = VhostUserFs::new( + String::from(device_socket), + String::from(tag), + 2, + 2, + 2, + epoll_mgr, + ) + .unwrap(); + + // invalid queue size + { + let kvm = Kvm::new().unwrap(); + let vm_fd = Arc::new(kvm.create_vm().unwrap()); + let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap(); + let resources = DeviceResources::new(); + let queues = vec![VirtioQueueConfig::::create(128, 0).unwrap()]; + let config = VirtioDeviceConfig::new( + Arc::new(mem), + vm_fd, + resources, + queues, + None, + Arc::new(NoopNotifier::new()), + ); + assert!(dev.activate(config).is_err()); + } + + // success + { + let kvm = Kvm::new().unwrap(); + let vm_fd = Arc::new(kvm.create_vm().unwrap()); + + let (_vmfd, irq_manager) = crate::tests::create_vm_and_irq_manager(); + let group = irq_manager + .create_group(InterruptSourceType::MsiIrq, 0, 3) + .unwrap(); + + let notifier = MsiNotifier::new(group.clone(), 1); + let notifier2 = MsiNotifier::new(group.clone(), 1); + let notifier3 = MsiNotifier::new(group.clone(), 1); + let mut queues = vec![ + VirtioQueueConfig::::create(128, 0).unwrap(), + VirtioQueueConfig::::create(128, 0).unwrap(), + VirtioQueueConfig::::create(128, 0).unwrap(), + ]; + queues[0].set_interrupt_notifier(Arc::new(notifier)); + queues[1].set_interrupt_notifier(Arc::new(notifier2)); + queues[2].set_interrupt_notifier(Arc::new(notifier3)); + + let f = TempFile::new().unwrap().into_file(); + f.set_len(0x400).unwrap(); + let mem = GuestMemoryMmap::from_ranges_with_files(&[( + GuestAddress(0), + 0x400, + Some(FileOffset::new(f, 0)), + )]) + .unwrap(); + let resources = DeviceResources::new(); + let config = VirtioDeviceConfig::new( + Arc::new(mem), + vm_fd, + resources, + queues, + None, + Arc::new(NoopNotifier::new()), + ); + + dev.activate(config).unwrap(); + } + + handler.join().unwrap(); + } +} diff --git a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/test_utils.rs b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/test_utils.rs index ac5fb9e1d7..c8b8693a99 100644 --- a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/test_utils.rs +++ b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_user/test_utils.rs @@ -610,7 +610,6 @@ impl AsRawFd for Endpoint { pub(crate) fn negotiate_slave( slave: &mut Endpoint, pfeatures: VhostUserProtocolFeatures, - use_ali_feature: bool, has_protocol_mq: bool, queue_num: u64, ) {