示例#1
0
def copy_file_to_samepath(session, test, params):
    """
    Copy autoit scripts and installer tool to the same path.

    :param session: The guest session object.
    :param test: kvm test object
    :param params: the dict used for parameters
    """
    logging.info("Copy autoit scripts and virtio-win-guest-tools.exe "
                 "to the same path.")
    dst_path = r"C:\\"
    vol_virtio_key = "VolumeName like '%virtio-win%'"
    vol_virtio = utils_misc.get_win_disk_vol(session, vol_virtio_key)
    installer_path = r"%s:\%s" % (vol_virtio, "virtio-win-guest-tools.exe")
    install_script_path = utils_misc.set_winutils_letter(
        session, params["install_script_path"])
    repair_script_path = utils_misc.set_winutils_letter(
        session, params["repair_script_path"])
    uninstall_script_path = utils_misc.set_winutils_letter(
        session, params["uninstall_script_path"])
    src_files = [
        installer_path, install_script_path, repair_script_path,
        uninstall_script_path
    ]
    for src_file in src_files:
        copy_cmd = "xcopy %s %s /Y" % (src_file, dst_path)
        status, output = session.cmd_status_output(copy_cmd)
        if status != 0:
            test.error("Copy file error," " the detailed info:\n%s." % output)
示例#2
0
def uninstall_driver(session, test, devcon_path, driver_name, device_name,
                     device_hwid):
    """
    Uninstall driver.

    :param session: The guest session object.
    :param test: kvm test object
    :param devcon_path: devcon.exe path.
    :param driver_name: driver name.
    :param device_name: device name.
    :param device_hwid: device hardware id.
    """
    devcon_path = utils_misc.set_winutils_letter(session, devcon_path)
    status, output = session.cmd_status_output("dir %s" % devcon_path,
                                               timeout=OPERATION_TIMEOUT)
    if status:
        test.error("Not found devcon.exe, details: %s" % output)
    logging.info("Uninstalling previous installed driver")
    for inf_name in _pnpdrv_info(session, device_name, ["InfName"]):
        uninst_store_cmd = "pnputil /f /d %s" % inf_name
        status, output = session.cmd_status_output(uninst_store_cmd,
                                                   INSTALL_TIMEOUT)
        if status:
            test.error("Failed to uninstall driver '%s' from store, "
                       "details:\n%s" % (driver_name, output))
    uninst_cmd = "%s remove %s" % (devcon_path, device_hwid)
    status, output = session.cmd_status_output(uninst_cmd, INSTALL_TIMEOUT)
    # acceptable status: OK(0), REBOOT(1)
    if status > 1:
        test.error("Failed to uninstall driver '%s', details:\n"
                   "%s" % (driver_name, output))
示例#3
0
    def verify_virtio_mode_guest_win(session, virtio_mode):
        """
        Verify virtio mode in windows guests. If device is in modern mode,
        device id should be larger than 1040. Else device memory range need
        to checked futher.

        :param session: shell Object
        :param virtio_mode: VirtIO mode for the device
        """
        device_name = params["device_name"]
        driver_name = params["driver_name"]
        session = utils_test.qemu.windrv_check_running_verifier(session, vm,
                                                                test, driver_name)
        devcon_folder = utils_misc.set_winutils_letter(session,
                                                       params["devcon_folder"])

        hwid = win_dev.get_hwids(session, device_name, devcon_folder)[0]
        device_id = int(hwid[17:21])

        if device_id > 1040:
            guest_mode = "modern"
        else:
            guest_mode = win_memory_range(session, devcon_folder, hwid, virtio_mode)

        if virtio_mode != guest_mode:
            test.fail("virtio mode in guest is not correct!")
示例#4
0
def trigger_crash(test, vm, params):
    """
    Trigger system crash with certain method.

    :param vm: target vm
    :parma params: test params
    """
    crash_method = params["crash_method"]
    if crash_method == "nmi":
        vm.monitor.nmi()
    elif crash_method in ("usb_keyboard", "ps2_keyboard"):
        crash_key1 = params["crash_key1"]
        crash_key2 = params["crash_key2"]
        vm.monitor.press_release_key(crash_key1)
        vm.send_key(crash_key2)
        vm.send_key(crash_key2)
    elif crash_method == "notmyfault_app":
        timeout = int(params.get("timeout", 360))
        session = vm.wait_for_login(timeout=timeout)
        cmd = params["notmyfault_cmd"] % random.randint(1, 8)
        notmyfault_cmd = utils_misc.set_winutils_letter(session, cmd)
        try:
            status, output = session.cmd_status_output(cmd=notmyfault_cmd,
                                                       timeout=timeout)
            if status:
                test.error("Command '%s' failed, status: %s, output: %s" %
                           (cmd, status, output))
        # notmyfault_app triggers BSOD of the guest, and it terminates
        # qemu process, so sometimes, it can not get the status of the cmd.
        except (aexpect.ShellTimeoutError, aexpect.ShellProcessTerminatedError,
                aexpect.ShellStatusError):
            pass
    else:
        test.cancel("Crash trigger method %s not supported, "
                    "please check cfg file for mistake." % crash_method)
示例#5
0
    def rw_disk_in_guest(session, plug_disks, iteration):
        """
        Do read/write on hotplug disks

        :param session: A shell session object.
        :param plug_disks: List for hotplug disks
        :param iteration: repeat times for hotplug.
        """
        if params.get("os_type") == "windows":
            if iteration == 0:
                get_windows_drive_letters(session, plug_disks)
            plug_disks = windows_drive_letters

        logging.info("Read/Writ on block device after hotplug.")
        disk_op_timeout = int(params.get("disk_op_timeout", 360))
        for disk in plug_disks:
            if params.get("os_type") not in ["linux", "windows"]:
                test.cancel("Unsupported OS type '%s'" % params.get("os_type"))
            else:
                test_cmd = params.get("disk_op_cmd") % (disk, disk)
                if params.get("os_type") == "windows":
                    test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
            status, output = session.cmd_status_output(test_cmd,
                                                       timeout=disk_op_timeout)
            if status:
                test.fail("Check for block device rw failed."
                          "Output: %s" % output)
示例#6
0
    def verify_virtio_mode_guest_win(session, virtio_mode):
        """
        Verify virtio mode in windows guests. If device is in modern mode,
        device id should be larger than 1040. Else device memory range need
        to checked futher.

        :param session: shell Object
        :param virtio_mode: VirtIO mode for the device
        """
        device_name = params["device_name"]
        driver_name = params["driver_name"]
        session = utils_test.qemu.windrv_check_running_verifier(
            session, vm, test, driver_name)
        devcon_folder = utils_misc.set_winutils_letter(session,
                                                       params["devcon_folder"])

        hwid = win_dev.get_hwids(session, device_name, devcon_folder)[0]
        device_id = int(hwid[17:21])

        if device_id > 1040:
            guest_mode = "modern"
        else:
            guest_mode = win_memory_range(session, devcon_folder, hwid,
                                          virtio_mode)

        if virtio_mode != guest_mode:
            test.fail("virtio mode in guest is not correct!")
