mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +00:00
tests: Abstract guest management under a struct
Create a struct to handle all the details for the guest under test including details of network and disks. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
eab639efe3
commit
93c2099ab6
581
src/main.rs
581
src/main.rs
@ -164,133 +164,13 @@ mod tests {
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
|
|
||||||
fn ssh_command(command: &str) -> String {
|
struct Guest {
|
||||||
let mut s = String::new();
|
tmp_dir: TempDir,
|
||||||
#[derive(Debug)]
|
disks: Vec<String>,
|
||||||
enum Error {
|
fw_path: String,
|
||||||
Connection,
|
guest_ip: String,
|
||||||
Authentication,
|
host_ip: String,
|
||||||
Command,
|
guest_mac: String,
|
||||||
};
|
|
||||||
|
|
||||||
let mut counter = 0;
|
|
||||||
loop {
|
|
||||||
match (|| -> Result<(), Error> {
|
|
||||||
let tcp = TcpStream::connect("192.168.2.2:22").map_err(|_| Error::Connection)?;
|
|
||||||
let mut sess = Session::new().unwrap();
|
|
||||||
sess.handshake(&tcp).map_err(|_| Error::Connection)?;
|
|
||||||
|
|
||||||
sess.userauth_password("admin", "cloud123")
|
|
||||||
.map_err(|_| Error::Authentication)?;
|
|
||||||
assert!(sess.authenticated());
|
|
||||||
|
|
||||||
let mut channel = sess.channel_session().map_err(|_| Error::Command)?;
|
|
||||||
channel.exec(command).map_err(|_| Error::Command)?;
|
|
||||||
|
|
||||||
// Intentionally ignore these results here as their failure
|
|
||||||
// does not precipitate a repeat
|
|
||||||
let _ = channel.read_to_string(&mut s);
|
|
||||||
let _ = channel.close();
|
|
||||||
let _ = channel.wait_close();
|
|
||||||
Ok(())
|
|
||||||
})() {
|
|
||||||
Ok(_) => break,
|
|
||||||
Err(e) => {
|
|
||||||
counter += 1;
|
|
||||||
if counter >= 6 {
|
|
||||||
panic!("Took too many attempts to run command. Last error: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
thread::sleep(std::time::Duration::new(10 * counter, 0));
|
|
||||||
}
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare_cloudinit(
|
|
||||||
tmp_dir: &TempDir,
|
|
||||||
guest_ip_addr: &str,
|
|
||||||
host_ip_addr: &str,
|
|
||||||
mac_addr: &str,
|
|
||||||
) -> String {
|
|
||||||
let cloudinit_file_path = String::from(tmp_dir.path().join("cloudinit").to_str().unwrap());
|
|
||||||
|
|
||||||
let cloud_init_directory = tmp_dir.path().join("cloud-init").join("openstack");
|
|
||||||
|
|
||||||
fs::create_dir_all(&cloud_init_directory.join("latest"))
|
|
||||||
.expect("Expect creating cloud-init directory to succeed");
|
|
||||||
|
|
||||||
let source_file_dir = std::env::current_dir()
|
|
||||||
.unwrap()
|
|
||||||
.join("test_data")
|
|
||||||
.join("cloud-init")
|
|
||||||
.join("openstack")
|
|
||||||
.join("latest");
|
|
||||||
|
|
||||||
fs::copy(
|
|
||||||
source_file_dir.join("meta_data.json"),
|
|
||||||
cloud_init_directory.join("latest").join("meta_data.json"),
|
|
||||||
)
|
|
||||||
.expect("Expect copying cloud-init meta_data.json to succeed");
|
|
||||||
|
|
||||||
let mut user_data_string = String::new();
|
|
||||||
|
|
||||||
fs::File::open(source_file_dir.join("user_data"))
|
|
||||||
.unwrap()
|
|
||||||
.read_to_string(&mut user_data_string)
|
|
||||||
.expect("Expected reading user_data file in to succeed");
|
|
||||||
|
|
||||||
user_data_string = user_data_string.replace("192.168.2.1", host_ip_addr);
|
|
||||||
user_data_string = user_data_string.replace("192.168.2.2", guest_ip_addr);
|
|
||||||
user_data_string = user_data_string.replace("12:34:56:78:90:ab", mac_addr);
|
|
||||||
|
|
||||||
fs::File::create(cloud_init_directory.join("latest").join("user_data"))
|
|
||||||
.unwrap()
|
|
||||||
.write_all(&user_data_string.as_bytes())
|
|
||||||
.expect("Expected writing out user_data to succeed");
|
|
||||||
|
|
||||||
std::process::Command::new("mkdosfs")
|
|
||||||
.args(&["-n", "config-2"])
|
|
||||||
.args(&["-C", cloudinit_file_path.as_str()])
|
|
||||||
.arg("8192")
|
|
||||||
.spawn()
|
|
||||||
.expect("Expect creating disk image to succeed");
|
|
||||||
|
|
||||||
std::process::Command::new("mcopy")
|
|
||||||
.arg("-o")
|
|
||||||
.args(&["-i", cloudinit_file_path.as_str()])
|
|
||||||
.args(&["-s", cloud_init_directory.to_str().unwrap(), "::"])
|
|
||||||
.spawn()
|
|
||||||
.expect("Expect copying files to disk image to succeed");
|
|
||||||
|
|
||||||
cloudinit_file_path
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare_files(tmp_dir: &TempDir) -> (Vec<String>, String) {
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
|
||||||
workload_path.push("workloads");
|
|
||||||
|
|
||||||
let mut fw_path = workload_path.clone();
|
|
||||||
fw_path.push("hypervisor-fw");
|
|
||||||
|
|
||||||
let mut osdisk_base_path = workload_path.clone();
|
|
||||||
osdisk_base_path.push("clear-29810-cloud.img");
|
|
||||||
|
|
||||||
let mut osdisk_raw_base_path = workload_path.clone();
|
|
||||||
osdisk_raw_base_path.push("clear-29810-cloud-raw.img");
|
|
||||||
|
|
||||||
let osdisk_path = String::from(tmp_dir.path().join("osdisk.img").to_str().unwrap());
|
|
||||||
let osdisk_raw_path = String::from(tmp_dir.path().join("osdisk_raw.img").to_str().unwrap());
|
|
||||||
let cloudinit_path =
|
|
||||||
prepare_cloudinit(&tmp_dir, "192.168.2.2", "192.168.2.1", "12:34:56:78:90:ab");
|
|
||||||
|
|
||||||
fs::copy(osdisk_base_path, &osdisk_path).expect("copying of OS source disk image failed");
|
|
||||||
fs::copy(osdisk_raw_base_path, &osdisk_raw_path)
|
|
||||||
.expect("copying of OS source disk raw image failed");
|
|
||||||
|
|
||||||
let disks = vec![osdisk_path, cloudinit_path, osdisk_raw_path];
|
|
||||||
|
|
||||||
(disks, String::from(fw_path.to_str().unwrap()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_virtiofsd(tmp_dir: &TempDir) -> (std::process::Child, String) {
|
fn prepare_virtiofsd(tmp_dir: &TempDir) -> (std::process::Child, String) {
|
||||||
@ -322,66 +202,218 @@ mod tests {
|
|||||||
(child, virtiofsd_socket_path)
|
(child, virtiofsd_socket_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cpu_count() -> u32 {
|
impl Guest {
|
||||||
ssh_command("grep -c processor /proc/cpuinfo")
|
fn new() -> Self {
|
||||||
.trim()
|
let tmp_dir = TempDir::new("ch").unwrap();
|
||||||
.parse()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_initial_apicid() -> u32 {
|
let mut guest = Guest {
|
||||||
ssh_command("grep \"initial apicid\" /proc/cpuinfo | grep -o \"[0-9]*\"")
|
tmp_dir,
|
||||||
.trim()
|
disks: Vec::new(),
|
||||||
.parse()
|
fw_path: String::new(),
|
||||||
.unwrap()
|
guest_ip: String::from("192.168.2.2"),
|
||||||
}
|
host_ip: String::from("192.168.2.1"),
|
||||||
|
guest_mac: String::from("12:34:56:78:90:ab"),
|
||||||
|
};
|
||||||
|
|
||||||
fn get_total_memory() -> u32 {
|
guest.prepare_files();
|
||||||
ssh_command("grep MemTotal /proc/meminfo | grep -o \"[0-9]*\"")
|
|
||||||
.trim()
|
|
||||||
.parse::<u32>()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_entropy() -> u32 {
|
guest
|
||||||
ssh_command("cat /proc/sys/kernel/random/entropy_avail")
|
}
|
||||||
.trim()
|
|
||||||
.parse::<u32>()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_pci_bridge_class() -> String {
|
fn prepare_cloudinit(&self) -> String {
|
||||||
ssh_command("cat /sys/bus/pci/devices/0000:00:00.0/class")
|
let cloudinit_file_path =
|
||||||
.trim()
|
String::from(self.tmp_dir.path().join("cloudinit").to_str().unwrap());
|
||||||
.to_string()
|
|
||||||
|
let cloud_init_directory = self.tmp_dir.path().join("cloud-init").join("openstack");
|
||||||
|
|
||||||
|
fs::create_dir_all(&cloud_init_directory.join("latest"))
|
||||||
|
.expect("Expect creating cloud-init directory to succeed");
|
||||||
|
|
||||||
|
let source_file_dir = std::env::current_dir()
|
||||||
|
.unwrap()
|
||||||
|
.join("test_data")
|
||||||
|
.join("cloud-init")
|
||||||
|
.join("openstack")
|
||||||
|
.join("latest");
|
||||||
|
|
||||||
|
fs::copy(
|
||||||
|
source_file_dir.join("meta_data.json"),
|
||||||
|
cloud_init_directory.join("latest").join("meta_data.json"),
|
||||||
|
)
|
||||||
|
.expect("Expect copying cloud-init meta_data.json to succeed");
|
||||||
|
|
||||||
|
let mut user_data_string = String::new();
|
||||||
|
|
||||||
|
fs::File::open(source_file_dir.join("user_data"))
|
||||||
|
.unwrap()
|
||||||
|
.read_to_string(&mut user_data_string)
|
||||||
|
.expect("Expected reading user_data file in to succeed");
|
||||||
|
|
||||||
|
user_data_string = user_data_string.replace("192.168.2.1", &self.host_ip);
|
||||||
|
user_data_string = user_data_string.replace("192.168.2.2", &self.guest_ip);
|
||||||
|
user_data_string = user_data_string.replace("12:34:56:78:90:ab", &self.guest_mac);
|
||||||
|
|
||||||
|
fs::File::create(cloud_init_directory.join("latest").join("user_data"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(&user_data_string.as_bytes())
|
||||||
|
.expect("Expected writing out user_data to succeed");
|
||||||
|
|
||||||
|
std::process::Command::new("mkdosfs")
|
||||||
|
.args(&["-n", "config-2"])
|
||||||
|
.args(&["-C", cloudinit_file_path.as_str()])
|
||||||
|
.arg("8192")
|
||||||
|
.output()
|
||||||
|
.expect("Expect creating disk image to succeed");
|
||||||
|
|
||||||
|
std::process::Command::new("mcopy")
|
||||||
|
.arg("-o")
|
||||||
|
.args(&["-i", cloudinit_file_path.as_str()])
|
||||||
|
.args(&["-s", cloud_init_directory.to_str().unwrap(), "::"])
|
||||||
|
.output()
|
||||||
|
.expect("Expect copying files to disk image to succeed");
|
||||||
|
|
||||||
|
cloudinit_file_path
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_files(&mut self) {
|
||||||
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
|
workload_path.push("workloads");
|
||||||
|
|
||||||
|
let mut fw_path = workload_path.clone();
|
||||||
|
fw_path.push("hypervisor-fw");
|
||||||
|
|
||||||
|
let mut osdisk_base_path = workload_path.clone();
|
||||||
|
osdisk_base_path.push("clear-29810-cloud.img");
|
||||||
|
|
||||||
|
let mut osdisk_raw_base_path = workload_path.clone();
|
||||||
|
osdisk_raw_base_path.push("clear-29810-cloud-raw.img");
|
||||||
|
|
||||||
|
let osdisk_path =
|
||||||
|
String::from(self.tmp_dir.path().join("osdisk.img").to_str().unwrap());
|
||||||
|
let osdisk_raw_path =
|
||||||
|
String::from(self.tmp_dir.path().join("osdisk_raw.img").to_str().unwrap());
|
||||||
|
let cloudinit_path = self.prepare_cloudinit();
|
||||||
|
|
||||||
|
fs::copy(osdisk_base_path, &osdisk_path)
|
||||||
|
.expect("copying of OS source disk image failed");
|
||||||
|
fs::copy(osdisk_raw_base_path, &osdisk_raw_path)
|
||||||
|
.expect("copying of OS source disk raw image failed");
|
||||||
|
|
||||||
|
let disks = vec![osdisk_path, cloudinit_path, osdisk_raw_path];
|
||||||
|
|
||||||
|
self.disks = disks;
|
||||||
|
self.fw_path = String::from(fw_path.to_str().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_net_string(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"tap=,mac={},ip={},mask=255.255.255.0",
|
||||||
|
self.guest_mac, self.host_ip
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssh_command(&self, command: &str) -> String {
|
||||||
|
let mut s = String::new();
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Error {
|
||||||
|
Connection,
|
||||||
|
Authentication,
|
||||||
|
Command,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut counter = 0;
|
||||||
|
loop {
|
||||||
|
match (|| -> Result<(), Error> {
|
||||||
|
let tcp = TcpStream::connect(format!("{}:22", self.guest_ip))
|
||||||
|
.map_err(|_| Error::Connection)?;
|
||||||
|
let mut sess = Session::new().unwrap();
|
||||||
|
sess.handshake(&tcp).map_err(|_| Error::Connection)?;
|
||||||
|
|
||||||
|
sess.userauth_password("admin", "cloud123")
|
||||||
|
.map_err(|_| Error::Authentication)?;
|
||||||
|
assert!(sess.authenticated());
|
||||||
|
|
||||||
|
let mut channel = sess.channel_session().map_err(|_| Error::Command)?;
|
||||||
|
channel.exec(command).map_err(|_| Error::Command)?;
|
||||||
|
|
||||||
|
// Intentionally ignore these results here as their failure
|
||||||
|
// does not precipitate a repeat
|
||||||
|
let _ = channel.read_to_string(&mut s);
|
||||||
|
let _ = channel.close();
|
||||||
|
let _ = channel.wait_close();
|
||||||
|
Ok(())
|
||||||
|
})() {
|
||||||
|
Ok(_) => break,
|
||||||
|
Err(e) => {
|
||||||
|
counter += 1;
|
||||||
|
if counter >= 6 {
|
||||||
|
panic!("Took too many attempts to run command. Last error: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread::sleep(std::time::Duration::new(10 * counter, 0));
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cpu_count(&self) -> u32 {
|
||||||
|
self.ssh_command("grep -c processor /proc/cpuinfo")
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_initial_apicid(&self) -> u32 {
|
||||||
|
self.ssh_command("grep \"initial apicid\" /proc/cpuinfo | grep -o \"[0-9]*\"")
|
||||||
|
.trim()
|
||||||
|
.parse()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_total_memory(&self) -> u32 {
|
||||||
|
self.ssh_command("grep MemTotal /proc/meminfo | grep -o \"[0-9]*\"")
|
||||||
|
.trim()
|
||||||
|
.parse::<u32>()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_entropy(&self) -> u32 {
|
||||||
|
self.ssh_command("cat /proc/sys/kernel/random/entropy_avail")
|
||||||
|
.trim()
|
||||||
|
.parse::<u32>()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pci_bridge_class(&self) -> String {
|
||||||
|
self.ssh_command("cat /sys/bus/pci/devices/0000:00:00.0/class")
|
||||||
|
.trim()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_launch() {
|
fn test_simple_launch() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
aver_eq!(tb, get_cpu_count(), 1);
|
aver_eq!(tb, guest.get_cpu_count(), 1);
|
||||||
aver_eq!(tb, get_initial_apicid(), 0);
|
aver_eq!(tb, guest.get_initial_apicid(), 0);
|
||||||
aver!(tb, get_total_memory() > 496_000);
|
aver!(tb, guest.get_total_memory() > 496_000);
|
||||||
aver!(tb, get_entropy() >= 1000);
|
aver!(tb, guest.get_entropy() >= 1000);
|
||||||
aver_eq!(tb, get_pci_bridge_class(), "0x060000");
|
aver_eq!(tb, guest.get_pci_bridge_class(), "0x060000");
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -392,25 +424,21 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_multi_cpu() {
|
fn test_multi_cpu() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "2"])
|
.args(&["--cpus", "2"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
aver_eq!(tb, get_cpu_count(), 2);
|
aver_eq!(tb, guest.get_cpu_count(), 2);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -421,25 +449,21 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_large_memory() {
|
fn test_large_memory() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=5120M"])
|
.args(&["--memory", "size=5120M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
aver!(tb, get_total_memory() > 5_063_000);
|
aver!(tb, guest.get_total_memory() > 5_063_000);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -450,17 +474,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_pci_msi() {
|
fn test_pci_msi() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -468,14 +488,15 @@ mod tests {
|
|||||||
|
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("grep -c PCI-MSI /proc/interrupts")
|
guest
|
||||||
|
.ssh_command("grep -c PCI-MSI /proc/interrupts")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
8
|
8
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -486,8 +507,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_vmlinux_boot() {
|
fn test_vmlinux_boot() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, _) = prepare_files(&tmp_dir);
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
workload_path.push("workloads");
|
workload_path.push("workloads");
|
||||||
|
|
||||||
@ -498,27 +518,28 @@ mod tests {
|
|||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&["--net", "tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0"])
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
.args(&["--cmdline", "root=PARTUUID=3cb0e0a5-925d-405e-bc55-edf0cec8f10a console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"])
|
.args(&["--cmdline", "root=PARTUUID=3cb0e0a5-925d-405e-bc55-edf0cec8f10a console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"])
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
aver_eq!(tb, get_cpu_count(), 1);
|
aver_eq!(tb, guest.get_cpu_count(), 1);
|
||||||
aver!(tb, get_total_memory() > 496_000);
|
aver!(tb, guest.get_total_memory() > 496_000);
|
||||||
aver!(tb, get_entropy() >= 1000);
|
aver!(tb, guest.get_entropy() >= 1000);
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("grep -c PCI-MSI /proc/interrupts")
|
guest
|
||||||
|
.ssh_command("grep -c PCI-MSI /proc/interrupts")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
8
|
8
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -529,8 +550,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_bzimage_boot() {
|
fn test_bzimage_boot() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, _) = prepare_files(&tmp_dir);
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
workload_path.push("workloads");
|
workload_path.push("workloads");
|
||||||
|
|
||||||
@ -541,27 +561,28 @@ mod tests {
|
|||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&["--net", "tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0"])
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
.args(&["--cmdline", "root=PARTUUID=3cb0e0a5-925d-405e-bc55-edf0cec8f10a console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"])
|
.args(&["--cmdline", "root=PARTUUID=3cb0e0a5-925d-405e-bc55-edf0cec8f10a console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"])
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
aver_eq!(tb, get_cpu_count(), 1);
|
aver_eq!(tb, guest.get_cpu_count(), 1);
|
||||||
aver!(tb, get_total_memory() > 496_000);
|
aver!(tb, guest.get_total_memory() > 496_000);
|
||||||
aver!(tb, get_entropy() >= 1000);
|
aver!(tb, guest.get_entropy() >= 1000);
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("grep -c PCI-MSI /proc/interrupts")
|
guest
|
||||||
|
.ssh_command("grep -c PCI-MSI /proc/interrupts")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
8
|
8
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -572,17 +593,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_split_irqchip() {
|
fn test_split_irqchip() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -590,7 +607,8 @@ mod tests {
|
|||||||
|
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'timer'")
|
guest
|
||||||
|
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'timer'")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -598,14 +616,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'cascade'")
|
guest
|
||||||
|
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'cascade'")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -616,9 +635,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_virtio_fs() {
|
fn test_virtio_fs() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, _) = prepare_files(&tmp_dir);
|
let (mut daemon_child, virtiofsd_socket_path) = prepare_virtiofsd(&guest.tmp_dir);
|
||||||
let (mut daemon_child, virtiofsd_socket_path) = prepare_virtiofsd(&tmp_dir);
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
workload_path.push("workloads");
|
workload_path.push("workloads");
|
||||||
|
|
||||||
@ -629,8 +647,8 @@ mod tests {
|
|||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M,file=/dev/shm"])
|
.args(&["--memory", "size=512M,file=/dev/shm"])
|
||||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&["--net", "tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0"])
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
.args(&[
|
.args(&[
|
||||||
"--fs",
|
"--fs",
|
||||||
format!(
|
format!(
|
||||||
@ -648,22 +666,22 @@ mod tests {
|
|||||||
// Mount shared directory through virtio_fs filesystem
|
// Mount shared directory through virtio_fs filesystem
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("mkdir -p mount_dir && sudo mount -t virtio_fs /dev/null mount_dir/ -o tag=virtiofs,rootmode=040000,user_id=1001,group_id=1001 && echo ok")
|
guest.ssh_command("mkdir -p mount_dir && sudo mount -t virtio_fs /dev/null mount_dir/ -o tag=virtiofs,rootmode=040000,user_id=1001,group_id=1001 && echo ok")
|
||||||
.trim(),
|
.trim(),
|
||||||
"ok"
|
"ok"
|
||||||
);
|
);
|
||||||
// Check file1 exists and its content is "foo"
|
// Check file1 exists and its content is "foo"
|
||||||
aver_eq!(tb, ssh_command("cat mount_dir/file1").trim(), "foo");
|
aver_eq!(tb, guest.ssh_command("cat mount_dir/file1").trim(), "foo");
|
||||||
// Check file2 does not exist
|
// Check file2 does not exist
|
||||||
aver_ne!(
|
aver_ne!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("ls mount_dir/file2").trim(),
|
guest.ssh_command("ls mount_dir/file2").trim(),
|
||||||
"mount_dir/file2"
|
"mount_dir/file2"
|
||||||
);
|
);
|
||||||
// Check file3 exists and its content is "bar"
|
// Check file3 exists and its content is "bar"
|
||||||
aver_eq!(tb, ssh_command("cat mount_dir/file3").trim(), "bar");
|
aver_eq!(tb, guest.ssh_command("cat mount_dir/file3").trim(), "bar");
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
let _ = daemon_child.wait();
|
let _ = daemon_child.wait();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -673,15 +691,14 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_virtio_pmem() {
|
fn test_virtio_pmem() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, _) = prepare_files(&tmp_dir);
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
workload_path.push("workloads");
|
workload_path.push("workloads");
|
||||||
|
|
||||||
let mut kernel_path = workload_path.clone();
|
let mut kernel_path = workload_path.clone();
|
||||||
kernel_path.push("vmlinux-custom");
|
kernel_path.push("vmlinux-custom");
|
||||||
|
|
||||||
let pmem_backend_path = tmp_dir.path().join("/tmp/pmem-file");
|
let pmem_backend_path = guest.tmp_dir.path().join("/tmp/pmem-file");
|
||||||
let mut pmem_backend_file = OpenOptions::new()
|
let mut pmem_backend_file = OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
@ -700,8 +717,8 @@ mod tests {
|
|||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&["--net", "tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0"])
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
.args(&[
|
.args(&[
|
||||||
"--pmem",
|
"--pmem",
|
||||||
format!(
|
format!(
|
||||||
@ -718,16 +735,16 @@ mod tests {
|
|||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
// Check for the presence of /dev/pmem0
|
// Check for the presence of /dev/pmem0
|
||||||
aver_eq!(tb, ssh_command("ls /dev/pmem0").trim(), "/dev/pmem0");
|
aver_eq!(tb, guest.ssh_command("ls /dev/pmem0").trim(), "/dev/pmem0");
|
||||||
// Check content
|
// Check content
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
&ssh_command("sudo cat /dev/pmem0").trim()[..pmem_backend_content.len()],
|
&guest.ssh_command("sudo cat /dev/pmem0").trim()[..pmem_backend_content.len()],
|
||||||
pmem_backend_content
|
pmem_backend_content
|
||||||
);
|
);
|
||||||
// Modify content
|
// Modify content
|
||||||
let new_content = "bar";
|
let new_content = "bar";
|
||||||
ssh_command(
|
guest.ssh_command(
|
||||||
format!(
|
format!(
|
||||||
"sudo bash -c 'echo {} > /dev/pmem0' && sudo sync /dev/pmem0",
|
"sudo bash -c 'echo {} > /dev/pmem0' && sudo sync /dev/pmem0",
|
||||||
new_content
|
new_content
|
||||||
@ -744,7 +761,7 @@ mod tests {
|
|||||||
new_content
|
new_content
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -754,8 +771,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_boot_from_virtio_pmem() {
|
fn test_boot_from_virtio_pmem() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, _) = prepare_files(&tmp_dir);
|
|
||||||
let mut workload_path = dirs::home_dir().unwrap();
|
let mut workload_path = dirs::home_dir().unwrap();
|
||||||
workload_path.push("workloads");
|
workload_path.push("workloads");
|
||||||
|
|
||||||
@ -766,14 +782,14 @@ mod tests {
|
|||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||||
.args(&["--disk", disks[1].as_str()])
|
.args(&["--disk", guest.disks[1].as_str()])
|
||||||
.args(&["--net", "tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0"])
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
.args(&[
|
.args(&[
|
||||||
"--pmem",
|
"--pmem",
|
||||||
format!(
|
format!(
|
||||||
"file={},size={}",
|
"file={},size={}",
|
||||||
disks[2],
|
guest.disks[2],
|
||||||
fs::metadata(&disks[2]).unwrap().len()
|
fs::metadata(&guest.disks[2]).unwrap().len()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
])
|
])
|
||||||
@ -784,10 +800,10 @@ mod tests {
|
|||||||
thread::sleep(std::time::Duration::new(20, 0));
|
thread::sleep(std::time::Duration::new(20, 0));
|
||||||
|
|
||||||
// Simple checks to validate the VM booted properly
|
// Simple checks to validate the VM booted properly
|
||||||
aver_eq!(tb, get_cpu_count(), 1);
|
aver_eq!(tb, guest.get_cpu_count(), 1);
|
||||||
aver!(tb, get_total_memory() > 496_000);
|
aver!(tb, guest.get_total_memory() > 496_000);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -797,16 +813,15 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_multiple_network_interfaces() {
|
fn test_multiple_network_interfaces() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&[
|
||||||
"--net",
|
"--net",
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
guest.default_net_string().as_str(),
|
||||||
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
||||||
"tap=,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
"tap=,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
||||||
])
|
])
|
||||||
@ -818,14 +833,15 @@ mod tests {
|
|||||||
// 3 network interfaces + default localhost ==> 4 interfaces
|
// 3 network interfaces + default localhost ==> 4 interfaces
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("ip -o link | wc -l")
|
guest
|
||||||
|
.ssh_command("ip -o link | wc -l")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -836,17 +852,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serial_disable() {
|
fn test_serial_disable() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.args(&["--serial", "off"])
|
.args(&["--serial", "off"])
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -856,7 +868,8 @@ mod tests {
|
|||||||
// Test that there is no ttyS0
|
// Test that there is no ttyS0
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
|
guest
|
||||||
|
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -866,14 +879,15 @@ mod tests {
|
|||||||
// Further test that we're MSI only now
|
// Further test that we're MSI only now
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("cat /proc/interrupts | grep -c 'IO-APIC'")
|
guest
|
||||||
|
.ssh_command("cat /proc/interrupts | grep -c 'IO-APIC'")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
@ -884,19 +898,15 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serial_file() {
|
fn test_serial_file() {
|
||||||
test_block!(tb, "", {
|
test_block!(tb, "", {
|
||||||
let tmp_dir = TempDir::new("ch").unwrap();
|
let guest = Guest::new();
|
||||||
let (disks, fw_path) = prepare_files(&tmp_dir);
|
|
||||||
|
|
||||||
let serial_path = tmp_dir.path().join("/tmp/serial-output");
|
let serial_path = guest.tmp_dir.path().join("/tmp/serial-output");
|
||||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||||
.args(&["--cpus", "1"])
|
.args(&["--cpus", "1"])
|
||||||
.args(&["--memory", "size=512M"])
|
.args(&["--memory", "size=512M"])
|
||||||
.args(&["--kernel", fw_path.as_str()])
|
.args(&["--kernel", guest.fw_path.as_str()])
|
||||||
.args(&["--disk", disks[0].as_str(), disks[1].as_str()])
|
.args(&["--disk", guest.disks[0].as_str(), guest.disks[1].as_str()])
|
||||||
.args(&[
|
.args(&["--net", guest.default_net_string().as_str()])
|
||||||
"--net",
|
|
||||||
"tap=,mac=12:34:56:78:90:ab,ip=192.168.2.1,mask=255.255.255.0",
|
|
||||||
])
|
|
||||||
.args(&[
|
.args(&[
|
||||||
"--serial",
|
"--serial",
|
||||||
format!("file={}", serial_path.to_str().unwrap()).as_str(),
|
format!("file={}", serial_path.to_str().unwrap()).as_str(),
|
||||||
@ -909,14 +919,15 @@ mod tests {
|
|||||||
// Test that there is a ttyS0
|
// Test that there is a ttyS0
|
||||||
aver_eq!(
|
aver_eq!(
|
||||||
tb,
|
tb,
|
||||||
ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
|
guest
|
||||||
|
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
ssh_command("sudo reboot");
|
guest.ssh_command("sudo reboot");
|
||||||
thread::sleep(std::time::Duration::new(10, 0));
|
thread::sleep(std::time::Duration::new(10, 0));
|
||||||
|
|
||||||
// Do this check after shutdown of the VM as an easy way to ensure
|
// Do this check after shutdown of the VM as an easy way to ensure
|
||||||
|
Loading…
Reference in New Issue
Block a user