def test_args_zipl(self, *mocks):
     update_boot_option(self.vm,
                        args_added="3",
                        need_reboot=False,
                        guest_arch_name="s390x")
     utils_test.check_kernel_cmdline.assert_called_once()
     self.assertEqual(2, self.session.cmd_status_output.call_count)
Esempio n. 2
0
def run(test, params, env):
    """
    support Virtual SPEC_CTRL inside guest

    1. check the 'v_spec_ctrl' on supported host
    2. add guest kernel command line 'spec_store_bypass_disable=on'
    3. verify the guest sets the spec ctrl properly on all the cpus.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    flags = params["flags"]
    check_host_flags = params.get_boolean("check_host_flags")
    if check_host_flags:
        check_cpu_flags(params, flags, test)

    supported_models = params.get("supported_models", "")
    cpu_model = params.get("cpu_model")
    if not cpu_model:
        cpu_model = cpu.get_qemu_best_cpu_model(params)
    if cpu_model not in supported_models.split():
        test.cancel("'%s' doesn't support this test case" % cpu_model)

    params["start_vm"] = "yes"
    vm_name = params['main_vm']
    env_process.preprocess_vm(test, params, env, vm_name)

    proc_cmdline = params["proc_cmdline"]
    vm = env.get_vm(vm_name)
    session = vm.wait_for_login()
    boot_option = params["boot_option"]
    check_output = str(session.cmd(proc_cmdline, timeout=60)).split()
    if boot_option and boot_option not in check_output:
        error_context.context("Add '%s' to guest" % boot_option, test.log.info)
        update_boot_option(vm, args_added=boot_option)
        session = vm.wait_for_login()

    test_dir = params["test_dir"]
    source_file = params["source_file"]
    src_msr = os.path.join(data_dir.get_deps_dir(), source_file)
    vm.copy_files_to(src_msr, test_dir)
    guest_dir = params["guest_dir"]
    compile_cmd = params["compile_cmd"]
    try:
        session.cmd(compile_cmd % guest_dir)
        check_msr = 'cd %s && ' % guest_dir + params["check_msr"]
        result = session.cmd_output(check_msr)
        nums_vcpus = session.cmd_output("grep processor /proc/cpuinfo -c")
        if result != nums_vcpus:
            test.fail("verify the guest sets the spec ctrl failed.")
    finally:
        session.cmd("rm -rf %s/msr* %s/master*" % (test_dir, test_dir))
        session.close()
        vm.verify_kernel_crash()
        if boot_option and boot_option not in check_output:
            update_boot_option(vm, args_removed=boot_option)
    def test_cmd_fail(self, *mocks):
        self.session.cmd_status_output.return_value = [
            1, self.some_error_message
        ]

        with self.assertRaises(exceptions.TestError) as e:
            update_boot_option(self.vm, args_added="3", need_reboot=False)
        self.assertIsNotNone(e.exception.args[0])
        LOG.error.assert_called_with(self.some_error_message)
Esempio n. 4
0
def run(test, params, env):
    """
    Test to disabling radix MMU mode on guest.
    Steps:
    1) There are two options, boot up a native(radix)guest or HPT guest.
    2) Check the MMU mode in the guest.
    3) Adding disable radix to guest's kernel line directly then reboot guest.
    4) Check again the MMU mode in the guest.
    5) Check guest call trace in dmesg log.


    :params test: QEMU test object.
    :params params: Dictionary with the test parameters.
    :params env: Dictionary with test environment.
    """
    def cpu_info_match(pattern):
        match = re.search(pattern, session.cmd_output("cat /proc/cpuinfo"))
        return True if match else False

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login()

    error_context.context("Check the MMU mode.", logging.info)
    if cpu_info_match('MMU'):
        if cpu_info_match('POWER9'):
            if cpu_info_match('Radix') is False:
                test.fail("mmu mode is not Radix, doesn't meet expectations.")
        else:
            if cpu_info_match('Hash') is False:
                test.fail("mmu mode is not Hash, doesn't meet expectations.")
    else:
        if params["mmu_option"] == 'yes':
            test.fail("There should be MMU mode.")
    utils_test.update_boot_option(vm, args_added="disable_radix")
    session = vm.wait_for_login()

    error_context.context("Check the MMU mode.", logging.info)
    if cpu_info_match('MMU'):
        if cpu_info_match('Hash') is False:
            test.fail("mmu mode is not Hash, mmu mode disabled failure.")
    else:
        if params["mmu_option"] == 'yes':
            test.fail("There should be MMU mode.")

    vm.verify_dmesg()
Esempio n. 5
0
def update_clksrc(vm, clksrc=None):
    """
    Update linux guest's clocksource and re-boot guest

    :params vm: Virtual machine for vm
    :params clksrc: Expected clocksource
    """
    params = vm.get_params()
    if 'fedora' in params["os_variant"] and clksrc and clksrc != 'kvm-clock':
        cpu_model_flags = params.get["cpu_model_flags"]
        params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock"

    error_context.context("Update guest kernel cli to '%s'" %
                          (clksrc or "kvm-clock"),
                          logging.info)
    if clksrc:
        boot_option_added = "clocksource=%s" % clksrc
        utils_test.update_boot_option(vm, args_added=boot_option_added)
Esempio n. 6
0
def update_clksrc(vm, clksrc=None):
    """
    Update linux guest's clocksource and re-boot guest

    :params vm: Virtual machine for vm
    :params clksrc: Expected clocksource, 'kvm-clock' by default
    """
    params = vm.get_params()
    if 'fedora' in params["os_variant"] and clksrc and clksrc != 'kvm-clock':
        cpu_model_flags = params.get["cpu_model_flags"]
        params["cpu_model_flags"] = cpu_model_flags + ",-kvmclock"

    error_context.context("Update guest kernel cli to '%s'" %
                          (clksrc or "kvm-clock"),
                          logging.info)
    utils_test.update_boot_option(vm, args_removed="clocksource=*")
    if clksrc and clksrc != 'kvm-clock':
        boot_option_added = "clocksource=%s" % clksrc
        utils_test.update_boot_option(vm, args_added=boot_option_added)
Esempio n. 7
0
 def start_test(self):
     operation = self.params["operation"]
     target_mems = self.params["target_mems"]
     stage = self.params.get("stage", "before")
     login_timeout = int(self.params.get("login_timeout", 360))
     sub_test_runner = (
         stage == 'during' and [
             self.run_background_test] or [
             self.run_sub_test])[0]
     func = getattr(self, "%s_memory" % operation)
     if not callable(func):
         self.test.error("Unsupported memory operation '%s'" % operation)
     vm = self.env.get_vm(self.params["main_vm"])
     vm.wait_for_login(timeout=login_timeout)
     bootup_time = time.time() - vm.start_time
     utils_test.update_boot_option(vm, args_added="movable_node")
     try:
         if stage != "after":
             sub_test = sub_test_runner()
             if self.params.get("sub_type") == "boot":
                 time.sleep(bootup_time/2)
             for target_mem in target_mems.split():
                 func(vm, target_mem)
                 self.check_memory(vm)
         else:
             for target_mem in target_mems.split():
                 func(vm, target_mem)
                 self.check_memory(vm)
             sub_test = sub_test_runner()
         if stage == "during":
             sub_test.join(timeout=3600)
         vm = self.env.get_vm(self.params["main_vm"])
         vm.reboot()
     finally:
         try:
             self.restore_memory(
                 vm, self.env.get_vm(
                     self.params['main_vm']))
         except Exception as details:
             logging.warn("Error happen when restore vm: %s" % details)
         self.close_sessions()
Esempio n. 8
0
    def start_test(self):
        """
        Prepare required test params, then for scalability test, hotplug
        memory 256 times, then unplug 256 times. Otherwise, repeat hotplug
        and unplug in turn for 256 times. This is test entry.
        """
        times = int(self.params["repeat_times"])
        target_mems = []
        for i in range(times):
            target_mems.append("mem%s" % i)
        vm = self.env.get_vm(self.params["main_vm"])
        session = vm.wait_for_login()
        if self.params.get('os_type') == 'linux':
            arg = "movable_node"
            utils_test.update_boot_option(vm, args_added=arg)
        original_mem = self.get_guest_total_mem(vm)
        if self.params["test_type"] == "scalability_test":
            error_context.context("Repeat hotplug memory for %s times" % times,
                                  logging.info)
            self.repeat_hotplug(vm, target_mems)
            if self.params.get('os_type') == 'linux':
                error_context.context(
                    "Repeat unplug memory for %s times" % times, logging.info)
                self.repeat_unplug(vm, target_mems)
        else:
            for target_mem in target_mems:
                error_context.context(
                    "Hotplug and unplug memory %s" % target_mem, logging.info)
                self.hotplug_memory(vm, target_mem)
                self.unplug_memory(vm, target_mem)

        if self.params.get('os_type') == 'linux':
            current_mem = self.get_guest_total_mem(vm)
            if current_mem != original_mem:
                self.test.fail("Guest memory changed about repeat"
                               " hotpug/unplug memory %d times" % times)
        vm.verify_kernel_crash()
        session.close()
Esempio n. 9
0
 def start_test(self):
     operation = self.params["operation"]
     target_mems = self.params["target_mems"]
     stage = self.params.get("stage", "before")
     login_timeout = int(self.params.get("login_timeout", 360))
     sub_test_runner = (stage == 'during' and [self.run_background_test]
                        or [self.run_sub_test])[0]
     func = getattr(self, "%s_memory" % operation)
     if not callable(func):
         self.test.error("Unsupported memory operation '%s'" % operation)
     vm = self.env.get_vm(self.params["main_vm"])
     vm.wait_for_login(timeout=login_timeout)
     bootup_time = time.time() - vm.start_time
     utils_test.update_boot_option(vm, args_added="movable_node")
     try:
         if stage != "after":
             sub_test = sub_test_runner()
             if self.params.get("sub_type") == "boot":
                 time.sleep(bootup_time / 2)
             for target_mem in target_mems.split():
                 func(vm, target_mem)
                 self.check_memory(vm)
         else:
             for target_mem in target_mems.split():
                 func(vm, target_mem)
                 self.check_memory(vm)
             sub_test = sub_test_runner()
         if stage == "during":
             sub_test.join(timeout=3600)
         vm = self.env.get_vm(self.params["main_vm"])
         vm.reboot()
     finally:
         try:
             self.restore_memory(vm,
                                 self.env.get_vm(self.params['main_vm']))
         except Exception as details:
             logging.warn("Error happen when restore vm: %s" % details)
         self.close_sessions()
Esempio n. 10
0
    def start_test(self):
        """
        Prepare required test params, then for scalability test, hotplug
        memory 256 times, then unplug 256 times. Otherwise, repeat hotplug
        and unplug in turn for 256 times. This is test entry.
        """
        times = int(self.params["repeat_times"])
        target_mems = []
        for i in range(times):
            target_mems.append("mem%s" % i)
        vm = self.env.get_vm(self.params["main_vm"])
        session = vm.wait_for_login()
        if self.params.get('os_type') == 'linux':
            arg = "movable_node"
            utils_test.update_boot_option(vm, args_added=arg)
        original_mem = self.get_guest_total_mem(vm)
        if self.params["test_type"] == "scalability_test":
            error_context.context("Repeat hotplug memory for %s times"
                                  % times, logging.info)
            self.repeat_hotplug(vm, target_mems)
            if self.params.get('os_type') == 'linux':
                error_context.context("Repeat unplug memory for %s times"
                                      % times, logging.info)
                self.repeat_unplug(vm, target_mems)
        else:
            for target_mem in target_mems:
                error_context.context("Hotplug and unplug memory %s"
                                      % target_mem, logging.info)
                self.hotplug_memory(vm, target_mem)
                self.unplug_memory(vm, target_mem)

        if self.params.get('os_type') == 'linux':
            current_mem = self.get_guest_total_mem(vm)
            if current_mem != original_mem:
                self.test.fail("Guest memory changed about repeat"
                               " hotpug/unplug memory %d times" % times)
        vm.verify_kernel_crash()
        session.close()
Esempio n. 11
0
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):
    """
    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))
