test: Add virtio-pmem integration tests

Add 2 integration tests to validate virtio-pmem works as expected.
One test takes care of checking the ability to read and write to this
persistent memory from the guest, and validates that the data is
carried over the virtualization boundary.
The other test ensures the VM can be booted directly from an image
that would be passed through virtio-pmem.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-06-20 13:26:11 -07:00 committed by Rob Bradford
parent 294c26bfb7
commit 785db6295e
3 changed files with 144 additions and 4 deletions

2
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ stage ("Builds") {
}
stage ('Install system packages') {
sh "sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq build-essential mtools libssl-dev pkg-config"
sh "sudo apt-get install -yq flex bison libelf-dev"
sh "sudo apt-get install -yq flex bison libelf-dev qemu-utils"
}
stage ('Install Rust') {
sh "nohup curl https://sh.rustup.rs -sSf | sh -s -- -y"

View File

@ -24,6 +24,14 @@ if [ ! -f "$OS_IMAGE" ]; then
popd
fi
OS_RAW_IMAGE_NAME="clear-29810-cloud-raw.img"
OS_RAW_IMAGE="$WORKLOADS_DIR/$OS_RAW_IMAGE_NAME"
if [ ! -f "$OS_RAW_IMAGE" ]; then
pushd $WORKLOADS_DIR
qemu-img convert -p -f qcow2 -O raw $OS_IMAGE_NAME $OS_RAW_IMAGE_NAME
popd
fi
# Build generic kernel
VMLINUX_IMAGE="$WORKLOADS_DIR/vmlinux"
BZIMAGE_IMAGE="$WORKLOADS_DIR/bzImage"

View File

@ -155,10 +155,11 @@ extern crate credibility;
#[cfg(feature = "integration_tests")]
mod tests {
use ssh2::Session;
use std::fs;
use std::io::Read;
use std::fs::{self, read, OpenOptions};
use std::io::{Read, Write};
use std::net::TcpStream;
use std::process::Command;
use std::string::String;
use std::thread;
fn ssh_command(command: &str) -> String {
@ -214,12 +215,18 @@ mod tests {
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 = "/tmp/osdisk.img";
let osdisk_raw_path = "/tmp/osdisk_raw.img";
let cloudinit_path = "/tmp/cloudinit.img";
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];
let disks = vec![osdisk_path, cloudinit_path, osdisk_raw_path];
(disks, String::from(fw_path.to_str().unwrap()))
}
@ -569,4 +576,129 @@ mod tests {
Ok(())
});
}
#[test]
fn test_virtio_pmem() {
test_block!(tb, "", {
let (disks, _) = prepare_files();
let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads");
let mut kernel_path = workload_path.clone();
kernel_path.push("vmlinux-custom");
let pmem_backend_path = "/tmp/pmem-file";
let mut pmem_backend_file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(pmem_backend_path)
.unwrap();
let pmem_backend_content = "foo";
pmem_backend_file
.write_all(pmem_backend_content.as_bytes())
.unwrap();
let pmem_backend_file_size = 0x1000;
pmem_backend_file.set_len(pmem_backend_file_size).unwrap();
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "size=512"])
.args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&["--disk", disks[0], disks[1]])
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
.args(&[
"--pmem",
format!(
"file={},size={}",
pmem_backend_path,
pmem_backend_file_size
)
.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"])
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(10, 0));
// Check for the presence of /dev/pmem0
aver_eq!(tb, ssh_command("ls /dev/pmem0").trim(), "/dev/pmem0");
// Check content
aver_eq!(
tb,
&ssh_command("sudo cat /dev/pmem0").trim()[..pmem_backend_content.len()],
pmem_backend_content
);
// Modify content
let new_content = "bar";
ssh_command(
format!(
"sudo bash -c 'echo {} > /dev/pmem0' && sudo sync /dev/pmem0",
new_content
)
.as_str(),
);
// Check content from host
aver_eq!(
tb,
&String::from_utf8(read(pmem_backend_path).unwrap())
.unwrap()
.as_str()[..new_content.len()],
new_content
);
ssh_command("sudo reboot");
let _ = child.wait();
// Cleanup the file
fs::remove_file(pmem_backend_path).unwrap();
Ok(())
});
}
#[test]
fn test_boot_from_virtio_pmem() {
test_block!(tb, "", {
let (disks, _) = prepare_files();
let mut workload_path = dirs::home_dir().unwrap();
workload_path.push("workloads");
let mut kernel_path = workload_path.clone();
kernel_path.push("vmlinux-custom");
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "size=512"])
.args(&["--kernel", kernel_path.to_str().unwrap()])
.args(&["--disk", disks[1]])
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
.args(&[
"--pmem",
format!(
"file={},size={}",
disks[2],
fs::metadata(disks[2]).unwrap().len()
)
.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"])
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(10, 0));
// Simple checks to validate the VM booted properly
aver_eq!(tb, get_cpu_count(), 1);
aver!(tb, get_total_memory() > 496_000);
ssh_command("sudo reboot");
let _ = child.wait();
Ok(())
});
}
}