vm/tests/device_simulation.rs

483 lines
13 KiB
Rust

//! 设备模拟集成测试
#[cfg(test)]
mod virtio_block_device {
/// VirtIO块设备操作
enum BlockOp {
Read { sector: u64, count: u32 },
Write { sector: u64, count: u32 },
}
/// VirtIO块设备模拟器
struct VirtioBlockDevice {
sector_size: u32,
total_sectors: u64,
data_buffer: Vec<u8>,
}
impl VirtioBlockDevice {
fn new(total_sectors: u64, sector_size: u32) -> Self {
Self {
sector_size,
total_sectors,
data_buffer: vec![0; (total_sectors as usize) * (sector_size as usize)],
}
}
fn read(&self, sector: u64, count: u32) -> Option<Vec<u8>> {
if sector + count as u64 > self.total_sectors {
return None;
}
let start = (sector as usize) * (self.sector_size as usize);
let end = start + (count as usize) * (self.sector_size as usize);
Some(self.data_buffer[start..end].to_vec())
}
fn write(&mut self, sector: u64, data: &[u8]) -> bool {
let count = data.len() / (self.sector_size as usize);
if sector + count as u64 > self.total_sectors {
return false;
}
let start = (sector as usize) * (self.sector_size as usize);
let end = start + data.len();
self.data_buffer[start..end].copy_from_slice(data);
true
}
}
#[test]
fn test_block_device_creation() {
let device = VirtioBlockDevice::new(1000, 512);
assert_eq!(device.total_sectors, 1000);
assert_eq!(device.sector_size, 512);
}
#[test]
fn test_block_read_operation() {
let device = VirtioBlockDevice::new(100, 512);
let data = device.read(0, 1);
assert!(data.is_some());
assert_eq!(data.unwrap().len(), 512);
}
#[test]
fn test_block_write_operation() {
let mut device = VirtioBlockDevice::new(100, 512);
let write_data = vec![0xAB; 512];
assert!(device.write(0, &write_data));
}
#[test]
fn test_block_boundary_check() {
let device = VirtioBlockDevice::new(10, 512);
// 超过容量的读取应该失败
assert!(device.read(0, 20).is_none());
}
#[test]
fn test_block_read_write_consistency() {
let mut device = VirtioBlockDevice::new(100, 512);
let write_data = vec![0xDEADBEEF as u8; 512];
device.write(5, &write_data);
let read_data = device.read(5, 1).unwrap();
assert_eq!(write_data, read_data);
}
}
#[cfg(test)]
mod virtio_network_device {
/// VirtIO网络数据包
struct NetworkPacket {
data: Vec<u8>,
size: usize,
}
impl NetworkPacket {
fn new(data: Vec<u8>) -> Self {
let size = data.len();
Self { data, size }
}
}
/// VirtIO网络设备模拟器
struct VirtioNetDevice {
rx_queue: Vec<NetworkPacket>,
tx_queue: Vec<NetworkPacket>,
max_queue_size: usize,
}
impl VirtioNetDevice {
fn new(max_queue_size: usize) -> Self {
Self {
rx_queue: Vec::new(),
tx_queue: Vec::new(),
max_queue_size,
}
}
fn send(&mut self, packet: NetworkPacket) -> bool {
if self.tx_queue.len() < self.max_queue_size {
self.tx_queue.push(packet);
true
} else {
false
}
}
fn receive(&mut self, packet: NetworkPacket) -> bool {
if self.rx_queue.len() < self.max_queue_size {
self.rx_queue.push(packet);
true
} else {
false
}
}
fn get_rx_packet(&mut self) -> Option<NetworkPacket> {
if self.rx_queue.is_empty() {
None
} else {
Some(self.rx_queue.remove(0))
}
}
fn get_tx_packet(&mut self) -> Option<NetworkPacket> {
if self.tx_queue.is_empty() {
None
} else {
Some(self.tx_queue.remove(0))
}
}
}
#[test]
fn test_net_device_creation() {
let device = VirtioNetDevice::new(256);
assert_eq!(device.rx_queue.len(), 0);
assert_eq!(device.tx_queue.len(), 0);
}
#[test]
fn test_net_send_packet() {
let mut device = VirtioNetDevice::new(256);
let packet = NetworkPacket::new(vec![1, 2, 3, 4]);
assert!(device.send(packet));
assert_eq!(device.tx_queue.len(), 1);
}
#[test]
fn test_net_receive_packet() {
let mut device = VirtioNetDevice::new(256);
let packet = NetworkPacket::new(vec![5, 6, 7, 8]);
assert!(device.receive(packet));
assert_eq!(device.rx_queue.len(), 1);
}
#[test]
fn test_net_queue_overflow() {
let mut device = VirtioNetDevice::new(2);
// 填满队列
assert!(device.send(NetworkPacket::new(vec![1])));
assert!(device.send(NetworkPacket::new(vec![2])));
// 第三个应该失败
assert!(!device.send(NetworkPacket::new(vec![3])));
}
#[test]
fn test_net_packet_retrieval() {
let mut device = VirtioNetDevice::new(256);
let data = vec![0xAA, 0xBB, 0xCC];
device.send(NetworkPacket::new(data.clone()));
let packet = device.get_tx_packet().unwrap();
assert_eq!(packet.data, data);
}
}
#[cfg(test)]
mod mmio_device_tests {
/// MMIO寄存器映射设备
struct MmioDevice {
registers: Vec<u32>,
register_count: usize,
}
impl MmioDevice {
fn new(register_count: usize) -> Self {
Self {
registers: vec![0; register_count],
register_count,
}
}
fn read_register(&self, offset: usize) -> Option<u32> {
if offset < self.register_count {
Some(self.registers[offset])
} else {
None
}
}
fn write_register(&mut self, offset: usize, value: u32) -> bool {
if offset < self.register_count {
self.registers[offset] = value;
true
} else {
false
}
}
fn read_register_field(&self, offset: usize, bit_offset: u32, mask: u32) -> Option<u32> {
self.read_register(offset).map(|val| (val >> bit_offset) & mask)
}
fn write_register_field(&mut self, offset: usize, bit_offset: u32, mask: u32, value: u32) -> bool {
if let Some(current) = self.read_register(offset) {
let masked = current & !(mask << bit_offset);
let new_val = masked | ((value & mask) << bit_offset);
self.write_register(offset, new_val)
} else {
false
}
}
}
#[test]
fn test_mmio_device_creation() {
let device = MmioDevice::new(16);
assert_eq!(device.register_count, 16);
}
#[test]
fn test_mmio_read_write() {
let mut device = MmioDevice::new(8);
assert!(device.write_register(0, 0xDEADBEEF));
assert_eq!(device.read_register(0), Some(0xDEADBEEF));
}
#[test]
fn test_mmio_boundary_check() {
let mut device = MmioDevice::new(4);
assert!(!device.write_register(10, 0x123));
assert!(device.read_register(10).is_none());
}
#[test]
fn test_mmio_field_operations() {
let mut device = MmioDevice::new(4);
// 写4位字段 (位3-7)
device.write_register_field(0, 3, 0x0F, 0x0A);
// 读回字段
let value = device.read_register_field(0, 3, 0x0F);
assert_eq!(value, Some(0x0A));
}
}
#[cfg(test)]
mod interrupt_handling {
/// 中断处理模拟
struct InterruptController {
pending_interrupts: u64,
enabled_interrupts: u64,
}
impl InterruptController {
fn new() -> Self {
Self {
pending_interrupts: 0,
enabled_interrupts: 0,
}
}
fn trigger(&mut self, irq: u32) {
if irq < 64 {
self.pending_interrupts |= 1u64 << irq;
}
}
fn enable(&mut self, irq: u32) {
if irq < 64 {
self.enabled_interrupts |= 1u64 << irq;
}
}
fn get_pending(&self) -> Option<u32> {
if self.pending_interrupts == 0 {
return None;
}
for i in 0..64 {
if (self.pending_interrupts & (1u64 << i)) != 0 &&
(self.enabled_interrupts & (1u64 << i)) != 0 {
return Some(i as u32);
}
}
None
}
fn acknowledge(&mut self, irq: u32) {
if irq < 64 {
self.pending_interrupts &= !(1u64 << irq);
}
}
}
#[test]
fn test_interrupt_trigger() {
let mut ic = InterruptController::new();
ic.trigger(5);
assert_eq!(ic.pending_interrupts, 1u64 << 5);
}
#[test]
fn test_interrupt_enable_disable() {
let mut ic = InterruptController::new();
ic.trigger(3);
ic.enable(3);
assert_eq!(ic.get_pending(), Some(3));
}
#[test]
fn test_interrupt_acknowledge() {
let mut ic = InterruptController::new();
ic.trigger(7);
ic.enable(7);
ic.acknowledge(7);
assert!(ic.get_pending().is_none());
}
#[test]
fn test_multiple_interrupts() {
let mut ic = InterruptController::new();
ic.trigger(1);
ic.trigger(2);
ic.trigger(3);
ic.enable(1);
ic.enable(2);
ic.enable(3);
// 应该返回最低的待处理中断
assert!(ic.get_pending().is_some());
}
}
#[cfg(test)]
mod virtio_gpu_device {
/// VirtIO GPU设备模拟器
struct VirtioGpuDevice {
resolution: (u32, u32),
framebuffer: Vec<u32>,
device_status: u32,
capabilities: u32,
}
impl VirtioGpuDevice {
fn new(width: u32, height: u32) -> Self {
Self {
resolution: (width, height),
framebuffer: vec![0; (width * height) as usize],
device_status: 0,
capabilities: 0x00000001, // 支持基本绘图命令
}
}
fn set_resolution(&mut self, width: u32, height: u32) -> bool {
self.resolution = (width, height);
self.framebuffer = vec![0; (width * height) as usize];
true
}
fn draw_pixel(&mut self, x: u32, y: u32, color: u32) -> bool {
if x < self.resolution.0 && y < self.resolution.1 {
let index = (y * self.resolution.0 + x) as usize;
self.framebuffer[index] = color;
true
} else {
false
}
}
fn draw_rectangle(&mut self, x: u32, y: u32, width: u32, height: u32, color: u32) -> bool {
if x + width > self.resolution.0 || y + height > self.resolution.1 {
return false;
}
for row in y..y + height {
for col in x..x + width {
let index = (row * self.resolution.0 + col) as usize;
self.framebuffer[index] = color;
}
}
true
}
fn get_pixel(&self, x: u32, y: u32) -> Option<u32> {
if x < self.resolution.0 && y < self.resolution.1 {
let index = (y * self.resolution.0 + x) as usize;
Some(self.framebuffer[index])
} else {
None
}
}
fn get_framebuffer(&self) -> &[u32] {
&self.framebuffer
}
}
#[test]
fn test_gpu_device_creation() {
let device = VirtioGpuDevice::new(1024, 768);
assert_eq!(device.resolution, (1024, 768));
assert_eq!(device.framebuffer.len(), (1024 * 768) as usize);
}
#[test]
fn test_gpu_draw_pixel() {
let mut device = VirtioGpuDevice::new(800, 600);
assert!(device.draw_pixel(100, 200, 0x00FF00));
assert_eq!(device.get_pixel(100, 200), Some(0x00FF00));
}
#[test]
fn test_gpu_draw_rectangle() {
let mut device = VirtioGpuDevice::new(800, 600);
assert!(device.draw_rectangle(10, 20, 50, 30, 0xFF0000));
// 检查矩形内的像素
assert_eq!(device.get_pixel(10, 20), Some(0xFF0000));
assert_eq!(device.get_pixel(59, 49), Some(0xFF0000));
// 检查矩形外的像素
assert_eq!(device.get_pixel(9, 19), Some(0x000000));
}
#[test]
fn test_gpu_resolution_change() {
let mut device = VirtioGpuDevice::new(800, 600);
assert!(device.set_resolution(1920, 1080));
assert_eq!(device.resolution, (1920, 1080));
assert_eq!(device.framebuffer.len(), (1920 * 1080) as usize);
}
#[test]
fn test_gpu_boundary_check() {
let mut device = VirtioGpuDevice::new(100, 100);
// 超出边界的绘制应该失败
assert!(!device.draw_pixel(150, 200, 0x0000FF));
assert!(!device.draw_rectangle(50, 50, 100, 100, 0xFFFFFF));
}
}