Esempio n. 13
0
def run(test, params, env):
    """
    Test send-key command, include all types of codeset and sysrq

    For normal sendkey test, we create a file to check the command
    execute by send-key. For sysrq test, check the /var/log/messages
    in RHEL or /var/log/syslog in Ubuntu and guest status
    """

    if not virsh.has_help_command('send-key'):
        test.cancel("This version of libvirt does not support the send-key "
                    "test")

    vm_name = params.get("main_vm", "avocado-vt-vm1")
    status_error = ("yes" == params.get("status_error", "no"))
    keystrokes = params.get("sendkey", "")
    codeset = params.get("codeset", "")
    holdtime = params.get("holdtime", "")
    sysrq_test = ("yes" == params.get("sendkey_sysrq", "no"))
    sleep_time = int(params.get("sendkey_sleeptime", 5))
    readonly = params.get("readonly", False)
    username = params.get("username")
    password = params.get("password")
    create_file = params.get("create_file_name")
    uri = params.get("virsh_uri")
    simultaneous = params.get("sendkey_simultaneous", "yes") == "yes"
    unprivileged_user = params.get('unprivileged_user')
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            test.cancel("API acl test not supported in current libvirt "
                        "version.")

    def send_line(send_str):
        """
        send string to guest with send-key and end with Enter
        """
        for send_ch in list(send_str):
            virsh.sendkey(vm_name, "KEY_%s" % send_ch.upper(),
                          ignore_status=False)

        virsh.sendkey(vm_name, "KEY_ENTER",
                      ignore_status=False)

    vm = env.get_vm(vm_name)
    vm.wait_for_login().close()

    # Boot the guest in text only mode so that send-key commands would succeed
    # in creating a file
    try:
        utils_test.update_boot_option(vm, args_added="3")
    except Exception as info:
        test.error(info)

    session = vm.wait_for_login()
    if sysrq_test:
        # In postprocess of previous testcase would pause and resume the VM
        # that would change the domstate to running (unpaused) and cause
        # sysrq reboot testcase to fail as the domstate persist across reboot
        # so it is better to destroy and start VM before the test starts
        if "KEY_B" in keystrokes:
            cmd_result = virsh.domstate(vm_name, '--reason', ignore_status=True)
            if "unpaused" in cmd_result.stdout.strip():
                vm.destroy()
                vm.start()
                session = vm.wait_for_login()
        LOG_FILE = "/var/log/messages"
        if "ubuntu" in vm.get_distro().lower():
            LOG_FILE = "/var/log/syslog"
        # Is 'rsyslog' installed on guest? It'll be what writes out
        # to LOG_FILE
        if not utils_package.package_install("rsyslog", session):
            test.fail("Fail to install rsyslog, make sure that you have "
                      "usable repo in guest")

        # clear messages, restart rsyslog, and make sure it's running
        session.cmd("echo '' > %s" % LOG_FILE)
        session.cmd("service rsyslog restart")
        ps_stat = session.cmd_status("ps aux |grep rsyslog")
        if ps_stat != 0:
            test.fail("rsyslog is not running in guest")

        # enable sysrq
        session.cmd("echo 1 > /proc/sys/kernel/sysrq")

    # make sure the environment is clear
    if create_file is not None:
        session.cmd("rm -rf %s" % create_file)

    try:
        # wait for tty started
        tty_stat = "ps aux|grep tty"
        timeout = 60
        while timeout >= 0 and \
                session.get_command_status(tty_stat) != 0:
            time.sleep(1)
            timeout = timeout - 1
        if timeout < 0:
            test.fail("Can not wait for tty started in 60s")

        # send user and passwd to guest to login
        send_line(username)
        time.sleep(2)
        send_line(password)
        time.sleep(2)

        if sysrq_test or simultaneous:
            output = virsh.sendkey(vm_name, keystrokes, codeset=codeset,
                                   holdtime=holdtime, readonly=readonly,
                                   unprivileged_user=unprivileged_user,
                                   uri=uri)
        else:
            # If multiple keycodes are specified, they are all sent
            # simultaneously to the guest, and they may be received
            # in random order. If you need distinct keypresses, you
            # must use multiple send-key invocations.
            for keystroke in keystrokes.split():
                output = virsh.sendkey(vm_name, keystroke, codeset=codeset,
                                       holdtime=holdtime, readonly=readonly,
                                       unprivileged_user=unprivileged_user,
                                       uri=uri)
                if output.exit_status:
                    test.fail("Failed to send key %s to guest: %s" %
                              (keystroke, output.stderr))
        time.sleep(sleep_time)
        if output.exit_status != 0:
            if status_error:
                logging.info("Failed to sendkey to guest as expected, Error:"
                             "%s.", output.stderr)
                return
            else:
                test.fail("Failed to send key to guest, Error:%s." %
                          output.stderr)
        elif status_error:
            test.fail("Expect fail, but succeed indeed.")

        if create_file is not None:
            # check if created file exist
            cmd_ls = "ls %s" % create_file
            sec_status, sec_output = session.get_command_status_output(cmd_ls)
            if sec_status == 0:
                logging.info("Succeed to create file with send key")
            else:
                test.fail("Fail to create file with send key, Error:%s" %
                          sec_output)
        elif sysrq_test:
            # check LOG_FILE info according to different key

            # Since there's no guarantee when messages will be written
            # we'll do a check and wait loop for up to 60 seconds
            timeout = 60
            while timeout >= 0:
                if "KEY_H" in keystrokes:
                    cmd = "cat %s | grep 'SysRq.*HELP'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                elif "KEY_M" in keystrokes:
                    cmd = "cat %s | grep 'SysRq.*Show Memory'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                elif "KEY_T" in keystrokes:
                    cmd = "cat %s | grep 'SysRq.*Show State'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                    # Sometimes SysRq.*Show State string missed in LOG_FILE
                    # as a fall back check for runnable tasks logged
                    if get_status != 0:
                        cmd = "cat %s | grep 'runnable tasks:'" % LOG_FILE
                        get_status = session.cmd_status(cmd)

                elif "KEY_B" in keystrokes:
                    session = vm.wait_for_login()
                    result = virsh.domstate(vm_name, '--reason', ignore_status=True)
                    output = result.stdout.strip()
                    logging.debug("The guest state: %s", output)
                    if not output.count("booted"):
                        get_status = 1
                    else:
                        get_status = 0
                        session.close()

                if get_status == 0:
                    timeout = -1
                else:
                    session.cmd("echo \"virsh sendkey waiting\" >> %s" % LOG_FILE)
                    time.sleep(1)
                    timeout = timeout - 1

            if get_status != 0:
                test.fail("SysRq does not take effect in guest, keystrokes is "
                          "%s" % keystrokes)
            else:
                logging.info("Succeed to send SysRq command")
        else:
            test.fail("Test cfg file invalid: either sysrq_params or "
                      "create_file_name must be defined")

    finally:
        if create_file is not None:
            session = vm.wait_for_login()
            session.cmd("rm -rf %s" % create_file)
        session.close()
