mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 04:04:45 +00:00
dragonball: add more unit test for vm
Added more unit tests for vm module. Fixes: #4899 Signed-off-by: wllenyj <wllenyj@linux.alibaba.com>
This commit is contained in:
parent
b29cbbfd2c
commit
dc90c6e30b
@ -250,6 +250,11 @@ impl AddressSpaceMgr {
|
||||
self.address_space.as_ref()
|
||||
}
|
||||
|
||||
/// Get the guest memory.
|
||||
pub fn vm_memory(&self) -> Option<<GuestAddressSpaceImpl as GuestAddressSpace>::T> {
|
||||
self.get_vm_as().map(|m| m.memory())
|
||||
}
|
||||
|
||||
/// Create the address space for a virtual machine.
|
||||
///
|
||||
/// This method is designed to be called when starting up a virtual machine instead of at
|
||||
|
@ -825,7 +825,14 @@ impl Vm {
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use kvm_ioctls::VcpuExit;
|
||||
use linux_loader::cmdline::Cmdline;
|
||||
use test_utils::skip_if_not_root;
|
||||
use vm_memory::GuestMemory;
|
||||
use vmm_sys_util::tempfile::TempFile;
|
||||
|
||||
use super::*;
|
||||
use crate::test_utils::tests::create_vm_for_test;
|
||||
|
||||
impl Vm {
|
||||
pub fn set_instance_state(&mut self, mstate: InstanceState) {
|
||||
@ -841,4 +848,202 @@ pub mod tests {
|
||||
let epoll_manager = EpollManager::default();
|
||||
Vm::new(None, instance_info, epoll_manager).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_vm_instance() {
|
||||
skip_if_not_root!();
|
||||
let vm = create_vm_instance();
|
||||
assert!(vm.check_health().is_err());
|
||||
assert!(vm.kernel_config.is_none());
|
||||
assert!(vm.get_reset_eventfd().is_none());
|
||||
assert!(!vm.is_vm_initialized());
|
||||
assert!(!vm.is_vm_running());
|
||||
assert!(vm.reset_console().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vm_init_guest_memory() {
|
||||
skip_if_not_root!();
|
||||
let vm_config = VmConfigInfo {
|
||||
vcpu_count: 1,
|
||||
max_vcpu_count: 3,
|
||||
cpu_pm: "off".to_string(),
|
||||
mem_type: "shmem".to_string(),
|
||||
mem_file_path: "".to_string(),
|
||||
mem_size_mib: 16,
|
||||
serial_path: None,
|
||||
cpu_topology: CpuTopology {
|
||||
threads_per_core: 1,
|
||||
cores_per_die: 1,
|
||||
dies_per_socket: 1,
|
||||
sockets: 1,
|
||||
},
|
||||
vpmu_feature: 0,
|
||||
};
|
||||
|
||||
let mut vm = create_vm_instance();
|
||||
vm.set_vm_config(vm_config);
|
||||
assert!(vm.init_guest_memory().is_ok());
|
||||
let vm_memory = vm.address_space.vm_memory().unwrap();
|
||||
|
||||
assert_eq!(vm_memory.num_regions(), 1);
|
||||
assert_eq!(vm_memory.last_addr(), GuestAddress(0xffffff));
|
||||
|
||||
// Reconfigure an already configured vm will be ignored and just return OK.
|
||||
let vm_config = VmConfigInfo {
|
||||
vcpu_count: 1,
|
||||
max_vcpu_count: 3,
|
||||
cpu_pm: "off".to_string(),
|
||||
mem_type: "shmem".to_string(),
|
||||
mem_file_path: "".to_string(),
|
||||
mem_size_mib: 16,
|
||||
serial_path: None,
|
||||
cpu_topology: CpuTopology {
|
||||
threads_per_core: 1,
|
||||
cores_per_die: 1,
|
||||
dies_per_socket: 1,
|
||||
sockets: 1,
|
||||
},
|
||||
vpmu_feature: 0,
|
||||
};
|
||||
vm.set_vm_config(vm_config);
|
||||
assert!(vm.init_guest_memory().is_ok());
|
||||
let vm_memory = vm.address_space.vm_memory().unwrap();
|
||||
assert_eq!(vm_memory.num_regions(), 1);
|
||||
assert_eq!(vm_memory.last_addr(), GuestAddress(0xffffff));
|
||||
|
||||
let obj_addr = GuestAddress(0xf0);
|
||||
vm_memory.write_obj(67u8, obj_addr).unwrap();
|
||||
let read_val: u8 = vm_memory.read_obj(obj_addr).unwrap();
|
||||
assert_eq!(read_val, 67u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vm_create_devices() {
|
||||
skip_if_not_root!();
|
||||
let vmm = Arc::new(Mutex::new(crate::vmm::tests::create_vmm_instance()));
|
||||
let epoll_mgr = EpollManager::default();
|
||||
|
||||
let mut guard = vmm.lock().unwrap();
|
||||
let vm = guard.get_vm_mut().unwrap();
|
||||
|
||||
let vm_config = VmConfigInfo {
|
||||
vcpu_count: 1,
|
||||
max_vcpu_count: 3,
|
||||
cpu_pm: "off".to_string(),
|
||||
mem_type: "shmem".to_string(),
|
||||
mem_file_path: "".to_string(),
|
||||
mem_size_mib: 16,
|
||||
serial_path: None,
|
||||
cpu_topology: CpuTopology {
|
||||
threads_per_core: 1,
|
||||
cores_per_die: 1,
|
||||
dies_per_socket: 1,
|
||||
sockets: 1,
|
||||
},
|
||||
vpmu_feature: 0,
|
||||
};
|
||||
|
||||
vm.set_vm_config(vm_config);
|
||||
assert!(vm.init_guest_memory().is_ok());
|
||||
assert!(vm.setup_interrupt_controller().is_ok());
|
||||
|
||||
let vm_memory = vm.address_space.vm_memory().unwrap();
|
||||
assert_eq!(vm_memory.num_regions(), 1);
|
||||
assert_eq!(vm_memory.last_addr(), GuestAddress(0xffffff));
|
||||
|
||||
let kernel_file = TempFile::new().unwrap();
|
||||
let cmd_line = Cmdline::new(64);
|
||||
|
||||
vm.set_kernel_config(KernelConfigInfo::new(
|
||||
kernel_file.into_file(),
|
||||
None,
|
||||
cmd_line,
|
||||
));
|
||||
|
||||
vm.init_devices(epoll_mgr).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vm_delete_devices() {
|
||||
skip_if_not_root!();
|
||||
let mut vm = create_vm_for_test();
|
||||
let epoll_mgr = EpollManager::default();
|
||||
|
||||
vm.setup_interrupt_controller().unwrap();
|
||||
vm.init_devices(epoll_mgr).unwrap();
|
||||
assert!(vm.remove_devices().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run_code() {
|
||||
skip_if_not_root!();
|
||||
|
||||
use std::io::{self, Write};
|
||||
// This example is based on https://lwn.net/Articles/658511/
|
||||
let code = [
|
||||
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
|
||||
0x00, 0xd8, /* add %bl, %al */
|
||||
0x04, b'0', /* add $'0', %al */
|
||||
0xee, /* out %al, (%dx) */
|
||||
0xb0, b'\n', /* mov $'\n', %al */
|
||||
0xee, /* out %al, (%dx) */
|
||||
0xf4, /* hlt */
|
||||
];
|
||||
let load_addr = GuestAddress(0x1000);
|
||||
let instance_info = Arc::new(RwLock::new(InstanceInfo::default()));
|
||||
let epoll_manager = EpollManager::default();
|
||||
let mut vm = Vm::new(None, instance_info, epoll_manager).unwrap();
|
||||
|
||||
let vcpu_count = 1;
|
||||
let vm_config = VmConfigInfo {
|
||||
vcpu_count,
|
||||
max_vcpu_count: 1,
|
||||
cpu_pm: "off".to_string(),
|
||||
mem_type: "shmem".to_string(),
|
||||
mem_file_path: "".to_string(),
|
||||
mem_size_mib: 10,
|
||||
serial_path: None,
|
||||
cpu_topology: CpuTopology {
|
||||
threads_per_core: 1,
|
||||
cores_per_die: 1,
|
||||
dies_per_socket: 1,
|
||||
sockets: 1,
|
||||
},
|
||||
vpmu_feature: 0,
|
||||
};
|
||||
|
||||
vm.set_vm_config(vm_config);
|
||||
vm.init_guest_memory().unwrap();
|
||||
|
||||
let vm_memory = vm.address_space.vm_memory().unwrap();
|
||||
vm_memory.write_obj(code, load_addr).unwrap();
|
||||
|
||||
let vcpu_fd = vm.vm_fd().create_vcpu(0).unwrap();
|
||||
let mut vcpu_sregs = vcpu_fd.get_sregs().unwrap();
|
||||
assert_ne!(vcpu_sregs.cs.base, 0);
|
||||
assert_ne!(vcpu_sregs.cs.selector, 0);
|
||||
vcpu_sregs.cs.base = 0;
|
||||
vcpu_sregs.cs.selector = 0;
|
||||
vcpu_fd.set_sregs(&vcpu_sregs).unwrap();
|
||||
|
||||
let mut vcpu_regs = vcpu_fd.get_regs().unwrap();
|
||||
|
||||
vcpu_regs.rip = 0x1000;
|
||||
vcpu_regs.rax = 2;
|
||||
vcpu_regs.rbx = 3;
|
||||
vcpu_regs.rflags = 2;
|
||||
vcpu_fd.set_regs(&vcpu_regs).unwrap();
|
||||
|
||||
match vcpu_fd.run().expect("run failed") {
|
||||
VcpuExit::IoOut(0x3f8, data) => {
|
||||
assert_eq!(data.len(), 1);
|
||||
io::stdout().write_all(data).unwrap();
|
||||
}
|
||||
VcpuExit::Hlt => {
|
||||
io::stdout().write_all(b"KVM_EXIT_HLT\n").unwrap();
|
||||
}
|
||||
r => panic!("unexpected exit reason: {:?}", r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user