示例#7
0
def run(test, params, env):
    """
    Run video in Windows guest
    1) Boot guest with the device.
    2) Run video by mplayer

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)
    video_player = utils_misc.set_winutils_letter(session,
                                                  params["mplayer_path"])
    video_url = params["video_url"]
    play_video_cmd = params["play_video_cmd"] % (video_player, video_url)
    error_context.context("Play video", logging.info)
    try:
        session.cmd(play_video_cmd, timeout=240)
    except Exception as details:
        raise exceptions.TestFail(details)

    play_video_duration = params.get("play_video_duration")
    if play_video_duration:
        time.sleep(int(play_video_duration))
        session.cmd("taskkill /IM %s /F" % video_player,
                    ignore_all_errors=True)
        session.close()
示例#8
0
    def _setup_environments():
        """
        Setup the guest test environment, includes close the useplatformclock,
        and copy gettime_cycles.exe related files to guest
        """
        vm = env.get_vm(params["main_vm"])
        vm.verify_alive()
        session = vm.wait_for_login(timeout=timeout)

        logging.info("Turn off the useplatformclock attribute")
        session.cmd(close_pltclk_cmd)

        logging.info("Reboot to check the useplatformclock is off")
        session = vm.reboot(session, timeout=timeout)
        s, o = session.cmd_status_output(check_pltclk_cmd)
        if s:
            test.error("Failed to check the useplatfromclock after reboot, "
                       "status=%s, output=%s" % (s, o))
        use_pltck = re.search(r'useplatformclock\s+no', o, re.I | re.M)
        if not use_pltck:
            test.error("The useplatfromclock isn't off after reboot, "
                       "output=%s" % o)

        logging.info("Copy the related files to the guest")
        for f in gettime_filenames:
            copy_file_cmd = utils_misc.set_winutils_letter(
                session, copy_cmd % f)
            session.cmd(copy_file_cmd)
        vm.graceful_shutdown(timeout=timeout)
示例#9
0
    def rw_disk_in_guest(session, plug_disks, iteration):
        """
        Do read/write on hotplug disks

        :param session: A shell session object.
        :param plug_disks: List for hotplug disks
        :param iteration: repeat times for hotplug.
        """
        if params.get("os_type") == "windows":
            if iteration == 0:
                get_windows_drive_letters(session, plug_disks)
            plug_disks = windows_drive_letters

        logging.info("Read/Writ on block device after hotplug.")
        disk_op_timeout = int(params.get("disk_op_timeout", 360))
        for disk in plug_disks:
            if params.get("os_type") not in ["linux", "windows"]:
                test.cancel("Unsupported OS type '%s'" % params.get("os_type"))
            else:
                test_cmd = params.get("disk_op_cmd") % (disk, disk)
                if params.get("os_type") == "windows":
                    test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
            status, output = session.cmd_status_output(test_cmd,
                                                       timeout=disk_op_timeout)
            if status:
                test.fail("Check for block device rw failed."
                          "Output: %s" % output)
示例#10
0
def save_random_file_to_vm(vm,
                           save_path,
                           count,
                           sync_bin,
                           blocksize=512,
                           timeout=240):
    """
    Save a random file to vm.

    :param vm: vm
    :param save_path: file path saved in vm
    :param count: block count
    :param sync_bin: sync binary path
    :param blocksize: block size, default 512
    :param timeout: time wait to finish
    """
    session = vm.wait_for_login()
    dd_cmd = "dd if=/dev/urandom of=%s bs=%s count=%s conv=fsync"
    with tempfile.NamedTemporaryFile() as f:
        dd_cmd = dd_cmd % (f.name, blocksize, count)
        process.run(dd_cmd, shell=True, timeout=timeout)
        vm.copy_files_to(f.name, save_path)
    sync_bin = utils_misc.set_winutils_letter(session, sync_bin)
    status, out = session.cmd_status_output(sync_bin, timeout=240)
    if status:
        raise EnvironmentError("Fail to execute %s: %s" % (sync_bin, out))
    session.close()
示例#11
0
def install_driver_by_virtio_media(session, test, devcon_path, media_type,
                                   driver_name, device_hwid):
    """
    Install driver by virtio media.

    :param session: The guest session object.
    :param test: kvm test object
    :param devcon_path: devcon.exe path.
    :param media_type: media type.
    :param driver_name: driver name.
    :param device_hwid: device hardware id.
    """
    devcon_path = utils_misc.set_winutils_letter(session, devcon_path)
    status, output = session.cmd_status_output("dir %s" % devcon_path,
                                               timeout=OPERATION_TIMEOUT)
    if status:
        test.error("Not found devcon.exe, details: %s" % output)
    error_context.context("Installing target driver", logging.info)
    installed_any = False
    for hwid in device_hwid.split():
        output = session.cmd_output("%s find %s" % (devcon_path, hwid))
        if re.search("No matching devices found", output, re.I):
            continue
        inf_path = get_driver_inf_path(session, test, media_type, driver_name)
        inst_cmd = "%s updateni %s %s" % (devcon_path, inf_path, hwid)
        status, output = session.cmd_status_output(inst_cmd, INSTALL_TIMEOUT)
        # acceptable status: OK(0), REBOOT(1)
        if status > 1:
            test.fail("Failed to install driver '%s', "
                      "details:\n%s" % (driver_name, output))
        installed_any |= True
    if not installed_any:
        test.error("Failed to find target devices "
                   "by hwids: '%s'" % device_hwid)
示例#12
0
def check_data_disks(test, params, env, vm, session):
    """
    Check guest data disks (except image1)

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    :param vm: VM object
    :param session: VM session
    """
    image_list = params.objects("images")
    del image_list[0]
    image_num = len(image_list)

    error_context.context("Check data disks in monitor!", logging.info)
    monitor_info_block = vm.monitor.info_block(False)
    blocks = ','.join(monitor_info_block.keys())
    for image in image_list:
        if image not in blocks:
            test.fail("drive_%s is missed: %s!" % (image, blocks))

    error_context.context("Read and write on data disks!", logging.info)
    os_type = params["os_type"]
    if os_type == "linux":
        sub_test_type = params.get("sub_test_type", "dd_test")
        for image in image_list:
            params["dd_if"] = "ZERO"
            params["dd_of"] = image
            utils_test.run_virt_sub_test(test, params, env, sub_test_type)

            params["dd_if"] = image
            params["dd_of"] = "NULL"
            utils_test.run_virt_sub_test(test, params, env, sub_test_type)
    elif os_type == "windows":
        iozone_cmd = params["iozone_cmd"]
        iozone_cmd = utils_misc.set_winutils_letter(session, iozone_cmd)
        data_image_size = params["data_image_size"]
        disks = utils_disk.get_windows_disks_index(session, data_image_size)
        disk_num = len(disks)
        if disk_num < image_num:
            err_msg = "set disk num: %d" % image_num
            err_msg += ", get in guest: %d" % disk_num
            test.fail("Fail to list all the volumes, %s" % err_msg)
        if not utils_disk.update_windows_disk_attributes(session, disks):
            test.fail("Failed to update windows disk attributes.")
        for disk in disks:
            drive_letter = utils_disk.configure_empty_disk(
                session, disk, data_image_size, os_type)
            if not drive_letter:
                test.fail("Fail to format disks.")
            iozone_cmd_disk = iozone_cmd % drive_letter[0]
            status, output = session.cmd_status_output(iozone_cmd_disk,
                                                       timeout=3600)
            if status:
                test.fail("Check block device '%s' failed! Output: %s" %
                          (drive_letter[0], output))
            utils_disk.clean_partition(session, disk, os_type)
    else:
        test.cancel("Unsupported OS type '%s'" % os_type)
示例#13
0
 def create_file(self, file_name):
     """
     Create file and record m5 value of them.
     :param file_name: the file need to be created
     """
     params = self.params
     session = self.get_session()
     file_create_cmd = params.get("create_command", "touch FILE")
     file_create_cmd = utils_misc.set_winutils_letter(session, file_create_cmd)
     test_exists_cmd = params.get("test_exists_cmd", "test -f FILE")
     if session.cmd_status(test_exists_cmd.replace("FILE", file_name)):
         session.cmd(file_create_cmd.replace("FILE", file_name), timeout=200)
     session.cmd("md5sum %s > %s.md5" % (file_name, file_name), timeout=200)
     sync_cmd = params.get("sync_cmd", "sync")
     sync_cmd = utils_misc.set_winutils_letter(session, sync_cmd)
     session.cmd(sync_cmd)
     session.close()
示例#14
0
 def create_file(self, file_name):
     """
     Create file and record m5 value of them.
     :param file_name: the file need to be created
     """
     params = self.params
     session = self.get_session()
     file_create_cmd = params.get("create_command", "touch FILE")
     file_create_cmd = utils_misc.set_winutils_letter(session, file_create_cmd)
     test_exists_cmd = params.get("test_exists_cmd", "test -f FILE")
     if session.cmd_status(test_exists_cmd.replace("FILE", file_name)):
         session.cmd(file_create_cmd.replace("FILE", file_name), timeout=200)
     session.cmd("md5sum %s > %s.md5" % (file_name, file_name), timeout=200)
     sync_cmd = params.get("sync_cmd", "sync")
     sync_cmd = utils_misc.set_winutils_letter(session, sync_cmd)
     session.cmd(sync_cmd)
     session.close()
示例#15
0
 def rss_test():
     logging.info(
         'Run the command "netkvm-wmi.cmd rss" to collect statistics')
     rss_test_cmd = utils_misc.set_winutils_letter(guest_session,
                                                   params["rss_test_cmd"])
     output = guest_session.cmd_output(rss_test_cmd)
     rss_statistics = output.splitlines()[1].split()
     rxerrors = int(rss_statistics[-4])
     rxmissed = int(rss_statistics[-2])
     if not (rxerrors == 0 and rxmissed == 0):
         test.fail("Rss support for virtio-net driver is bad")
     logging.info("Rss support for virtio-net driver is works well")
示例#16
0
 def install_ntttcp(session):
     """ Install ntttcp through a remote session """
     logging.info("Installing NTttcp ...")
     try:
         # Don't install ntttcp if it's already installed
         error_context.context("NTttcp directory already exists")
         session.cmd(params.get("check_ntttcp_cmd"))
     except aexpect.ShellCmdError:
         ntttcp_install_cmd = params.get("ntttcp_install_cmd")
         ntttcp_install_cmd = utils_misc.set_winutils_letter(
             session, ntttcp_install_cmd)
         error_context.context("Installing NTttcp on guest")
         session.cmd(ntttcp_install_cmd % (platform, platform), timeout=200)
示例#17
0
 def run_io_test():
     """ Run io test on the hot plugged disks. """
     error_context.context("Run io test on the hot plugged disks.",
                           logging.info)
     session = vm.wait_for_login(timeout=timeout)
     if windows:
         drive_letter = drive_letters[index]
         test_cmd = disk_op_cmd % (drive_letter, drive_letter)
         test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
     else:
         test_cmd = disk_op_cmd % (new_disk, new_disk)
     session.cmd(test_cmd, timeout=disk_op_timeout)
     session.close()
示例#18
0
def run(test, params, env):
    """
    QEMU windows guest vitio device irq check test

    1) Start guest with virtio device.
    2) Make sure driver verifier enabled in guest.
    3) Get irq info in guest and check the value of irq number.

    :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, timeout):
        """
        Check virtio device's irq number, irq number should be greater than zero.

        :param session: use for sending cmd
        :param device_name: name of the specified device
        :param devcon_folder: Full path for devcon.exe
        :param timeout: Timeout in seconds.
        """
        hwids = win_dev.get_hwids(session, device_name, devcon_folder, timeout)
        if not hwids:
            test.error("Didn't find %s device info from guest" % device_name)
        for hwid in hwids:
            get_irq_cmd = '%sdevcon.exe resources @"%s" | find "IRQ"' % (
                devcon_folder, hwid)
            output = session.cmd_output(get_irq_cmd)
            irq_value = re.split(r':+', output)[1]
            if ctypes.c_int32(int(irq_value)).value < 0:
                test.fail("%s's irq is not correct." % device_name,
                          logging.info)

    driver = params["driver_name"]
    device_name = params["device_name"]
    timeout = int(params.get("login_timeout", 360))

    error_context.context("Boot guest with %s device" % driver, logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)
    session = utils_test.qemu.windrv_check_running_verifier(
        session, vm, test, driver, timeout)

    error_context.context("Check %s's irq number" % device_name, logging.info)
    devcon_folder = utils_misc.set_winutils_letter(session,
                                                   params["devcon_folder"])
    irq_check(session, device_name, devcon_folder, timeout)

    if session:
        session.close()
示例#19
0
def run(test, params, env):
    """
    sigverif test:
    1) Boot guest with related virtio devices
    2) Run sigverif command(an autoit script) in guest
    3) Open sigverif log and check whether driver is signed

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """

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

    driver_name = params["driver_name"]
    driver_verifier = params.get("driver_verifier", driver_name)
    session = utils_test.qemu.windrv_check_running_verifier(
        session, vm, test, driver_verifier)

    run_sigverif_cmd = utils_misc.set_winutils_letter(
        session, params["run_sigverif_cmd"])
    sigverif_log = params["sigverif_log"]
    check_sigverif_cmd = params["check_sigverif_cmd"] % driver_name
    clean_sigverif_cmd = params["clean_sigverif_cmd"]

    error_context.context("Run sigverif in windows guest", logging.info)
    session.cmd(clean_sigverif_cmd, ignore_all_errors=True)
    vm.send_key('meta_l-d')
    time.sleep(60)
    status, output = session.cmd_status_output(run_sigverif_cmd)
    if status != 0:
        test.error(output)

    if not utils_misc.wait_for(
            lambda: system.file_exists(session, sigverif_log), 180, 0, 5):
        test.error("sigverif logs are not created")

    try:
        error_context.context(
            "Open sigverif logs and check driver signature"
            " status", logging.info)
        output = session.cmd_output(check_sigverif_cmd)
        pattern = r"%s.sys.*\s{2,}Signed" % driver_name
        if not re.findall(pattern, output, re.M):
            test.fail(
                "%s driver is not digitally signed, details info is:\n %s" %
                (driver_name, output))
    finally:
        error_context.context("Clean sigverif logs", logging.info)
        session.cmd(clean_sigverif_cmd, ignore_all_errors=True)
示例#20
0
 def save_file(self, dst):
     login_timeout = int(self.params.get("login_timeout", 360))
     cmd = self.params.get("sync_bin", "sync")
     error.context("save file('%s') md5sum in guest" % dst, logging.info)
     self.__create_file(dst)
     session = self.vm.wait_for_login(timeout=login_timeout)
     logging.info("sync guest data")
     cmd = utils_misc.set_winutils_letter(session, cmd)
     status, output = session.cmd_status_output(cmd)
     if status != 0:
         logging.error("Execute '%s' with failures('%s') " % (cmd, output))
         return None
     session.close()
     return self.__md5sum(dst)
示例#21
0
 def save_file(self, dst):
     login_timeout = int(self.params.get("login_timeout", 360))
     cmd = self.params.get("sync_bin", "sync")
     error.context("save file('%s') md5sum in guest" % dst, logging.info)
     self.__create_file(dst)
     session = self.vm.wait_for_login(timeout=login_timeout)
     logging.info("sync guest data")
     cmd = utils_misc.set_winutils_letter(session, cmd)
     status, output = session.cmd_status_output(cmd)
     if status != 0:
         logging.error("Execute '%s' with failures('%s') " % (cmd, output))
         return None
     session.close()
     return self.__md5sum(dst)
示例#22
0
    def run_bg_test_simu(bg_stress_test):
        """
        Run backgroud test simultaneously with main_test.
        background test: e.g. rng_bat/balloon_test/netperf ...
        main test: e.g reboot/shutdown/stop/cont/driver_load ...

        :param bg_stress_test: Background test.
        :return: return the background case thread if it's successful;
                 else raise error.
        """
        error_context.context("Run test %s background" % bg_stress_test,
                              logging.info)
        stress_thread = None
        wait_time = float(params.get("wait_bg_time", 60))
        target_process = params.get("target_process", "")
        bg_stress_run_flag = params.get("bg_stress_run_flag")
        # Need to set bg_stress_run_flag in some cases to make sure all
        # necessary steps are active
        env[bg_stress_run_flag] = False
        if params.get("bg_stress_test_is_cmd", "no") == "yes":
            session = vm.wait_for_login()
            bg_stress_test = utils_misc.set_winutils_letter(
                session, bg_stress_test)
            session.sendline(bg_stress_test)
        else:
            stress_thread = utils_misc.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()

        for event in params.get("check_setup_events", "").strip().split():
            if not utils_misc.wait_for(lambda: params.get(event),
                                       600, 0, 1):
                test.error("Background test not in ready state since haven't "
                           "received event %s" % event)
            # Clear event
            params[event] = False

        check_bg_timeout = float(params.get('check_bg_timeout', 120))
        if not utils_misc.wait_for(lambda: check_bg_running(target_process),
                                   check_bg_timeout, 0, 1):
            test.fail("Backgroud test %s is not alive!" % bg_stress_test)
        if params.get("set_bg_stress_flag", "no") == "yes":
            logging.info("Wait %s test start" % bg_stress_test)
            if not utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                       wait_time, 0, 0.5):
                err = "Fail to start %s test" % bg_stress_test
                test.error(err)
        env["bg_status"] = 1
        return stress_thread