Esempio n. 14
0
def run(test, params, env):
    """
    Test send-key command, include all types of codeset and sysrq

    For normal sendkey test, we create a file to check the command
    execute by send-key. For sysrq test, check the /var/log/messages
    in RHEL or /var/log/syslog in Ubuntu and guest status
    """

    if not virsh.has_help_command('send-key'):
        test.cancel("This version of libvirt does not support the send-key "
                    "test")

    vm_name = params.get("main_vm", "avocado-vt-vm1")
    status_error = ("yes" == params.get("status_error", "no"))
    keystrokes = params.get("sendkey", "")
    codeset = params.get("codeset", "")
    holdtime = params.get("holdtime", "")
    hold_timeout = eval(params.get("hold_timeout", "1"))
    sysrq_test = ("yes" == params.get("sendkey_sysrq", "no"))
    sleep_time = int(params.get("sendkey_sleeptime", 5))
    readonly = params.get("readonly", False)
    username = params.get("username")
    password = params.get("password")
    create_file = params.get("create_file_name")
    uri = params.get("virsh_uri")
    simultaneous = params.get("sendkey_simultaneous", "yes") == "yes"
    unprivileged_user = params.get('unprivileged_user')
    is_crash = ("yes" == params.get("is_crash", "no"))
    add_panic_device = ("yes" == params.get("add_panic_device", "yes"))
    need_keyboard_device = ("yes" == params.get("need_keyboard_device", "yes"))
    panic_model = params.get('panic_model', 'isa')
    force_vm_boot_text_mode = ("yes" == params.get("force_vm_boot_text_mode",
                                                   "yes"))
    crash_dir = "/var/crash"
    if unprivileged_user:
        if unprivileged_user.count('EXAMPLE'):
            unprivileged_user = '******'

    if not libvirt_version.version_compare(1, 1, 1):
        if params.get('setup_libvirt_polkit') == 'yes':
            test.cancel("API acl test not supported in current libvirt "
                        "version.")

    def send_line(send_str):
        """
        send string to guest with send-key and end with Enter
        """
        for send_ch in list(send_str):
            virsh.sendkey(vm_name,
                          "KEY_%s" % send_ch.upper(),
                          ignore_status=False)

        virsh.sendkey(vm_name, "KEY_ENTER", ignore_status=False)

    def add_keyboard_device(vm_name):
        """
        Add keyboard to guest if guest doesn't have

        :params: vm_name: the guest name
        """
        inputs = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)\
            .get_devices(device_type="input")
        for input_device in inputs:
            if input_device.type_name == "keyboard":
                logging.debug("Guest already has a keyboard device")
                return

        kbd = Input("keyboard")
        kbd.input_bus = "virtio"
        logging.debug("Add keyboard device %s" % kbd)
        result = virsh.attach_device(vm_name, kbd.xml)
        if result.exit_status:
            test.error("Failed to add keyboard device")

    vm = env.get_vm(vm_name)
    # Part of sysrq tests need keyboard device otherwise the sysrq cmd doesn't
    # work. Refer to BZ#1526862
    if need_keyboard_device:
        add_keyboard_device(vm_name)
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    vm.wait_for_login().close()

    if force_vm_boot_text_mode:
        # Boot the guest in text only mode so that send-key commands would succeed
        # in creating a file
        try:
            utils_test.update_boot_option(
                vm, args_added="3", guest_arch_name=params.get('vm_arch_name'))
        except Exception as info:
            test.error(info)

    session = vm.wait_for_login()
    if sysrq_test:
        # In postprocess of previous testcase would pause and resume the VM
        # that would change the domstate to running (unpaused) and cause
        # sysrq reboot testcase to fail as the domstate persist across reboot
        # so it is better to destroy and start VM before the test starts
        if "KEY_B" in keystrokes:
            cmd_result = virsh.domstate(vm_name,
                                        '--reason',
                                        ignore_status=True)
            if "unpaused" in cmd_result.stdout.strip():
                vm.destroy()
                vm.start()
                session = vm.wait_for_login()
        if is_crash:
            session.cmd("rm -rf {0}; mkdir {0}".format(crash_dir))
            libvirt.update_on_crash(vm_name, "destroy")
            if add_panic_device:
                libvirt.add_panic_device(vm_name, model=panic_model)
            if not vm.is_alive():
                vm.start()
            session = vm.wait_for_login()
        LOG_FILE = "/var/log/messages"
        if "ubuntu" in vm.get_distro().lower():
            LOG_FILE = "/var/log/syslog"
        # Is 'rsyslog' installed on guest? It'll be what writes out
        # to LOG_FILE
        if not utils_package.package_install("rsyslog", session):
            test.fail("Fail to install rsyslog, make sure that you have "
                      "usable repo in guest")

        # clear messages, restart rsyslog, and make sure it's running
        session.cmd("echo '' > %s" % LOG_FILE)
        # check the result of restart rsyslog
        status, output = session.cmd_status_output("service rsyslog restart")
        if status:
            # To avoid 'Exec format error'
            utils_package.package_remove("rsyslog", session)
            utils_package.package_install("rsyslog", session)
            # if rsyslog.service is masked, need to unmask rsyslog
            if "Unit rsyslog.service is masked" in output:
                session.cmd("systemctl unmask rsyslog")
            session.cmd("echo '' > %s" % LOG_FILE)
            session.cmd("service rsyslog restart")
        ps_stat = session.cmd_status("ps aux |grep rsyslog")
        if ps_stat != 0:
            test.fail("rsyslog is not running in guest")

        # enable sysrq
        session.cmd("echo 1 > /proc/sys/kernel/sysrq")

    # make sure the environment is clear
    if create_file is not None:
        session.cmd("rm -rf %s" % create_file)

    try:
        # wait for tty started
        tty_stat = "ps aux|grep tty"
        timeout = 60
        while timeout >= 0 and \
                session.get_command_status(tty_stat) != 0:
            time.sleep(1)
            timeout = timeout - 1
        if timeout < 0:
            test.fail("Can not wait for tty started in 60s")

        # send user and passwd to guest to login
        send_line(username)
        time.sleep(2)
        send_line(password)
        time.sleep(2)

        if sysrq_test or simultaneous:
            output = virsh.sendkey(vm_name,
                                   keystrokes,
                                   codeset=codeset,
                                   holdtime=holdtime,
                                   readonly=readonly,
                                   unprivileged_user=unprivileged_user,
                                   uri=uri)
        else:
            # If multiple keycodes are specified, they are all sent
            # simultaneously to the guest, and they may be received
            # in random order. If you need distinct keypresses, you
            # must use multiple send-key invocations.
            for keystroke in keystrokes.split():
                output = virsh.sendkey(vm_name,
                                       keystroke,
                                       codeset=codeset,
                                       holdtime=holdtime,
                                       readonly=readonly,
                                       unprivileged_user=unprivileged_user,
                                       uri=uri)
                if output.exit_status:
                    test.fail("Failed to send key %s to guest: %s" %
                              (keystroke, output.stderr))
        time.sleep(sleep_time)
        if output.exit_status != 0:
            if status_error:
                logging.info(
                    "Failed to sendkey to guest as expected, Error:"
                    "%s.", output.stderr)
                return
            else:
                test.fail("Failed to send key to guest, Error:%s." %
                          output.stderr)
        elif status_error:
            test.fail("Expect fail, but succeed indeed.")

        if create_file is not None:
            # check if created file exist
            cmd_ls = "ls %s" % create_file
            if not wait.wait_for(
                    lambda: session.get_command_status_output(cmd_ls),
                    hold_timeout,
                    step=5):
                test.fail("Fail to create file with send key")
            logging.info("Succeed to create file with send key")
        elif sysrq_test:
            # check LOG_FILE info according to different key

            # Since there's no guarantee when messages will be written
            # we'll do a check and wait loop for up to 60 seconds
            timeout = 60
            while timeout >= 0:
                if "KEY_H" in keystrokes:
                    cmd = "cat %s | grep -i 'SysRq.*HELP'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                elif "KEY_M" in keystrokes:
                    cmd = "cat %s | grep -i 'SysRq.*Show Memory'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                elif "KEY_T" in keystrokes:
                    cmd = "cat %s | grep -i 'SysRq.*Show State'" % LOG_FILE
                    get_status = session.cmd_status(cmd)
                    # Sometimes SysRq.*Show State string missed in LOG_FILE
                    # as a fall back check for runnable tasks logged
                    if get_status != 0:
                        cmd = "cat %s | grep 'runnable tasks:'" % LOG_FILE
                        get_status = session.cmd_status(cmd)

                elif "KEY_B" in keystrokes:
                    session = vm.wait_for_login()
                    result = virsh.domstate(vm_name,
                                            '--reason',
                                            ignore_status=True)
                    output = result.stdout.strip()
                    logging.debug("The guest state: %s", output)
                    if not output.count("booted"):
                        get_status = 1
                    else:
                        get_status = 0
                        session.close()
                # crash
                elif is_crash:
                    dom_state = virsh.domstate(vm_name,
                                               "--reason").stdout.strip()
                    logging.debug("domain state is %s" % dom_state)
                    if "crashed" in dom_state:
                        get_status = 0
                    else:
                        get_status = 1

                if get_status == 0:
                    timeout = -1
                else:
                    if not is_crash:
                        session.cmd("echo \"virsh sendkey waiting\" >> %s" %
                                    LOG_FILE)
                    time.sleep(1)
                    timeout = timeout - 1

            if get_status != 0:
                test.fail("SysRq does not take effect in guest, keystrokes is "
                          "%s" % keystrokes)
            else:
                logging.info("Succeed to send SysRq command")
        else:
            test.fail("Test cfg file invalid: either sysrq_params or "
                      "create_file_name must be defined")

    finally:
        if create_file is not None:
            session = vm.wait_for_login()
            session.cmd("rm -rf %s" % create_file)
        session.close()
        vmxml_backup.sync()
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)
Esempio n. 16
0
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()

    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"]
    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 = 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"))
    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.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):
                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)

            # 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:
        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)
