From 7cdb72434680960a556ff40e67c14431d337f288 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 26 May 2026 20:38:39 +0200 Subject: [PATCH] virtio-devices: Add activator unit test scaffolding Add TestVirtioDevice with a controllable ActivateResult, TestVirtioInterrupt that records delivered interrupt types, and a make_activator helper that builds a complete VirtioPciDeviceActivator with observable status, activated flag, interrupt log, and barrier. Assisted-by: Claude:Opus-4.7 Signed-off-by: Anatol Belski --- virtio-devices/src/transport/pci_device.rs | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index db6fe517b..b91856e59 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -1525,4 +1525,73 @@ mod unit_tests { assert_eq!(bar_offset, 0); assert_eq!(access_len, 2); } + + struct TestVirtioDevice { + result: Mutex>, + } + + impl VirtioDevice for TestVirtioDevice { + fn device_type(&self) -> u32 { + 0 + } + fn queue_max_sizes(&self) -> &[u16] { + &[] + } + fn activate(&mut self, _context: crate::device::ActivationContext) -> ActivateResult { + self.result.lock().unwrap().take().unwrap() + } + } + + struct TestVirtioInterrupt { + triggers: Mutex>, + } + + impl VirtioInterrupt for TestVirtioInterrupt { + fn trigger(&self, int_type: VirtioInterruptType) -> std::io::Result<()> { + self.triggers.lock().unwrap().push(int_type); + Ok(()) + } + fn set_notifier( + &self, + _int_type: u32, + _notifier: Option, + _vm: &dyn hypervisor::Vm, + ) -> std::io::Result<()> { + Ok(()) + } + } + + fn make_activator( + result: ActivateResult, + ) -> ( + VirtioPciDeviceActivator, + Arc, + Arc, + Arc, + Arc, + ) { + let interrupt = Arc::new(TestVirtioInterrupt { + triggers: Mutex::new(Vec::new()), + }); + let status = Arc::new(AtomicU8::new(DEVICE_DRIVER_OK as u8)); + let device_activated = Arc::new(AtomicBool::new(false)); + let device = Arc::new(Mutex::new(TestVirtioDevice { + result: Mutex::new(Some(result)), + })); + let memory = GuestMemoryAtomic::new( + GuestMemoryMmap::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(), + ); + let barrier = Arc::new(Barrier::new(2)); + let activator = VirtioPciDeviceActivator { + interrupt: interrupt.clone(), + memory: Some(memory), + device, + device_activated: device_activated.clone(), + queues: Some(Vec::new()), + barrier: Some(barrier.clone()), + id: "test-dev".to_string(), + status: status.clone(), + }; + (activator, status, device_activated, interrupt, barrier) + } }