From 57f70c0761caa7c00906e00b09551860c10ce28d Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 10 Jun 2021 17:03:57 +0200 Subject: [PATCH] tests: Simplify Windows guest boot and DHCP setup A new method has been introduced for WindowsGuest, that would poll on the SSH connection and try to execute a test command. When successfull, the polling stops and the guest is considered finished boot. The downside of this method is that the network setup is needed always even if the test doesn't use network, however it complies with the behavior of other tests. I also observe a bit more stability on the local test run, however it still appears to be a resource issue so some sporadic fails are possible on a slower machine. The hardcoded timeouts for guest boot and DHCP setup have been removed. The dnsmasq invocation uses `--bind-dynamic` so then the daemon can be started while the target interface could be down yet. Signed-off-by: Anatol Belski Co-authored-by: Sebastien Boeuf --- tests/integration.rs | 96 +++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/tests/integration.rs b/tests/integration.rs index 1b71bd1e4..eb07464a8 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -5367,7 +5367,7 @@ mod tests { .arg("--log-queries") .arg(listen_address.as_str()) .arg("--except-interface=lo") - .arg("--bind-interfaces") + .arg("--bind-dynamic") // Allow listening to host_ip while the interface is not ready yet. .arg("--conf-file=/dev/null") .arg(dhcp_host.as_str()) .arg(dhcp_range.as_str()) @@ -5484,6 +5484,39 @@ mod tests { fname )) } + + fn wait_for_boot(&self) -> bool { + let cmd = "dir /b c:\\ | find \"Windows\""; + let tmo_max = 180; + // The timeout increase by n*1+n*2+n*3+..., therefore the initial + // interval must be small. + let tmo_int = 2; + let out = ssh_command_ip_with_auth( + cmd, + &self.auth, + &self.guest.network.guest_ip, + { + let mut ret = 1; + let mut tmo_acc = 0; + loop { + tmo_acc += tmo_int * ret; + if tmo_acc >= tmo_max { + break; + } + ret += 1; + } + ret + }, + tmo_int, + ) + .unwrap(); + + if "Windows" == out.trim() { + return true; + } + + false + } } fn vcpu_threads_count(pid: u32) -> u8 { @@ -5551,14 +5584,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(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + windows_guest.shutdown(); }); @@ -5618,14 +5649,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(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + windows_guest.shutdown(); }); @@ -5671,13 +5700,10 @@ mod tests { assert!(pipesize >= PIPE_SIZE && pipesize1 >= PIPE_SIZE); - // 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)); + + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); let snapshot_dir = temp_snapshot_dir_path(&tmp_dir); @@ -5753,15 +5779,12 @@ mod tests { .spawn() .unwrap(); - // 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(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + let vcpu_num = 2; // Check the initial number of CPUs the guest sees assert_eq!(windows_guest.cpu_count(), vcpu_num); @@ -5830,15 +5853,12 @@ mod tests { .spawn() .unwrap(); - // 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(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + let ram_size = 2 * 1024 * 1024 * 1024; // Check the initial number of RAM the guest sees let current_ram_size = windows_guest.ram_size(); @@ -5907,15 +5927,12 @@ mod tests { .spawn() .unwrap(); - // 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(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + // Initially present network device let netdev_num = 1; assert_eq!(windows_guest.netdev_count(), netdev_num); @@ -5982,17 +5999,14 @@ mod tests { .spawn() .unwrap(); - // 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 disk = windows_guest.disk_new(); let r = std::panic::catch_unwind(|| { + // Wait to make sure Windows boots up + assert!(windows_guest.wait_for_boot()); + // Initially present disk device let disk_num = 1; assert_eq!(windows_guest.disk_count(), disk_num);