Esempio n. 17
0
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(test, params, env):
    """
    Timer device check guest after update kernel line without kvmclock:

    1) Boot a guest with kvm-clock
    2) Check the current clocksource in guest
    3) Check the available clocksource in guest
    4) Update "clocksource=" parameter in guest kernel cli
    5) Boot guest system
    6) Check the current clocksource in guest

    :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):
        if expected not in session.cmd(cur_clk):
            test.fail("Guest didn't use '%s' clocksource" % expected)

    error_context.context("Boot a guest with kvm-clock", test.log.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)

    error_context.context("Check the current clocksource in guest",
                          test.log.info)
    cur_clk = params["cur_clk"]
    if "kvm-clock" not in session.cmd(cur_clk):
        error_context.context("Update guest kernel cli to kvm-clock",
                              test.log.info)
        utils_time.update_clksrc(vm, clksrc="kvm-clock")
        session = vm.wait_for_login(timeout=timeout)
        verify_guest_clock_source(session, "kvm-clock")

    error_context.context("Check the available clocksource in guest",
                          test.log.info)
    avl_clk = params["avl_clk"]
    try:
        available_clksrc_list = session.cmd(avl_clk).split()
    except Exception as detail:
        test.fail("Couldn't get guest available clock source."
                  " Detail: '%s'" % detail)
    try:
        for avl_clksrc in available_clksrc_list:
            if avl_clksrc == "kvm-clock":
                continue
            error_context.context(
                "Update guest kernel cli to '%s'" % avl_clksrc, test.log.info)
            utils_time.update_clksrc(vm, clksrc=avl_clksrc)
            session = vm.wait_for_login(timeout=timeout)
            error_context.context("Check the current clocksource in guest",
                                  test.log.info)
            verify_guest_clock_source(session, avl_clksrc)
    finally:
        error_context.context("Restore guest kernel cli", test.log.info)
        proc_cmdline = "cat /proc/cmdline"
        check_output = str(session.cmd(proc_cmdline, timeout=60))
        clk_removed = re.search("clocksource.*", check_output).group()
        utils_test.update_boot_option(vm, args_removed=clk_removed)
        session = vm.wait_for_login(timeout=timeout)
        verify_guest_clock_source(session, "kvm-clock")
Esempio n. 19
0
def run(test, params, env):
    """
    MULTI_QUEUE chang queues number test

    1) Boot up VM, and login guest
    2) Check guest pci msi support and reset it as expection
    3) Run bg_stress_test(pktgen, netperf or file copy) if needed
    4) Change queues number repeatly during stress test running

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def change_queues_number(session, ifname, q_number, queues_status=None):
        """
        Change queues number
        """
        mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number)
        if not queues_status:
            queues_status = get_queues_status(session, ifname)

        if q_number != queues_status[1] and q_number <= queues_status[0]:
            expect_status = 0
        else:
            expect_status = 1

        status, output = session.cmd_status_output(mq_set_cmd)
        cur_queues_status = get_queues_status(session, ifname)
        if status != expect_status:
            err_msg = "Change queues number failed, "
            err_msg += "current queues set is %s, " % queues_status[1]
            err_msg += "max allow queues set is %s, " % queues_status[0]
            err_msg += "when run cmd: '%s', " % mq_set_cmd
            err_msg += "expect exit status is: %s, " % expect_status
            err_msg += "output: '%s'" % output
            raise error.TestFail(err_msg)
        if not status and cur_queues_status == queues_status:
            raise error.TestFail("params is right, but change queues failed")
        elif status and cur_queues_status != queues_status:
            raise error.TestFail("No need change queues number")
        return [int(_) for _ in cur_queues_status]

    def get_queues_status(session, ifname, timeout=240):
        """
        Get queues status
        """
        mq_get_cmd = "ethtool -l %s" % ifname
        nic_mq_info = session.cmd_output(mq_get_cmd, timeout=timeout)
        queues_reg = re.compile(r"Combined:\s+(\d)", re.I)
        queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines()))
        if len(queues_info) != 2:
            err_msg = "Oops, get guest queues info failed, "
            err_msg += "make sure your guest support MQ.\n"
            err_msg += "Check cmd is: '%s', " % mq_get_cmd
            err_msg += "Command output is: '%s'." % nic_mq_info
            raise error.TestNAError(err_msg)
        return [int(x) for x in queues_info]

    error.context("Init guest and try to login", logging.info)
    login_timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm.wait_for_login(timeout=login_timeout)

    if params.get("pci_nomsi", "no") == "yes":
        error.context("Disable pci msi in guest", logging.info)
        utils_test.update_boot_option(vm, args_added="pci=nomsi")
        vm.wait_for_login(timeout=login_timeout)

    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    bg_stress_test = params.get("run_bgstress")
    try:

        ifnames = []
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(session_serial,
                                                vm.virtnet[nic_index].mac)
            ifnames.append(ifname)

        if bg_stress_test:
            error.context("Run test %s background" % bg_stress_test,
                          logging.info)
            stress_thread = ""
            wait_time = float(params.get("wait_bg_time", 60))
            bg_stress_run_flag = params.get("bg_stress_run_flag")
            env[bg_stress_run_flag] = False
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
            utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                wait_time, 0, 5,
                                "Wait %s start background" % bg_stress_test)

        error.context("Change queues number repeatly", logging.info)
        repeat_counts = int(params.get("repeat_counts", 10))
        for nic_index, nic in enumerate(vm.virtnet):
            if "virtio" not in nic['nic_model']:
                continue
            queues = int(vm.virtnet[nic_index].queues)
            if queues == 1:
                logging.info("Nic with single queue, skip and continue")
                continue
            ifname = ifnames[nic_index]
            default_change_list = xrange(1, int(queues))
            change_list = params.get("change_list")
            if change_list:
                change_list = change_list.split(",")
            else:
                change_list = default_change_list

            for repeat_num in xrange(1, repeat_counts + 1):
                error.context("Change queues number -- %sth" % repeat_num,
                              logging.info)
                try:
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)
                except aexpect.ShellProcessTerminatedError:
                    vm = env.get_vm(params["main_vm"])
                    session = vm.wait_for_serial_login(timeout=login_timeout)
                    session_serial = session
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)

        if bg_stress_test:
            env[bg_stress_run_flag] = False
            if stress_thread:
                try:
                    stress_thread.join()
                except Exception, e:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    raise error.TestError(err_msg % (bg_stress_test, e))

    finally:
        env[bg_stress_run_flag] = False
        if session_serial:
            session_serial.close()