示例#23
0
    def run_bg_test_sep(sub_type):
        """
        Run background test separately with main_test.
        background test: e.g. rng_bat/balloon_test/netperf ...
        main test: e.g. reboot/shutdown/stop/cont/driver_load ...

        :params: sub_type: Background test.
        """
        if params.get("bg_stress_test_is_cmd", "no") == "yes":
            session = vm.wait_for_login()
            sub_type = utils_misc.set_winutils_letter(session, sub_type)
            session.cmd(sub_type, timeout=600)
            session.close()
        else:
            utils_test.run_virt_sub_test(test, params, env, sub_type)
示例#24
0
def install_driver_by_installer(session, test, run_install_cmd,
                                installer_pkg_check_cmd):
    """
    Install driver by installer.

    :param session: The guest session object.
    :param test: kvm test object
    :param run_install_cmd: install cmd.
    :param installer_pkg_check_cmd: installer pkg check cmd.
    """
    run_install_cmd = utils_misc.set_winutils_letter(session, run_install_cmd)
    session.cmd(run_install_cmd)
    if not utils_misc.wait_for(
            lambda: not session.cmd_status(installer_pkg_check_cmd), 360):
        test.fail("Virtio-win-guest-tools is not installed.")
    time.sleep(60)
示例#25
0
    def run_bg_test_sep(sub_type):
        """
        Run background test separately with main_test.
        background test: e.g. rng_bat/balloon_test/netperf ...
        main test: e.g. reboot/shutdown/stop/cont/driver_load ...

        :params: sub_type: Background test.
        """
        if params.get("bg_stress_test_is_cmd", "no") == "yes":
            session = vm.wait_for_login()
            sub_type = utils_misc.set_winutils_letter(
                session, sub_type)
            session.cmd(sub_type, timeout=600)
            session.close()
        else:
            utils_test.run_virt_sub_test(test, params, env, sub_type)
示例#26
0
def run(test, params, env):
    """
    sigverif test:
    1) Boot guest with related virtio devices
    2) Run sigverif command(an autoit script) in guest
    3) Open sigverif log and check whether driver is signed

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """

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

    driver_name = params["driver_name"]
    session = utils_test.qemu.windrv_check_running_verifier(session, vm,
                                                            test, driver_name)

    run_sigverif_cmd = utils_misc.set_winutils_letter(
        session, params["run_sigverif_cmd"])
    sigverif_log = params["sigverif_log"]
    check_sigverif_cmd = params["check_sigverif_cmd"] % driver_name
    clean_sigverif_cmd = params["clean_sigverif_cmd"]

    error_context.context("Run sigverif in windows guest", logging.info)
    session.cmd(clean_sigverif_cmd, ignore_all_errors=True)
    status, output = session.cmd_status_output(run_sigverif_cmd)
    if status != 0:
        test.error(output)

    if not utils_misc.wait_for(lambda: system.file_exists(session,
                               sigverif_log), 180, 0, 5):
        test.error("sigverif logs are not created")

    try:
        error_context.context("Open sigverif logs and check driver signature"
                              " status", logging.info)
        output = session.cmd_output(check_sigverif_cmd)
        pattern = r"%s.sys.*\s{2,}Signed" % driver_name
        if not re.findall(pattern, output, re.M):
            test.fail("%s driver is not digitally signed, details info is:\n %s"
                      % (driver_name, output))
    finally:
        error_context.context("Clean sigverif logs", logging.info)
        session.cmd(clean_sigverif_cmd, ignore_all_errors=True)
示例#27
0
def install_windbg(test, params, session, timeout=600):
    """
    Install Windows Debug Tools.

    :param test: kvm test object
    :param params: the dict used for parameters.
    :param session: The guest session object.
    :param timeout: waiting debug tool install finish.
    """
    logging.info("Install Windows Debug Tools in guest.")
    windbg_install_cmd = params["windbg_install_cmd"]
    windbg_install_cmd = utils_misc.set_winutils_letter(
        session, windbg_install_cmd % params["feature"])
    session.cmd(windbg_install_cmd)
    if not utils_misc.wait_for(lambda: check_windbg_installed(params, session),
                               timeout=timeout):
        test.fail("windbg tool has not been installed")
示例#28
0
 def wmi_facility_test(session):
     driver_name = params["driver_name"]
     wmi_check_cmd = params["wmi_check_cmd"]
     pattern = params["pattern"]
     session = utils_test.qemu.windrv_check_running_verifier(
         session, vm, test, driver_name, timeout)
     wmi_check_cmd = utils_misc.set_winutils_letter(session, wmi_check_cmd)
     error_context.context("Run wmi check in guest.", test.log.info)
     output = session.cmd_output(wmi_check_cmd)
     queue_num = re.findall(pattern, output, re.M)
     try:
         if not queue_num or queue_num[0] != num_queues:
             test.fail("The queue_num from guest is not match with expected.\n"
                       "queue_num from guest is %s, expected is %s"
                       % (queue_num, num_queues))
     finally:
         session.close()
示例#29
0
    def kmplayer_install(session):
        """
        Install kmplayer

        :param session: VM session
        """
        error_context.context("Install kmplayer ...", logging.info)
        guest_name = params["guest_name"]
        alias_map = params["guest_alias"]
        guest_list = dict([x.split(":") for x in alias_map.split(",")])
        guest_name = guest_list[guest_name]

        install_cmd = params["kmplayer_install_cmd"] % guest_name
        install_cmd = utils_misc.set_winutils_letter(session, install_cmd)
        s, o = session.cmd_status_output(install_cmd, timeout=240)
        if s != 0:
            raise exceptions.TestError("Failed to install kmplayer %s" % o)
def run(test, params, env):
    """
    KVM windows virtio driver signed status check test:
    1) Start a windows guest with virtio driver iso/floppy
    2) Generate a tested driver file list.
    3) use SignTool.exe to verify whether all drivers digital signed

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)
    signtool_cmd = params["signtool_cmd"]
    list_files_cmd = 'dir /s /b %s | find /i "%s" | find "%s"'

    try:
        error_context.context("Running SignTool check test in guest...",
                              logging.info)
        file_type = [".cat", ".sys", ".inf", "Wdf"]
        tested_list = []
        viowin_letter, path = get_driver_file_path(session, params)
        for ftype in file_type:
            cmd = list_files_cmd % (viowin_letter, path, ftype)
            list_file = session.cmd_output(cmd, timeout)
            driver_file = re.findall(r".*%s$" % ftype, list_file, re.M)
            tested_list.extend(driver_file)
        if (len(tested_list) < 3) or (".cat" not in tested_list[0]):
            test.fail("The tested files were not included in %s disk" %
                      viowin_letter)
        signtool_cmd = utils_misc.set_winutils_letter(session, signtool_cmd)
        check_info = "Number of files successfully Verified: (1)"
        for driver_file in tested_list[1:]:
            test_cmd = signtool_cmd % (tested_list[0], driver_file)
            status, output = session.cmd_status_output(test_cmd)
            sign_num = re.findall(check_info, output)[0]
            if (status != 0) or (int(sign_num) != 1):
                test.fail(
                    "%s signtool verify failed, check the output details:\n %s"
                    % (driver_file, output))
    finally:
        session.close()
示例#31
0
def run(test, params, env):
    """
    KVM windows virtio driver signed status check test:
    1) Start a windows guest with virtio driver iso/floppy
    2) Generate a tested driver file list.
    3) use SignTool.exe to verify whether all drivers digital signed

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)
    signtool_cmd = params["signtool_cmd"]
    list_files_cmd = 'dir /s /b %s | find /i "%s" | find "%s"'

    try:
        error_context.context("Running SignTool check test in guest...",
                              logging.info)
        file_type = [".cat", ".sys", ".inf", "Wdf"]
        tested_list = []
        viowin_letter, path = get_driver_file_path(session, params)
        for ftype in file_type:
            cmd = list_files_cmd % (viowin_letter, path, ftype)
            list_file = session.cmd_output(cmd, timeout)
            driver_file = re.findall(r".*%s$" % ftype, list_file, re.M)
            tested_list.extend(driver_file)
        if (len(tested_list) < 3) or (".cat" not in tested_list[0]):
            test.fail("The tested files were not included in %s disk"
                      % viowin_letter)
        signtool_cmd = utils_misc.set_winutils_letter(session, signtool_cmd)
        check_info = "Number of files successfully Verified: (1)"
        for driver_file in tested_list[1:]:
            test_cmd = signtool_cmd % (tested_list[0], driver_file)
            status, output = session.cmd_status_output(test_cmd)
            sign_num = re.findall(check_info, output)[0]
            if (status != 0) or (int(sign_num) != 1):
                test.fail("%s signtool verify failed, check the output details:\n %s"
                          % (driver_file, output))
    finally:
        session.close()
示例#32
0
    def _install_win(self, src, dst, timeout):
        """
        Install a package from source file to destination directory in windows.
        """
        def _find_exe_file():
            """
            Find the path of the given executable file in windows.
            """
            cmd_dir = r'CD %s && DIR /S /B %s.exe' % (dst, self.name)
            s, o = self.session.cmd_status_output(cmd_dir, timeout=timeout)
            if not s:
                return '"{}"'.format(o.splitlines()[0])
            return None

        cmd = utils_misc.set_winutils_letter(
            self.session, r'msiexec /a "%s" /qn TARGETDIR="%s"' % (src, dst))
        self.session.cmd_output(cmd, timeout=timeout)
        if not utils_misc.wait_for(lambda: _find_exe_file(), timeout,
                                   step=3.0):
            raise TestError('Failed to install fio under %.2f.' % timeout)
示例#33
0
    def _install_win(self, src, dst, timeout):
        """
        Install a package from source file to destination directory in windows.
        """
        def _find_exe_file():
            """
            Find the path of the given executable file in windows.
            """
            cmd_dir = r'CD %s && DIR /S /B %s.exe' % (dst, self.name)
            s, o = self.session.cmd_status_output(cmd_dir, timeout=timeout)
            if not s:
                return '"{}"'.format(o.splitlines()[0])
            return None

        cmd = utils_misc.set_winutils_letter(
            self.session, r'msiexec /a "%s" /qn TARGETDIR="%s"' % (src, dst))
        self.session.cmd_output(cmd, timeout=timeout)
        if not utils_misc.wait_for(
                lambda: _find_exe_file(), timeout, step=3.0):
            raise TestError('Failed to install fio under %.2f.' % timeout)
示例#34
0
def dump_windbg_check(test, params, session):
    """
    Check the dump file can be open through windbg tool.

    :param test: kvm test object
    :param params: the dict used for parameters.
    :param session: The guest session object.
    """
    logging.info("Check the dump file can be opened by windbg tool")
    chk_dump_cmd = params["chk_dump_cmd"]
    log_file = params["dump_analyze_file"]
    chk_dump_cmd = utils_misc.set_winutils_letter(session, chk_dump_cmd)
    session.cmd(chk_dump_cmd)
    if not utils_misc.wait_for(lambda: check_log_exist(session, log_file),
                               timeout=120):
        test.error("Cannot generate dump analyze log.")
    chk_id_cmd = params["chk_id_cmd"] % log_file
    status, output = session.cmd_status_output(chk_id_cmd)
    if status:
        output = session.cmd_output("type %s" % log_file)
        test.fail("Check dump file failed, output as %s" % output)
示例#35
0
def io_test(session, disk_op_cmd, disks, windows=False, image_size=None):
    """
    Perform io test on disks
    :param session: vm session
    :param disk_op_cmd: The disk operation command
    :param plug_disks: The list of disks
    :param windows: If it is windows guest
    :param image_size: The size of images, only for windows
    """
    for index, disk in enumerate(disks):
        if windows:
            if not utils_disk.update_windows_disk_attributes(session, disk):
                raise exceptions.TestError("Failed to clear readonly for all"
                                           " disks and online them in guest")
            partition = utils_disk.configure_empty_windows_disk(
                session, disk, image_size)
            test_cmd = disk_op_cmd % (partition[0], partition[0])
            test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
        else:
            test_cmd = disk_op_cmd % (disk, disk)
        session.cmd(test_cmd, timeout=360)
