tests: Dynamically assign IPs for Windows integration tests

Relying on dnsmasq running on the host, the Windows guest are now
getting allocated with the expected IP addresses. This allows for
multiple VMs, therefore multiple tests to run in parallel.

The end goal is to reduce the time spent running Windows integration
tests.

Fixes #1891

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-05-06 15:18:05 +02:00
parent aa76c9db2e
commit 0a00df2e7e
3 changed files with 77 additions and 17 deletions

2
Jenkinsfile vendored
View File

@ -170,7 +170,7 @@ pipeline{
}
}
stage ('Worker build - Windows guest') {
agent { node { label 'groovy-win' } }
agent { node { label 'groovy' } }
stages {
stage ('Checkout') {
steps {

View File

@ -44,7 +44,7 @@ export RUST_BACKTRACE=1
# Only run with 1 thread to avoid tests interfering with one another because
# Windows has a static IP configured
time cargo test $features_test "tests::windows::$test_filter" -- --test-threads=1
time cargo test $features_test "tests::windows::$test_filter"
RES=$?
dmsetup remove_all -f

View File

@ -5260,7 +5260,7 @@ mod tests {
return ssh_command_ip_with_auth(
"powershell -Command \"(Get-CimInstance win32_computersystem).NumberOfLogicalProcessors\"",
&self.auth,
"192.168.249.2",
&self.guest.network.guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
@ -5274,7 +5274,7 @@ mod tests {
return ssh_command_ip_with_auth(
"powershell -Command \"(Get-CimInstance win32_computersystem).TotalPhysicalMemory\"",
&self.auth,
"192.168.249.2",
&self.guest.network.guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
@ -5288,7 +5288,7 @@ mod tests {
return ssh_command_ip_with_auth(
"powershell -Command \"netsh int ipv4 show interfaces | Select-String ethernet | Measure-Object -Line | Format-Table -HideTableHeaders\"",
&self.auth,
"192.168.249.2",
&self.guest.network.guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
@ -5302,7 +5302,7 @@ mod tests {
ssh_command_ip_with_auth(
"shutdown /r /t 0",
&self.auth,
"192.168.249.2",
&self.guest.network.guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
@ -5313,12 +5313,36 @@ mod tests {
ssh_command_ip_with_auth(
"shutdown /s",
&self.auth,
"192.168.249.2",
&self.guest.network.guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
.unwrap();
}
fn run_dnsmasq(&self) -> std::process::Child {
let listen_address = format!("--listen-address={}", self.guest.network.host_ip);
let dhcp_host = format!(
"--dhcp-host={},{}",
self.guest.network.guest_mac, self.guest.network.guest_ip
);
let dhcp_range = format!(
"--dhcp-range=eth,{},{}",
self.guest.network.guest_ip, self.guest.network.guest_ip
);
Command::new("dnsmasq")
.arg("--no-daemon")
.arg("--log-queries")
.arg(listen_address.as_str())
.arg("--except-interface=lo")
.arg("--bind-interfaces")
.arg("--conf-file=/dev/null")
.arg(dhcp_host.as_str())
.arg(dhcp_range.as_str())
.spawn()
.unwrap()
}
}
fn vcpu_threads_count(pid: u32) -> u8 {
@ -5362,10 +5386,10 @@ mod tests {
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=4G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
.default_disks()
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.args(&["--net", "tap="])
.default_disks()
.default_net()
.capture_output()
.spawn()
.unwrap();
@ -5378,6 +5402,12 @@ mod tests {
assert!(pipesize >= PIPE_SIZE && pipesize1 >= PIPE_SIZE);
thread::sleep(std::time::Duration::new(60, 0));
let mut child_dnsmasq = windows_guest.run_dnsmasq();
// Give some time for the guest to reach dnsmasq and get
// assigned the right IP address.
thread::sleep(std::time::Duration::new(30, 0));
let r = std::panic::catch_unwind(|| {
windows_guest.shutdown();
});
@ -5386,6 +5416,8 @@ mod tests {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let _ = child_dnsmasq.kill();
handle_child_output(r, &output);
}
@ -5411,10 +5443,10 @@ mod tests {
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=4G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
.default_disks()
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.args(&["--net", "tap="])
.default_disks()
.default_net()
.capture_output()
.spawn()
.unwrap();
@ -5429,6 +5461,11 @@ mod tests {
// Wait to make sure Windows boots up
thread::sleep(std::time::Duration::new(60, 0));
let mut child_dnsmasq = windows_guest.run_dnsmasq();
// Give some time for the guest to reach dnsmasq and get
// assigned the right IP address.
thread::sleep(std::time::Duration::new(30, 0));
let snapshot_dir = temp_snapshot_dir_path(&tmp_dir);
// Pause the VM
@ -5472,6 +5509,8 @@ mod tests {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let _ = child_dnsmasq.kill();
handle_child_output(r, &output);
}
@ -5497,10 +5536,10 @@ mod tests {
.args(&["--cpus", "boot=2,max=8,kvm_hyperv=on"])
.args(&["--memory", "size=4G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
.default_disks()
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.args(&["--net", "tap="])
.default_disks()
.default_net()
.capture_output()
.spawn()
.unwrap();
@ -5508,6 +5547,11 @@ mod tests {
// Wait to make sure Windows boots up
thread::sleep(std::time::Duration::new(60, 0));
let mut child_dnsmasq = windows_guest.run_dnsmasq();
// Give some time for the guest to reach dnsmasq and get
// assigned the right IP address.
thread::sleep(std::time::Duration::new(30, 0));
let r = std::panic::catch_unwind(|| {
let vcpu_num = 2;
// Check the initial number of CPUs the guest sees
@ -5546,6 +5590,8 @@ mod tests {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let _ = child_dnsmasq.kill();
handle_child_output(r, &output);
}
@ -5571,10 +5617,10 @@ mod tests {
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=2G,hotplug_size=5G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
.default_disks()
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.args(&["--net", "tap="])
.default_disks()
.default_net()
.capture_output()
.spawn()
.unwrap();
@ -5582,6 +5628,11 @@ mod tests {
// Wait to make sure Windows boots up
thread::sleep(std::time::Duration::new(60, 0));
let mut child_dnsmasq = windows_guest.run_dnsmasq();
// Give some time for the guest to reach dnsmasq and get
// assigned the right IP address.
thread::sleep(std::time::Duration::new(30, 0));
let r = std::panic::catch_unwind(|| {
let ram_size = 2 * 1024 * 1024 * 1024;
// Check the initial number of RAM the guest sees
@ -5620,6 +5671,8 @@ mod tests {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let _ = child_dnsmasq.kill();
handle_child_output(r, &output);
}
@ -5645,10 +5698,10 @@ mod tests {
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=2G,hotplug_size=5G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
.default_disks()
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.args(&["--net", "tap="])
.default_disks()
.default_net()
.capture_output()
.spawn()
.unwrap();
@ -5656,6 +5709,11 @@ mod tests {
// Wait to make sure Windows boots up
thread::sleep(std::time::Duration::new(60, 0));
let mut child_dnsmasq = windows_guest.run_dnsmasq();
// Give some time for the guest to reach dnsmasq and get
// assigned the right IP address.
thread::sleep(std::time::Duration::new(30, 0));
let r = std::panic::catch_unwind(|| {
// Initially present network device
let netdev_num = 1;
@ -5692,6 +5750,8 @@ mod tests {
let _ = child.kill();
let output = child.wait_with_output().unwrap();
let _ = child_dnsmasq.kill();
handle_child_output(r, &output);
}
}