Esempio n. 20
0
def run(test, params, env):
    """
    vhost is no longer disabled when guest does not use MSI-X.
    The vhostforce flag is no longer required.

    1) Start guest with different NIC option
    2) Check virtio device's irq number,irq number should be greater than one.
    3) Disable msi of guest
    4) Reboot guest,check if msi is disabled and irq number should be equal to 1.
    5) Check network and vhost process (transfer data).
    6) Check md5 value of both sides.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def irq_check(session, device_name, devcon_folder):
        hwid = win_dev.get_hwids(session, device_name, devcon_folder,
                                 login_timeout)[0]
        get_irq_cmd = params["get_irq_cmd"] % (devcon_folder, hwid)
        irq_list = re.findall(r':\s+(\d+)', session.cmd_output(get_irq_cmd),
                              re.M)
        if not irq_list:
            test.error("device %s's irq checked fail" % device_name)
        return irq_list

    def get_file_md5sum(file_name, session, timeout):
        """
        return: Return the md5sum value of the guest.
        """
        logging.info("Get md5sum of the file:'%s'", file_name)
        s, o = session.cmd_status_output("md5sum %s" % file_name,
                                         timeout=timeout)
        if s != 0:
            test.error("Get file md5sum failed as %s" % o)
        return re.findall(r"\w{32}", o)[0]

    tmp_dir = params["tmp_dir"]
    filesize = int(params.get("filesize"))
    dd_cmd = params["dd_cmd"]
    delete_cmd = params["delete_cmd"]
    file_md5_check_timeout = int(params.get("file_md5_check_timeout"))
    login_timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_serial_login()

    if params.get("os_type") == "linux":
        error_context.context("Check the pci msi in guest", logging.info)
        pci_id = session.cmd("lspci |grep Eth |awk {'print $1'}").strip()
        status = session.cmd("lspci -vvv -s %s|grep MSI-X" % pci_id).strip()
        enable_status = re.search(r'Enable\+', status, re.M | re.I)
        if enable_status.group() == "Enable+":
            error_context.context("Disable pci msi in guest", logging.info)
            utils_test.update_boot_option(vm, args_added="pci=nomsi")
            session_msi = vm.wait_for_serial_login(timeout=login_timeout)
            pci_id = session_msi.cmd(
                "lspci |grep Eth |awk {'print $1'}").strip()
            status = session_msi.cmd("lspci -vvv -s %s|grep MSI-X" %
                                     pci_id).strip()
            session_msi.close()
            change_status = re.search(r'Enable\-', status, re.M | re.I)
            if change_status.group() != "Enable-":
                test.fail("virtio device's statuts is not correct")
        elif enable_status.group() != "Enable+":
            test.fail("virtio device's statuts is not correct")
    else:
        driver = params.get("driver_name")
        driver_verifier = params.get("driver_verifier", driver)

        device_name = params["device_name"]
        devcon_folder = utils_misc.set_winutils_letter(session,
                                                       params["devcon_folder"])
        error_context.context("Boot guest with %s device" % driver,
                              logging.info)
        session = utils_test.qemu.windrv_check_running_verifier(
            session, vm, test, driver_verifier, login_timeout)
        error_context.context("Check %s's irq number" % device_name,
                              logging.info)
        irq_list = irq_check(session, device_name, devcon_folder)
        irq_nums = len(irq_list)
        if not irq_nums > 1 and\
                max(ctypes.c_int32(int(irq)).value for irq in irq_list) < 0:
            test.fail("%s's irq is not correct." % device_name)
        if params.get("msi_cmd"):
            error_context.context("Disable MSI in guest", logging.info)
            hwid_msi = win_dev.get_hwids(session, device_name, devcon_folder,
                                         login_timeout)[0]
            session.cmd(params["msi_cmd"] % (hwid_msi, 0))
            session = vm.reboot(session=session)
            error_context.context("Check %s's irq number" % device_name,
                                  logging.info)
            irq_list = irq_check(session, device_name, devcon_folder)
            irq_nums = len(irq_list)
            if not irq_nums == 1 and \
                    min(ctypes.c_int32(int(irq)).value for irq in irq_list) > 0:
                test.fail("%s's irq is not correct." % device_name)

    # prepare test data
    guest_path = (tmp_dir + "src-%s" % utils_misc.generate_random_string(8))
    host_path = os.path.join(test.tmpdir,
                             "tmp-%s" % utils_misc.generate_random_string(8))
    logging.info("Test setup: Creating %dMB file on host", filesize)
    process.run(dd_cmd % host_path, shell=True)

    try:
        src_md5 = crypto.hash_file(host_path, algorithm="md5")
        logging.info("md5 value of data from src: %s", src_md5)
        # transfer data
        error_context.context("Transfer data from host to %s" % vm.name,
                              logging.info)
        vm.copy_files_to(host_path, guest_path)
        dst_md5 = get_file_md5sum(guest_path,
                                  session,
                                  timeout=file_md5_check_timeout)
        logging.info("md5 value of data in %s: %s", vm.name, dst_md5)
        if dst_md5 != src_md5:
            test.fail("File changed after transfer host -> %s" % vm.name)
    finally:
        os.remove(host_path)
        session.cmd(delete_cmd % guest_path,
                    timeout=login_timeout,
                    ignore_all_errors=True)
        session.close()
 def test_args_no_zipl(self, *mocks):
     update_boot_option(self.vm, args_added="3", need_reboot=False)
     utils_test.check_kernel_cmdline.assert_called_once()
     self.session.cmd_status_output.assert_called_once()
Esempio n. 22
0
def run(test, params, env):
    """
    MULTI_QUEUE chang queues number test

    1) Boot up VM, and login guest
    2) Check guest pci msi support and reset it as expection
    3) Enable the queues in guest
    4) Run bg_stress_test(pktgen, netperf or file copy) if needed
    5) Change queues number repeatly during stress test running
    6) Ping external host (local host, if external host not available)

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def change_queues_number(session, ifname, q_number, queues_status=None):
        """
        Change queues number
        """
        mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number)
        if not queues_status:
            queues_status = get_queues_status(session, ifname)

        if (q_number != queues_status[1] and q_number <= queues_status[0] and
                q_number > 0):
            expect_status = 0
        else:
            expect_status = 1

        status, output = session.cmd_status_output(mq_set_cmd, safe=True)
        cur_queues_status = get_queues_status(session, ifname)
        if status != expect_status:
            err_msg = "Change queues number failed, "
            err_msg += "current queues set is %s, " % queues_status[1]
            err_msg += "max allow queues set is %s, " % queues_status[0]
            err_msg += "when run cmd: '%s', " % mq_set_cmd
            err_msg += "expect exit status is: %s, " % expect_status
            err_msg += "output: '%s'" % output
            raise error.TestFail(err_msg)
        if not status and cur_queues_status == queues_status:
            raise error.TestFail("params is right, but change queues failed")
        elif status and cur_queues_status != queues_status:
            raise error.TestFail("No need change queues number")
        return [int(_) for _ in cur_queues_status]

    def get_queues_status(session, ifname, timeout=240):
        """
        Get queues status
        """
        mq_get_cmd = "ethtool -l %s" % ifname
        nic_mq_info = session.cmd_output(mq_get_cmd, timeout=timeout,
                                         safe=True)
        queues_reg = re.compile(r"Combined:\s+(\d)", re.I)
        queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines()))
        if len(queues_info) != 2:
            err_msg = "Oops, get guest queues info failed, "
            err_msg += "make sure your guest support MQ.\n"
            err_msg += "Check cmd is: '%s', " % mq_get_cmd
            err_msg += "Command output is: '%s'." % nic_mq_info
            raise error.TestNAError(err_msg)
        return [int(x) for x in queues_info]

    def enable_multi_queues(vm):
        sess = vm.wait_for_serial_login(timeout=login_timeout)
        error.context("Enable multi queues in guest.", logging.info)
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(sess, nic.mac)
            queues = int(nic.queues)
            change_queues_number(sess, ifname, queues)

    def ping_test(dest_ip, ping_time, lost_raito, session=None):
        status, output = utils_test.ping(dest=dest_ip, timeout=ping_time,
                                         session=session)
        packets_lost = utils_test.get_loss_ratio(output)
        if packets_lost > lost_raito:
            err = " %s%% packages lost during ping. " % packets_lost
            err += "Ping command log:\n %s" % "\n".join(output.splitlines()[-3:])
            raise error.TestFail(err)

    error.context("Init guest and try to login", logging.info)
    login_timeout = int(params.get("login_timeout", 360))
    bg_stress_test = params.get("run_bgstress")
    bg_stress_run_flag = params.get("bg_stress_run_flag")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm.wait_for_login(timeout=login_timeout)

    if params.get("pci_nomsi", "no") == "yes":
        error.context("Disable pci msi in guest", logging.info)
        utils_test.update_boot_option(vm, args_added="pci=nomsi")
        vm.wait_for_login(timeout=login_timeout)

    enable_multi_queues(vm)

    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    s_session = None
    bg_ping = params.get("bg_ping")
    b_ping_lost_ratio = int(params.get("background_ping_package_lost_ratio", 5))
    f_ping_lost_ratio = int(params.get("final_ping_package_lost_ratio", 5))
    guest_ip = vm.get_address()
    b_ping_time = int(params.get("background_ping_time", 60))
    f_ping_time = int(params.get("final_ping_time", 60))
    bg_test = None
    try:

        ifnames = []
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(session_serial,
                                                vm.virtnet[nic_index].mac)
            ifnames.append(ifname)

        if bg_stress_test:
            error.context("Run test %s background" % bg_stress_test,
                          logging.info)
            stress_thread = ""
            wait_time = float(params.get("wait_bg_time", 60))
            env[bg_stress_run_flag] = False
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
            if bg_stress_run_flag:
                utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                    wait_time, 0, 5,
                                    "Wait %s start background" % bg_stress_test)
        if bg_ping == "yes":
            error.context("Ping guest from host", logging.info)
            args = (guest_ip, b_ping_time, b_ping_lost_ratio)
            bg_test = utils.InterruptedThread(ping_test, args)
            bg_test.start()

        error.context("Change queues number repeatly", logging.info)
        repeat_counts = int(params.get("repeat_counts", 10))
        for nic_index, nic in enumerate(vm.virtnet):
            if "virtio" not in nic['nic_model']:
                continue
            queues = int(vm.virtnet[nic_index].queues)
            if queues == 1:
                logging.info("Nic with single queue, skip and continue")
                continue
            ifname = ifnames[nic_index]
            default_change_list = xrange(1, int(queues + 1))
            change_list = params.get("change_list")
            if change_list:
                change_list = change_list.split(",")
            else:
                change_list = default_change_list

            for repeat_num in xrange(1, repeat_counts + 1):
                error.context("Change queues number -- %sth" % repeat_num,
                              logging.info)
                try:
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)
                except aexpect.ShellProcessTerminatedError:
                    vm = env.get_vm(params["main_vm"])
                    session = vm.wait_for_serial_login(timeout=login_timeout)
                    session_serial = session
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)

        if params.get("ping_after_changing_queues", "yes") == "yes":
            default_host = "www.redhat.com"
            try:
                ext_host = utils_net.get_host_default_gateway()
            except error.CmdError:
                logging.warn("Can't get specified host,"
                             " Fallback to default host '%s'", default_host)
                ext_host = default_host
            if not ext_host:
                # Fallback to a hardcode host, eg:
                ext_host = default_host
            s_session = vm.wait_for_login(timeout=login_timeout)
            txt = "ping %s after changing queues in guest."
            error.context(txt, logging.info)
            ping_test(ext_host, f_ping_time, f_ping_lost_ratio, s_session)

        if bg_stress_test:
            env[bg_stress_run_flag] = False
            if stress_thread:
                error.context("wait for background test finish", logging.info)
                try:
                    stress_thread.join()
                except Exception, err:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    raise error.TestError(err_msg % (bg_stress_test, err))

    finally:
        if bg_stress_test:
            env[bg_stress_run_flag] = False
        if session_serial:
            session_serial.close()
        if s_session:
            s_session.close()
        if bg_test:
            error.context("Wait for background ping test finish.",
                          logging.info)
            try:
                bg_test.join()
            except Exception, err:
                txt = "Fail to wait background ping test finish. "
                txt += "Got error message %s" % err
                raise error.TestFail(txt)
