block_hotplug.py 6.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
import logging
import re
import time

from virttest import data_dir
from virttest import storage
from virttest import error_context
from virttest import utils_test
from virttest.qemu_devices import qdevices

from avocado.core import exceptions


@error_context.context_aware
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

36
    def find_disk(vm, cmd):
37 38 39 40 41 42 43 44 45
        """
        Find all disks in guest.
        """
        if params.get("os_type") == "linux":
            pattern = params.get("get_disk_pattern", "^/dev/vd[a-z]*$")
        else:
            pattern = "^\d+"
            cmd = params.get("get_disk_index", "wmic diskdrive get index")

46
        session = vm.wait_for_login(timeout=timeout)
47 48
        output = session.cmd_output_safe(cmd)
        disks = re.findall(pattern, output, re.M)
49
        session.close()
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        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")
    pause = float(params.get("virtio_block_pause", 5.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 = []

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

    for i in xrange(repeat_times):
        error_context.context("Hotplug block device (iteration %d)" % i,
                              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":
                if params.get("need_controller", "no") == "yes":
                    controller_model = params.get("controller_model")
                    controller = qdevices.QDevice(controller_model)
                    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
                        raise exceptions.TestFail(err)

96
                disks_before_plug = find_disk(vm, get_disk_cmd)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

                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)
                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
                    raise exceptions.TestFail(err)
                time.sleep(pause)

113
                disks_after_plug = find_disk(vm, get_disk_cmd)
114 115 116 117 118 119
                new_disks = get_new_disk(disks_before_plug, disks_after_plug)
            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])
120
                new_disks = find_disk(vm, get_disk_cmd)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138

            device_list.append(device)
            if not new_disks:
                raise exceptions.TestFail("Cannot find new disk after hotplug.")

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

            error_context.context("Check block device after hotplug.",
                                  logging.info)
            if params.get("pci_test_cmd"):
                if params.get("os_type") == "linux":
                    test_cmd = params.get("pci_test_cmd") % (disk, disk)
                else:
                    test_cmd = re.sub("PCI_NUM", "%s" % (num + 1),
                                      params.get("pci_test_cmd"))
139
                session = vm.wait_for_login(timeout=timeout)
140
                s, o = session.cmd_status_output(test_cmd, timeout=disk_op_timeout)
141
                session.close()
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
                if s:
                    raise exceptions.TestFail("Check for block device failed "
                                              "after hotplug, Output: %r" % o)

        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)

        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)" % i,
                                  logging.info)
            device_list[num].unplug(vm.monitor)
            device_list[num].verify_unplug("", vm.monitor)
            time.sleep(pause)

        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)