示例#36
0
    def _prepare_test_environment():
        """
        Prepare the test tools, such as hv_tlbflush & stress

        return: a running HostStress object
        """

        copy_tlbflush_cmd = params["copy_tlbflush_cmd"]

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

        logging.info("Copy tlbflush tool related files")
        for f in tlbflush_filenames:
            copy_file_cmd = utils_misc.set_winutils_letter(
                session, copy_tlbflush_cmd % f)
            session.cmd(copy_file_cmd)

        logging.info("Create a large file for test")
        create_test_file_cmd = params["create_test_file_cmd"]
        test_file_size = params["test_file_size"]
        test_file_size = utils_numeric.normalize_data_size(test_file_size,
                                                           order_magnitude="B")
        session.cmd(create_test_file_cmd % test_file_size)
        vm.graceful_shutdown(timeout=timeout)

        stress_type = params.get("stress_type", "stress")
        stress_pkg_name = params.get("stress_pkg_name", "stress-1.0.4.tar.gz")
        stress_root_dir = data_dir.get_deps_dir("stress")
        downloaded_file_path = os.path.join(stress_root_dir, stress_pkg_name)
        host_cpu_count = cpu.total_cpus_count()

        host_stress = utils_test.HostStress(
            stress_type,
            params,
            download_type="tarball",
            downloaded_file_path=downloaded_file_path,
            stress_args="--cpu %s > /dev/null 2>&1& " % host_cpu_count)
        return host_stress
示例#37
0
    def run_bg_stress_test(bg_stress_test):
        """
        Run backgroud test.

        :param bg_stress_test: Background test.
        :return: return the background case thread if it's successful;
                 else raise error.
        """
        error_context.context("Run test %s background" % bg_stress_test,
                              logging.info)
        stress_thread = None
        wait_time = float(params.get("wait_bg_time", 60))
        target_process = params.get("target_process", "")
        bg_stress_run_flag = params.get("bg_stress_run_flag")
        # Need to set bg_stress_run_flag in some cases to make sure all
        # necessary steps are active
        env[bg_stress_run_flag] = False
        if params.get("bg_stress_test_is_cmd", "no") == "yes":
            session = vm.wait_for_login()
            bg_stress_test = utils_misc.set_winutils_letter(
                session, bg_stress_test)
            session.sendline(bg_stress_test)
        else:
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
        if not utils_misc.wait_for(lambda: check_bg_running(target_process),
                                   120, 0, 1):
            raise exceptions.TestFail("Backgroud test %s is not "
                                      "alive!" % bg_stress_test)
        if params.get("set_bg_stress_flag", "no") == "yes":
            logging.info("Wait %s test start" % bg_stress_test)
            if not utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                       wait_time, 0, 0.5):
                err = "Fail to start %s test" % bg_stress_test
                raise exceptions.TestError(err)
        env["bg_status"] = 1
        return stress_thread
示例#38
0
    def run_bg_stress_test(bg_stress_test):
        """
        Run backgroud test.

        :param bg_stress_test: Background test.
        :return: return the background case thread if it's successful;
                 else raise error.
        """
        error_context.context("Run test %s background" % bg_stress_test,
                              logging.info)
        stress_thread = None
        wait_time = float(params.get("wait_bg_time", 60))
        target_process = params.get("target_process", "")
        bg_stress_run_flag = params.get("bg_stress_run_flag")
        # Need to set bg_stress_run_flag in some cases to make sure all
        # necessary steps are active
        env[bg_stress_run_flag] = False
        if params.get("bg_stress_test_is_cmd", "no") == "yes":
            session = vm.wait_for_login()
            bg_stress_test = utils_misc.set_winutils_letter(
                session, bg_stress_test)
            session.sendline(bg_stress_test)
        else:
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
        if not utils_misc.wait_for(lambda: check_bg_running(target_process),
                                   120, 0, 1):
            raise exceptions.TestFail("Backgroud test %s is not "
                                      "alive!" % bg_stress_test)
        if params.get("set_bg_stress_flag", "no") == "yes":
            logging.info("Wait %s test start" % bg_stress_test)
            if not utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                       wait_time, 0, 0.5):
                err = "Fail to start %s test" % bg_stress_test
                raise exceptions.TestError(err)
        env["bg_status"] = 1
        return stress_thread
示例#39
0
 def get_disk_op_cmd(disk_op_cmd, disk_size):
     """
     Find the disk driver letter and format the disk, and get
     disk driver letter,return disk_op_command
     """
     if os_type == "windows":
         disk_op_cmd = utils_misc.set_winutils_letter(session, disk_op_cmd)
         logging.info("Get windows disk index that to be formatted")
         disk_id = utils_disk.get_windows_disks_index(session, disk_size)
         if not utils_disk.update_windows_disk_attributes(session, disk_id):
             test.error("Failed to enable data disk %s" % disk_id)
         d_letter = utils_disk.configure_empty_windows_disk(session,
                                                            disk_id[0],
                                                            disk_size)[0]
         output_path = d_letter + ":\\test.dat"
     else:
         disks = utils_disk.get_linux_disks(session)
         for key, value in disks.items():
             if value[1] == disk_size and value[2] == "disk":
                 output_path = key
     if not output_path:
         test.fail("Can not get output file path in guest.")
     disk_op_cmd %= output_path
     return disk_op_cmd
示例#40
0
def trigger_crash(test, vm, params):
    """
    Trigger system crash with certain method.

    :param vm: target vm
    :parma params: test params
    """
    crash_method = params["crash_method"]
    if crash_method == "nmi":
        vm.monitor.nmi()
    elif crash_method in ("usb_keyboard", "ps2_keyboard"):
        crash_key1 = params["crash_key1"]
        crash_key2 = params["crash_key2"]
        vm.monitor.press_release_key(crash_key1)
        vm.send_key(crash_key2)
        vm.send_key(crash_key2)
    elif crash_method == "notmyfault_app":
        timeout = int(params.get("timeout", 360))
        session = vm.wait_for_login(timeout=timeout)
        cmd = params["notmyfault_cmd"] % random.randint(1, 8)
        notmyfault_cmd = utils_misc.set_winutils_letter(session, cmd)
        try:
            status, output = session.cmd_status_output(cmd=notmyfault_cmd,
                                                       timeout=timeout)
            if status:
                test.error("Command '%s' failed, status: %s, output: %s" %
                           (cmd, status, output))
        # notmyfault_app triggers BSOD of the guest, and it terminates
        # qemu process, so sometimes, it can not get the status of the cmd.
        except (aexpect.ShellTimeoutError,
                aexpect.ShellProcessTerminatedError,
                aexpect.ShellStatusError):
            pass
    else:
        test.cancel("Crash trigger method %s not supported, "
                    "please check cfg file for mistake." % crash_method)
示例#41
0
def run(test, params, env):
    """
    Run IOzone for windows on a windows guest:
    1) Log into a guest
    2) Execute the IOzone test contained in the winutils.iso
    3) Get results
    4) Postprocess it with the IOzone postprocessing module

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    def post_result(results_path, analysisdir):
        """
        Pick results from an IOzone run, generate a series graphs

        :params results_path: iozone test result path
        :params analysisdir: output of analysis result
        """
        a = postprocess_iozone.IOzoneAnalyzer(list_files=[results_path],
                                              output_dir=analysisdir)
        a.analyze()
        p = postprocess_iozone.IOzonePlotter(results_file=results_path,
                                             output_dir=analysisdir)
        p.plot_all()

    def get_driver():
        """
        Get driver name
        """
        driver_name = params.get("driver_name", "")
        drive_format = params.get("drive_format")
        if not driver_name:
            if "scsi" in drive_format:
                driver_name = "vioscsi"
            elif "virtio" in drive_format:
                driver_name = "viostor"
            else:
                driver_name = None
        return driver_name

    timeout = int(params.get("login_timeout", 360))
    iozone_timeout = int(params.get("iozone_timeout"))
    disk_letter = params.get("disk_letter", 'C')
    disk_index = params.get("disk_index", "2")
    results_path = os.path.join(test.resultsdir,
                                'raw_output_%s' % test.iteration)
    analysisdir = os.path.join(test.resultsdir, 'analysis_%s' % test.iteration)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)
    driver_name = get_driver()
    if driver_name:
        session = utils_test.qemu.windrv_check_running_verifier(session, vm,
                                                                test, driver_name,
                                                                timeout)
    if params.get("format_disk", "no") == "yes":
        error_context.context("Format disk", logging.info)
        utils_misc.format_windows_disk(session, disk_index,
                                       mountpoint=disk_letter)
    cmd = params["iozone_cmd"]
    iozone_cmd = utils_misc.set_winutils_letter(session, cmd)
    error_context.context("Running IOzone command on guest, timeout %ss"
                          % iozone_timeout, logging.info)

    status, results = session.cmd_status_output(cmd=iozone_cmd,
                                                timeout=iozone_timeout)
    error_context.context("Write results to %s" % results_path, logging.info)
    if status != 0:
        test.fail("iozone test failed: %s" % results)

    with open(results_path, 'w') as file:
        file.write(results)

    if params.get("post_result", "no") == "yes":
        error_context.context("Generate graph of test result", logging.info)
        post_result(results_path, analysisdir)
示例#42
0
def run(test, params, env):
    """
    KVM driver load test:
    1) Log into a guest
    2) Get the driver device id(Windows) or module name(Linux) from guest
    3) Unload/load the device driver
    4) Check if the device still works properly
    5) Repeat step 3-4 several times

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    def load_driver(cmd, driver_id):
        """
        Load driver
        :param cmd: Driver load cmd
        :param driver_id: Driver id in windows guest
        """
        nic_index = len(vm.virtnet) - 1
        session = vm.wait_for_login(nic_index=nic_index)
        if params["os_type"] == "windows":
            cmd = cmd.replace("DRIVER_ID", driver_id)

        status, output = session.cmd_status_output(cmd)
        session.close()
        if status != 0:
            test.fail("failed to load driver, %s" % output)

    def unload_driver(cmd, driver_id):
        """
        Unload driver
        :param cmd: Driver unload cmd
        :param driver_id: Driver id in windows guest
        """
        nic_index = len(vm.virtnet) - 1
        session = vm.wait_for_login(nic_index=nic_index)
        if params["os_type"] == "windows":
            cmd = cmd.replace("DRIVER_ID", driver_id)

        status, output = session.cmd_status_output(cmd)
        session.close()
        if status != 0:
            if "reboot" in output:
                vm.reboot()
                session.close()
            else:
                test.fail("failed to unload driver, %s" % output)

    def get_driver_id(cmd, pattern):
        """
        Get driver id from guest
        :param cmd: cmd to get driver info
        :param pattern: pattern to filter driver id
        """
        nic_index = len(vm.virtnet) - 1
        session = vm.wait_for_login(nic_index=nic_index)
        output = session.cmd_output(cmd)
        driver_id = re.findall(pattern, output)
        if not driver_id:
            test.fail("Didn't find driver info from guest %s" % output)

        driver_id = driver_id[0]
        if params["os_type"] == "windows":
            driver_id = '^&'.join(driver_id.split('&'))
        session.close()
        return driver_id

    def service_operate(cmd, ignore_error=False):
        """
        Stop/Start service
        :param cmd: cmd to stop/start service
        :param ignore_error: ignore the cmd error while it's True
                             else raise the error
        """
        session = vm.wait_for_login()
        session.cmd(cmd, ignore_all_errors=ignore_error)
        session.close()

    error_context.context("Try to log into guest.", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)
    stop_service_cmd = params.get("stop_service_cmd")
    start_service_cmd = params.get("start_service_cmd")

    driver_id_pattern = params["driver_id_pattern"]
    driver_id_cmd = utils_misc.set_winutils_letter(
        session, params["driver_id_cmd"])
    driver_load_cmd = utils_misc.set_winutils_letter(
        session, params["driver_load_cmd"])
    driver_unload_cmd = utils_misc.set_winutils_letter(
        session, params["driver_unload_cmd"])
    session.close()

    if stop_service_cmd:
        logging.info("Stop service before driver load testing")
        service_operate(stop_service_cmd)

    try:
        for repeat in range(0, int(params.get("repeats", 1))):
            error_context.context("Unload and load the driver. Round %s" %
                                  repeat, logging.info)
            logging.info("Get driver info from guest")
            driver_id = get_driver_id(driver_id_cmd, driver_id_pattern)

            error_context.context("Unload the driver", logging.info)
            unload_driver(driver_unload_cmd, driver_id)
            time.sleep(5)
            error_context.context("Load the driver", logging.info)
            load_driver(driver_load_cmd, driver_id)
            time.sleep(5)
    finally:
        if start_service_cmd:
            logging.info("Restart service after driver load testing")
            service_operate(start_service_cmd, ignore_error=True)

    test_after_load = params.get("test_after_load")
    if test_after_load:
        utils_test.run_virt_sub_test(test, params, env,
                                     sub_type=test_after_load)