def run(test, params, env):
    """
    Test to change the kernel param based on user input.

    1. Prepare test environment, boot the guest
    2. Change the kernel parameter as per user input
    3. Reboot the guest and check whether /proc/cmdline reflects
    4. Check the boot log in guest dmesg and validate
    5. Perform any test operation if any, based on kernel param change
    6. Recover test environment
    """
    vms = params.get("vms").split()
    kernel_param = params.get("kernel_param", "quiet")
    kernel_param_remove = params.get("kernel_param_remove", "")
    if not kernel_param:
        kernel_param = None
    if not kernel_param_remove:
        kernel_param_remove = None
    cpu_check = params.get("hardware", "").upper()
    boot_log = params.get("boot_log", None)
    status_error = params.get("status_error", "no") == "yes"
    vm_dict = {}
    vm_list = env.get_all_vms()
    # To ensure host that doesn't support Radix MMU gets skipped
    if cpu_check:
        cpu_model = utils_misc.get_cpu_info()['Model name'].upper()
        if cpu_check not in cpu_model:
            logging.info("This test will work for %s", cpu_check)
            test.skip("Test is not applicable for %s" % cpu_model)
    # back up vmxml
    for vm_name in vms:
        vm_dict[vm_name] = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    try:
        for vm in vm_list:
            session = vm.wait_for_login()
            utils_test.update_boot_option(vm, args_added=kernel_param,
                                          args_removed=kernel_param_remove,
                                          need_reboot=True)
            if boot_log:
                session = vm.wait_for_login()
                # To ensure guest that doesn't support Radix MMU gets skipped
                if cpu_check:
                    cmd = "grep cpu /proc/cpuinfo | awk '{print $3}' | "
                    cmd += "head -n 1"
                    status, output = session.cmd_status_output(cmd)
                    if status:
                        test.error("couldn't get cpu information from guest "
                                   "%s" % vm.name)
                    if cpu_check not in output.upper() and "radix" in boot_log:
                        test.skip("radix MMU not supported in %s" % output)
                status, output = session.cmd_status_output("dmesg")
                if status:
                    logging.error(output)
                    test.error("unable to get dmesg from guest: %s" %
                               vm.name)
                if status_error:
                    if boot_log in output:
                        test.fail("Able to find %s in dmesg of guest: "
                                  "%s" % (boot_log, vm.name))
                    logging.info("unable to find %s in dmesg of guest: %s",
                                 boot_log, vm.name)
                else:
                    if boot_log not in output:
                        test.fail("unable to find %s in dmesg of guest: "
                                  "%s" % (boot_log, vm.name))
                    logging.info("Able to find %s in dmesg of guest: %s",
                                 boot_log, vm.name)
            if session:
                session.close()
    finally:
        # close the session and recover the vms
        if session:
            session.close()
        for vm in vm_list:
            vm.destroy()
            vm_dict[vm.name].sync()
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)
Esempio n. 25
0
def run(test, params, env):
    """
    Verify the login guest with multi backends spapr-vty:
    1) Boot guest with multi spapr-vty with backend
    2) Modify the kernel cfg file to specify the backend
    3) For pty and file backend:
      3.1) Open and close chardev
    4) For unix_socket and tcp_socket:
      4.1) Login guest
      4.2) Create and delete files inside guest
    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    prompt = params.get("shell_prompt")
    create_delete_file = params["create_delete_file"]
    vm = env.get_vm(params["main_vm"])
    vm.wait_for_login()
    for serial_id in params.objects("serials"):
        if serial_id != "vs1":
            hvc_id = int(serial_id.replace('vs', '')) - 1
            kernel_params = "console=hvc%s,115200" % hvc_id
            utils_test.update_boot_option(vm, args_added=kernel_params)

        backend = params.object_params(serial_id)["chardev_backend"]
        serial_device = vm.devices.get(serial_id)
        chardev_qid = serial_device.get_param("chardev")
        chardev_device = vm.devices.get_by_qid(chardev_qid)[0]

        logging.info("The currently tested backend is %s.", backend)
        if backend == 'unix_socket':
            session = vm.wait_for_serial_login(timeout=60)
            session.cmd(create_delete_file)
            session.close()
        elif backend == 'tcp_socket':
            session = remote.remote_login(client='nc',
                                          host=chardev_device.params['host'],
                                          port=chardev_device.params['port'],
                                          username=params['username'],
                                          password=params['password'],
                                          prompt=prompt,
                                          timeout=240)
            session.cmd(create_delete_file)
            session.close()
        elif backend == 'pty':
            chardev_info = vm.monitor.human_monitor_cmd('info chardev')
            hostfile = re.findall(
                '%s: filename=pty:(/dev/pts/\\d)?' % serial_id, chardev_info)
            if not hostfile:
                test.fail("Can't find the corresponding pty backend: %s" %
                          chardev_info)
            fd_pty = os.open(hostfile[0], os.O_RDWR | os.O_NONBLOCK)
            os.close(fd_pty)
        elif backend == 'file':
            filename = chardev_device.params['path']
            with open(filename) as f:
                if 'Linux' not in f.read():
                    test.fail("Guest boot fail with file backend.")
        elif backend == 'null':
            session = vm.wait_for_login()
            session.cmd(create_delete_file)

        vm.verify_dmesg()
    vm.destroy()
Esempio n. 26
0
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))
Esempio n. 27
0
def run(test, params, env):
    """
    MULTI_QUEUE chang queues number test

    1) Boot up VM, and login guest
    2) Check guest pci msi support and reset it as expection
    3) Enable the queues in guest
    4) Run bg_stress_test(pktgen, netperf or file copy) if needed
    5) Change queues number repeatly during stress test running
    6) Ping external host (local host, if external host not available)

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def change_queues_number(session, ifname, q_number, queues_status=None):
        """
        Change queues number
        """
        mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number)
        if not queues_status:
            queues_status = get_queues_status(session, ifname)

        if (q_number != queues_status[1] and q_number <= queues_status[0]
                and q_number > 0):
            expect_status = 0
        else:
            expect_status = 1

        status, output = session.cmd_status_output(mq_set_cmd)
        cur_queues_status = get_queues_status(session, ifname)
        if status != expect_status:
            err_msg = "Change queues number failed, "
            err_msg += "current queues set is %s, " % queues_status[1]
            err_msg += "max allow queues set is %s, " % queues_status[0]
            err_msg += "when run cmd: '%s', " % mq_set_cmd
            err_msg += "expect exit status is: %s, " % expect_status
            err_msg += "output: '%s'" % output
            raise error.TestFail(err_msg)
        if not status and cur_queues_status == queues_status:
            raise error.TestFail("params is right, but change queues failed")
        elif status and cur_queues_status != queues_status:
            raise error.TestFail("No need change queues number")
        return [int(_) for _ in cur_queues_status]

    def get_queues_status(session, ifname, timeout=240):
        """
        Get queues status
        """
        mq_get_cmd = "ethtool -l %s" % ifname
        nic_mq_info = session.cmd_output(mq_get_cmd, timeout=timeout)
        queues_reg = re.compile(r"Combined:\s+(\d)", re.I)
        queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines()))
        if len(queues_info) != 2:
            err_msg = "Oops, get guest queues info failed, "
            err_msg += "make sure your guest support MQ.\n"
            err_msg += "Check cmd is: '%s', " % mq_get_cmd
            err_msg += "Command output is: '%s'." % nic_mq_info
            raise error.TestNAError(err_msg)
        return [int(x) for x in queues_info]

    def enable_multi_queues(vm):
        sess = vm.wait_for_serial_login(timeout=login_timeout)
        error.context("Enable multi queues in guest.", logging.info)
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(sess, nic.mac)
            queues = int(nic.queues)
            change_queues_number(sess, ifname, queues)

    def ping_test(dest_ip, ping_time, lost_raito, session=None):
        status, output = utils_test.ping(dest=dest_ip,
                                         timeout=ping_time,
                                         session=session)
        packets_lost = utils_test.get_loss_ratio(output)
        if packets_lost > lost_raito:
            err = " %s%% packages lost during ping. " % packets_lost
            err += "Ping command log:\n %s" % "\n".join(
                output.splitlines()[-3:])
            raise error.TestFail(err)

    error.context("Init guest and try to login", logging.info)
    login_timeout = int(params.get("login_timeout", 360))
    bg_stress_test = params.get("run_bgstress")
    bg_stress_run_flag = params.get("bg_stress_run_flag")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm.wait_for_login(timeout=login_timeout)

    if params.get("pci_nomsi", "no") == "yes":
        error.context("Disable pci msi in guest", logging.info)
        utils_test.update_boot_option(vm, args_added="pci=nomsi")
        vm.wait_for_login(timeout=login_timeout)

    enable_multi_queues(vm)

    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    s_session = None
    bg_ping = params.get("bg_ping")
    b_ping_lost_ratio = int(params.get("background_ping_package_lost_ratio",
                                       5))
    f_ping_lost_ratio = int(params.get("final_ping_package_lost_ratio", 5))
    guest_ip = vm.get_address()
    b_ping_time = int(params.get("background_ping_time", 60))
    f_ping_time = int(params.get("final_ping_time", 60))
    bg_test = None
    try:

        ifnames = []
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(session_serial,
                                                vm.virtnet[nic_index].mac)
            ifnames.append(ifname)

        if bg_stress_test:
            error.context("Run test %s background" % bg_stress_test,
                          logging.info)
            stress_thread = ""
            wait_time = float(params.get("wait_bg_time", 60))
            env[bg_stress_run_flag] = False
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
            if bg_stress_run_flag:
                utils_misc.wait_for(
                    lambda: env.get(bg_stress_run_flag), wait_time, 0, 5,
                    "Wait %s start background" % bg_stress_test)
        if bg_ping == "yes":
            error.context("Ping guest from host", logging.info)
            args = (guest_ip, b_ping_time, b_ping_lost_ratio)
            bg_test = utils.InterruptedThread(ping_test, args)
            bg_test.start()

        error.context("Change queues number repeatly", logging.info)
        repeat_counts = int(params.get("repeat_counts", 10))
        for nic_index, nic in enumerate(vm.virtnet):
            if "virtio" not in nic['nic_model']:
                continue
            queues = int(vm.virtnet[nic_index].queues)
            if queues == 1:
                logging.info("Nic with single queue, skip and continue")
                continue
            ifname = ifnames[nic_index]
            default_change_list = xrange(1, int(queues + 1))
            change_list = params.get("change_list")
            if change_list:
                change_list = change_list.split(",")
            else:
                change_list = default_change_list

            for repeat_num in xrange(1, repeat_counts + 1):
                error.context("Change queues number -- %sth" % repeat_num,
                              logging.info)
                try:
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(
                            session_serial, ifname, int(q_number),
                            queues_status)
                except aexpect.ShellProcessTerminatedError:
                    vm = env.get_vm(params["main_vm"])
                    session = vm.wait_for_serial_login(timeout=login_timeout)
                    session_serial = session
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(
                            session_serial, ifname, int(q_number),
                            queues_status)

        if params.get("ping_after_changing_queues", "yes") == "yes":
            default_host = "www.redhat.com"
            ext_host_get_cmd = params.get("ext_host_get_cmd", "")
            try:
                ext_host = utils.system_output(ext_host_get_cmd)
            except error.CmdError:
                logging.warn(
                    "Can't get specified host with cmd '%s',"
                    " Fallback to default host '%s'", ext_host_get_cmd,
                    default_host)
                ext_host = default_host
            if not ext_host:
                # Fallback to a hardcode host, eg:
                ext_host = default_host
            s_session = vm.wait_for_login(timeout=login_timeout)
            txt = "ping %s after changing queues in guest."
            error.context(txt, logging.info)
            ping_test(ext_host, f_ping_time, f_ping_lost_ratio, s_session)

        if bg_stress_test:
            env[bg_stress_run_flag] = False
            if stress_thread:
                error.context("wait for background test finish", logging.info)
                try:
                    stress_thread.join()
                except Exception, err:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    raise error.TestError(err_msg % (bg_stress_test, err))

    finally:
        if bg_stress_test:
            env[bg_stress_run_flag] = False
        if session_serial:
            session_serial.close()
        if s_session:
            s_session.close()
        if bg_test:
            error.context("Wait for background ping test finish.",
                          logging.info)
            try:
                bg_test.join()
            except Exception, err:
                txt = "Fail to wait background ping test finish. "
                txt += "Got error message %s" % err
                raise error.TestFail(txt)
