def verify_timedrift(session, is_hardware=False): """ Verify timedrift between host and guest. :param session: VM session. :param is_hardware: if need to verify guest's hardware time. """ # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = float( params.get("timerdevice_drift_threshold", 3)) time_type = "system" if not is_hardware else "harware" error_context.context("Check the %s time on guest" % time_type, test.log.info) host_time, guest_time = utils_test.get_time(session, time_command, time_filter_re, time_format) if is_hardware: guest_time = get_hwtime(session) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's %s time is different with" " host's system time. Host time: '%s', guest time:" " '%s'" % (time_type, host_time, guest_time))
def verify_timedrift(session, is_hardware=False): """ Verify timedrift between host and guest. :param session: VM session. :param is_hardware: if need to verify guest's hardware time. """ # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = float(params.get( "timerdevice_drift_threshold", 3)) time_type = "system" if not is_hardware else "harware" error_context.context("Check the %s time on guest" % time_type, logging.info) host_time, guest_time = utils_test.get_time(session, time_command, time_filter_re, time_format) if is_hardware: guest_time = get_hwtime(session) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's %s time is different with" " host's system time. Host time: '%s', guest time:" " '%s'" % (time_type, host_time, guest_time))
def check_diff(self, mig_data): logging.debug("Sleep 10s") time.sleep(10) time_drifted = False for vm in mig_data.vms: session = vm.wait_for_login() if self.is_src: error.context("Check the clocksource in guest.", logging.info) check_clocksource_cmd = params.get("check_clocksource_cmd") clocksource = params.get("clocksource", "kvm-clock") current_clocksource = session.cmd(check_clocksource_cmd) current_clocksource = re.findall(clocksource, current_clocksource) current_clocksource = "".join(current_clocksource) logging.info("current_clocksource in guest is: '%s'", current_clocksource) if clocksource == "kvm-clock": s = current_clocksource == "kvm-clock" else: s = current_clocksource != "kvm-clock" if not s: raise error.TestFail("Guest didn't use '%s' " "clocksource" % clocksource) error.context("Check the system time on guest and host.", logging.info) (ht, gt) = utils_test.get_time(session, self.time_command, self.time_filter_re, self.time_format) session.cmd(self.create_file) if vm.name not in self.start_ht.keys(): (self.start_ht[vm.name], self.start_gt[vm.name]) = (ht, gt) if abs(ht - gt) > self.diff_limit: logging.warning( "Host and %s time diff %s is greater " "than time_diff_limit:%s", vm.name, abs(ht - gt), self.diff_limit) logging.warning("Host time:%s Guest %s time:%s", ht, vm.name, gt) else: self.diff_ht[vm.name] = ht - self.start_ht[vm.name] self.diff_gt[vm.name] = gt - self.start_gt[vm.name] gh_diff = self.diff_ht[vm.name] - self.diff_gt[vm.name] if gh_diff > self.diff_limit: time_drifted = True if time_drifted: difs = "" for vm in mig_data.vms: difs += ( "\n VM=%s HOST=%ss GUEST=%ss" " DIFF=%s" % (vm.name, self.diff_ht[vm.name], self.diff_gt[vm.name], (self.diff_ht[vm.name] - self.diff_gt[vm.name]))) raise error.TestError("Time DIFFERENCE for VM is greater than" " LIMIT:%ss.%s\n" % (self.diff_limit, difs))
def check_diff(self, mig_data): logging.debug("Sleep 10s") time.sleep(10) time_drifted = False for vm in mig_data.vms: session = vm.wait_for_login() if self.is_src: error.context("Check the clocksource in guest.", logging.info) check_clocksource_cmd = params.get("check_clocksource_cmd") clocksource = params.get("clocksource", "kvm-clock") current_clocksource = session.cmd(check_clocksource_cmd) logging.info("current_clocksource in guest is: '%s'" % current_clocksource) if clocksource == "kvm-clock": s = current_clocksource == "kvm-clock" else: s = current_clocksource != "kvm-clock" if not s: raise error.TestFail("Guest didn't use '%s' " "clocksource" % clocksource) error.context("Check the system time on guest and host.", logging.info) (ht, gt) = utils_test.get_time(session, self.time_command, self.time_filter_re, self.time_format) session.cmd(self.create_file) if vm.name not in self.start_ht.keys(): (self.start_ht[vm.name], self.start_gt[vm.name]) = (ht, gt) if abs(ht - gt) > self.diff_limit: logging.warning("Host and %s time diff %s is greater " "than time_diff_limit:%s" % (vm.name, abs(ht - gt), self.diff_limit)) logging.warning("Host time:%s Guest %s time:%s" % (ht, vm.name, gt)) else: self.diff_ht[vm.name] = ht - self.start_ht[vm.name] self.diff_gt[vm.name] = gt - self.start_gt[vm.name] gh_diff = self.diff_ht[vm.name] - self.diff_gt[vm.name] if gh_diff > self.diff_limit: time_drifted = True if time_drifted: difs = "" for vm in mig_data.vms: difs += ("\n VM=%s HOST=%ss GUEST=%ss" " DIFF=%s" % (vm.name, self.diff_ht[vm.name], self.diff_gt[vm.name], (self.diff_ht[vm.name] - self.diff_gt[vm.name]))) raise error.TestError("Time DIFFERENCE for VM is greater than" " LIMIT:%ss.%s\n" % (self.diff_limit, difs))
def check_diff(self, mig_data): logging.debug("Sleep 10s") time.sleep(10) time_drifted = False for vm in mig_data.vms: session = vm.wait_for_login() (ht, gt) = utils_test.get_time(session, self.time_command, self.time_filter_re, self.time_format) session.cmd(self.create_file) if not vm.name in self.start_ht.keys(): (self.start_ht[vm.name], self.start_gt[vm.name]) = (ht, gt) if abs(ht - gt) > self.diff_limit: logging.warning("Host and %s time diff %s is greater " "than time_diff_limit:%s" % (vm.name, abs(ht - gt), self.diff_limit)) logging.warning("Host time:%s Guest %s time:%s" % (ht, vm.name, gt)) else: self.diff_ht[vm.name] = ht - self.start_ht[vm.name] self.diff_gt[vm.name] = gt - self.start_gt[vm.name] gh_diff = self.diff_ht[vm.name] - self.diff_gt[vm.name] if gh_diff > self.diff_limit: time_drifted = True if time_drifted: difs = "" for vm in mig_data.vms: difs += ("\n VM=%s HOST=%ss GUEST=%ss" " DIFF=%s" % (vm.name, self.diff_ht[vm.name], self.diff_gt[vm.name], (self.diff_ht[vm.name] - self.diff_gt[vm.name]))) raise error.TestError("Time DIFFERENCE for VM is greater than" " LIMIT:%ss.%s\n" % (self.diff_limit, difs))
def run(test, params, env): """ Time drift test with reboot: 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Reboot the guest. 4) Take a second time reading. 5) If the drift (in seconds) is higher than a user specified value, fail. :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() boot_option_added = params.get("boot_option_added") boot_option_removed = params.get("boot_option_removed") if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_removed, args_added=boot_option_added) timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] drift_threshold = float(params.get("drift_threshold", "10")) drift_threshold_single = float(params.get("drift_threshold_single", "3")) reboot_iterations = int(params.get("reboot_iterations", 1)) try: # Get initial time # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Reboot for i in range(reboot_iterations): # Get time before current iteration (ht0_, gt0_) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Run current iteration logging.info("Rebooting: iteration %d of %d...", (i + 1), reboot_iterations) session = vm.reboot(session, timeout=timeout) # Get time after current iteration (ht1_, gt1_) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report iteration results host_delta = ht1_ - ht0_ guest_delta = gt1_ - gt0_ drift = abs(host_delta - guest_delta) logging.info("Host duration (iteration %d): %.2f", (i + 1), host_delta) logging.info("Guest duration (iteration %d): %.2f", (i + 1), guest_delta) logging.info("Drift at iteration %d: %.2f seconds", (i + 1), drift) # Fail if necessary if drift > drift_threshold_single: raise error.TestFail("Time drift too large at iteration %d: " "%.2f seconds" % (i + 1, drift)) # Get final time (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: if session: session.close() # remove flags add for this test. if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_added, args_added=boot_option_removed) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = abs(host_delta - guest_delta) logging.info("Host duration (%d reboots): %.2f", reboot_iterations, host_delta) logging.info("Guest duration (%d reboots): %.2f", reboot_iterations, guest_delta) logging.info("Drift after %d reboots: %.2f seconds", reboot_iterations, drift) # Fail if necessary if drift > drift_threshold: raise error.TestFail("Time drift too large after %d reboots: " "%.2f seconds" % (reboot_iterations, drift))
def run(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ clock_sync_command = params["clock_sync_command"] login_timeout = int(params.get("login_timeout", "240")) date_time_command = params.get("date_time_command", r"date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", r"(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] test_type = params["timedrift_sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error_context.context("Sync host machine with clock server", logging.info) process.system(clock_sync_command, shell=True) session = vm.wait_for_login(timeout=login_timeout) error_context.context("Get clock from host and guest VM using `date`", logging.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *before_date) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](test, params, vm, session) else: test.cancel("Unable to found subwork %s in %s test file." % (sub_work, __file__)) vm = env.get_vm(vm_name) session = vm.wait_for_login(timeout=login_timeout) error_context.context("Get clock from host and guest VM using `date`", logging.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *after_date) if test_type == 'guest_suspend': date_diff = time_diff(before_date, after_date) if date_diff > tolerance: test.fail("date %ss difference is" "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (date_diff[1], tolerance)) elif test_type == "guest_pause_resume": date_diff = time_diff_host_guest(before_date, after_date) if date_diff[1] > tolerance: test.fail("date %ss difference is " "'guest_time_after-guest_time_before'" " out of tolerance %ss" % (date_diff[1], tolerance))
if params.get("timerdevice_file_operation") == "yes": error.context("Do some file operation on guest", logging.info) session.cmd("dd if=/dev/zero of=/tmp/timer-test-file bs=1M count=100") return # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = params.get("timerdevice_drift_threshold", 3) error.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: raise error.TestFail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error.context( "Check the hardware time on guest and host", logging.info) host_time = utils.system_output(get_hw_time_cmd) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: raise error.TestFail("The guest's hardware time is different with"
def run_timedrift_no_net(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ clock_server = params.get("clock_server", "clock.redhat.com") ntputil_install = params.get("ntputil_install", "yum install -y ntpdate") login_timeout = int(params.get("login_timeout", "240")) guest_clock_source = params.get("guest_clock_source", "kvm-clock") date_time_command = params.get("date_time_command", "date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", "(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") hwclock_time_command = params.get("hwclock_time_command", "LC_TIME=C hwclock -u") hwclock_time_filter_re = params.get("hwclock_time_filter_re", "(.+)") hwclock_time_format = params.get("hwclock_time_format", "%a %b %d %H:%M:%S %Y") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error.context("Check if ntp utils are host in system.", logging.info) try: utils_misc.find_command("ntpdate") except ValueError: error.context("Install ntp utils `%s`." % (ntputil_install), logging.info) utils.run(ntputil_install) error.context("Sync host machine with clock server %s" % (clock_server), logging.info) utils.run("ntpdate %s" % (clock_server)) error.context("Check clock source on guest VM", logging.info) session = vm.wait_for_serial_login(timeout=login_timeout) out = session.cmd_output("cat /sys/devices/system/clocksource/" "clocksource0/current_clocksource") if not guest_clock_source in out: raise error.TestFail("Clock source %s missing in guest clock " "sources %s." % (guest_clock_source, out)) error.context("Get clock from host and guest VM using `date`", logging.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug(before_date) error.context("Get clock from host and guest VM using `hwclock`", logging.info) before_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) logging.debug(before_hwclock) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](params, vm, session) else: raise error.TestNAError("Unable to found subwork %s in %s test file." % (sub_work, __file__)) session = vm.wait_for_serial_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug(after_date) error.context("Get clock from host and guest VM using `hwclock`", logging.info) after_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) logging.debug(after_hwclock) date_diff = time_diff(before_date, after_date) hwclock_diff = time_diff(before_hwclock, after_hwclock) if date_diff > tolerance and hwclock_diff > tolerance: raise error.TestFail("hwclock %ss and date %ss difference is" " out of tolerance %ss" % (hwclock_diff, date_diff, tolerance)) elif date_diff > tolerance: raise error.TestFail("date %ss difference is" " out of tolerance %ss" % (date_diff, tolerance)) elif hwclock_diff > tolerance: raise error.TestFail("hwclock %ss difference is" " out of tolerance %ss" % (hwclock_diff, tolerance))
def run_timedrift_with_migration(test, params, env): """ Time drift test with migration: 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Migrate the guest. 4) Take a second time reading. 5) If the drift (in seconds) is higher than a user specified value, fail. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") drift_threshold = float(params.get("drift_threshold", "10")) drift_threshold_single = float(params.get("drift_threshold_single", "3")) migration_iterations = int(params.get("migration_iterations", 1)) try: # Get initial time # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Migrate for i in range(migration_iterations): # Get time before current iteration (ht0_, gt0_) = utils_test.get_time(session, time_command, time_filter_re, time_format) session.close() # Run current iteration logging.info("Migrating: iteration %d of %d...", (i + 1), migration_iterations) vm.migrate() # Log in logging.info("Logging in after migration...") session = vm.wait_for_login(timeout=30) logging.info("Logged in after migration") # Get time after current iteration (ht1_, gt1_) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report iteration results host_delta = ht1_ - ht0_ guest_delta = gt1_ - gt0_ drift = abs(host_delta - guest_delta) logging.info("Host duration (iteration %d): %.2f", (i + 1), host_delta) logging.info("Guest duration (iteration %d): %.2f", (i + 1), guest_delta) logging.info("Drift at iteration %d: %.2f seconds", (i + 1), drift) # Fail if necessary if drift > drift_threshold_single: raise error.TestFail("Time drift too large at iteration %d: " "%.2f seconds" % (i + 1, drift)) # Get final time (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: if session: session.close() # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = abs(host_delta - guest_delta) logging.info("Host duration (%d migrations): %.2f", migration_iterations, host_delta) logging.info("Guest duration (%d migrations): %.2f", migration_iterations, guest_delta) logging.info("Drift after %d migrations: %.2f seconds", migration_iterations, drift) # Fail if necessary if drift > drift_threshold: raise error.TestFail("Time drift too large after %d migrations: " "%.2f seconds" % (migration_iterations, drift))
def run_timedrift(test, params, env): """ Time drift test (mainly for Windows guests): 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Run load on the guest and host. 4) Take a second time reading. 5) Stop the load and rest for a while. 6) Take a third time reading. 7) If the drift immediately after load is higher than a user- specified value (in %), fail. If the drift after the rest period is higher than a user-specified value, fail. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ # Helper functions def set_cpu_affinity(pid, mask): """ Set the CPU affinity of all threads of the process with PID pid. Do this recursively for all child processes as well. @param pid: The process ID. @param mask: The CPU affinity mask. @return: A dict containing the previous mask for each thread. """ tids = commands.getoutput("ps -L --pid=%s -o lwp=" % pid).split() prev_masks = {} for tid in tids: prev_mask = commands.getoutput("taskset -p %s" % tid).split()[-1] prev_masks[tid] = prev_mask commands.getoutput("taskset -p %s %s" % (mask, tid)) children = commands.getoutput("ps --ppid=%s -o pid=" % pid).split() for child in children: prev_masks.update(set_cpu_affinity(child, mask)) return prev_masks def restore_cpu_affinity(prev_masks): """ Restore the CPU affinity of several threads. @param prev_masks: A dict containing TIDs as keys and masks as values. """ for tid, mask in prev_masks.items(): commands.getoutput("taskset -p %s %s" % (mask, tid)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") guest_load_command = params.get("guest_load_command") guest_load_stop_command = params.get("guest_load_stop_command") host_load_command = params.get("host_load_command") guest_load_instances = int(params.get("guest_load_instances", "1")) host_load_instances = int(params.get("host_load_instances", "0")) # CPU affinity mask for taskset cpu_mask = params.get("cpu_mask", "0xFF") load_duration = float(params.get("load_duration", "30")) rest_duration = float(params.get("rest_duration", "10")) drift_threshold = float(params.get("drift_threshold", "200")) drift_threshold_after_rest = float( params.get("drift_threshold_after_rest", "200")) guest_load_sessions = [] host_load_sessions = [] try: # Set the VM's CPU affinity prev_affinity = set_cpu_affinity(vm.get_shell_pid(), cpu_mask) try: # Open shell sessions with the guest logging.info("Starting load on guest...") for i in range(guest_load_instances): load_session = vm.login() # Set output func to None to stop it from being called so we # can change the callback function and the parameters it takes # with no problems load_session.set_output_func(None) load_session.set_output_params(()) load_session.set_output_prefix("(guest load %d) " % i) load_session.set_output_func(logging.debug) guest_load_sessions.append(load_session) # Get time before load # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Run some load on the guest for load_session in guest_load_sessions: load_session.sendline(guest_load_command) # Run some load on the host logging.info("Starting load on host...") for i in range(host_load_instances): host_load_sessions.append( aexpect.run_bg(host_load_command, output_func=logging.debug, output_prefix="(host load %d) " % i, timeout=0.5)) # Set the CPU affinity of the load process pid = host_load_sessions[-1].get_pid() set_cpu_affinity(pid, cpu_mask) # Sleep for a while (during load) logging.info("Sleeping for %s seconds...", load_duration) time.sleep(load_duration) # Get time delta after load (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) finally: logging.info("Cleaning up...") # Restore the VM's CPU affinity restore_cpu_affinity(prev_affinity) # Stop the guest load if guest_load_stop_command: session.cmd_output(guest_load_stop_command) # Close all load shell sessions for load_session in guest_load_sessions: load_session.close() for load_session in host_load_sessions: load_session.close() # Sleep again (rest) logging.info("Sleeping for %s seconds...", rest_duration) time.sleep(rest_duration) # Get time after rest (ht2, gt2) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: session.close() # Report results host_delta_total = ht2 - ht0 guest_delta_total = gt2 - gt0 drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta logging.info("Total host duration including rest: %.2f", host_delta_total) logging.info("Total guest duration including rest: %.2f", guest_delta_total) logging.info("Total drift after rest: %.2f%%", drift_total) # Fail the test if necessary if abs(drift) > drift_threshold: raise error.TestFail("Time drift too large: %.2f%%" % drift) if abs(drift_total) > drift_threshold_after_rest: raise error.TestFail("Time drift too large after rest period: %.2f%%" % drift_total)
def run(test, params, env): """ Timer device boot guest: 1) Sync the host system time with ntp server 2) Add some load on host (Optional) 3) Boot the guest with specific clock source 4) Check the clock source currently used on guest 5) Do some file operation on guest (Optional) 6) Check the system time on guest and host (Optional) 7) Check the hardware time on guest and host (Optional) 8) Sleep period of time before reboot (Optional) 9) Reboot guest (Optional) 10) Check the system time on guest and host (Optional) 11) Check the hardware time on guest and host (Optional) :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def verify_guest_clock_source(session, expected): error_context.context("Check the current clocksource in guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if expected not in session.cmd(cmd): test.fail("Guest didn't use '%s' clocksource" % expected) error_context.context("Sync the host system time with ntp server", logging.info) process.system("ntpdate clock.redhat.com") timerdevice_host_load_cmd = params.get("timerdevice_host_load_cmd") if timerdevice_host_load_cmd: error_context.context("Add some load on host", logging.info) process.system(timerdevice_host_load_cmd, shell=True) host_load_stop_cmd = params["timerdevice_host_load_stop_cmd"] funcatexit.register(env, params["type"], _system, host_load_stop_cmd) error_context.context("Boot a guest with kvm-clock", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) timerdevice_clksource = params.get("timerdevice_clksource") if timerdevice_clksource: try: verify_guest_clock_source(session, timerdevice_clksource) except Exception: clksrc = timerdevice_clksource error_context.context("Shutdown guest") vm.destroy() env.unregister_vm(vm.name) error_context.context("Update guest kernel cli to '%s'" % clksrc, logging.info) image_filename = storage.get_image_filename( params, data_dir.get_data_dir()) grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") kernel_cfg_pattern = params.get("kernel_cfg_pos_reg", r".*vmlinuz-\d+.*") disk_obj = utils_disk.GuestFSModiDisk(image_filename) kernel_cfg_original = disk_obj.read_file(grub_file) try: logging.warn("Update the first kernel entry to" " '%s' only" % clksrc) kernel_cfg = re.findall(kernel_cfg_pattern, kernel_cfg_original)[0] except IndexError as detail: test.error("Couldn't find the kernel config, regex" " pattern is '%s', detail: '%s'" % (kernel_cfg_pattern, detail)) if "clocksource=" in kernel_cfg: kernel_cfg_new = re.sub(r"clocksource=.*?\s", "clocksource=%s" % clksrc, kernel_cfg) else: kernel_cfg_new = "%s %s" % (kernel_cfg, "clocksource=%s" % clksrc) disk_obj.replace_image_file_content(grub_file, kernel_cfg, kernel_cfg_new) error_context.context("Boot the guest", logging.info) vm_name = params["main_vm"] cpu_model_flags = params.get("cpu_model_flags") params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock" env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context("Check the current clocksource in guest", logging.info) verify_guest_clock_source(session, clksrc) error_context.context("Kill all ntp related processes") session.cmd("pkill ntp; true") if params.get("timerdevice_file_operation") == "yes": error_context.context("Do some file operation on guest", logging.info) session.cmd("dd if=/dev/zero of=/tmp/timer-test-file bs=1M count=100") return # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = params.get("timerdevice_drift_threshold", 3) error_context.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error_context.context("Check the hardware time on guest and host", logging.info) host_time = process.system_output(get_hw_time_cmd, shell=True) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's hardware time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) if params.get("timerdevice_reboot_test") == "yes": sleep_time = params.get("timerdevice_sleep_time") if sleep_time: error_context.context("Sleep '%s' secs before reboot" % sleep_time, logging.info) sleep_time = int(sleep_time) time.sleep(sleep_time) session = vm.reboot() error_context.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error_context.context("Check the hardware time on guest and host", logging.info) host_time = process.system_output(get_hw_time_cmd, shell=True) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's hardware time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time))
def run_timedrift(test, params, env): """ Time drift test (mainly for Windows guests): 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Run load on the guest and host. 4) Take a second time reading. 5) Stop the load and rest for a while. 6) Take a third time reading. 7) If the drift immediately after load is higher than a user- specified value (in %), fail. If the drift after the rest period is higher than a user-specified value, fail. @param test: QEMU test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ # Helper functions def set_cpu_affinity(pid, mask): """ Set the CPU affinity of all threads of the process with PID pid. Do this recursively for all child processes as well. @param pid: The process ID. @param mask: The CPU affinity mask. @return: A dict containing the previous mask for each thread. """ tids = commands.getoutput("ps -L --pid=%s -o lwp=" % pid).split() prev_masks = {} for tid in tids: prev_mask = commands.getoutput("taskset -p %s" % tid).split()[-1] prev_masks[tid] = prev_mask commands.getoutput("taskset -p %s %s" % (mask, tid)) children = commands.getoutput("ps --ppid=%s -o pid=" % pid).split() for child in children: prev_masks.update(set_cpu_affinity(child, mask)) return prev_masks def restore_cpu_affinity(prev_masks): """ Restore the CPU affinity of several threads. @param prev_masks: A dict containing TIDs as keys and masks as values. """ for tid, mask in prev_masks.items(): commands.getoutput("taskset -p %s %s" % (mask, tid)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") guest_load_command = params.get("guest_load_command") guest_load_stop_command = params.get("guest_load_stop_command") host_load_command = params.get("host_load_command") guest_load_instances = int(params.get("guest_load_instances", "1")) host_load_instances = int(params.get("host_load_instances", "0")) # CPU affinity mask for taskset cpu_mask = params.get("cpu_mask", "0xFF") load_duration = float(params.get("load_duration", "30")) rest_duration = float(params.get("rest_duration", "10")) drift_threshold = float(params.get("drift_threshold", "200")) drift_threshold_after_rest = float(params.get("drift_threshold_after_rest", "200")) guest_load_sessions = [] host_load_sessions = [] try: # Set the VM's CPU affinity prev_affinity = set_cpu_affinity(vm.get_shell_pid(), cpu_mask) try: # Open shell sessions with the guest logging.info("Starting load on guest...") for i in range(guest_load_instances): load_session = vm.login() # Set output func to None to stop it from being called so we # can change the callback function and the parameters it takes # with no problems load_session.set_output_func(None) load_session.set_output_params(()) load_session.set_output_prefix("(guest load %d) " % i) load_session.set_output_func(logging.debug) guest_load_sessions.append(load_session) # Get time before load # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Run some load on the guest for load_session in guest_load_sessions: load_session.sendline(guest_load_command) # Run some load on the host logging.info("Starting load on host...") for i in range(host_load_instances): host_load_sessions.append( aexpect.run_bg(host_load_command, output_func=logging.debug, output_prefix="(host load %d) " % i, timeout=0.5)) # Set the CPU affinity of the load process pid = host_load_sessions[-1].get_pid() set_cpu_affinity(pid, cpu_mask) # Sleep for a while (during load) logging.info("Sleeping for %s seconds...", load_duration) time.sleep(load_duration) # Get time delta after load (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) finally: logging.info("Cleaning up...") # Restore the VM's CPU affinity restore_cpu_affinity(prev_affinity) # Stop the guest load if guest_load_stop_command: session.cmd_output(guest_load_stop_command) # Close all load shell sessions for load_session in guest_load_sessions: load_session.close() for load_session in host_load_sessions: load_session.close() # Sleep again (rest) logging.info("Sleeping for %s seconds...", rest_duration) time.sleep(rest_duration) # Get time after rest (ht2, gt2) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: session.close() # Report results host_delta_total = ht2 - ht0 guest_delta_total = gt2 - gt0 drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta logging.info("Total host duration including rest: %.2f", host_delta_total) logging.info("Total guest duration including rest: %.2f", guest_delta_total) logging.info("Total drift after rest: %.2f%%", drift_total) # Fail the test if necessary if abs(drift) > drift_threshold: raise error.TestFail("Time drift too large: %.2f%%" % drift) if abs(drift_total) > drift_threshold_after_rest: raise error.TestFail("Time drift too large after rest period: %.2f%%" % drift_total)
def run(test, params, env): """ Time manage test: 1) Generate stress in host. 2) Run atleast 15 vms with "driftfix=slew" option 3) Reboot the guest. 4) Repeat the step 3 for all guests and check whether the guest responds properly(not any watchdog reported). 5) TODO: Improve the way of checking the response and run some stress inside guest too. 6) Continue the step 4 for 10 iterations and record the guest/host realtime, calculate drift in time for each iterations. 7) Print the drift values for all sessions 8) TODO: Validate if the drift value has to be within defined value :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ # Checking the main vm is alive vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters login_timeout = float(params.get("login_timeout", 240)) host_load_command = params["host_load_command"] host_load_kill_command = params["host_load_kill_command"] time_command = params["time_command"] time_filter_re = params["time_filter_re"] time_format = params["time_format"] # Intialize the variables itr = 0 num = 2 host_load_sessions = [] sessions = [session] prev_time = [] curr_time = [] timedrift = [] totaldrift = [] vmnames = ["virt-tests-vm1"] # Run some load on the host logging.info("Starting load on host.") host_load_sessions.append(aexpect.run_bg(host_load_command, output_func=logging.debug, output_prefix="host load ", timeout=0.5)) # Boot the VMs try: while num <= int(params["max_vms"]): # Clone vm according to the first one vm_name = "virt-tests-vm%d" % num vmnames.append(vm_name) vm_params = vm.params.copy() curr_vm = vm.clone(vm_name, vm_params) env.register_vm(vm_name, curr_vm) env_process.preprocess_vm(test, vm_params, env, vm_name) params["vms"] += " " + vm_name sessions.append(curr_vm.wait_for_login(timeout=login_timeout)) logging.info("Guest #%d booted up successfully", num) # Check whether all previous shell sessions are responsive error.context("checking responsiveness of the booted guest") for se in sessions: se.cmd(params["alive_test_cmd"]) num += 1 while itr <= int(params["max_itrs"]): for vmid, se in enumerate(sessions): # Get the respective vm object vmname = "virt-tests-vm%d" % (vmid + 1) vm = env.get_vm(vmname) # Run current iteration logging.info( "Rebooting:vm%d iteration %d " % ((vmid + 1), itr)) se = vm.reboot(se, timeout=timeout) # Remember the current changed session sessions[vmid] = se error.context("checking responsiveness of guest") se.cmd(params["alive_test_cmd"]) if itr == 0: (ht0, gt0) = utils_test.get_time(se, time_command, time_filter_re, time_format) prev_time.append((ht0, gt0)) else: (ht1, gt1) = utils_test.get_time(se, time_command, time_filter_re, time_format) curr_time.append((ht1, gt1)) if itr != 0: for i in range(int(params["max_vms"])): hdelta = curr_time[i][0] - prev_time[i][0] gdelta = curr_time[i][1] - prev_time[i][1] drift = "%.2f" % (100.0 * (hdelta - gdelta) / hdelta) timedrift.append(drift) totaldrift.append(timedrift) prev_time = curr_time timedrift = [] curr_time = [] # Wait for some time before next iteration time.sleep(30) itr += 1 logging.info("The time drift values for all VM sessions/iterations") logging.info("VM-Name:%s" % vmnames) for idx, value in enumerate(totaldrift): logging.info("itr-%2d:%s" % (idx + 1, value)) finally: for se in sessions: # Closing all the sessions. se.close() logging.info("killing load on host.") host_load_sessions.append(aexpect.run_bg(host_load_kill_command, output_func=logging.debug, output_prefix="host load kill", timeout=0.5))
def run(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ login_timeout = int(params.get("login_timeout", "240")) guest_clock_source = params.get("guest_clock_source", "kvm-clock") date_time_command = params.get("date_time_command", "date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", r"(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") hwclock_time_command = params.get("hwclock_time_command") hwclock_time_filter_re = params.get("hwclock_time_filter_re", r"(.+)") hwclock_time_format = params.get("hwclock_time_format", "%a %b %d %H:%M:%S %Y") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] test_type = params["timedrift_sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error_context.context("Sync host machine with clock server %s", test.log.info) clock_sync_command = params["clock_sync_command"] process.system(clock_sync_command, shell=True) error_context.context("Check clock source on guest VM", test.log.info) session = vm.wait_for_serial_login(timeout=login_timeout) out = session.cmd_output("cat /sys/devices/system/clocksource/" "clocksource0/current_clocksource") if guest_clock_source not in out: test.fail("Clock source %s missing in guest clock " "sources %s." % (guest_clock_source, out)) error_context.context("Get clock from host and guest VM using `date`", test.log.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) test.log.debug("date: host time=%ss guest time=%ss", *before_date) error_context.context("Get clock from host and guest VM using `hwclock`", test.log.info) before_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) test.log.debug("hwclock: host time=%ss guest time=%ss", *before_hwclock) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](test, params, vm, session) else: test.cancel("Unable to found subwork %s in %s test file." % (sub_work, __file__)) session = vm.wait_for_serial_login(timeout=login_timeout) error_context.context("Get clock from host and guest VM using `date`", test.log.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) test.log.debug("date: host time=%ss guest time=%ss", *after_date) error_context.context("Get clock from host and guest VM using `hwclock`", test.log.info) after_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) test.log.debug("hwclock: host time=%ss guest time=%ss", *after_hwclock) if test_type == 'guest_suspend': date_diff = time_diff(before_date, after_date) hwclock_diff = time_diff(before_hwclock, after_hwclock) if date_diff > tolerance and hwclock_diff > tolerance: test.fail("hwclock %ss and date %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (hwclock_diff, date_diff, tolerance)) elif date_diff > tolerance: test.fail("date %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (date_diff, tolerance)) elif hwclock_diff > tolerance: test.fail("hwclock %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (hwclock_diff, tolerance)) elif test_type == "guest_pause_resume": date_diff = time_diff(before_date, after_date) if date_diff > tolerance: test.fail("date %ss difference is" "'guest_time_after-guest_time_before'" " out of tolerance %ss" % (date_diff, tolerance))
def run(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ clock_server = params.get("clock_server", "clock.redhat.com") ntputil_install = params.get("ntputil_install", "yum install -y ntpdate") login_timeout = int(params.get("login_timeout", "240")) date_time_command = params.get( "date_time_command", r"date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", r"(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] test_type = params["timedrift_sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error.context("Check if ntp utils are host in system.", logging.info) try: utils_misc.find_command("ntpdate") except ValueError: error.context("Install ntp utils `%s`." % (ntputil_install), logging.info) utils.run(ntputil_install) error.context("Sync host machine with clock server %s" % (clock_server), logging.info) utils.run("ntpdate %s" % (clock_server)) session = vm.wait_for_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *before_date) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](params, vm, session) else: raise error.TestNAError("Unable to found subwork %s in %s test file." % (sub_work, __file__)) vm = env.get_vm(vm_name) session = vm.wait_for_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *after_date) if test_type == 'guest_suspend': date_diff = time_diff(before_date, after_date) if date_diff > tolerance: raise error.TestFail("date %ss difference is" "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (date_diff[1], tolerance)) elif test_type == "guest_pause_resume": date_diff = time_diff_host_guest(before_date, after_date) if date_diff[1] > tolerance: raise error.TestFail("date %ss difference is " "'guest_time_after-guest_time_before'" " out of tolerance %ss" % (date_diff[1], tolerance))
def run(test, params, env): """ Time drift test with vm's cpu offline/online: 1) Log into a guest (the vcpu num >= 2). 2) Take a time reading from the guest and host. 3) Set cpu offline in vm. 4) Take the time from the guest and host as given frequency. 5) Set cpu online, which was set offline before 5) Take the time from the guest and host as given frequency. 6) If the drift (in seconds) is higher than a user specified value, fail. :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() boot_option_added = params.get("boot_option_added") boot_option_removed = params.get("boot_option_removed") if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_removed, args_added=boot_option_added) session = vm.wait_for_login(timeout=login_timeout) # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") # Use this value to measure the drift. drift_threshold = int(params.get("drift_threshold", 10)) # The time interval to check vm's time interval_gettime = int(params.get("interval_gettime", 600)) test_duration = float(params.get("test_duration", "120")) stop_time = int(params.get("stop_time", 60)) try: # Get time before set cpu offline # (ht stands for host time, gt stands for guest time) error_context.context("get time before set cpu offline") (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Check cpu number error_context.context("check guest cpu number") smp = int(params.get("smp")) if smp < 2: test.error("The guest only has %d vcpu," "unsupport cpu offline" % smp) # Set cpu offline error_context.context("set cpu offline ") offline_cpu_cmd = params.get("offline_cpu_cmd") s, o = session.cmd_status_output(offline_cpu_cmd) if s != 0: logging.error(o) test.error("Failed set guest cpu offline") # Sleep for a while after set cpu offline time.sleep(stop_time) # Get time after set cpu offline error_context.context("get time after set cpu offline") (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) if abs(drift) > drift_threshold: test.fail("Time drift too large: %.2f%%" % drift) # Set cpu online again error_context.context("set cpu online") online_cpu_cmd = params.get("online_cpu_cmd") s, o = session.cmd_status_output(online_cpu_cmd) if s != 0: logging.error(o) test.error("Failed set guest cpu online") error_context.context("get time after set cpu online") start_time = time.time() while (time.time() - start_time) < test_duration: # Get time delta after set cpu online (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) time.sleep(interval_gettime) if abs(drift) > drift_threshold: test.fail("Time drift too large: %.2f%%" % drift) finally: session.close() # remove flags add for this test. if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_added, args_added=boot_option_removed)
if params.get("timerdevice_file_operation") == "yes": error.context("Do some file operation on guest", logging.info) session.cmd("dd if=/dev/zero of=/tmp/timer-test-file bs=1M count=100") return # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = params.get("timerdevice_drift_threshold", 3) error.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: raise error.TestFail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error.context("Check the hardware time on guest and host", logging.info) host_time = utils.system_output(get_hw_time_cmd) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: raise error.TestFail("The guest's hardware time is different with"
def run(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ clock_server = params.get("clock_server", "clock.redhat.com") ntputil_install = params.get("ntputil_install", "yum install -y ntpdate") login_timeout = int(params.get("login_timeout", "240")) guest_clock_source = params.get("guest_clock_source", "kvm-clock") date_time_command = params.get("date_time_command", "date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", r"(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") hwclock_time_command = params.get("hwclock_time_command") hwclock_time_filter_re = params.get("hwclock_time_filter_re", r"(.+)") hwclock_time_format = params.get("hwclock_time_format", "%a %b %d %H:%M:%S %Y") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] test_type = params["timedrift_sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error.context("Check if ntp utils are host in system.", logging.info) try: utils.find_command("ntpdate") except ValueError: error.context("Install ntp utils `%s`." % (ntputil_install), logging.info) utils.run(ntputil_install) error.context("Sync host machine with clock server %s" % (clock_server), logging.info) utils.run("ntpdate %s" % (clock_server)) error.context("Check clock source on guest VM", logging.info) session = vm.wait_for_serial_login(timeout=login_timeout) out = session.cmd_output("cat /sys/devices/system/clocksource/" "clocksource0/current_clocksource") if guest_clock_source not in out: raise error.TestFail("Clock source %s missing in guest clock " "sources %s." % (guest_clock_source, out)) error.context("Get clock from host and guest VM using `date`", logging.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *before_date) error.context("Get clock from host and guest VM using `hwclock`", logging.info) before_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) logging.debug("hwclock: host time=%ss guest time=%ss", *before_hwclock) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](params, vm, session) else: raise error.TestNAError("Unable to found subwork %s in %s test file." % (sub_work, __file__)) session = vm.wait_for_serial_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *after_date) error.context("Get clock from host and guest VM using `hwclock`", logging.info) after_hwclock = utils_test.get_time(session, hwclock_time_command, hwclock_time_filter_re, hwclock_time_format) logging.debug("hwclock: host time=%ss guest time=%ss", *after_hwclock) if test_type == 'guest_suspend': date_diff = time_diff(before_date, after_date) hwclock_diff = time_diff(before_hwclock, after_hwclock) if date_diff > tolerance and hwclock_diff > tolerance: raise error.TestFail("hwclock %ss and date %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (hwclock_diff, date_diff, tolerance)) elif date_diff > tolerance: raise error.TestFail("date %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (date_diff, tolerance)) elif hwclock_diff > tolerance: raise error.TestFail("hwclock %ss difference is " "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (hwclock_diff, tolerance)) elif test_type == "guest_pause_resume": date_diff = time_diff(before_date, after_date) if date_diff > tolerance: raise error.TestFail("date %ss difference is" "'guest_time_after-guest_time_before'" " out of tolerance %ss" % (date_diff, tolerance))
def run(test, params, env): """ Time drift test (mainly for Windows guests): 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Run load on the guest and host. 4) Take a second time reading. 5) Stop the load and rest for a while. 6) Take a third time reading. 7) If the drift immediately after load is higher than a user- specified value (in %), fail. If the drift after the rest period is higher than a user-specified value, fail. :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ # Helper functions def set_cpu_affinity(pid, mask): """ Set the CPU affinity of all threads of the process with PID pid. Do this recursively for all child processes as well. :param pid: The process ID. :param mask: The CPU affinity mask. :return: A dict containing the previous mask for each thread. """ tids = decode_to_text( process.system_output("ps -L --pid=%s -o lwp=" % pid, verbose=False, ignore_status=True)).split() prev_masks = {} for tid in tids: prev_mask = decode_to_text( process.system_output("taskset -p %s" % tid, verbose=False)).split()[-1] prev_masks[tid] = prev_mask process.system("taskset -p %s %s" % (mask, tid), verbose=False) children = decode_to_text( process.system_output("ps --ppid=%s -o pid=" % pid, verbose=False, ignore_status=True)).split() for child in children: prev_masks.update(set_cpu_affinity(child, mask)) return prev_masks def restore_cpu_affinity(prev_masks): """ Restore the CPU affinity of several threads. :param prev_masks: A dict containing TIDs as keys and masks as values. """ for tid, mask in prev_masks.items(): process.system("taskset -p %s %s" % (mask, tid), verbose=False, ignore_status=True) vm = env.get_vm(params["main_vm"]) vm.verify_alive() boot_option_added = params.get("boot_option_added") boot_option_removed = params.get("boot_option_removed") if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_removed, args_added=boot_option_added) if params["os_type"] == "windows": utils_time.sync_timezone_win(vm) timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_serial_login(timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] guest_load_command = params["guest_load_command"] guest_load_stop_command = params["guest_load_stop_command"] host_load_command = params["host_load_command"] guest_load_instances = params["guest_load_instances"] host_load_instances = params["host_load_instances"] if not guest_load_instances and not host_load_instances: host_load_instances = cpu.total_cpus_count() guest_load_instances = vm.get_cpu_count() else: host_load_instances = int(host_load_instances) guest_load_instances = int(guest_load_instances) # CPU affinity mask for taskset cpu_mask = int(params.get("cpu_mask", "0xFF"), 16) load_duration = float(params.get("load_duration", "30")) rest_duration = float(params.get("rest_duration", "10")) drift_threshold = float(params.get("drift_threshold", "200")) drift_threshold_after_rest = float( params.get("drift_threshold_after_rest", "200")) test_duration = float(params.get("test_duration", "60")) interval_gettime = float(params.get("interval_gettime", "20")) guest_load_sessions = [] host_load_sessions = [] try: # Set the VM's CPU affinity prev_affinity = set_cpu_affinity(vm.get_shell_pid(), cpu_mask) try: # Open shell sessions with the guest logging.info("Starting load on guest...") for i in range(guest_load_instances): load_session = vm.wait_for_login(timeout=timeout) # Set output func to None to stop it from being called so we # can change the callback function and the parameters it takes # with no problems load_session.set_output_func(None) load_session.set_output_params(()) load_session.set_output_prefix("(guest load %d) " % i) load_session.set_output_func(logging.debug) guest_load_sessions.append(load_session) # Get time before load # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Run some load on the guest if params["os_type"] == "linux": for i, load_session in enumerate(guest_load_sessions): load_session.sendline(guest_load_command % i) else: for load_session in guest_load_sessions: load_session.sendline(guest_load_command) # Run some load on the host logging.info("Starting load on host...") for i in range(host_load_instances): load_cmd = aexpect.run_bg(host_load_command, output_func=logging.debug, output_prefix="(host load %d) " % i, timeout=0.5) host_load_sessions.append(load_cmd) # Set the CPU affinity of the load process pid = load_cmd.get_pid() set_cpu_affinity(pid, cpu_mask << i) # Sleep for a while (during load) logging.info("Sleeping for %s seconds...", load_duration) time.sleep(load_duration) start_time = time.time() while (time.time() - start_time) < test_duration: # Get time delta after load (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) time.sleep(interval_gettime) finally: logging.info("Cleaning up...") # Restore the VM's CPU affinity restore_cpu_affinity(prev_affinity) # Stop the guest load if guest_load_stop_command: session.cmd_output(guest_load_stop_command) # Close all load shell sessions for load_session in guest_load_sessions: load_session.close() for load_session in host_load_sessions: load_session.close() # Sleep again (rest) logging.info("Sleeping for %s seconds...", rest_duration) time.sleep(rest_duration) # Get time after rest (ht2, gt2) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: session.close() # remove flags add for this test. if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_added, args_added=boot_option_removed) # Report results host_delta_total = ht2 - ht0 guest_delta_total = gt2 - gt0 drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta logging.info("Total host duration including rest: %.2f", host_delta_total) logging.info("Total guest duration including rest: %.2f", guest_delta_total) logging.info("Total drift after rest: %.2f%%", drift_total) # Fail the test if necessary if abs(drift) > drift_threshold: test.fail("Time drift too large: %.2f%%" % drift) if abs(drift_total) > drift_threshold_after_rest: test.fail("Time drift too large after rest period: %.2f%%" % drift_total)
def run_timedrift_with_stop(test, params, env): """ Time drift test with stop/continue the guest: 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Stop the running of the guest 4) Sleep for a while 5) Continue the guest running 6) Take a second time reading. 7) If the drift (in seconds) is higher than a user specified value, fail. :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) sleep_time = int(params.get("sleep_time", 30)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() boot_option_added = params.get("boot_option_added") boot_option_removed = params.get("boot_option_removed") if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_removed, args_added=boot_option_added) session = vm.wait_for_login(timeout=login_timeout) # Collect test parameters: # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] drift_threshold = float(params.get("drift_threshold", "10")) drift_threshold_single = float(params.get("drift_threshold_single", "3")) stop_iterations = int(params.get("stop_iterations", 1)) stop_time = int(params.get("stop_time", 60)) stop_with_signal = params.get("stop_with_signal") == "yes" # Get guest's pid. pid = vm.get_pid() try: # Get initial time # (ht stands for host time, gt stands for guest time) (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Stop the guest for i in range(stop_iterations): # Get time before current iteration (ht0_, gt0_) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Run current iteration logging.info("Stop %s second: iteration %d of %d...", stop_time, (i + 1), stop_iterations) if stop_with_signal: logging.debug("Stop guest") os.kill(pid, signal.SIGSTOP) time.sleep(stop_time) logging.debug("Continue guest") os.kill(pid, signal.SIGCONT) else: vm.pause() time.sleep(stop_time) vm.resume() # Sleep for a while to wait the interrupt to be reinjected logging.info("Waiting for the interrupt to be reinjected ...") time.sleep(sleep_time) # Get time after current iteration (ht1_, gt1_) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report iteration results host_delta = ht1_ - ht0_ guest_delta = gt1_ - gt0_ drift = abs(host_delta - guest_delta) logging.info("Host duration (iteration %d): %.2f", (i + 1), host_delta) logging.info("Guest duration (iteration %d): %.2f", (i + 1), guest_delta) logging.info("Drift at iteration %d: %.2f seconds", (i + 1), drift) # Fail if necessary if drift > drift_threshold_single: raise error.TestFail("Time drift too large at iteration %d: " "%.2f seconds" % (i + 1, drift)) # Get final time (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) finally: if session: session.close() # remove flags add for this test. if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_added, args_added=boot_option_removed) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = abs(host_delta - guest_delta) logging.info("Host duration (%d stops): %.2f", stop_iterations, host_delta) logging.info("Guest duration (%d stops): %.2f", stop_iterations, guest_delta) logging.info("Drift after %d stops: %.2f seconds", stop_iterations, drift) # Fail if necessary if drift > drift_threshold: raise error.TestFail("Time drift too large after %d stops: " "%.2f seconds" % (stop_iterations, drift))
def run_timedrift_with_cpu_offline(test, params, env): """ Time drift test with vm's cpu offline/online: 1) Log into a guest (the vcpu num >= 2). 2) Take a time reading from the guest and host. 3) Set cpu offline in vm. 4) Take the time from the guest and host as given frequency. 5) Set cpu online, which was set offline before 5) Take the time from the guest and host as given frequency. 6) If the drift (in seconds) is higher than a user specified value, fail. :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() boot_option_added = params.get("boot_option_added") boot_option_removed = params.get("boot_option_removed") if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_removed, args_added=boot_option_added) session = vm.wait_for_login(timeout=login_timeout) # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") # Use this value to measure the drift. drift_threshold = params.get("drift_threshold") # The time interval to check vm's time interval_gettime = int(params.get("interval_gettime", 600)) test_duration = float(params.get("test_duration", "60")) try: # Get time before set cpu offine # (ht stands for host time, gt stands for guest time) error.context("get time before set cpu offline") (ht0, gt0) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Check cpu number error.context("check guest cpu number") smp = int(params.get("smp")) if smp < 2: raise error.TestError("The guest only has %d vcpu," "unsupport cpu offline" % smp) # Set cpu offline error.context("set cpu offline ") offline_cpu_cmd = params.get("offline_cpu_cmd") s, o = session.cmd_status_output(offline_cpu_cmd) if s != 0: logging.error(o) raise error.TestError("Failed set guest cpu offline") # Get time after set cpu offline error.context("get time after set cpu offline") (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) if abs(drift) > drift_threshold: raise error.TestFail("Time drift too large: %.2f%%" % drift) # Set cpu online again error.context("set cpu online") online_cpu_cmd = params.get("online_cpu_cmd") s, o = session.cmd_status_output(online_cpu_cmd) if s != 0: logging.error(o) raise error.TestError("Failed set guest cpu online") error.context("get time after set cpu online") start_time = time.time() while (time.time() - start_time) < test_duration: # Get time delta after set cpu online (ht1, gt1) = utils_test.get_time(session, time_command, time_filter_re, time_format) # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = 100.0 * (host_delta - guest_delta) / host_delta logging.info("Host duration: %.2f", host_delta) logging.info("Guest duration: %.2f", guest_delta) logging.info("Drift: %.2f%%", drift) time.sleep(interval_gettime) if abs(drift) > drift_threshold: raise error.TestFail("Time drift too large: %.2f%%" % drift) finally: session.close() # remove flags add for this test. if boot_option_added or boot_option_removed: utils_test.update_boot_option(vm, args_removed=boot_option_added, args_added=boot_option_removed)
def run_time_manage(test, params, env): """ Time manage test: 1) Generate stress in host. 2) Run atleast 15 vms with "driftfix=slew" option 3) Reboot the guest. 4) Repeat the step 3 for all guests and check whether the guest responds properly(not any watchdog reported). 5) TODO: Improve the way of checking the response and run some stress inside guest too. 6) Continue the step 4 for 10 iterations and record the guest/host realtime, calculate drift in time for each iterations. 7) Print the drift values for all sessions 8) TODO: Validate if the drift value has to be within defined value :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ # Checking the main vm is alive vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # Collect test parameters login_timeout = float(params.get("login_timeout", 240)) host_load_command = params["host_load_command"] host_load_kill_command = params["host_load_kill_command"] time_command = params["time_command"] time_filter_re = params["time_filter_re"] time_format = params["time_format"] # Intialize the variables itr = 0 num = 2 host_load_sessions = [] sessions = [session] prev_time = [] curr_time = [] timedrift = [] totaldrift = [] vmnames = ["virt-tests-vm1"] # Run some load on the host logging.info("Starting load on host.") host_load_sessions.append( aexpect.run_bg(host_load_command, output_func=logging.debug, output_prefix="host load ", timeout=0.5)) # Boot the VMs try: while num <= int(params["max_vms"]): # Clone vm according to the first one vm_name = "virt-tests-vm%d" % num vmnames.append(vm_name) vm_params = vm.params.copy() curr_vm = vm.clone(vm_name, vm_params) env.register_vm(vm_name, curr_vm) env_process.preprocess_vm(test, vm_params, env, vm_name) params["vms"] += " " + vm_name sessions.append(curr_vm.wait_for_login(timeout=login_timeout)) logging.info("Guest #%d booted up successfully", num) # Check whether all previous shell sessions are responsive error.context("checking responsiveness of the booted guest") for se in sessions: se.cmd(params["alive_test_cmd"]) num += 1 while itr <= int(params["max_itrs"]): for vmid, se in enumerate(sessions): # Get the respective vm object vmname = "virt-tests-vm%d" % (vmid + 1) vm = env.get_vm(vmname) # Run current iteration logging.info("Rebooting:vm%d iteration %d " % ((vmid + 1), itr)) se = vm.reboot(se, timeout=timeout) # Remember the current changed session sessions[vmid] = se error.context("checking responsiveness of guest") se.cmd(params["alive_test_cmd"]) if itr == 0: (ht0, gt0) = utils_test.get_time(se, time_command, time_filter_re, time_format) prev_time.append((ht0, gt0)) else: (ht1, gt1) = utils_test.get_time(se, time_command, time_filter_re, time_format) curr_time.append((ht1, gt1)) if itr != 0: for i in range(int(params["max_vms"])): hdelta = curr_time[i][0] - prev_time[i][0] gdelta = curr_time[i][1] - prev_time[i][1] drift = "%.2f" % (100.0 * (hdelta - gdelta) / hdelta) timedrift.append(drift) totaldrift.append(timedrift) prev_time = curr_time timedrift = [] curr_time = [] # Wait for some time before next iteration time.sleep(30) itr += 1 logging.info("The time drift values for all VM sessions/iterations") logging.info("VM-Name:%s" % vmnames) for idx, value in enumerate(totaldrift): logging.info("itr-%2d:%s" % (idx + 1, value)) finally: for se in sessions: # Closing all the sessions. se.close() logging.info("killing load on host.") host_load_sessions.append( aexpect.run_bg(host_load_kill_command, output_func=logging.debug, output_prefix="host load kill", timeout=0.5))
def run(test, params, env): """ Timer device boot guest: 1) Sync the host system time with ntp server 2) Add some load on host (Optional) 3) Boot the guest with specific clock source 4) Check the clock source currently used on guest 5) Do some file operation on guest (Optional) 6) Check the system time on guest and host (Optional) 7) Check the hardware time on guest and host (Optional) 8) Sleep period of time before reboot (Optional) 9) Reboot guest (Optional) 10) Check the system time on guest and host (Optional) 11) Check the hardware time on guest and host (Optional) :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def verify_guest_clock_source(session, expected): error_context.context("Check the current clocksource in guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if expected not in session.cmd(cmd): test.fail("Guest didn't use '%s' clocksource" % expected) error_context.context("Sync the host system time with ntp server", logging.info) process.system("ntpdate clock.redhat.com") timerdevice_host_load_cmd = params.get("timerdevice_host_load_cmd") if timerdevice_host_load_cmd: error_context.context("Add some load on host", logging.info) process.system(timerdevice_host_load_cmd, shell=True) host_load_stop_cmd = params["timerdevice_host_load_stop_cmd"] funcatexit.register(env, params["type"], _system, host_load_stop_cmd) error_context.context("Boot a guest with kvm-clock", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) timerdevice_clksource = params.get("timerdevice_clksource") if timerdevice_clksource: try: verify_guest_clock_source(session, timerdevice_clksource) except Exception: clksrc = timerdevice_clksource error_context.context("Shutdown guest") vm.destroy() env.unregister_vm(vm.name) error_context.context("Update guest kernel cli to '%s'" % clksrc, logging.info) image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) grub_file = params.get("grub_file", "/boot/grub2/grub.cfg") kernel_cfg_pattern = params.get("kernel_cfg_pos_reg", r".*vmlinuz-\d+.*") disk_obj = utils_disk.GuestFSModiDisk(image_filename) kernel_cfg_original = disk_obj.read_file(grub_file) try: logging.warn("Update the first kernel entry to" " '%s' only" % clksrc) kernel_cfg = re.findall(kernel_cfg_pattern, kernel_cfg_original)[0] except IndexError as detail: test.error("Couldn't find the kernel config, regex" " pattern is '%s', detail: '%s'" % (kernel_cfg_pattern, detail)) if "clocksource=" in kernel_cfg: kernel_cfg_new = re.sub(r"clocksource=.*?\s", "clocksource=%s" % clksrc, kernel_cfg) else: kernel_cfg_new = "%s %s" % (kernel_cfg, "clocksource=%s" % clksrc) disk_obj.replace_image_file_content(grub_file, kernel_cfg, kernel_cfg_new) error_context.context("Boot the guest", logging.info) vm_name = params["main_vm"] cpu_model_flags = params.get("cpu_model_flags") params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock" env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) error_context.context("Check the current clocksource in guest", logging.info) verify_guest_clock_source(session, clksrc) error_context.context("Kill all ntp related processes") session.cmd("pkill ntp; true") if params.get("timerdevice_file_operation") == "yes": error_context.context("Do some file operation on guest", logging.info) session.cmd("dd if=/dev/zero of=/tmp/timer-test-file bs=1M count=100") return # Command to run to get the current time time_command = params["time_command"] # Filter which should match a string to be passed to time.strptime() time_filter_re = params["time_filter_re"] # Time format for time.strptime() time_format = params["time_format"] timerdevice_drift_threshold = params.get("timerdevice_drift_threshold", 3) error_context.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error_context.context( "Check the hardware time on guest and host", logging.info) host_time = process.system_output(get_hw_time_cmd, shell=True) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's hardware time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) if params.get("timerdevice_reboot_test") == "yes": sleep_time = params.get("timerdevice_sleep_time") if sleep_time: error_context.context("Sleep '%s' secs before reboot" % sleep_time, logging.info) sleep_time = int(sleep_time) time.sleep(sleep_time) session = vm.reboot() error_context.context("Check the system time on guest and host", logging.info) (host_time, guest_time) = utils_test.get_time(session, time_command, time_filter_re, time_format) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's system time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time)) get_hw_time_cmd = params.get("get_hw_time_cmd") if get_hw_time_cmd: error_context.context( "Check the hardware time on guest and host", logging.info) host_time = process.system_output(get_hw_time_cmd, shell=True) guest_time = session.cmd(get_hw_time_cmd) drift = abs(float(host_time) - float(guest_time)) if drift > timerdevice_drift_threshold: test.fail("The guest's hardware time is different with" " host's. Host time: '%s', guest time:" " '%s'" % (host_time, guest_time))