示例#43
0
def run(test, params, env):
    """
    Qemu virtio-rng device test:
    1) boot guest with virtio-rng device
    3) check host random device opened by qemu (optional)
    4) enable driver verifier in guest
    5) check device using right driver in guest.
    6) read random data from guest.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    def is_dev_used_by_qemu(dev_file, vm_pid):
        """
        Check host random device opened by qemu.

        :param dev_file: host random device name.
        :param vm_pid: qemu process ID.
        :return: Match objects or None.
        """
        lsof_cmd = "lsof %s" % dev_file
        output = process.system_output(lsof_cmd, ignore_status=True).decode()
        return re.search(r"\s+%s\s+" % vm_pid, output, re.M)

    rng_data_rex = params.get("rng_data_rex", r".*")
    dev_file = params.get("filename_passthrough")
    timeout = float(params.get("login_timeout", 360))
    rng_dll_register_cmd = params.get("rng_dll_register_cmd")
    read_rng_timeout = float(params.get("read_rng_timeout", "360"))
    cmd_timeout = float(params.get("session_cmd_timeout", "360"))
    driver_name = params["driver_name"]
    os_type = params["os_type"]
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm_pid = vm.get_pid()

    if dev_file:
        error_context.context("Check '%s' used by qemu" % dev_file,
                              logging.info)
        if not is_dev_used_by_qemu(dev_file, vm_pid):
            msg = "Qemu (pid=%d) not using host passthrough " % vm_pid
            msg += "device '%s'" % dev_file
            test.fail(msg)
    session = vm.wait_for_login(timeout=timeout)

    if os_type == "windows":
        session = utils_test.qemu.windrv_check_running_verifier(session, vm,
                                                                test, driver_name,
                                                                timeout)
    else:
        error_context.context("verify virtio-rng device driver", logging.info)
        verify_cmd = params["driver_verifier_cmd"]
        try:
            output = session.cmd_output_safe(verify_cmd, timeout=cmd_timeout)
        except aexpect.ShellTimeoutError:
            err = "%s timeout, pls check if it's a product bug" % verify_cmd
            test.fail(err)

        if not re.search(r"%s" % driver_name, output, re.M):
            msg = "Verify device driver failed, "
            msg += "guest report driver is %s, " % output
            msg += "expect is '%s'" % driver_name
            test.fail(msg)

    error_context.context("Read virtio-rng device to get random number",
                          logging.info)
    read_rng_cmd = utils_misc.set_winutils_letter(
        session, params["read_rng_cmd"])

    if rng_dll_register_cmd:
        logging.info("register 'viorngum.dll' into system")
        session.cmd(rng_dll_register_cmd, timeout=120)

    if os_type == "linux":
        check_rngd_service = params.get("check_rngd_service")
        if check_rngd_service:
            output = session.cmd_output(check_rngd_service)
            if 'running' not in output:
                start_rngd_service = params["start_rngd_service"]
                status, output = session.cmd_status_output(start_rngd_service)
                if status:
                    test.error(output)

    if params.get("test_duration"):
        start_time = time.time()
        while (time.time() - start_time) < float(params.get("test_duration")):
            output = session.cmd_output(read_rng_cmd,
                                        timeout=read_rng_timeout)
            if len(re.findall(rng_data_rex, output, re.M)) < 2:
                test.fail("Unable to read random numbers from guest: %s"
                          % output)
    else:
        output = session.cmd_output(read_rng_cmd, timeout=read_rng_timeout)
        if len(re.findall(rng_data_rex, output, re.M)) < 2:
            test.fail("Unable to read random numbers from guest: %s" % output)
    session.close()
示例#44
0
def run(test, params, env):
    """
    QEMU windows guest vitio device irq check test

    1) Start guest with virtio device.
    2) Make sure driver verifier enabled in guest.
    3) Get irq info in guest and check the value of irq number.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def get_vectors_fqtree():
        """
        Get device vectors from qemu info qtree.
        """
        device_type = params["device_type"]
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        for node in qtree.get_nodes():
            if (isinstance(node, qemu_qtree.QtreeDev) and
                    node.qtree['type'] == device_type):
                vectors = node.qtree["vectors"].split()[0]
                return vectors

    def irq_check(session, device_name, devcon_folder, timeout):
        """
        Check virtio device's irq number, irq number should be greater than zero.

        :param session: use for sending cmd
        :param device_name: name of the specified device
        :param devcon_folder: Full path for devcon.exe
        :param timeout: Timeout in seconds.
        """
        hwids = win_dev.get_hwids(session, device_name, devcon_folder, timeout)
        if not hwids:
            test.error("Didn't find %s device info from guest" % device_name)
        if params.get("check_vectors", "no") == "yes":
            vectors = int(get_vectors_fqtree())
        for hwid in hwids:
            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)
            irq_nums = len(irq_list)
            for irq_symbol in (ctypes.c_int32(int(irq)).value for irq in irq_list):
                if (irq_nums == 1 and irq_symbol < 0) or (irq_nums > 1 and irq_symbol >= 0):
                    test.fail("%s's irq is not correct." % device_name)
                elif irq_nums > 1 and (irq_nums != vectors):
                    test.fail("%s's irq nums not equal to vectors." % device_name)

    def set_msi_fguest(enable=True):
        """
        Disable or enable MSI from guest.
        """
        hwid = win_dev.get_hwids(session, device_name, devcon_folder, timeout)[0]
        session.cmd(params["msi_cmd"] % (hwid, 0 if enable else 1))

    driver = params["driver_name"]
    device_name = params["device_name"]
    timeout = int(params.get("login_timeout", 360))
    restore_msi = False

    error_context.context("Boot guest with %s device" % driver, logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)
    session = utils_test.qemu.windrv_check_running_verifier(session, vm,
                                                            test, driver,
                                                            timeout)

    error_context.context("Check %s's irq number" % device_name, logging.info)
    devcon_folder = utils_misc.set_winutils_letter(session, params["devcon_folder"])
    if params.get("msi_cmd"):
        error_context.context("Set MSI in guest", logging.info)
        set_msi_fguest(enable=True)
        session = vm.reboot(session=session)
        restore_msi = True
    irq_check(session, device_name, devcon_folder, timeout)

    if restore_msi:
        set_msi_fguest(enable=False)

    if session:
        session.close()