def run(test, params, env):
    """
    Test to change the kernel param based on user input.

    1. Prepare test environment, boot the guest
    2. Change the kernel parameter as per user input
    3. Reboot the guest and check whether /proc/cmdline reflects
    4. Check the boot log in guest dmesg and validate
    5. Perform any test operation if any, based on kernel param change
    6. Recover test environment
    """
    vms = params.get("vms").split()
    kernel_param = params.get("kernel_param", "quiet")
    kernel_param_remove = params.get("kernel_param_remove", "")
    if not kernel_param:
        kernel_param = None
    if not kernel_param_remove:
        kernel_param_remove = None
    cpu_check = params.get("hardware", "").upper()
    boot_log = params.get("boot_log", None)
    check_cmdline_only = "yes" == params.get("check_cmdline_only", "no")
    status_error = params.get("status_error", "no") == "yes"
    vm_dict = {}
    vm_list = env.get_all_vms()
    # To ensure host that doesn't support Radix MMU gets skipped
    if cpu_check:
        cpu_model = cpu.get_cpu_info()['Model name'].upper()
        if cpu_check not in cpu_model:
            logging.info("This test will work for %s", cpu_check)
            test.skip("Test is not applicable for %s" % cpu_model)
    # back up vmxml
    for vm_name in vms:
        vm_dict[vm_name] = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    try:
        for vm in vm_list:
            session = vm.wait_for_login()
            if check_cmdline_only:
                check_cmdline(
                    session,
                    params.get(
                        "expect_in_cmdline",
                        "expect_in_cmdline not defined in test configuration"))
            else:
                utils_test.update_boot_option(vm,
                                              args_added=kernel_param,
                                              args_removed=kernel_param_remove,
                                              need_reboot=True)
            if boot_log:
                session = vm.wait_for_login()
                # To ensure guest that doesn't support Radix MMU gets skipped
                if cpu_check:
                    cmd = "grep cpu /proc/cpuinfo | awk '{print $3}' | "
                    cmd += "head -n 1"
                    status, output = session.cmd_status_output(cmd)
                    if status:
                        test.error("couldn't get cpu information from guest "
                                   "%s" % vm.name)
                    if cpu_check not in output.upper() and "radix" in boot_log:
                        test.skip("radix MMU not supported in %s" % output)
                status, output = session.cmd_status_output("dmesg")
                if status:
                    logging.error(output)
                    test.error("unable to get dmesg from guest: %s" % vm.name)
                if status_error:
                    if boot_log in output:
                        test.fail("Able to find %s in dmesg of guest: "
                                  "%s" % (boot_log, vm.name))
                    logging.info("unable to find %s in dmesg of guest: %s",
                                 boot_log, vm.name)
                else:
                    if boot_log not in output:
                        test.fail("unable to find %s in dmesg of guest: "
                                  "%s" % (boot_log, vm.name))
                    logging.info("Able to find %s in dmesg of guest: %s",
                                 boot_log, vm.name)
            if session:
                session.close()
    finally:
        # close the session and recover the vms
        if session:
            session.close()
        for vm in vm_list:
            vm.destroy()
            vm_dict[vm.name].sync()
