tests: Switch to launching by command

Launch the test binary by command rather than using using the vmm layer.
This makes it easier to manage the running VM as you can explicitly kill
it.

Also switch to using credibility for the tests which catches assertions
and continues with subsequent commands and reports the issues at the
end. This means it is possible to cleanup even on failed test runs.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-06-04 16:24:39 +01:00
parent ddce3df826
commit 1f53488003
4 changed files with 108 additions and 38 deletions

11
Cargo.lock generated
View File

@ -132,6 +132,7 @@ name = "cloud-hypervisor"
version = "0.1.0"
dependencies = [
"clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)",
"credibility 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ssh2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"vmm 0.1.0",
@ -150,6 +151,15 @@ name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "credibility"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "devices"
version = "0.1.0"
@ -715,6 +725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum credibility 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fae7a162fd5b462bc49704873a89950a655d44161add4be07e00e64c4c83a5bf"
"checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1"
"checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d"
"checksum epoll 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f0680f2a6f2a17fa7a8668a27c54e45e1ad1cf8a632f56a7c19b9e4e3bbe8a"

View File

@ -11,6 +11,7 @@ vmm = { path = "vmm" }
[dev-dependencies]
ssh2 = "=0.3.3"
dirs = "2.0.0"
credibility = "0.1.3"
[features]
default = []

View File

@ -28,8 +28,8 @@ rm /tmp/cloudinit.img
mkdosfs -n config-2 -C /tmp/cloudinit.img 8192
mcopy -oi /tmp/cloudinit.img -s test_data/cloud-init/openstack ::
cargo test --features "integration_tests" --no-run
find target/debug/deps/ -name cloud_hypervisor* | xargs -n1 sudo setcap cap_net_admin+ep
cargo build
sudo setcap cap_net_admin+ep target/debug/cloud-hypervisor
# Tests must be executed serially for now as they have a hardcoded IP address
cargo test --features "integration_tests" -- --test-threads=1

View File

@ -119,15 +119,18 @@ fn main() {
#[cfg(test)]
#[cfg(feature = "integration_tests")]
mod tests {
extern crate vmm;
#[macro_use]
extern crate credibility;
#[cfg(test)]
#[cfg(feature = "integration_tests")]
mod tests {
use ssh2::Session;
use std::fs;
use std::io::Read;
use std::net::TcpStream;
use std::process::Command;
use std::thread;
use vmm::config;
fn ssh_command(command: &str) -> String {
let mut s = String::new();
@ -192,47 +195,102 @@ mod tests {
(disks, String::from(fw_path.to_str().unwrap()))
}
fn get_cpu_count() -> u32 {
ssh_command("grep -c processor /proc/cpuinfo")
.trim()
.parse()
.unwrap()
}
fn get_total_memory() -> u32 {
ssh_command("grep MemTotal /proc/meminfo | grep -o \"[0-9]*\"")
.trim()
.parse::<u32>()
.unwrap()
}
fn get_entropy() -> u32 {
ssh_command("cat /proc/sys/kernel/random/entropy_avail")
.trim()
.parse::<u32>()
.unwrap()
}
#[test]
fn test_simple_launch() {
let handler = thread::spawn(|| {
test_block!(tb, "", {
let (disks, fw_path) = prepare_files();
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "512"])
.args(&["--kernel", fw_path.as_str()])
.args(&["--disk", disks[0], disks[1]])
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
.spawn()
.unwrap();
let vm_config = config::VmConfig::parse(config::VmParams {
cpus: "1",
memory: "512",
kernel: fw_path.as_str(),
cmdline: None,
disks,
rng: "/dev/urandom",
net: Some("tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"),
})
.expect("Failed parsing parameters");
thread::sleep(std::time::Duration::new(10, 0));
vmm::boot_kernel(vm_config).expect("Booting kernel failed");
aver_eq!(tb, get_cpu_count(), 1);
aver_eq!(tb, get_total_memory(), 496_400);
aver!(tb, get_entropy() >= 1000);
ssh_command("sudo reboot");
thread::sleep(std::time::Duration::new(10, 0));
let _ = child.kill();
let _ = child.wait();
Ok(())
});
thread::sleep(std::time::Duration::new(10, 0));
assert_eq!(ssh_command("grep -c processor /proc/cpuinfo").trim(), "1");
assert_eq!(
ssh_command("grep MemTotal /proc/meminfo").trim(),
"MemTotal: 496400 kB"
);
assert!(
ssh_command("cat /proc/sys/kernel/random/entropy_avail")
.trim()
.parse::<u32>()
.unwrap()
>= 1000
);
ssh_command("sudo reboot");
handler.join().unwrap();
}
#[test]
fn test_simple_launch_again() {
test_simple_launch()
fn test_multi_cpu() {
test_block!(tb, "", {
let (disks, fw_path) = prepare_files();
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "2"])
.args(&["--memory", "512"])
.args(&["--kernel", fw_path.as_str()])
.args(&["--disk", disks[0], disks[1]])
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(10, 0));
aver_eq!(tb, get_cpu_count(), 2);
ssh_command("sudo reboot");
thread::sleep(std::time::Duration::new(10, 0));
let _ = child.kill();
let _ = child.wait();
Ok(())
});
}
#[test]
fn test_large_memory() {
test_block!(tb, "", {
let (disks, fw_path) = prepare_files();
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "5120"])
.args(&["--kernel", fw_path.as_str()])
.args(&["--disk", disks[0], disks[1]])
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(10, 0));
aver!(tb, get_total_memory() > 5_063_800);
ssh_command("sudo reboot");
thread::sleep(std::time::Duration::new(10, 0));
let _ = child.kill();
let _ = child.wait();
Ok(())
});
}
}