示例#45
0
def run(test, params, env):
    """
    Qemu multiqueue test for virtio-scsi controller:

    1) Boot up a guest with virtio-scsi device which support multi-queue and
       the vcpu and images number of guest should match the multi-queue number
    2) Check the multi queue option from monitor
    3) Check device init status in guest
    4) Load I/O in all targets
    5) Check the interrupt queues in guest

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def proc_interrupts_results(results, irqs_pattern):
        results_dict = {}
        cpu_count = 0
        cpu_list = []
        for line in results.splitlines():
            line = line.strip()
            if re.match("CPU0", line):
                cpu_list = re.findall(r"CPU\d+", line)
                cpu_count = len(cpu_list)
                continue
            if cpu_count > 0:
                irq_key = re.split(":", line)[0]
                if re.findall(irqs_pattern, re.split(":", line)[-1]):
                    results_dict[irq_key] = {}
                    content = line[len(irq_key) + 1:].strip()
                    if len(re.split(r"\s+", content)) < cpu_count:
                        continue
                    count = 0
                    irq_des = ""
                    for irq_item in re.split(r"\s+", content):
                        if count < cpu_count:
                            if count == 0:
                                results_dict[irq_key]["count"] = []
                            results_dict[irq_key]["count"].append(irq_item)
                        else:
                            irq_des += " %s" % irq_item
                        count += 1
                    results_dict[irq_key]["irq_des"] = irq_des.strip()
        if not results_dict:
            test.error("Couldn't find virtio request interrupts from procfs")
        return results_dict, cpu_list

    timeout = float(params.get("login_timeout", 240))
    host_cpu_num = utils_cpu.online_cpus_count()
    while host_cpu_num:
        num_queues = str(host_cpu_num)
        host_cpu_num &= host_cpu_num - 1
    params['smp'] = num_queues
    params['num_queues'] = num_queues
    images_num = int(num_queues)
    extra_image_size = params.get("image_size_extra_images", "512M")
    system_image = params.get("images")
    system_image_drive_format = params.get("system_image_drive_format",
                                           "virtio")
    params["drive_format_%s" % system_image] = system_image_drive_format

    error_context.context("Boot up guest with block devcie with num_queues"
                          " is %s and smp is %s" % (num_queues, params['smp']),
                          logging.info)
    for vm in env.get_all_vms():
        if vm.is_alive():
            vm.destroy()
    for extra_image in range(images_num):
        image_tag = "stg%s" % extra_image
        params["images"] += " %s" % image_tag
        params["image_name_%s" % image_tag] = "images/%s" % image_tag
        params["image_size_%s" % image_tag] = extra_image_size
        params["force_create_image_%s" % image_tag] = "yes"
        image_params = params.object_params(image_tag)
        env_process.preprocess_image(test, image_params, image_tag)

    params["start_vm"] = "yes"
    vm = env.get_vm(params["main_vm"])
    env_process.preprocess_vm(test, params, env, vm.name)
    session = vm.wait_for_login(timeout=timeout)

    if params.get("os_type") == "windows":
        driver_name = params["driver_name"]
        wmi_check_cmd = params["wmi_check_cmd"]
        pattern = params["pattern"]
        session = utils_test.qemu.windrv_check_running_verifier(session, vm, test,
                                                                driver_name, timeout)
        wmi_check_cmd = utils_misc.set_winutils_letter(session, wmi_check_cmd)
        error_context.context("Run wmi check in guest.", logging.info)
        output = session.cmd_output(wmi_check_cmd)
        queue_num = re.findall(pattern, output, re.M)
        try:
            if not queue_num or queue_num[0] != num_queues:
                test.fail("The queue_num from guest is not match with expected.\n"
                          "queue_num from guest is %s, expected is %s"
                          % (queue_num, num_queues))
        finally:
            session.close()
            return
    error_context.context("Check irqbalance service status", logging.info)
    output = session.cmd_output("systemctl status irqbalance")
    if not re.findall("Active: active", output):
        session.cmd("systemctl start irqbalance")
        output = session.cmd_output("systemctl status irqbalance")
        output = utils_misc.strip_console_codes(output)
        if not re.findall("Active: active", output):
            test.cancel("Can not start irqbalance inside guest. "
                        "Skip this test.")

    error_context.context("Pin vcpus to host cpus", logging.info)
    host_numa_nodes = utils_misc.NumaInfo()
    vcpu_num = 0
    for numa_node_id in host_numa_nodes.nodes:
        numa_node = host_numa_nodes.nodes[numa_node_id]
        for _ in range(len(numa_node.cpus)):
            if vcpu_num >= len(vm.vcpu_threads):
                break
            vcpu_tid = vm.vcpu_threads[vcpu_num]
            logging.debug("pin vcpu thread(%s) to cpu"
                          "(%s)" % (vcpu_tid,
                                    numa_node.pin_cpu(vcpu_tid)))
            vcpu_num += 1

    error_context.context("Verify num_queues from monitor", logging.info)
    qtree = qemu_qtree.QtreeContainer()
    try:
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
    except AttributeError:
        test.cancel("Monitor deson't supoort qtree skip this test")
    error_msg = "Number of queues mismatch: expect %s"
    error_msg += " report from monitor: %s(%s)"
    scsi_bus_addr = ""
    qtree_num_queues_full = ""
    qtree_num_queues = ""
    for node in qtree.get_nodes():
        if isinstance(node, qemu_qtree.QtreeDev) and (
                node.qtree['type'] == "virtio-scsi-device"):
            qtree_num_queues_full = node.qtree["num_queues"]
            qtree_num_queues = re.search(
                "[0-9]+",
                qtree_num_queues_full).group()
        elif isinstance(node, qemu_qtree.QtreeDev) and node.qtree['type'] == "virtio-scsi-pci":
            scsi_bus_addr = node.qtree['addr']

    if qtree_num_queues != num_queues:
        error_msg = error_msg % (num_queues,
                                 qtree_num_queues,
                                 qtree_num_queues_full)
        test.fail(error_msg)
    if not scsi_bus_addr:
        test.error("Didn't find addr from qtree. Please check the log.")
    error_context.context("Check device init status in guest", logging.info)
    irq_check_cmd = params.get("irq_check_cmd", "cat /proc/interrupts")
    output = session.cmd_output(irq_check_cmd)
    irq_name = params.get("irq_regex")
    prev_irq_results, _ = proc_interrupts_results(output, irq_name)
    logging.debug('The info of interrupters before testing:')
    for irq_watch in prev_irq_results.keys():
        logging.debug('%s : %s %s' % (irq_watch, prev_irq_results[irq_watch]['count'],
                                      prev_irq_results[irq_watch]['irq_des']))

    error_context.context("Pin the interrupters to vcpus", logging.info)
    cpu_select = 1
    for irq_id in prev_irq_results.keys():
        bind_cpu_cmd = "echo %s > /proc/irq/%s/smp_affinity" % \
                       (hex(cpu_select).replace('0x', ''), irq_id)
        cpu_select = cpu_select << 1
        session.cmd(bind_cpu_cmd)

    error_context.context("Load I/O in all targets", logging.info)
    get_dev_cmd = params.get("get_dev_cmd", "ls /dev/[svh]d*")
    output = session.cmd_output(get_dev_cmd)
    system_dev = re.findall(r"/dev/[svh]d\w+(?=\d+)", output)[0]
    dd_timeout = int(re.findall(r"\d+", extra_image_size)[0])
    fill_cmd = ""
    count = 0
    for dev in re.split(r"\s+", output):
        if not dev:
            continue
        if not re.findall(system_dev, dev):
            fill_cmd += " dd of=%s if=/dev/urandom bs=1M " % dev
            fill_cmd += "count=%s oflag=direct &" % dd_timeout
            count += 1
    if count != images_num:
        test.error("Disks are not all show up in system. Output "
                   "from the check command: %s" % output)
    # As Bug 1177332 exists, mq is not supported completely.
    # So don't considering performance currently, dd_timeout is longer.
    dd_timeout = dd_timeout * images_num * 2
    session.cmd(fill_cmd, timeout=dd_timeout)

    dd_thread_num = count
    while dd_thread_num:
        time.sleep(5)
        dd_thread_num = session.cmd_output("pgrep -x dd", timeout=dd_timeout)

    error_context.context("Check the interrupt queues in guest", logging.info)
    output = session.cmd_output(irq_check_cmd)
    next_irq_results, cpu_list = proc_interrupts_results(output, irq_name)
    logging.debug('The info of interrupters after testing :')
    for irq_watch in next_irq_results.keys():
        logging.debug('%s : %s %s' % (irq_watch, next_irq_results[irq_watch]['count'],
                                      next_irq_results[irq_watch]['irq_des']))
    irq_bit_map = 0
    for irq_watch in next_irq_results.keys():
        for index, count in enumerate(next_irq_results[irq_watch]["count"]):
            if (int(count) - int(prev_irq_results[irq_watch]["count"][index])) > 0:
                irq_bit_map |= 2 ** index

    error_msg = ""
    cpu_not_used = []
    for index, cpu in enumerate(cpu_list):
        if 2 ** index & irq_bit_map != 2 ** index:
            cpu_not_used.append(cpu)

    if cpu_not_used:
        logging.debug("Interrupt info from procfs:\n%s" % output)
        error_msg = " ".join(cpu_not_used)
        if len(cpu_not_used) > 1:
            error_msg += " are"
        else:
            error_msg += " is"
        error_msg += " not used during test. Please check debug log for"
        error_msg += " more information."
        test.fail(error_msg)
示例#46
0
def run(test, params, env):
    """
    This Test is mainly used as subtests
    1) Boot up VM
    2) Uninstall driver (Optional)
    3) Reboot vm (Based on step 2)
    4) Update / Downgrade / Install driver
    5) Reboot vm
    6) Verify installed driver

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    inst_timeout = int(params.get("driver_install_timeout", INSTALL_TIMEOUT))
    driver_name = params["driver_name"]
    device_name = params["device_name"]
    device_hwid = params["device_hwid"]

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

    # wait for cdroms having driver installed in case that
    # they are new appeared in this test
    utils_misc.wait_for(lambda: utils_misc.get_winutils_vol(session),
                        timeout=OPERATION_TIMEOUT, step=10)

    devcon_path = utils_misc.set_winutils_letter(session,
                                                 params["devcon_path"])
    status, output = session.cmd_status_output("dir %s" % devcon_path,
                                               timeout=OPERATION_TIMEOUT)
    if status:
        test.error("Not found devcon.exe, details: %s" % output)

    media_type = params["virtio_win_media_type"]
    try:
        get_drive_letter = getattr(virtio_win, "drive_letter_%s" % media_type)
        get_product_dirname = getattr(virtio_win,
                                      "product_dirname_%s" % media_type)
        get_arch_dirname = getattr(virtio_win, "arch_dirname_%s" % media_type)
    except AttributeError:
        test.error("Not supported virtio win media type '%s'", media_type)
    viowin_ltr = get_drive_letter(session)
    if not viowin_ltr:
        test.error("Could not find virtio-win drive in guest")
    guest_name = get_product_dirname(session)
    if not guest_name:
        test.error("Could not get product dirname of the vm")
    guest_arch = get_arch_dirname(session)
    if not guest_arch:
        test.error("Could not get architecture dirname of the vm")

    inf_middle_path = ("{name}\\{arch}" if media_type == "iso"
                       else "{arch}\\{name}").format(name=guest_name,
                                                     arch=guest_arch)
    inf_find_cmd = 'dir /b /s %s\\%s.inf | findstr "\\%s\\\\"'
    inf_find_cmd %= (viowin_ltr, driver_name, inf_middle_path)
    inf_path = session.cmd(inf_find_cmd, timeout=OPERATION_TIMEOUT).strip()
    logging.info("Found inf file '%s'", inf_path)

    expected_ver = session.cmd("findstr DriverVer= %s" % inf_path,
                               timeout=OPERATION_TIMEOUT)
    expected_ver = expected_ver.strip().split(",", 1)[-1]
    if not expected_ver:
        test.error("Failed to find driver version from inf file")
    logging.info("Target version is '%s'", expected_ver)

    if params.get("need_uninstall", "no") == "yes":
        error_context.context("Uninstalling previous installed driver",
                              logging.info)
        for inf_name in _pnpdrv_info(session, device_name, ["InfName"]):
            uninst_store_cmd = "pnputil /f /d %s" % inf_name
            status, output = session.cmd_status_output(uninst_store_cmd,
                                                       inst_timeout)
            if status:
                test.error("Failed to uninstall driver '%s' from store, "
                           "details:\n%s" % (driver_name, output))

        uninst_cmd = "%s remove %s" % (devcon_path, device_hwid)
        status, output = session.cmd_status_output(uninst_cmd, inst_timeout)
        # acceptable status: OK(0), REBOOT(1)
        if status > 1:
            test.error("Failed to uninstall driver '%s', details:\n"
                       "%s" % (driver_name, output))

        session = vm.reboot(session)

    error_context.context("Installing certificates", logging.info)
    cert_files = utils_misc.set_winutils_letter(session,
                                                params.get("cert_files", ""))
    cert_files = [cert.split("=", 1) for cert in cert_files.split()]
    for store, cert in cert_files:
        _chk_cert(session, cert)
        _add_cert(session, cert, store)

    error_context.context("Installing target driver", logging.info)
    installed_any = False
    for hwid in device_hwid.split():
        output = session.cmd_output("%s find %s" % (devcon_path, hwid))
        if re.search("No matching devices found", output, re.I):
            continue
        inst_cmd = "%s updateni %s %s" % (devcon_path, inf_path, hwid)
        status, output = session.cmd_status_output(inst_cmd, inst_timeout)
        # acceptable status: OK(0), REBOOT(1)
        if status > 1:
            test.fail("Failed to install driver '%s', "
                      "details:\n%s" % (driver_name, output))
        installed_any |= True
    if not installed_any:
        test.error("Failed to find target devices "
                   "by hwids: '%s'" % device_hwid)

    error_context.context("Verifying target driver", logging.info)
    session = vm.reboot(session)
    windrv_verify_running(session, test, driver_name)

    ver_list = _pnpdrv_info(session, device_name, ["DriverVersion"])
    if expected_ver not in ver_list:
        test.fail("The expected driver version is '%s', but "
                  "found '%s'" % (expected_ver, ver_list))
    session.close()