Esempio n. 29
0
def run_timedrift_monotonicity(test, params, env):
    """
    Check guest time monotonicity during migration:

    1) Log into a guest.
    2) Take time from guest.
    3) Migrate the guest.
    4) Keep guest running for a period after migration,
       and record the time log.
    5) Analyse log if it is exist.

    @param test: QEMU test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    def get_time(cmd, test_time, session):
        if os.path.isfile(host_path):
            os.remove(host_path)
        lasttv = "0"
        cmd_timeout=int(params.get("cmd_timeout"))
        start_time = time.time()
        while (time.time() - start_time) < test_time :
            tv = session.cmd_output(cmd, timeout=cmd_timeout)
            if params.get("os_type") == 'windows':
                list = re.split('[:]',tv)
                tv = str(int(list[0])*3600 + int(list[1])*60 + float(list[2]))
            if float(tv) < float(lasttv):
                p_tv = "time value = " + tv + "\n"
                p_lasttv = "last time value = " + lasttv + "\n"
                time_log = file(host_path, 'a')
                time_log.write("time went backwards:\n" + p_tv + p_lasttv)
                time_log.close()
            lasttv = tv
            time.sleep(0.1)

    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))
    session1 = vm.wait_for_login(timeout=timeout)

    host_path = params.get("host_path")
    cmd = params.get("cmd_get_time")
    test_time = int(params.get("time_linger","60"))

    try:
        # take time
        logging.info("Start take guest time")
        bg = utils.InterruptedThread(get_time,(cmd,test_time,session1))
        bg.start()

        # migration
        logging.info("Start migration")
        vm.migrate()

        # log in
        logging.info("Logging in after migration...")
        session2 = vm.wait_for_login(timeout=timeout)
        if not session2:
            raise error.TestFail("Could not log in after migration")
        logging.info("Logged in after migration")

        # linger a while
        time.sleep(test_time)

        # analyse the result
        if os.path.isfile(host_path):
            log_dir = os.path.join(test.outputdir,
                                   "timedrift-monotonicity-result.txt")
            shutil.copyfile(host_path, log_dir)
            myfile = file(host_path, 'r')
            for line in myfile:
                if "time went backwards" in line:
                    myfile.close()
                    raise error.TestFail("Failed Time Monotonicity testing, "
                                         "Please check log %s" % host_path)
    finally:
        session1.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)