示例#47
0
文件: rng_bat.py 项目: CongLi/tp-qemu
def run(test, params, env):
    """
    Qemu virtio-rng device test:
    1) boot guest with virtio-rng device
    3) check host random device opened by qemu (optional)
    4) enable driver verifier in guest
    5) check device using right driver in guest.
    6) read random data from guest.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    def is_dev_used_by_qemu(dev_file, vm_pid):
        """
        Check host random device opened by qemu.

        :param dev_file: host random device name.
        :param vm_pid: qemu process ID.
        :return: Match objects or None.
        """
        lsof_cmd = "lsof %s" % dev_file
        output = process.system_output(lsof_cmd, ignore_status=True)
        return re.search(r"\s+%s\s+" % vm_pid, output, re.M)

    def check_driver_status(session, check_cmd, driver_id):
        """
        :param session: VM session
        :param check_cmd: cmd to check driver status
        :param driver_id: driver id
        """
        check_cmd = check_cmd.replace("DRIVER_ID", driver_id)
        status, output = session.cmd_status_output(check_cmd)
        if "disabled" in output:
            raise exceptions.TestFail("Driver is disable")

    def get_driver_id(session, cmd, pattern):
        """
        :param session: VM session
        :param cmd: cmd to get driver id
        :param pattern: driver id pattern
        """
        output = session.cmd_output(cmd)
        driver_id = re.findall(pattern, output)
        if not driver_id:
            raise exceptions.TestFail("Didn't find driver info from guest %s"
                                      % output)
        driver_id = driver_id[0]
        driver_id = '^&'.join(driver_id.split('&'))
        return driver_id

    rng_data_rex = params.get("rng_data_rex", r".*")
    dev_file = params.get("filename_passthrough")
    timeout = float(params.get("login_timeout", 360))
    rng_dll_register_cmd = params.get("rng_dll_register_cmd")
    read_rng_timeout = float(params.get("read_rng_timeout", "360"))
    cmd_timeout = float(params.get("session_cmd_timeout", "360"))
    driver_name = params["driver_name"]
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm_pid = vm.get_pid()

    if dev_file:
        error_context.context("Check '%s' used by qemu" % dev_file,
                              logging.info)
        if not is_dev_used_by_qemu(dev_file, vm_pid):
            msg = "Qemu (pid=%d) not using host passthrough " % vm_pid
            msg += "device '%s'" % dev_file
            raise exceptions.TestFail(msg)

    if params["os_type"] == "windows":
        utils_test.qemu.setup_win_driver_verifier(driver_name,
                                                  vm, timeout)
        error_context.context("Check driver status", logging.info)
        session = vm.wait_for_login(timeout=timeout)
        driver_id_cmd = utils_misc.set_winutils_letter(
            session, params["driver_id_cmd"])
        driver_id = get_driver_id(session, driver_id_cmd,
                                  params["driver_id_pattern"])
        if params.get("driver_check_cmd"):
            driver_check_cmd = utils_misc.set_winutils_letter(
                session, params.get("driver_check_cmd"))
            check_driver_status(session, driver_check_cmd, driver_id)
    else:
        error_context.context("verify virtio-rng device driver", logging.info)
        session = vm.wait_for_login(timeout=timeout)
        verify_cmd = params["driver_verifier_cmd"]
        try:
            output = session.cmd_output_safe(verify_cmd, timeout=cmd_timeout)
        except aexpect.ShellTimeoutError:
            err = "%s timeout, pls check if it's a product bug" % verify_cmd
            raise exceptions.TestFail(err)

        if not re.search(r"%s" % driver_name, output, re.M):
            msg = "Verify device driver failed, "
            msg += "guest report driver is %s, " % output
            msg += "expect is '%s'" % driver_name
            raise exceptions.TestFail(msg)

    error_context.context("Read virtio-rng device to get random number",
                          logging.info)
    read_rng_cmd = utils_misc.set_winutils_letter(
        session, params["read_rng_cmd"])

    if rng_dll_register_cmd:
        logging.info("register 'viorngum.dll' into system")
        session.cmd(rng_dll_register_cmd, timeout=120)

    output = session.cmd_output(read_rng_cmd, timeout=read_rng_timeout)
    if len(re.findall(rng_data_rex, output, re.M)) < 2:
        raise exceptions.TestFail("Unable to read random numbers from"
                                  "guest: %s" % output)
    session.close()
示例#48
0
def run(test, params, env):
    """
    Test hotplug of block devices.

    1) Boot up guest with/without block device(s).
    2) Hoplug block device and verify
    3) Do read/write data on hotplug block.
    4) Unplug block device and verify

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def find_image(image_name):
        """
        Find the path of the iamge.
        """
        image_params = params.object_params(image_name)
        o = storage.get_image_filename(image_params, data_dir.get_data_dir())
        return o

    def find_disk(vm, cmd):
        """
        Find all disks in guest.
        """
        if params.get("os_type") == "linux":
            pattern = params.get("get_disk_pattern", "^/dev/vd[a-z]*$")
        elif params.get("os_type") == "windows":
            pattern = "^\d+"
            cmd = params.get("get_disk_index", "wmic diskdrive get index")
        else:
            test.cancel("Unsupported OS type '%s'" % params.get("os_type"))

        session = vm.wait_for_login(timeout=timeout)
        output = session.cmd_output_safe(cmd)
        disks = re.findall(pattern, output, re.M)
        session.close()
        return disks

    def get_new_disk(disk1, disk2):
        """
        Get the different disk between disk1 and disk2.
        """
        disk = list(set(disk2).difference(set(disk1)))
        return disk

    img_list = params.get("images").split()
    img_format_type = params.get("img_format_type", "qcow2")
    pci_type = params.get("pci_type", "virtio-blk-pci")
    #sometimes, ppc can't get new plugged disk in 5s, so time to 10s
    pause = float(params.get("virtio_block_pause", 10.0))
    blk_num = int(params.get("blk_num", 1))
    repeat_times = int(params.get("repeat_times", 3))
    timeout = int(params.get("login_timeout", 360))
    disk_op_timeout = int(params.get("disk_op_timeout", 360))
    get_disk_cmd = params.get("get_disk_cmd")
    context_msg = "Running sub test '%s' %s"
    device_list = []
    disk_index = params.objects("disk_index")
    disk_letter = params.objects("disk_letter")

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

    for iteration in xrange(repeat_times):
        error_context.context("Hotplug block device (iteration %d)" % iteration,
                              logging.info)

        sub_type = params.get("sub_type_before_plug")
        if sub_type:
            error_context.context(context_msg % (sub_type, "before hotplug"),
                                  logging.info)
            utils_test.run_virt_sub_test(test, params, env, sub_type)

        for num in xrange(blk_num):
            device = qdevices.QDevice(pci_type)
            if params.get("need_plug") == "yes":
                disks_before_plug = find_disk(vm, get_disk_cmd)

                if params.get("need_controller", "no") == "yes":
                    controller_model = params.get("controller_model")
                    controller = qdevices.QDevice(controller_model)
                    bus_extra_param = params.get("bus_extra_params_%s" % img_list[num + 1])
                    # TODO:Add iothread support for qdevice
                    if bus_extra_param and "iothread" in bus_extra_param:
                        match = re.search("iothread=(\w+)", bus_extra_param)
                        if match:
                            qdevice_params = {"iothread": match.group(1)}
                            controller.params.update(qdevice_params)
                    controller.hotplug(vm.monitor)
                    ver_out = controller.verify_hotplug("", vm.monitor)
                    if not ver_out:
                        err = "%s is not in qtree after hotplug" % controller_model
                        test.fail(err)

                drive = qdevices.QRHDrive("block%d" % num)
                drive.set_param("file", find_image(img_list[num + 1]))
                drive.set_param("format", img_format_type)
                drive_id = drive.get_param("id")
                drive.hotplug(vm.monitor)

                device.set_param("drive", drive_id)
                device.set_param("id", "block%d" % num)
                blk_extra_param = params.get("blk_extra_params_%s" % img_list[num + 1])
                if blk_extra_param and "iothread" in blk_extra_param:
                    match = re.search("iothread=(\w+)", blk_extra_param)
                    if match:
                        device.set_param("iothread", match.group(1))
                device.hotplug(vm.monitor)
                ver_out = device.verify_hotplug("", vm.monitor)
                if not ver_out:
                    err = "%s is not in qtree after hotplug" % pci_type
                    test.fail(err)
                plug_status = utils_misc.wait_for(lambda: len(get_new_disk(disks_before_plug,
                                                  find_disk(vm, get_disk_cmd))) != 0, pause)
                if plug_status:
                    disks_after_plug = find_disk(vm, get_disk_cmd)
                    new_disks = get_new_disk(disks_before_plug, disks_after_plug)
                else:
                    test.fail("Can't get new disks")
            else:
                if params.get("drive_format") in pci_type:
                    get_disk_cmd += " | egrep -v '^/dev/[hsv]da[0-9]*$'"

                device.set_param("id", img_list[num + 1])
                new_disks = find_disk(vm, get_disk_cmd)

            device_list.append(device)
            if not new_disks:
                test.fail("Cannot find new disk after hotplug.")

            if params.get("need_plug") == "yes":
                disk = new_disks[0]
            else:
                disk = new_disks[num]

            session = vm.wait_for_login(timeout=timeout)
            if params.get("os_type") == "windows":
                if iteration == 0:
                    error_context.context("Format disk", logging.info)
                    utils_misc.format_windows_disk(session, disk_index[num],
                                                   mountpoint=disk_letter[num])
            error_context.context("Check block device after hotplug.",
                                  logging.info)
            if params.get("disk_op_cmd"):
                if params.get("os_type") == "linux":
                    test_cmd = params.get("disk_op_cmd") % (disk, disk)
                elif params.get("os_type") == "windows":
                    test_cmd = params.get("disk_op_cmd") % (disk_letter[num],
                                                            disk_letter[num])
                    test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
                else:
                    test.cancel("Unsupported OS type '%s'" % params.get("os_type"))

                status, output = session.cmd_status_output(test_cmd,
                                                           timeout=disk_op_timeout)
                if status:
                    test.fail("Check for block device failed "
                              "after hotplug, Output: %r" % output)
            session.close()

        sub_type = params.get("sub_type_after_plug")
        if sub_type:
            error_context.context(context_msg % (sub_type, "after hotplug"),
                                  logging.info)
            utils_test.run_virt_sub_test(test, params, env, sub_type)
            if vm.is_dead():
                return

        sub_type = params.get("sub_type_before_unplug")
        if sub_type:
            error_context.context(context_msg % (sub_type, "before unplug"),
                                  logging.info)
            utils_test.run_virt_sub_test(test, params, env, sub_type)

        for num in xrange(blk_num):
            error_context.context("Unplug block device (iteration %d)" % iteration,
                                  logging.info)
            disks_before_unplug = find_disk(vm, get_disk_cmd)
            device_list[num].unplug(vm.monitor)
            device_list[num].verify_unplug("", vm.monitor)
            unplug_status = utils_misc.wait_for(lambda: len(get_new_disk(find_disk(vm, get_disk_cmd),
                                                disks_before_unplug)) != 0, pause)
            if not unplug_status:
                test.fail("Failed to unplug disks")

        sub_type = params.get("sub_type_after_unplug")
        if sub_type:
            error_context.context(context_msg % (sub_type, "after unplug"),
                                  logging.info)
            utils_test.run_virt_sub_test(test, params, env, sub_type)
示例#49
0
def run(test, params, env):
    """
    live_snapshot chain test:

    Will test snapshot as following steps:
    1. Boot up guest with base image
    2. Do pre snapshot operates(option)
    3. Do live snapshot
    4. Do post snapshot operates(option)
    5. Check the base and snapshot images(option)

    :param test: Kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def generate_snapshot_chain(snapshot_chain, snapshot_num):
        for i in range(snapshot_num):
            snapshot_tag = "sn%s" % i
            snapshot_chain += " %s" % snapshot_tag
            params["image_name_%s" % snapshot_tag] = "images/%s" % snapshot_tag
        if snapshot_num > 0:
            params["check_base_image_%s" % snapshot_tag] = "yes"
        return snapshot_chain

    def get_base_image(snapshot_chain, snapshot_file):
        try:
            index = snapshot_chain.index(snapshot_file)
        except ValueError:
            index = -1

        if index > 0:
            base_image = snapshot_chain[index - 1]
        else:
            base_image = None
        return base_image

    def do_operate(params, key_word):
        operate_cmd = params.get(key_word)
        timeout = int(params.get("operate_timeout", "60"))
        for cmd in re.findall("{(.+?)}", operate_cmd):
            if re.match("shell:", cmd):
                cmd = cmd[6:]
                session.cmd(cmd, timeout=timeout)
            elif re.match("shell_no_reply:", cmd):
                cmd = cmd[15:]
                session.sendline(cmd)
                time.sleep(timeout)
            elif re.match("monitor:", cmd):
                cmd = cmd[8:]
                vm.monitor.send_args_cmd(cmd)

    def cleanup_images(snapshot_chain, params):
        if not params.get("remove_snapshot_images"):
            return []
        errs = []
        for index, image in enumerate(snapshot_chain):
            try:
                image_params = params.object_params(image)
                if index != 0:
                    image = qemu_storage.QemuImg(
                        image_params, data_dir.get_data_dir(), image)
                    if not os.path.exists(image.image_filename):
                        errs.append("Image %s was not created during test."
                                    % image.image_filename)
                    image.remove()
            except Exception as details:
                errs.append("Fail to remove image %s: %s"
                            % (image.image_filename, details))
        return errs

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    snapshot_chain = params.get("snapshot_chain")
    snapshot_num = int(params.get("snapshot_num", 0))
    file_create_cmd = params.get("file_create_cmd")
    file_check_cmd = params.get("file_check_cmd")
    file_dir = params.get("file_dir")
    dir_create_cmd = params.get("dir_create_cmd")
    md5_cmd = params.get("md5_cmd")
    sync_cmd = params.get("sync_bin", "sync")

    snapshot_chain = generate_snapshot_chain(snapshot_chain, snapshot_num)
    snapshot_chain = re.split(r"\s+", snapshot_chain)
    session = vm.wait_for_login(timeout=timeout)
    sync_cmd = utils_misc.set_winutils_letter(session, sync_cmd)

    md5_value = {}
    files_in_guest = {}
    try:
        for index, image in enumerate(snapshot_chain):
            image_params = params.object_params(image)
            if image_params.get("file_create"):
                session.cmd(dir_create_cmd % file_dir)
            if index > 0:
                snapshot_file = storage.get_image_filename(image_params,
                                                           data_dir.get_data_dir())
                base_image = get_base_image(snapshot_chain, image)
                base_image_params = params.object_params(base_image)
                base_file = storage.get_image_filename(base_image_params,
                                                       data_dir.get_data_dir())
                snapshot_format = image_params.get("image_format")

                error_context.context("Do pre snapshot operates", logging.info)
                if image_params.get("pre_snapshot_cmd"):
                    do_operate(image_params, "pre_snapshot_cmd")

                error_context.context("Do live snapshot ", logging.info)
                vm.live_snapshot(base_file, snapshot_file, snapshot_format)

                error_context.context("Do post snapshot operates",
                                      logging.info)
                if image_params.get("post_snapshot_cmd"):
                    do_operate(image_params, "post_snapshot_cmd")
                md5 = ""
                if image_params.get("file_create"):
                    session.cmd(file_create_cmd % image)
                    md5 = session.cmd_output(md5_cmd % image)
                md5_value[image] = md5_value[base_image].copy()
                md5_value[image].update({image: md5})
            elif index == 0:
                md5 = ""
                if params.get("file_create"):
                    session.cmd(file_create_cmd % image)
                    md5 = session.cmd_output(md5_cmd % image)
                md5_value[image] = {image: md5}
            status, output = session.cmd_status_output(sync_cmd)
            if status != 0:
                test.error("Execute '%s' with failures('%s') " %
                           (sync_cmd, output))
            if image_params.get("check_alive_cmd"):
                session.cmd(image_params.get("check_alive_cmd"))
            if image_params.get("file_create"):
                files_check = session.cmd(file_check_cmd % file_dir)
                files_in_guest[image] = files_check
        session.close()

        error_context.context("Reboot guest", logging.info)
        if image_params.get("need_reboot", "no") == "yes":
            vm.monitor.cmd("system_reset")
            vm.verify_alive()

        error_context.context("Do base files check", logging.info)
        snapshot_chain_backward = snapshot_chain[:]
        snapshot_chain_backward.reverse()

        for index, image in enumerate(snapshot_chain_backward):
            image_params = params.object_params(image)
            if image_params.get("check_base_image"):
                vm.destroy()
                vm.create(params=image_params)
                vm.verify_alive()

                session = vm.wait_for_login(timeout=timeout)
                if image_params.get("file_create"):
                    for file in md5_value[image]:
                        md5 = session.cmd_output(md5_cmd % file)
                        if md5 != md5_value[image][file]:
                            error_message = "File %s in image %s changed " %\
                                            (file, image)
                            error_message += "from '%s' to '%s'(md5)" %\
                                             (md5_value[image][file], md5)
                            test.fail(error_message)
                    files_check = session.cmd(file_check_cmd % file_dir)
                    if files_check != files_in_guest[image]:
                        error_message = "Files in image %s is not as expect:" %\
                                        image
                        error_message += "Before shut down: %s" %\
                            files_in_guest[image]
                        error_message += "Now: %s" % files_check
                        test.fail(error_message)
                if image_params.get("image_check"):
                    image = qemu_storage.QemuImg(
                        image_params, data_dir.get_data_dir(), image)
                    image.check_image(image_params, data_dir.get_data_dir())
                session.close()

        error_context.context("Remove snapshot images", logging.info)
        if vm.is_alive():
            vm.destroy()
        errs = cleanup_images(snapshot_chain, params)
        test.assertFalse(errs, "Errors occurred while removing images:\n%s"
                         % "\n".join(errs))
    except Exception as details:
        error_context.context("Force-cleaning after exception: %s" % details,
                              logging.error)
        if vm.is_alive():
            vm.destroy()
        cleanup_images(snapshot_chain, params)
        raise
示例#50
0
def run(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest with virtio data disk
    2) Format the disk and copy file to it
    3) Stop the guest and boot up it again with the data disk set to readonly
    4) Try to copy file to the data disk
    5) Try to copy file from the data disk

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    error_context.context(
        "TEST STEPS 1: Try to log into guest.", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 2: Format the disk and copy file to it", logging.info)
    os_type = params["os_type"]
    copy_cmd = params.get("copy_cmd", "copy %s %s")
    disk_idx = params.get("disk_index", 1)
    fs_type = params.get("fstype", "ntfs")
    drive_letter = params.get("drive_letter", "I:")
    disk_size = params.get("partition_size_data", "200M")
    src_file = utils_misc.set_winutils_letter(
        session, params["src_file"], label="WIN_UTILS")
    utils_misc.format_guest_disk(session, disk_idx, drive_letter,
                                 disk_size, fs_type, os_type)
    dst_file = params["dst_file"]
    session.cmd(copy_cmd % (src_file, dst_file))

    msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk"
    msg += " set to readonly"
    error_context.context(msg, logging.info)
    session.close()
    vm.destroy()

    data_img = params.get("images").split()[-1]
    params["image_readonly_%s" % data_img] = "yes"
    params["force_create_image_%s" % data_img] = "no"
    env_process.preprocess(test, params, env)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 4: Write to the readonly disk expect:"
        "The media is write protected", logging.info)
    dst_file_readonly = params["dst_file_readonly"]
    o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly))
    if not o.find("write protect"):
        raise exceptions.TestFail(
            "Write in readonly disk should failed\n. {}".format(o))

    error_context.context(
        "TEST STEPS 5: Try to read from the readonly disk", logging.info)
    s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\"))
    if s != 0:
        raise exceptions.TestFail("Read file failed\n. {}".format(o))

    session.close()
示例#51
0
def run(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest with virtio data disk
    2) Format the disk and copy file to it
    3) Stop the guest and boot up it again with the data disk set to readonly
    4) Try to copy file to the data disk
    5) Try to copy file from the data disk

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    error_context.context(
        "TEST STEPS 1: Try to log into guest.", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 2: Format the disk and copy file to it", logging.info)
    os_type = params["os_type"]
    copy_cmd = params.get("copy_cmd", "copy %s %s")
    fstype = params.get("fstype", "ntfs")
    data_image_size = params.get("image_size_data", "1G")
    data_image_num = int(params.get("data_image_num",
                                    len(params.objects("images")) - 1))
    error_context.context("Get windows disk index that to "
                          "be formatted", logging.info)
    disk_index_list = utils_disk.get_windows_disks_index(session, data_image_size)
    if len(disk_index_list) < data_image_num:
        test.fail("Fail to list all data disks. "
                  "Set disk number: %d, "
                  "get disk number in guest: %d."
                  % (data_image_num, len(disk_index_list)))
    src_file = utils_misc.set_winutils_letter(
        session, params["src_file"], label="WIN_UTILS")
    error_context.context("Clear readonly for all disks and online "
                          "them in guest.", logging.info)
    if not utils_disk.update_windows_disk_attributes(session, disk_index_list):
        test.fail("Failed to update windows disk attributes.")
    error_context.context("Format disk %s in guest." % disk_index_list[0],
                          logging.info)
    drive_letter = utils_disk.configure_empty_disk(
        session, disk_index_list[0], data_image_size, os_type, fstype=fstype)
    if not drive_letter:
        test.fail("Fail to format disks.")
    dst_file = params["dst_file"] % drive_letter[0]
    session.cmd(copy_cmd % (src_file, dst_file))

    msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk"
    msg += " set to readonly"
    error_context.context(msg, logging.info)
    session.close()
    vm.destroy()

    data_img = params.get("images").split()[-1]
    params["image_readonly_%s" % data_img] = "yes"
    params["force_create_image_%s" % data_img] = "no"
    env_process.preprocess(test, params, env)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 4: Write to the readonly disk expect:"
        "The media is write protected", logging.info)
    dst_file_readonly = params["dst_file_readonly"] % drive_letter[0]
    o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly))
    if not o.find("write protect"):
        test.fail("Write in readonly disk should failed\n. {}".format(o))

    error_context.context(
        "TEST STEPS 5: Try to read from the readonly disk", logging.info)
    s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\"))
    if s != 0:
        test.fail("Read file failed\n. {}".format(o))

    session.close()
示例#52
0
def run(test, params, env):
    """
    Test hotplug of block devices.

    1) Boot up guest with/without block device(s).
    2) Hoplug block device and verify
    3) Do read/write data on hotplug block.
    4) Unplug block device and verify

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def find_disk(vm, cmd):
        """
        Find all disks in guest.
        """
        if params.get("os_type") == "linux":
            pattern = params.get("get_disk_pattern", "^/dev/vd[a-z]*$")
        elif params.get("os_type") == "windows":
            pattern = r"^\d+"
            cmd = params.get("get_disk_index", "wmic diskdrive get index")
        else:
            test.cancel("Unsupported OS type '%s'" % params.get("os_type"))

        session = vm.wait_for_login(timeout=timeout)
        output = session.cmd_output_safe(cmd)
        disks = re.findall(pattern, output, re.M)
        session.close()
        return disks

    def get_new_disk(disk1, disk2):
        """
        Get the different disk between disk1 and disk2.
        """
        disk = list(set(disk2).difference(set(disk1)))
        return disk

    def run_sub_test(params, plug_tag):
        """
        Run subtest before/after hotplug/unplug device.

        :param plug_tag: identify when to run subtest,
                         ex, before_hotplug.
        :return: whether vm was successfully shut-down
                 if needed
        """
        sub_type = params.get("sub_type_%s" % plug_tag)
        if sub_type:
            error_context.context(context_msg % (sub_type, plug_tag),
                                  logging.info)
            utils_test.run_virt_sub_test(test, params, env, sub_type)
            if sub_type == "shutdown" and vm.is_dead():
                return True
        return None

    img_list = params.get("images").split()
    #sometimes, ppc can't get new plugged disk in 5s, so time to 10s
    pause = float(params.get("virtio_block_pause", 10.0))
    blk_num = int(params.get("blk_num", 1))
    repeat_times = int(params.get("repeat_times", 3))
    timeout = int(params.get("login_timeout", 360))
    disk_op_timeout = int(params.get("disk_op_timeout", 360))
    get_disk_cmd = params.get("get_disk_cmd")
    context_msg = "Running sub test '%s' %s"
    disk_index = params.objects("disk_index")
    disk_letter = params.objects("disk_letter")

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

    for iteration in range(repeat_times):
        device_list = []
        error_context.context("Hotplug block device (iteration %d)" % iteration,
                              logging.info)

        plug_tag = "before_plug"
        run_sub_test(params, plug_tag)

        for num in range(blk_num):
            image_name = img_list[num + 1]
            image_params = params.object_params(image_name)
            if params.get("need_plug") == "yes":
                disks_before_plug = find_disk(vm, get_disk_cmd)
                devs = vm.devices.images_define_by_params(image_name,
                                                          image_params, 'disk')
                for dev in devs:
                    ret = vm.devices.simple_hotplug(dev, vm.monitor)
                    if ret[1] is False:
                        test.fail("Failed to hotplug device '%s'."
                                  "Output:\n%s" % (dev, ret[0]))
                plug_disks = utils_misc.wait_for(lambda: get_new_disk(disks_before_plug,
                                                 find_disk(vm, get_disk_cmd)), pause)
                if not plug_disks:
                    test.fail("Failed to hotplug device to guest")
                disk = plug_disks[0]

                session = vm.wait_for_login(timeout=timeout)
                if params.get("os_type") == "windows":
                    if iteration == 0:
                        error_context.context("Format disk", logging.info)
                        utils_misc.format_windows_disk(session, disk_index[num],
                                                       mountpoint=disk_letter[num])
                error_context.context("Check block device after hotplug.",
                                      logging.info)
                if params.get("disk_op_cmd"):
                    if params.get("os_type") == "linux":
                        test_cmd = params.get("disk_op_cmd") % (disk, disk)
                    elif params.get("os_type") == "windows":
                        test_cmd = params.get("disk_op_cmd") % (disk_letter[num],
                                                                disk_letter[num])
                        test_cmd = utils_misc.set_winutils_letter(session, test_cmd)
                    else:
                        test.cancel("Unsupported OS type '%s'" % params.get("os_type"))

                    status, output = session.cmd_status_output(test_cmd,
                                                               timeout=disk_op_timeout)
                    if status:
                        test.fail("Check for block device failed."
                                  "Output: %s" % output)
                session.close()

                devs = [dev for dev in devs if not isinstance(dev, qdevices.QDrive)]
                device_list.extend(devs)
            else:
                for device in vm.devices:
                    if device.get_param("id") == img_list[num + 1]:
                        device_list.append(device)

        plug_tag = "after_plug"
        vm_switched_off = run_sub_test(params, plug_tag)
        if vm_switched_off:
            return

        plug_tag = "before_unplug"
        run_sub_test(params, plug_tag)

        error_context.context("Unplug block device (iteration %d)" % iteration,
                              logging.info)
        disks_before_unplug = find_disk(vm, get_disk_cmd)
        for device in reversed(device_list):
            ret = vm.devices.simple_unplug(device, vm.monitor)
            if ret[1] is False:
                test.fail("Failed to unplug device '%s'."
                          "Output:\n%s" % (device, ret[0]))

        unplug_disks = utils_misc.wait_for(lambda: get_new_disk(find_disk(vm, get_disk_cmd),
                                           disks_before_unplug), pause)
        if len(unplug_disks) != blk_num:
            test.fail("Failed to unplug devices from guest, need to unplug: %d,"
                      "actual unplug: %d" % (blk_num, len(unplug_disks)))

        plug_tag = "after_unplug"
        run_sub_test(params, plug_tag)