Esempio n. 1
0
def run(test, params, env):
    """
    Runs CPU hotplug test:

    1) Boot the vm with -smp X,maxcpus=Y
    2) After logged into the vm, check CPUs number
    3) Send the monitor command cpu_set [cpu id] for each cpu we wish to have
    4) Verify if guest has the additional CPUs showing up
    5) reboot the vm
    6) recheck guest get hot-pluged CPUs
    7) Try to bring them online by writing 1 to the 'online' file inside
       that dir(Linux guest only)
    8) Run the CPU Hotplug test suite shipped with autotest inside guest
       (Linux guest only)

    :param test: QEMU test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    error.context(
        "boot the vm, with '-smp X,maxcpus=Y' option,"
        "thus allow hotplug vcpu", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    n_cpus_add = int(params.get("n_cpus_add", 1))
    maxcpus = int(params.get("maxcpus", 160))
    current_cpus = int(params.get("smp", 1))
    onoff_iterations = int(params.get("onoff_iterations", 20))
    cpu_hotplug_cmd = params['cpu_hotplug_cmd']

    if n_cpus_add + current_cpus > maxcpus:
        logging.warn("CPU quantity more than maxcpus, set it to %s", maxcpus)
        total_cpus = maxcpus
    else:
        total_cpus = current_cpus + n_cpus_add

    error.context("check if CPUs in guest matches qemu cmd "
                  "before hot-plug", logging.info)
    if not utils_misc.check_if_vm_vcpu_match(current_cpus, vm):
        raise error.TestError("CPU quantity mismatch cmd before hotplug !")

    for i in range(current_cpus, total_cpus):
        error.context("hot-pluging vCPU %s" % i, logging.info)
        vm.monitor.send_args_cmd(cpu_hotplug_cmd % i)

    output = vm.monitor.send_args_cmd("info cpus")
    logging.debug("Output of info CPUs:\n%s", output)

    cpu_regexp = re.compile("CPU #(\d+)")
    total_cpus_monitor = len(cpu_regexp.findall(output))
    if total_cpus_monitor != total_cpus:
        raise error.TestFail("Monitor reports %s CPUs, when VM should have"
                             " %s" % (total_cpus_monitor, total_cpus))
    # Windows is a little bit lazy that needs more secs to recognize.
    error.context(
        "hotplugging finished, let's wait a few sec and"
        " check CPUs quantity in guest.", logging.info)
    if not utils_misc.wait_for(
            lambda: utils_misc.check_if_vm_vcpu_match(total_cpus, vm),
            60 + total_cpus,
            first=10,
            step=5.0,
            text="retry later"):
        raise error.TestFail("CPU quantity mismatch cmd after hotplug !")
    error.context("rebooting the vm and check CPU quantity !", logging.info)
    session = vm.reboot()
    if not utils_misc.check_if_vm_vcpu_match(total_cpus, vm):
        raise error.TestFail("CPU quantity mismatch cmd after hotplug "
                             "and reboot !")

    # Window guest doesn't support online/offline test
    if params['os_type'] == "windows":
        return

    error.context("locating online files for guest's new CPUs")
    r_cmd = 'find /sys/devices/system/cpu/cpu*/online -maxdepth 0 -type f'
    online_files = session.cmd(r_cmd)
    # Sometimes the return value include command line itself
    if "find" in online_files:
        online_files = " ".join(online_files.strip().split("\n")[1:])
    logging.debug("CPU online files detected: %s", online_files)
    online_files = online_files.split()
    online_files.sort()

    if not online_files:
        raise error.TestFail("Could not find CPUs that can be "
                             "enabled/disabled on guest")

    control_path = os.path.join(test.virtdir, "control", "cpu_hotplug.control")

    timeout = int(params.get("cpu_hotplug_timeout", 300))
    error.context("running cpu_hotplug autotest after cpu addition")
    utils_test.run_autotest(vm, session, control_path, timeout, test.outputdir,
                            params)

    # Last, but not least, let's offline/online the CPUs in the guest
    # several times
    irq = 15
    irq_mask = "f0"
    for i in xrange(onoff_iterations):
        session.cmd("echo %s > /proc/irq/%s/smp_affinity" % (irq_mask, irq))
        for online_file in online_files:
            session.cmd("echo 0 > %s" % online_file)
        for online_file in online_files:
            session.cmd("echo 1 > %s" % online_file)
Esempio n. 2
0
def run_kernbench(test, params, env):
    """
    Run kernbench for performance testing.

    1) Set up testing environment.
    2) Get a kernel code.
    3) Make the kernel with kernbench -M or time make -j 2*smp

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def download_if_not_exists():
        if not os.path.exists(file_name):
            cmd = "wget -t 10 -c -P %s %s" % (tmp_dir, file_link)
            utils.system(cmd)

    def cmd_status_output(cmd, timeout=360):
        s = 0
        o = ""
        if "guest" in test_type:
            (s, o) = session.cmd_status_output(cmd, timeout=timeout)
        else:
            (s, o) = commands.getstatusoutput(cmd)
        return (s, o)

    def check_ept():
        output = utils.system_output("grep 'flags' /proc/cpuinfo")
        flags = output.splitlines()[0].split(':')[1].split()
        need_ept = params.get("need_ept", "no")
        if 'ept' not in flags and "yes" in need_ept:
            raise error.TestNAError(
                "This test requires a host that supports EPT")
        elif 'ept' in flags and "no" in need_ept:
            cmd = "modprobe -r kvm_intel && modprobe kvm_intel ept=0"
            utils.system(cmd, timeout=100)
        elif 'ept' in flags and "yes" in need_ept:
            cmd = "modprobe -r kvm_intel && modprobe kvm_intel ept=1"
            utils.system(cmd, timeout=100)

    def install_gcc():
        logging.info("Update gcc to request version....")
        cmd = "rpm -q gcc"
        cpp_link = params.get("cpp_link")
        gcc_link = params.get("gcc_link")
        libgomp_link = params.get("libgomp_link")
        libgcc_link = params.get("libgcc_link")
        (s, o) = cmd_status_output(cmd)
        if s:
            cmd = "rpm -ivh %s --nodeps; rpm -ivh %s --nodeps; rpm -ivh %s"\
                  " --nodeps; rpm -ivh %s --nodeps" % (libgomp_link,
                                                       libgcc_link, cpp_link, gcc_link)
        else:
            gcc = o.splitlines()[0].strip()
            if gcc in gcc_link:
                cmd = "rpm -e %s && rpm -ivh %s" % (gcc, gcc_link)
            else:
                cmd = "rpm -ivh %s --nodeps; rpm -ivh %s --nodeps; rpm -ivh"\
                      " %s --nodeps; rpm -ivh %s --nodeps" % (libgomp_link,
                                                              libgcc_link, cpp_link, gcc_link)
        (s, o) = cmd_status_output(cmd)
        if s:
            logging.debug("Fail to install gcc.output:%s" % o)

    def record_result(result):
        re_result = params.get("re_result")
        (m_value, s_value) = re.findall(re_result, result)[0]
        s_value = float(m_value) * 60 + float(s_value)
        shortname = params.get("shortname")
        result_str = "%s: %ss\n" % (shortname, s_value)
        result_file = params.get("result_file")
        f1 = open(result_file, "a+")
        result = f1.read()
        result += result_str
        f1.write(result_str)
        f1.close()
        open(os.path.basename(result_file), 'w').write(result)
        logging.info("Test result got from %s:\n%s" % (result_file, result))

    test_type = params.get("test_type")
    guest_thp_cmd = params.get("guest_thp_cmd")
    cmd_timeout = int(params.get("cmd_timeout", 1200))
    tmp_dir = params.get("tmp_dir", "/tmp/kernbench/")
    check_ept()
    vm_name = params.get("main_vm", "vm1")
    cpu_multiplier = int(params.get("cpu_multiplier", 2))
    session = None
    if "guest" in test_type:
        env_process.preprocess_vm(test, params, env, vm_name)
        vm = env.get_vm(params["main_vm"])
        vm.verify_alive()
        session = vm.wait_for_login(
            timeout=int(params.get("login_timeout", 360)))

    # Create tmp folder and download files if need.
    if not os.path.exists(tmp_dir):
        utils.system("mkdir %s" % tmp_dir)
    files = params.get("files_need").split()
    for file in files:
        file_link = params.get("%s_link" % file)
        file_name = os.path.join(tmp_dir, os.path.basename(file_link))
        download_if_not_exists()

    if "guest" in test_type:
        logging.info("test in guest")
        vm.copy_files_to(tmp_dir, os.path.dirname(tmp_dir))
        if guest_thp_cmd is not None:
            session.cmd_output(guest_thp_cmd)
    try:
        if params.get("update_gcc") and params.get("update_gcc") == "yes":
            install_gcc()
        pre_cmd = params.get("pre_cmd")
        (s, o) = cmd_status_output(pre_cmd, timeout=cmd_timeout)
        if s:
            raise error.TestError("Fail command:%s\nOutput: %s" % (pre_cmd, o))

        if "guest" in test_type:
            cpu_num = params.get("smp")
        else:
            cpu_num = utils.count_cpus()
        test_cmd = params.get("test_cmd") % (int(cpu_num) * cpu_multiplier)
        logging.info("Start making the kernel ....")
        (s, o) = cmd_status_output(test_cmd, timeout=cmd_timeout)
        if s:
            raise error.TestError(
                "Fail command:%s\n Output:%s" % (test_cmd, o))
        else:
            logging.info("Output for command %s is:\n %s" % (test_cmd, o))
            record_result(o)
    finally:
        if params.get("post_cmd"):
            cmd_status_output(params.get("post_cmd"), timeout=cmd_timeout)
        if session:
            session.close()
Esempio n. 3
0
def run_jumbo(test, params, env):
    """
    Test the RX jumbo frame function of vnics:

    1) Boot the VM.
    2) Change the MTU of guest nics and host taps depending on the NIC model.
    3) Add the static ARP entry for guest NIC.
    4) Wait for the MTU ok.
    5) Verify the path MTU using ping.
    6) Ping the guest with large frames.
    7) Increment size ping.
    8) Flood ping the guest with large frames.
    9) Verify the path MTU.
    10) Recover the MTU.

    @param test: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    mtu = params.get("mtu", "1500")
    max_icmp_pkt_size = int(mtu) - 28
    flood_time = params.get("flood_time", "300")
    os_type = params.get("os_type")
    os_variant = params.get("os_variant")

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

    ifname = vm.get_ifname(0)
    ip = vm.get_address(0)
    if ip is None:
        raise error.TestError("Could not get the IP address")

    try:
        error.context("Changing the MTU of guest", logging.info)
        # Environment preparation
        mac = vm.get_mac_address(0)
        if os_type == "linux":
            ethname = utils_net.get_linux_ifname(session, mac)
            guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu)
        else:
            connection_id = utils_net.get_windows_nic_attribute(session,
                                                            "macaddress",
                                                            mac,
                                                            "netconnectionid")

            index = utils_net.get_windows_nic_attribute(session,
                                                        "netconnectionid",
                                                        connection_id,
                                                        "index")
            if os_variant == "winxp":
                pnpdevice_id = utils_net.get_windows_nic_attribute(session,
                                                            "netconnectionid",
                                                             connection_id,
                                                             "pnpdeviceid")
                cd_num = utils_misc.get_winutils_vol(session)
                copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num
                session.cmd(copy_cmd)


            reg_set_mtu_pattern = params.get("reg_mtu_cmd")
            mtu_key_word = params.get("mtu_key", "MTU")
            reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word,
                                                 int(mtu))
            guest_mtu_cmd = "%s " % reg_set_mtu

        session.cmd(guest_mtu_cmd)
        if os_type == "windows":
            mode = "netsh"
            if os_variant == "winxp":
                connection_id = pnpdevice_id.split("&")[-1]
                mode = "devcon"
            utils_net.restart_windows_guest_network(session_serial,
                                                    connection_id,
                                                    mode=mode)


        error.context("Chaning the MTU of host tap ...", logging.info)
        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
        utils.run(host_mtu_cmd)

        error.context("Add a temporary static ARP entry ...", logging.info)
        arp_add_cmd = "arp -s %s %s -i %s" % (ip, mac, ifname)
        utils.run(arp_add_cmd)

        def is_mtu_ok():
            s, _ = utils_test.ping(ip, 1, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=2)
            return s == 0

        def verify_mtu():
            logging.info("Verify the path MTU")
            s, o = utils_test.ping(ip, 10, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       hint="do", timeout=15)
            if s != 0 :
                logging.error(o)
                raise error.TestFail("Path MTU is not as expected")
            if utils_test.get_loss_ratio(o) != 0:
                logging.error(o)
                raise error.TestFail("Packet loss ratio during MTU "
                                     "verification is not zero")

        def flood_ping():
            logging.info("Flood with large frames")
            utils_test.ping(ip, interface=ifname,
                                packetsize=max_icmp_pkt_size,
                                flood=True, timeout=float(flood_time))

        def large_frame_ping(count=100):
            logging.info("Large frame ping")
            _, o = utils_test.ping(ip, count, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       timeout=float(count) * 2)
            ratio = utils_test.get_loss_ratio(o)
            if ratio != 0:
                raise error.TestFail("Loss ratio of large frame ping is %s" %
                                     ratio)

        def size_increase_ping(step=random.randrange(90, 110)):
            logging.info("Size increase ping")
            for size in range(0, max_icmp_pkt_size + 1, step):
                logging.info("Ping %s with size %s", ip, size)
                s, o = utils_test.ping(ip, 1, interface=ifname,
                                           packetsize=size,
                                           hint="do", timeout=1)
                if s != 0:
                    s, o = utils_test.ping(ip, 10, interface=ifname,
                                               packetsize=size,
                                               adaptive=True, hint="do",
                                               timeout=20)

                    if utils_test.get_loss_ratio(o) > int(params.get(
                                                      "fail_ratio", 50)):
                        raise error.TestFail("Ping loss ratio is greater "
                                             "than 50% for size %s" % size)

        logging.info("Waiting for the MTU to be OK")
        wait_mtu_ok = 10
        if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1):
            logging.debug(commands.getoutput("ifconfig -a"))
            raise error.TestError("MTU is not as expected even after %s "
                                  "seconds" % wait_mtu_ok)

        # Functional Test
        error.context("Checking whether MTU change is ok", logging.info)
        verify_mtu()
        large_frame_ping()
        size_increase_ping()

        # Stress test
        flood_ping()
        verify_mtu()

    finally:
        # Environment clean
        if session:
            session.close()
        if utils.system("grep '%s.*%s' /proc/net/arp" % (ip, ifname)) == '0':
            utils.run("arp -d %s -i %s" % (ip, ifname))
            logging.info("Removing the temporary ARP entry successfully")
Esempio n. 4
0
def test_active_nodedev_reset(device, vm, expect_succeed):
    """
    Test nodedev-reset when the specified device is attached to a VM

    :param devices        : Specified node device to be tested.
    :param vm             : VM the device is to be attached to.
    :param expect_succeed : 'yes' for expect command run successfully
                            and 'no' for fail.
    :raise TestFail       : If result doesn't meet expectation.
    :raise TestError      : If failed to recover environment.
    """
    # Split device name such as `pci_0000_00_19_0` and fill the XML.
    hostdev_xml = """
<hostdev mode='subsystem' type='%s' managed='yes'>
    <source>
        <address domain='0x%s' bus='0x%s' slot='0x%s' function='0x%s'/>
    </source>
</hostdev>""" % tuple(device.split('_'))

    try:
        # The device need to be detached before attach to VM.
        virsh.nodedev_detach(device)
        try:
            # Backup VM XML.
            vmxml = VMXML.new_from_inactive_dumpxml(vm.name)

            # Generate a temp file to store host device XML.
            dev_fd, dev_fname = tempfile.mkstemp(dir=data_dir.get_tmp_dir())
            os.close(dev_fd)

            dev_file = open(dev_fname, 'w')
            dev_file.write(hostdev_xml)
            dev_file.close()

            # Only live VM allows attach device.
            if not vm.is_alive():
                vm.start()

            try:
                result = virsh.attach_device(vm.name, dev_fname)
                logging.debug(result)

                test_nodedev_reset([device], expect_succeed)
            finally:
                # Detach device from VM.
                result = virsh.detach_device(vm.name, dev_fname)
                # Raise error when detach failed.
                if result.exit_status:
                    raise error.TestError(
                        'Failed to dettach device %s from %s. Result:\n %s' %
                        (device, vm.name, result))
        finally:
            # Cleanup temp XML file and recover test VM.
            os.remove(dev_fname)
            vmxml.sync()
    finally:
        # Reattach node device
        result = virsh.nodedev_reattach(device)
        # Raise error when reattach failed.
        if result.exit_status:
            raise error.TestError(
                'Failed to reattach nodedev %s. Result:\n %s' %
                (device, result))
def run(test, params, env):
    """
    KVM sr-iov hotplug negatvie test:
    1) Boot up VM.
    2) Try to remove sr-iov device driver module (optional)
    3) Hotplug sr-iov device to VM with negative parameters
    4) Verify that qemu could handle the negative parameters
       check hotplug error message (optional)

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

    def make_pci_add_cmd(pa_pci_id, pci_addr="auto"):
        pci_add_cmd = ("pci_add pci_addr=%s host host=%s,if=%s" %
                       (pci_addr, pa_pci_id, pci_model))
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd

    def make_device_add_cmd(pa_pci_id, pci_addr=None):
        device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id()
        pci_add_cmd = ("device_add id=%s,driver=pci-assign,host=%s" %
                       (device_id, pa_pci_id))
        if pci_addr is not None:
            pci_add_cmd += ",addr=%s" % pci_addr
        if params.get("hotplug_params"):
            assign_param = params.get("hotplug_params").split()
            for param in assign_param:
                value = params.get(param)
                if value:
                    pci_add_cmd += ",%s=%s" % (param, value)
        return pci_add_cmd

    neg_msg = params.get("negative_msg")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    rp_times = int(params.get("repeat_times", 1))
    pci_model = params.get("pci_model", "pci-assign")
    pci_invaild_addr = params.get("pci_invaild_addr")
    modprobe_cmd = params.get("modprobe_cmd")

    device = {}
    device["type"] = params.get("hotplug_device_type", "vf")
    device['mac'] = utils_net.generate_mac_address_simple()
    if params.get("device_name"):
        device["name"] = params.get("device_name")

    if vm.pci_assignable is not None:
        pa_pci_ids = vm.pci_assignable.request_devs(device)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.send_args_cmd("help")

    if not cmd_output:
        raise error.TestError("Unknow version of qemu")

    cmd_type = utils_misc.find_substring(str(cmd_output), "pci_add",
                                                          "device_add")
    for j in range(rp_times):
        if cmd_type == "pci_add":
            pci_add_cmd = make_pci_add_cmd(pa_pci_ids[0], pci_invaild_addr)
        elif cmd_type == "device_add":
            pci_add_cmd = make_device_add_cmd(pa_pci_ids[0], pci_invaild_addr)
        try:
            msg = "Adding pci device with command '%s'" % pci_add_cmd
            error.context(msg, logging.info)
            case_fail = False
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
            case_fail = True
        except Exception, err:
            if neg_msg:
                msg = "Check negative hotplug error message"
                error.context(msg, logging.info)
                if neg_msg not in str(err):
                    msg = "Could not find '%s' in" % neg_msg
                    msg += " command output '%s'" % add_output
                    raise error.TestFail(msg)
            logging.debug("Could not boot up vm, %s" % err)
        if case_fail:
            if neg_msg:
                msg = "Check negative hotplug error message"
                error.context(msg, logging.info)
                if neg_msg not in str(add_output):
                    msg = "Could not find '%s' in" % neg_msg
                    msg += " command output '%s'" % add_output
                    raise error.TestFail(msg)
            logging.debug("Could not boot up vm, %s" % add_output)
Esempio n. 6
0
        def test(self):
            create_floppy(params)
            params["start_vm"] = "yes"
            vm_name = params.get("main_vm", "vm1")
            env_process.preprocess_vm(test, params, env, vm_name)
            vm = env.get_vm(vm_name)
            vm.verify_alive()
            self.session = vm.wait_for_login(timeout=login_timeout)

            self.dest_dir = params.get("mount_dir")
            # If mount_dir specified, treat guest as a Linux OS
            # Some Linux distribution does not load floppy at boot and Windows
            # needs time to load and init floppy driver
            if self.dest_dir:
                lsmod = self.session.cmd("lsmod")
                if not 'floppy' in lsmod:
                    self.session.cmd("modprobe floppy")
            else:
                time.sleep(20)

            error.context("Formating floppy disk before using it")
            format_cmd = params["format_floppy_cmd"]
            self.session.cmd(format_cmd, timeout=120)
            logging.info("Floppy disk formatted successfully")

            if self.dest_dir:
                error.context("Mounting floppy")
                self.session.cmd("mount -t vfat %s %s" %
                                 (guest_floppy_path, self.dest_dir))
            error.context("Testing floppy")
            self.session.cmd(params["test_floppy_cmd"])

            error.context("Copying file to the floppy")
            md5_cmd = params.get("md5_cmd")
            if md5_cmd:
                md5_source = self.session.cmd("%s %s" %
                                              (params["md5_cmd"], source_file))
                try:
                    md5_source = md5_source.split(" ")[0]
                except IndexError:
                    error.TestError("Failed to get md5 from source file,"
                                    " output: '%s'" % md5_source)
            else:
                md5_source = None

            self.session.cmd("%s %s %s" %
                             (params["copy_cmd"], source_file, dest_file))
            logging.info("Succeed to copy file '%s' into floppy disk" %
                         source_file)

            error.context("Checking if the file is unchanged after copy")
            if md5_cmd:
                md5_dest = self.session.cmd("%s %s" %
                                            (params["md5_cmd"], dest_file))
                try:
                    md5_dest = md5_dest.split(" ")[0]
                except IndexError:
                    error.TestError("Failed to get md5 from dest file,"
                                    " output: '%s'" % md5_dest)
                if md5_source != md5_dest:
                    raise error.TestFail("File changed after copy to floppy")
            else:
                md5_dest = None
                self.session.cmd(
                    "%s %s %s" %
                    (params["diff_file_cmd"], source_file, dest_file))
Esempio n. 7
0
def run(test, params, env):
    """
    TestStep:
    1) Exec the stap script in host
    2) Boot the guest, and do some operation(if needed).
    3) Check the output of the stap
    params:
    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def create_patterns_reg(trace_key):
        """
        Create a regular exp using the tracing key, the purpose is checking
        the systemtap output is accord with expected.
        """
        pattern_reg = ""
        for tracing_key in trace_key.split():
            pattern_reg += "%s=\d+," % tracing_key
        return pattern_reg.rstrip(",")

    error.base_context("Qemu_Tracing Test")
    error.context("Test start ...")

    probe_var_key = params.get("probe_var_key")
    checking_pattern_re = create_patterns_reg(probe_var_key)
    capdata_timeout = int(params.get("capdata_timeout", "360"))
    timeout = int(params.get("login_timeout", "360"))
    time_inter = int(params.get("time_inter", "1"))

    if params.get("extra_params"):
        params["extra_params"] = params.get("extra_params")

    if params.get("boot_with_cdrom") == 'yes':
        iso_path = "%s/test.iso" % data_dir.get_tmp_dir()
        create_cmd = "dd if=/dev/zero of=%s bs=1M count=10" % iso_path
        if utils.system(create_cmd, ignore_status=True) != 0:
            raise error.TestNAError("Create test iso failed")
        params["cdrom_cd1"] = iso_path

    if params.get("start_vm", "yes") == "no":
        params["start_vm"] = "yes"
        env_process.preprocess_vm(test, params, env, params.get("main_vm"))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    _params = params.object_params(vm.monitor.protocol)
    if _params.get("cmds_exec"):
        for cmd in _params.get("cmds_exec").split(","):
            if re.findall(":", cmd):
                cmd_type = cmd.split(":")[0]
                exec_cmds = cmd.split(":")[1]
            else:
                cmd_type = "bash"
                exec_cmds = cmd
            for cmd_exec in exec_cmds.split(";"):
                msg = "Execute %s cmd '%s'" % (cmd_type, cmd_exec)
                error.context(msg, logging.info)
                if cmd_type == "monitor":
                    vm.monitor.send_args_cmd(cmd_exec)
                elif cmd_type == "bash":
                    guest_session = vm.wait_for_login(timeout=timeout)
                    guest_session.cmd(cmd_exec)

    error.context("Get the output of stap script", logging.info)
    stap_log_file = utils_misc.get_path(test.profdir, "systemtap.log")

    start_time = time.time()
    while (time.time() - start_time) < capdata_timeout:
        if os.path.isfile(stap_log_file):
            fd = open(stap_log_file, 'r')
            data = fd.read()
            if (not data) or (not re.findall(checking_pattern_re, data)):
                time.sleep(time_inter)
                fd.close()
                continue
            elif data and re.findall(checking_pattern_re, data):
                logging.info("Capture the data successfully")
                logging.info("The capture data is like: %s" %
                             re.findall(checking_pattern_re, data)[-1])
                fd.close()
                break
        else:
            time.sleep(time_inter)
    else:
        raise error.TestError("Timeout for capature the stap log data")
Esempio n. 8
0
def result_sum(topdir, params, guest_ver, resultsdir, test):
    case_type = params.get("test")
    unit_std = params.get("unit_std", "M")
    no_table_list = params.get("no_table_list", "").split()
    ignore_cases = params.get("ignore_cases", "").split()
    repeatn = ""
    if "repeat" in test.outputdir:
        repeatn = re.findall("repeat\d+", test.outputdir)[0]
    category_key = re.split("/", test.outputdir)[-1]
    category_key = re.split(case_type, category_key)[0]
    category_key = re.sub("\.repeat\d+", "", category_key)

    kvm_ver = utils.system_output(params.get('ver_cmd', "rpm -q qemu-kvm"))
    host_ver = os.uname()[2]
    test.write_test_keyval({'kvm-userspace-ver': kvm_ver})
    test.write_test_keyval({'host-kernel-ver': host_ver})
    test.write_test_keyval({'guest-kernel-ver': guest_ver})
    # Find the results files

    results_files = {}
    file_list = [
        'guest_result', 'guest_monitor_result.*sum', 'host_monitor_result.*sum'
    ]
    if params.get("file_list"):
        file_list = params.get("file_list").split()

    for files in os.walk(topdir):
        if files[2]:
            for file in files[2]:
                jump_flag = False
                for ignore_case in ignore_cases:
                    if ignore_case in files[0]:
                        jump_flag = True
                if jump_flag:
                    continue
                file_dir_norpt = re.sub("\.repeat\d+", "", files[0])
                if (repeatn in files[0] and category_key in file_dir_norpt
                        and case_type in files[0]):
                    for i, pattern in enumerate(file_list):
                        if re.findall(pattern, file):
                            prefix = re.findall("%s\.[\d\w_\.]+" % case_type,
                                                file_dir_norpt)[0]
                            prefix = re.sub("\.|_", "--", prefix)
                            if prefix not in results_files.keys():
                                results_files[prefix] = []
                                tmp = []
                                for j in range(len(file_list)):
                                    tmp.append(None)
                                results_files[prefix] = tmp
                            tmp_file = utils_misc.get_path(files[0], file)
                            results_files[prefix][i] = tmp_file

    # Start to read results from results file and monitor file
    results_matrix = {}
    no_table_results = {}
    thread_tag = params.get("thread_tag", "thread")
    order_list = []
    for prefix in results_files:
        marks = params.get("marks", "").split()
        case_infos = prefix.split("--")
        case_type = case_infos[0]
        threads = ""
        refresh_order_list = True
        prefix_perf = prefix
        if case_type == "ffsb":
            category = "-".join(case_infos[:-1])
            threads = case_infos[-1]
        elif case_type == "qcow2perf":
            refresh_order_list = False
            if len(case_infos) > 2:
                category = "-".join(case_infos[:-2])
                thread_tag = case_infos[-2]
                threads = " "
                marks[0] = re.sub("TIME", case_infos[-1], marks[0])
            else:
                category = case_infos[-1]
                marks[0] = re.sub("TIME", case_infos[-1], marks[0])
            prefix_perf = "--".join(case_infos[:-1])
        else:
            category = "-".join(case_infos)
        if refresh_order_list:
            order_list = []
        if (category not in results_matrix.keys()
                and category not in no_table_list):
            results_matrix[category] = {}
        if threads:
            if threads not in results_matrix[category].keys():
                results_matrix[category][threads] = {}
                results_matrix["thread_tag"] = thread_tag
            tmp_dic = results_matrix[category][threads]
        elif category not in no_table_list:
            tmp_dic = results_matrix[category]

        result_context_file = open(results_files[prefix][0], 'r')
        result_context = result_context_file.read()
        result_context_file.close()
        for mark in marks:
            mark_tag, mark_key = mark.split(":")
            datas = re.findall(mark_key, result_context)
            if isinstance(datas[0], tuple):
                data = time_ana(datas[0])
            else:
                tmp_data = 0.0
                for data in datas:
                    if re.findall("[bmkg]", data, re.I):
                        data = utils_misc.normalize_data_size(data, unit_std)
                    tmp_data += float(data)
                data = str(tmp_data)
            if data:
                if mark_tag in no_table_list:
                    no_table_results[mark_tag] = utils_misc.aton(data)
                    perf_value = no_table_results[mark_tag]
                else:
                    tmp_dic[mark_tag] = utils_misc.aton(data)
                    perf_value = tmp_dic[mark_tag]
            else:
                raise error.TestError("Can not get the right data from result."
                                      "Please check the debug file.")
            if mark_tag not in no_table_list and mark_tag not in order_list:
                order_list.append(mark_tag)
            test.write_perf_keyval(
                {'%s-%s' % (prefix_perf, mark_tag): perf_value})
        # start analyze the mpstat results
        if params.get('mpstat') == "yes":
            guest_cpu_infos = mpstat_ana(results_files[prefix][1])
            for vcpu in guest_cpu_infos:
                if vcpu != "all":
                    tmp_dic[vcpu] = float(guest_cpu_infos[vcpu])
                    order_list.append(vcpu)
            host_cpu_infos = mpstat_ana(results_files[prefix][2])
            tmp_dic["Hostcpu"] = float(host_cpu_infos["all"])
            order_list.append("Hostcpu")
        # Add some special key for cases
        if case_type == "ffsb":
            tmp_dic["MBps_per_Hostcpu"] = (tmp_dic["Thro-MBps"] /
                                           tmp_dic["Hostcpu"])
            order_list.append("MBps_per_Hostcpu")
        elif case_type == "iozone":
            sum_kbps = 0
            for mark in marks:
                mark_tag, _ = mark.split(":")
                sum_kbps += tmp_dic[mark_tag]
            tmp_dic["SUMKbps_per_Hostcpu"] = sum_kbps / tmp_dic["Hostcpu"]
            order_list.append("SUMKbps_per_Hostcpu")

    sum_marks = params.get("sum_marks", "").split()
    sum_matrix = {}
    order_line = ""
    if results_matrix.get("thread_tag"):
        headline = "%20s|" % results_matrix["thread_tag"]
        results_matrix.pop("thread_tag")
    else:
        headline = ""
    for index, tag in enumerate(order_list):
        headline += "%s|" % format_result(tag)
        order_line += "DATA%d|" % index
    headline = headline.rstrip("|")
    order_line = order_line.rstrip("|")

    result_path = utils_misc.get_path(resultsdir, "%s-result.RHS" % case_type)
    if os.path.isfile(result_path):
        result_file = open(result_path, "r+")
    else:
        result_file = open(result_path, "w")
        result_file.write("### kvm-userspace-version : %s\n" % kvm_ver)
        result_file.write("### kvm-version : %s\n" % host_ver)
        result_file.write("### guest-kernel-version :%s\n" % guest_ver)

    test.write_test_keyval({'category': headline})
    result_file.write("Category:ALL\n")
    matrix_order = params.get("matrix_order", "").split()
    if not matrix_order:
        matrix_order = results_matrix.keys()
        matrix_order.sort()
    for category in matrix_order:
        out_loop_line = order_line
        result_file.write("%s\n" % category)
        line = ""
        write_out_loop = True
        result_file.write("%s\n" % headline)
        for item in results_matrix[category]:
            if isinstance(results_matrix[category][item], dict):
                tmp_dic = results_matrix[category][item]
                line = "%s|" % format_result(item)
                for tag in order_list:
                    line += "%s|" % format_result(tmp_dic[tag])
                    if tag in sum_marks:
                        sum_matrix = get_sum_result(sum_matrix, tmp_dic[tag],
                                                    tag)
                result_file.write("%s\n" % line.rstrip("|"))
                write_out_loop = False
            else:
                #line += "%s|" % format_result(results_matrix[category][item])
                re_data = "DATA%s" % order_list.index(item)
                out_loop_line = re.sub(
                    re_data, format_result(results_matrix[category][item]),
                    out_loop_line)
                if tag in sum_marks:
                    sum_matrix = get_sum_result(sum_matrix, tmp_dic[tag], tag)
        if write_out_loop:
            result_file.write("%s\n" % out_loop_line)

    if sum_matrix:
        if case_type == "ffsb":
            sum_matrix["MBps_per_Hostcpu"] = (sum_matrix["Thro-MBps"] /
                                              sum_matrix["Hostcpu"])
            sum_marks.append("MBps_per_Hostcpu")
        result_file.write("Category:SUM\n")
        headline = ""
        line = ""
        if len(sum_matrix) < 4:
            for i in range(4 - len(sum_matrix)):
                headline += "%20s|" % "None"
                line += "%20d|" % 0
        for tag in sum_marks:
            headline += "%20s|" % tag
            line += "%s|" % format_result(sum_matrix[tag])

        result_file.write("%s\n" % headline.rstrip("|"))
        result_file.write("%s\n" % line.rstrip("|"))

    if no_table_results:
        no_table_order = params.get("no_table_order", "").split()
        if not no_table_order:
            no_table_order = no_table_results.keys()
            no_table_order.sort()
        for item in no_table_order:
            result_file.write("%s: %s\n" % (item, no_table_results[item]))

    result_file.close()
Esempio n. 9
0
def run(test, params, env):
    """
    KVM performance test:

    The idea is similar to 'client/tests/kvm/tests/autotest.py',
    but we can implement some special requests for performance
    testing.

    :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()

    test_timeout = int(params.get("test_timeout", 240))
    monitor_cmd = params["monitor_cmd"]
    login_timeout = int(params.get("login_timeout", 360))
    test_cmd = params["test_cmd"]
    guest_path = params.get("result_path", "/tmp/guest_result")
    test_src = params["test_src"]
    test_patch = params.get("test_patch")

    # Prepare test environment in guest
    session = vm.wait_for_login(timeout=login_timeout)

    prefix = test.outputdir.split(".performance.")[0]
    summary_results = params.get("summary_results")
    guest_ver = session.cmd_output("uname -r").strip()

    if summary_results:
        result_dir = params.get("result_dir", os.path.dirname(test.outputdir))
        result_sum(result_dir, params, guest_ver, test.resultsdir, test)
        session.close()
        return

    guest_launcher = os.path.join(test.virtdir, "scripts/cmd_runner.py")
    vm.copy_files_to(guest_launcher, "/tmp")
    md5value = params.get("md5value")

    tarball = utils.unmap_url_cache(test.tmpdir, test_src, md5value)
    test_src = re.split("/", test_src)[-1]
    vm.copy_files_to(tarball, "/tmp")

    session.cmd("rm -rf /tmp/src*")
    session.cmd("mkdir -p /tmp/src_tmp")
    session.cmd("tar -xf /tmp/%s -C %s" % (test_src, "/tmp/src_tmp"))

    # Find the newest file in src tmp directory
    cmd = "ls -rt /tmp/src_tmp"
    s, o = session.cmd_status_output(cmd)
    if len(o) > 0:
        new_file = re.findall("(.*)\n", o)[-1]
    else:
        raise error.TestError("Can not decompress test file in guest")
    session.cmd("mv /tmp/src_tmp/%s /tmp/src" % new_file)

    if test_patch:
        test_patch_path = os.path.join(data_dir.get_deps_dir(), 'performance',
                                       test_patch)
        vm.copy_files_to(test_patch_path, "/tmp/src")
        session.cmd("cd /tmp/src && patch -p1 < /tmp/src/%s" % test_patch)

    compile_cmd = params.get("compile_cmd")
    if compile_cmd:
        session.cmd("cd /tmp/src && %s" % compile_cmd)

    prepare_cmd = params.get("prepare_cmd")
    if prepare_cmd:
        s, o = session.cmd_status_output(prepare_cmd, test_timeout)
        if s != 0:
            raise error.TestError("Fail to prepare test env in guest")

    cmd = "cd /tmp/src && python /tmp/cmd_runner.py \"%s &> " % monitor_cmd
    cmd += "/tmp/guest_result_monitor\"  \"/tmp/src/%s" % test_cmd
    cmd += " &> %s \" \"/tmp/guest_result\""
    cmd += " %s" % int(test_timeout)

    test_cmd = cmd
    # Run guest test with monitor
    tag = cmd_runner_monitor(vm,
                             monitor_cmd,
                             test_cmd,
                             guest_path,
                             timeout=test_timeout)

    # Result collecting
    result_list = [
        "/tmp/guest_result_%s" % tag,
        "/tmp/host_monitor_result_%s" % tag,
        "/tmp/guest_monitor_result_%s" % tag
    ]
    guest_results_dir = os.path.join(test.outputdir, "guest_results")
    if not os.path.exists(guest_results_dir):
        os.mkdir(guest_results_dir)
    ignore_pattern = params.get("ignore_pattern")
    head_pattern = params.get("head_pattern")
    row_pattern = params.get("row_pattern")
    for i in result_list:
        if re.findall("monitor_result", i):
            result = utils_test.summary_up_result(i, ignore_pattern,
                                                  head_pattern, row_pattern)
            fd = open("%s.sum" % i, "w")
            sum_info = {}
            head_line = ""
            for keys in result:
                head_line += "\t%s" % keys
                for col in result[keys]:
                    col_sum = "line %s" % col
                    if col_sum in sum_info:
                        sum_info[col_sum] += "\t%s" % result[keys][col]
                    else:
                        sum_info[col_sum] = "%s\t%s" % (col, result[keys][col])
            fd.write("%s\n" % head_line)
            for keys in sum_info:
                fd.write("%s\n" % sum_info[keys])
            fd.close()
            shutil.copy("%s.sum" % i, guest_results_dir)
        shutil.copy(i, guest_results_dir)

    session.cmd("rm -rf /tmp/src")
    session.cmd("rm -rf guest_test*")
    session.cmd("rm -rf pid_file*")
    session.close()
Esempio n. 10
0
def run(test, params, env):
    """
    Qemu host nic bonding test:
    1) Load bonding module with mode 802.3ad
    2) Bring up bond interface
    3) Add nics to bond interface
    4) Add a new bridge and add bond interface to it
    5) Get ip address for bridge
    6) Boot up guest with the bridge
    7) Checking guest netowrk via ping
    8) Start file transfer between guest and host
    9) Disable and enable physical interfaces during file transfer

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    bond_iface = params.get("bond_iface", "bond0")
    bond_br_name = params.get("bond_br_name", "br_bond0")
    timeout = int(params.get("login_timeout", 240))
    remote_host = params.get("dsthost")
    ping_timeout = int(params.get("ping_timeout", 240))
    bonding_timeout = int(params.get("bonding_timeout", 1))
    bonding_mode = params.get("bonding_mode")
    if not bonding_mode:
        bonding_mode = "1"
    params['netdst'] = bond_br_name
    host_bridges = utils_net.Bridge()

    error.context("Load bonding module with mode 802.3ad", logging.info)
    if not utils.system("lsmod|grep bonding", ignore_status=True):
        utils.system("modprobe -r bonding")

    utils.system("modprobe bonding mode=%s" % bonding_mode)

    error.context("Bring up %s" % bond_iface, logging.info)
    host_ifaces = utils_net.get_host_iface()

    if bond_iface not in host_ifaces:
        raise error.TestError("Can not find bond0 in host")

    bond_iface = utils_net.Interface(bond_iface)
    bond_iface.up()
    bond_mac = bond_iface.get_mac()

    host_ph_iface_pre = params.get("host_ph_iface_prefix", "en")
    host_iface_bonding = int(params.get("host_iface_bonding", 2))

    host_ph_ifaces = [_ for _ in host_ifaces if re.match(host_ph_iface_pre, _)]

    ifaces_in_use = host_bridges.list_iface()
    host_ph_ifaces_un = list(set(host_ph_ifaces) - set(ifaces_in_use))

    if (len(host_ph_ifaces_un) < 2
            or len(host_ph_ifaces_un) < host_iface_bonding):
        raise error.TestErrorNA("Host need %s nics"
                                " at least." % host_iface_bonding)

    error.context("Add nics to %s" % bond_iface.name, logging.info)
    host_ifaces_bonding = host_ph_ifaces_un[:host_iface_bonding]
    ifenslave_cmd = "ifenslave %s" % bond_iface.name
    op_ifaces = []
    for host_iface_bonding in host_ifaces_bonding:
        op_ifaces.append(utils_net.Interface(host_iface_bonding))
        ifenslave_cmd += " %s" % host_iface_bonding
    utils.system(ifenslave_cmd)

    error.context("Add a new bridge and add %s to it." % bond_iface.name,
                  logging.info)
    if bond_br_name not in host_bridges.list_br():
        host_bridges.add_bridge(bond_br_name)
    host_bridges.add_port(bond_br_name, bond_iface.name)

    error.context("Get ip address for bridge", logging.info)
    utils.system("pkill dhclient; dhclient %s" % bond_br_name)

    error.context("Boot up guest with bridge %s" % bond_br_name, logging.info)
    params["start_vm"] = "yes"
    vm_name = params.get("main_vm")
    env_process.preprocess_vm(test, params, env, vm_name)
    vm = env.get_vm(vm_name)
    session = vm.wait_for_login(timeout=timeout)

    error.context("Checking guest netowrk via ping.", logging.info)
    ping_cmd = params.get("ping_cmd")
    ping_cmd = re.sub("REMOTE_HOST", remote_host, ping_cmd)
    session.cmd(ping_cmd, timeout=ping_timeout)

    error.context("Start file transfer", logging.info)
    f_transfer = utils.InterruptedThread(utils_test.run_virt_sub_test,
                                         args=(
                                             test,
                                             params,
                                             env,
                                         ),
                                         kwargs={"sub_type": "file_transfer"})
    f_transfer.start()
    utils_misc.wait_for(
        lambda: utils.system_output("pidof scp", ignore_status=True), 30)

    error.context(
        "Disable and enable physical "
        "interfaces in %s" % bond_br_name, logging.info)
    while True:
        for op_iface in op_ifaces:
            logging.debug("Turn down %s" % op_iface.name)
            op_iface.down()
            time.sleep(bonding_timeout)
            logging.debug("Bring up %s" % op_iface.name)
            op_iface.up()
            time.sleep(bonding_timeout)
        if not f_transfer.is_alive():
            break
    f_transfer.join()
Esempio n. 11
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    virsh_dargs = {'debug': True, 'ignore_status': False}

    def create_iface_xml(iface_mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        source = ast.literal_eval(iface_source)
        if source:
            iface.source = source
        iface.model = iface_model if iface_model else "virtio"
        iface.mac_address = iface_mac
        driver_dict = {}
        driver_host = {}
        driver_guest = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        if iface_driver_host:
            driver_host = ast.literal_eval(iface_driver_host)
        if iface_driver_guest:
            driver_guest = ast.literal_eval(iface_driver_guest)
        iface.driver = iface.new_driver(driver_attr=driver_dict,
                                        driver_host=driver_host,
                                        driver_guest=driver_guest)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    def modify_iface_xml(update, status_error=False):
        """
        Modify interface xml options
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        xml_devices = vmxml.devices
        iface_index = xml_devices.index(
            xml_devices.by_device_tag("interface")[0])
        iface = xml_devices[iface_index]
        if iface_model:
            iface.model = iface_model
        else:
            del iface.model
        if iface_type:
            iface.type_name = iface_type
        del iface.source
        source = ast.literal_eval(iface_source)
        if source:
            net_ifs = utils_net.get_net_if(state="UP")
            # Check source device is valid or not,
            # if it's not in host interface list, try to set
            # source device to first active interface of host
            if (iface.type_name == "direct" and source.has_key('dev')
                    and source['dev'] not in net_ifs):
                logging.warn(
                    "Source device %s is not a interface"
                    " of host, reset to %s", source['dev'], net_ifs[0])
                source['dev'] = net_ifs[0]
            iface.source = source
        backend = ast.literal_eval(iface_backend)
        if backend:
            iface.backend = backend
        driver_dict = {}
        driver_host = {}
        driver_guest = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        if iface_driver_host:
            driver_host = ast.literal_eval(iface_driver_host)
        if iface_driver_guest:
            driver_guest = ast.literal_eval(iface_driver_guest)
        iface.driver = iface.new_driver(driver_attr=driver_dict,
                                        driver_host=driver_host,
                                        driver_guest=driver_guest)
        if iface.address:
            del iface.address

        logging.debug("New interface xml file: %s", iface)
        if unprivileged_user:
            # Create disk image for unprivileged user
            disk_index = xml_devices.index(
                xml_devices.by_device_tag("disk")[0])
            disk_xml = xml_devices[disk_index]
            logging.debug("source: %s", disk_xml.source)
            disk_source = disk_xml.source.attrs["file"]
            cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}"
                   "".format(disk_source, dst_disk, unprivileged_user))
            utils.run(cmd)
            disk_xml.source = disk_xml.new_disk_source(
                attrs={"file": dst_disk})
            vmxml.devices = xml_devices
            # Remove all channels to avoid of permission problem
            channels = vmxml.get_devices(device_type="channel")
            for channel in channels:
                vmxml.del_device(channel)

            vmxml.xmltreefile.write()
            logging.debug("New VM xml: %s", vmxml)
            utils.run("chmod a+rw %s" % vmxml.xml)
            virsh.define(vmxml.xml, **virsh_dargs)
        # Try to modify interface xml by update-device or edit xml
        elif update:
            iface.xmltreefile.write()
            ret = virsh.update_device(vm_name, iface.xml, ignore_status=True)
            libvirt.check_exit_status(ret, status_error)
        else:
            vmxml.devices = xml_devices
            vmxml.xmltreefile.write()
            vmxml.sync()

    def check_offloads_option(if_name, driver_options, session=None):
        """
        Check interface offloads by ethtool output
        """
        offloads = {
            "csum": "tx-checksumming",
            "gso": "generic-segmentation-offload",
            "tso4": "tcp-segmentation-offload",
            "tso6": "tx-tcp6-segmentation",
            "ecn": "tx-tcp-ecn-segmentation",
            "ufo": "udp-fragmentation-offload"
        }
        if session:
            ret, output = session.cmd_status_output("ethtool -k %s | head"
                                                    " -18" % if_name)
        else:
            out = utils.run("ethtool -k %s | head -18" % if_name)
            ret, output = out.exit_status, out.stdout
        if ret:
            raise error.TestFail("ethtool return error code")
        logging.debug("ethtool output: %s", output)
        for offload in driver_options.keys():
            if offloads.has_key(offload):
                if (output.count(offloads[offload]) and not output.count(
                        "%s: %s" %
                    (offloads[offload], driver_options[offload]))):
                    raise error.TestFail(
                        "offloads option %s: %s isn't"
                        " correct in ethtool output" %
                        (offloads[offload], driver_options[offload]))

    def run_xml_test(iface_mac):
        """
        Test for interface options in vm xml
        """
        # Get the interface object according the mac address
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_devices = vmxml.get_devices(device_type="interface")
        iface = None
        for iface_dev in iface_devices:
            if iface_dev.mac_address == iface_mac:
                iface = iface_dev
        if not iface:
            raise error.TestFail("Can't find interface with mac"
                                 " '%s' in vm xml" % iface_mac)
        driver_dict = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        for driver_opt in driver_dict.keys():
            if not driver_dict[driver_opt] == iface.driver.driver_attr[
                    driver_opt]:
                raise error.TestFail(
                    "Can't see driver option %s=%s in vm xml" %
                    (driver_opt, driver_dict[driver_opt]))
        if iface_target:
            if (not iface.target.has_key("dev")
                    or not iface.target["dev"].startswith(iface_target)):
                raise error.TestFail("Can't see device target dev in vm xml")
            # Check macvtap mode by ip link command
            if iface_target == "macvtap" and iface.source.has_key("mode"):
                cmd = "ip -d link show %s" % iface.target["dev"]
                output = utils.run(cmd).stdout
                logging.debug("ip link output: %s", output)
                mode = iface.source["mode"]
                if mode == "passthrough":
                    mode = "passthru"
                if not output.count("macvtap  mode %s" % mode):
                    raise error.TestFail("Failed to verify macvtap mode")

    def run_cmdline_test(iface_mac):
        """
        Test for qemu-kvm command line options
        """
        cmd = ("ps -ef | grep %s | grep -v grep " % vm_name)
        if test_vhost_net:
            cmd += " | grep 'vhost=on'"
        ret = utils.run(cmd)
        if ret.exit_status:
            raise error.TestFail("Can't parse qemu-kvm command line")

        logging.debug("Command line %s", ret.stdout)
        if iface_model == "virtio":
            model_option = "device virtio-net-pci"
        else:
            model_option = "device rtl8139"
        iface_cmdline = re.findall(
            r"%s,(.+),mac=%s" % (model_option, iface_mac), ret.stdout)
        if not iface_cmdline:
            raise error.TestFail("Can't see %s with mac %s in command"
                                 " line" % (model_option, iface_mac))

        cmd_opt = {}
        for opt in iface_cmdline[0].split(','):
            tmp = opt.rsplit("=")
            cmd_opt[tmp[0]] = tmp[1]
        logging.debug("Command line options %s", cmd_opt)

        driver_dict = {}
        # Test <driver> xml options.
        if iface_driver:
            iface_driver_dict = ast.literal_eval(iface_driver)
            for driver_opt in iface_driver_dict.keys():
                if driver_opt == "name":
                    continue
                elif driver_opt == "txmode":
                    if iface_driver_dict["txmode"] == "iothread":
                        driver_dict["tx"] = "bh"
                    else:
                        driver_dict["tx"] = iface_driver_dict["txmode"]
                elif driver_opt == "queues":
                    driver_dict["mq"] = "on"
                    driver_dict["vectors"] = str(
                        int(iface_driver_dict["queues"]) * 2 + 2)
                else:
                    driver_dict[driver_opt] = iface_driver_dict[driver_opt]
        # Test <driver><host/><driver> xml options.
        if iface_driver_host:
            driver_dict.update(ast.literal_eval(iface_driver_host))
        # Test <driver><guest/><driver> xml options.
        if iface_driver_guest:
            driver_dict.update(ast.literal_eval(iface_driver_guest))

        for driver_opt in driver_dict.keys():
            if (not cmd_opt.has_key(driver_opt)
                    or not cmd_opt[driver_opt] == driver_dict[driver_opt]):
                raise error.TestFail("Can't see option '%s=%s' in qemu-kvm "
                                     " command line" %
                                     (driver_opt, driver_dict[driver_opt]))
        if test_backend:
            guest_pid = ret.stdout.rsplit()[1]
            cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid)
            if utils.system(cmd, ignore_status=True):
                raise error.TestFail("Guest process didn't open backend file" %
                                     backend["tap"])
            cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid)
            if utils.system(cmd, ignore_status=True):
                raise error.TestFail("Guest process didn't open backend file" %
                                     backend["tap"])

    def get_guest_ip(session, mac):
        """
        Wrapper function to get guest ip address
        """
        utils_net.restart_guest_network(session, mac)
        # Wait for IP address is ready
        utils_misc.wait_for(lambda: utils_net.get_guest_ip_addr(session, mac),
                            10)
        return utils_net.get_guest_ip_addr(session, mac)

    def check_user_network(session):
        """
        Check user network ip address on guest
        """
        vm_ips = []
        vm_ips.append(get_guest_ip(session, iface_mac_old))
        if attach_device:
            vm_ips.append(get_guest_ip(session, iface_mac))
        logging.debug("IP address on guest: %s", vm_ips)
        if len(vm_ips) != len(set(vm_ips)):
            raise error.TestFail("Duplicated IP address on guest. "
                                 "Check bug: https://bugzilla.redhat."
                                 "com/show_bug.cgi?id=1147238")

        for vm_ip in vm_ips:
            if vm_ip is None or not vm_ip.startswith("10.0.2."):
                raise error.TestFail("Found wrong IP address" " on guest")
        # Check gateway address
        gateway = utils_net.get_net_gateway(session.cmd_output)
        if gateway != "10.0.2.2":
            raise error.TestFail("The gateway on guest is not" " right")
        # Check dns server address
        ns_list = utils_net.get_net_nameserver(session.cmd_output)
        if "10.0.2.3" not in ns_list:
            raise error.TestFail("The dns server can't be found" " on guest")

    def check_mcast_network(session):
        """
        Check multicast ip address on guests
        """
        src_addr = ast.literal_eval(iface_source)['address']
        add_session = additional_vm.wait_for_serial_login()
        vms_sess_dict = {vm_name: session, additional_vm.name: add_session}

        # Check mcast address on host
        cmd = "netstat -g | grep %s" % src_addr
        if utils.run(cmd, ignore_status=True).exit_status:
            raise error.TestFail("Can't find multicast ip address" " on host")
        vms_ip_dict = {}
        # Get ip address on each guest
        for vms in vms_sess_dict.keys():
            vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms)
            vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac)
            if not vm_ip:
                raise error.TestFail("Can't get multicast ip"
                                     " address on guest")
            vms_ip_dict.update({vms: vm_ip})
        if len(set(vms_ip_dict.values())) != len(vms_sess_dict):
            raise error.TestFail("Got duplicated multicast ip address")
        logging.debug("Found ips on guest: %s", vms_ip_dict)

        # Run omping server on host
        if not utils_misc.yum_install(["omping"]):
            raise error.TestError("Failed to install omping" " on host")
        cmd = ("iptables -F;omping -m %s %s" %
               (src_addr, "192.168.122.1 %s" % ' '.join(vms_ip_dict.values())))
        # Run a backgroup job waiting for connection of client
        bgjob = utils.AsyncJob(cmd)

        # Run omping client on guests
        for vms in vms_sess_dict.keys():
            # omping should be installed first
            if not utils_misc.yum_install(["omping"], vms_sess_dict[vms]):
                raise error.TestError("Failed to install omping" " on guest")
            cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" %
                   (src_addr, "192.168.122.1 %s" % vms_ip_dict[vms]))
            ret, output = vms_sess_dict[vms].cmd_status_output(cmd)
            logging.debug("omping ret: %s, output: %s", ret, output)
            if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%')
                    or not output.count('unicast, xmt/rcv/%loss = 5/5/0%')):
                raise error.TestFail("omping failed on guest")
        # Kill the backgroup job
        bgjob.kill_func()

    status_error = "yes" == params.get("status_error", "no")
    start_error = "yes" == params.get("start_error", "no")
    unprivileged_user = params.get("unprivileged_user")

    # Interface specific attributes.
    iface_type = params.get("iface_type", "network")
    iface_source = params.get("iface_source", "{}")
    iface_driver = params.get("iface_driver")
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_backend = params.get("iface_backend", "{}")
    iface_driver_host = params.get("iface_driver_host")
    iface_driver_guest = params.get("iface_driver_guest")
    attach_device = params.get("attach_iface_device")
    change_option = "yes" == params.get("change_iface_options", "no")
    update_device = "yes" == params.get("update_iface_device", "no")
    additional_guest = "yes" == params.get("additional_guest", "no")
    serial_login = "******" == params.get("serial_login", "no")
    test_option_cmd = "yes" == params.get("test_iface_option_cmd", "no")
    test_option_xml = "yes" == params.get("test_iface_option_xml", "no")
    test_vhost_net = "yes" == params.get("test_vhost_net", "no")
    test_option_offloads = "yes" == params.get("test_option_offloads", "no")
    test_iface_user = "******" == params.get("test_iface_user", "no")
    test_iface_mcast = "yes" == params.get("test_iface_mcast", "no")
    test_libvirtd = "yes" == params.get("test_libvirtd", "no")
    test_guest_ip = "yes" == params.get("test_guest_ip", "no")
    test_backend = "yes" == params.get("test_backend", "no")

    if iface_driver_host or iface_driver_guest or test_backend:
        if not libvirt_version.version_compare(1, 2, 8):
            raise error.TestNAError("Offloading/backend options not "
                                    "supported in this libvirt version")
    if iface_driver and "queues" in ast.literal_eval(iface_driver):
        if not libvirt_version.version_compare(1, 0, 6):
            raise error.TestNAError("Queues options not supported"
                                    " in this libvirt version")

    if unprivileged_user:
        virsh_dargs["unprivileged_user"] = unprivileged_user
        # Create unprivileged user if needed
        cmd = ("grep {0} /etc/passwd || "
               "useradd {0}".format(unprivileged_user))
        utils.run(cmd)
        # Need another disk image for unprivileged user to access
        dst_disk = "/tmp/%s.img" % unprivileged_user

    # Destroy VM first
    if vm.is_alive():
        vm.destroy(gracefully=False)

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    # iface_mac will update if attach a new interface
    iface_mac = iface_mac_old
    # Additional vm for test
    additional_vm = None
    libvirtd = utils_libvirtd.Libvirtd()

    try:
        # Build the xml and run test.
        try:
            # Prepare interface backend files
            if test_backend:
                if not os.path.exists("/dev/vhost-net"):
                    utils.run("modprobe vhost-net")
                backend = ast.literal_eval(iface_backend)
                backend_tap = "/dev/net/tun"
                backend_vhost = "/dev/vhost-net"
                if not backend:
                    backend["tap"] = backend_tap
                    backend["vhost"] = backend_vhost
                if not start_error:
                    # Create backend files for normal test
                    if not os.path.exists(backend["tap"]):
                        os.rename(backend_tap, backend["tap"])
                    if not os.path.exists(backend["vhost"]):
                        os.rename(backend_vhost, backend["vhost"])
            # Edit the interface xml.
            if change_option:
                modify_iface_xml(update=False)
            # Check vhost driver.
            if test_vhost_net:
                if os.path.exists("/dev/vhost-net"):
                    cmd = ("modprobe -r {0}; lsmod | "
                           "grep {0}".format("vhost_net"))
                    if not utils.system(cmd, ignore_status=True):
                        raise error.TestError("Can't remove "
                                              "vhost_net driver")

            # Attach a interface when vm is shutoff
            if attach_device == 'config':
                iface_mac = utils_net.generate_mac_address_simple()
                iface_xml_obj = create_iface_xml(iface_mac)
                iface_xml_obj.xmltreefile.write()
                ret = virsh.attach_device(vm_name,
                                          iface_xml_obj.xml,
                                          flagstr="--config",
                                          ignore_status=True)
                libvirt.check_exit_status(ret)

            # Clone additional vm
            if additional_guest:
                guest_name = "%s_%s" % (vm_name, '1')
                # Clone additional guest
                timeout = params.get("clone_timeout", 360)
                utils_libguestfs.virt_clone_cmd(vm_name,
                                                guest_name,
                                                True,
                                                timeout=timeout)
                additional_vm = vm.clone(guest_name)
                additional_vm.start()
                #additional_vm.wait_for_login()

            # Start the VM.
            if unprivileged_user:
                virsh.start(vm_name, **virsh_dargs)
                cmd = ("su - %s -c 'virsh console %s'" %
                       (unprivileged_user, vm_name))
                session = aexpect.ShellSession(cmd)
                session.sendline()
                remote.handle_prompts(session, params.get("username"),
                                      params.get("password"), "[\#\$]", 30)
                # Get ip address on guest
                if not get_guest_ip(session, iface_mac):
                    raise error.TestError("Can't get ip address on guest")
            else:
                # Will raise VMStartError exception if start fails
                vm.start()
                if serial_login:
                    session = vm.wait_for_serial_login()
                else:
                    session = vm.wait_for_login()
            if start_error:
                raise error.TestFail("VM started unexpectedly")

            if test_vhost_net:
                if utils.system("lsmod | grep vhost_net", ignore_status=True):
                    raise error.TestFail("vhost_net module can't be"
                                         " loaded automatically")

            # Attach a interface when vm is running
            if attach_device == 'live':
                iface_mac = utils_net.generate_mac_address_simple()
                iface_xml_obj = create_iface_xml(iface_mac)
                iface_xml_obj.xmltreefile.write()
                ret = virsh.attach_device(vm_name,
                                          iface_xml_obj.xml,
                                          flagstr="--live",
                                          ignore_status=True)
                libvirt.check_exit_status(ret)
                # Need sleep here for attachment take effect
                time.sleep(5)

            # Update a interface options
            if update_device:
                modify_iface_xml(update=True, status_error=status_error)

            # Run tests for qemu-kvm command line options
            if test_option_cmd:
                run_cmdline_test(iface_mac)
            # Run tests for vm xml
            if test_option_xml:
                run_xml_test(iface_mac)
            # Run tests for offloads options
            if test_option_offloads:
                if iface_driver_host:
                    ifname_guest = utils_net.get_linux_ifname(
                        session, iface_mac)
                    check_offloads_option(ifname_guest,
                                          ast.literal_eval(iface_driver_host),
                                          session)
                if iface_driver_guest:
                    ifname_host = libvirt.get_ifname_host(vm_name, iface_mac)
                    check_offloads_option(ifname_host,
                                          ast.literal_eval(iface_driver_guest))

            if test_iface_user:
                # Test user type network
                check_user_network(session)
            if test_iface_mcast:
                # Test mcast type network
                check_mcast_network(session)
            # Check guest ip address
            if test_guest_ip:
                if not get_guest_ip(session, iface_mac):
                    raise error.TestFail("Guest can't get a"
                                         " valid ip address")

            session.close()
            # Restart libvirtd and guest, then test again
            if test_libvirtd:
                libvirtd.restart()
                vm.destroy()
                vm.start()
                if test_option_xml:
                    run_xml_test(iface_mac)

            # Detach hot/cold-plugged interface at last
            if attach_device:
                ret = virsh.detach_device(vm_name,
                                          iface_xml_obj.xml,
                                          flagstr="",
                                          ignore_status=True)
                libvirt.check_exit_status(ret)

        except virt_vm.VMStartError, e:
            logging.info(str(e))
            if start_error:
                pass
            else:
                raise error.TestFail('VM Failed to start for some reason!')

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        # Restore interface backend files
        if test_backend:
            if not os.path.exists(backend_tap):
                os.rename(backend["tap"], backend_tap)
            if not os.path.exists(backend_vhost):
                os.rename(backend["vhost"], backend_vhost)
        if unprivileged_user:
            virsh.remove_domain(vm_name, "--remove-all-storage", **virsh_dargs)
        if additional_vm:
            virsh.remove_domain(additional_vm.name, "--remove-all-storage")
            # Kill all omping server process on host
            utils.system("pidof omping && killall omping", ignore_status=True)
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
Esempio n. 12
0
        error.context("Check the src and dst file is same", logging.info)
        src_md5 = sessions[0].cmd_output(md5_check % src_file).split()[0]
        dst_md5 = sessions[1].cmd_output(md5_check % dst_file).split()[0]

        if dst_md5 != src_md5:
            debug_msg = "Files md5sum mismatch!"
            debug_msg += "source file md5 is '%s', after transfer md5 is '%s'"
            raise error.TestFail(debug_msg % (src_md5, dst_md5), logging.info)
        logging.info("Files md5sum match, file md5 is '%s'" % src_md5)

        error.context("Checking network private", logging.info)
        tcpdump_check_cmd = params["tcpdump_check_cmd"]
        tcpdump_kill_cmd = params["tcpdump_kill_cmd"]
        tcpdump_check_cmd = re.sub("ADDR0", addresses[0], tcpdump_check_cmd)
        tcpdump_check_cmd = re.sub("ADDR1", addresses[1], tcpdump_check_cmd)
        status = mon_session.cmd_status(tcpdump_check_cmd)
        if status:
            raise error.TestError("Tcpdump process terminate exceptly")
        mon_session.cmd(tcpdump_kill_cmd)
        dthread.join()

    finally:
        sessions[0].cmd(" %s %s " % (clean_cmd, src_file))
        sessions[1].cmd(" %s %s " % (clean_cmd, src_file))
        if mon_session:
            mon_session.close()
        for session in sessions:
            if session:
                session.close()
Esempio n. 13
0
    def _parse_params(self):
        '''
        Parses the params items for entries related to this repo

        This method currently does everything that the parent class __init__()
        method does, that is, sets all instance variables needed by other
        methods. That means it's not strictly necessary to call parent's
        __init__().
        '''
        config_prefix = 'git_repo_%s' % self.name
        logging.debug('Parsing parameters for git repo %s, configuration '
                      'prefix is %s' % (self.name, config_prefix))

        self.base_uri = self.params.get('%s_base_uri' % config_prefix)
        if self.base_uri is None:
            logging.debug('Git repo %s base uri is not set' % self.name)
        else:
            logging.debug('Git repo %s base uri: %s' % (self.name,
                                                        self.base_uri))

        self.uri = self.params.get('%s_uri' % config_prefix)
        logging.debug('Git repo %s uri: %s' % (self.name, self.uri))

        self.branch = self.params.get('%s_branch' % config_prefix, 'master')
        logging.debug('Git repo %s branch: %s' % (self.name, self.branch))

        self.lbranch = self.params.get('%s_lbranch' % config_prefix)
        if self.lbranch is None:
            self.lbranch = self.branch
        logging.debug('Git repo %s lbranch: %s' % (self.name, self.lbranch))

        self.commit = self.params.get('%s_commit' % config_prefix)
        if self.commit is None:
            logging.debug('Git repo %s commit is not set' % self.name)
        else:
            logging.debug('Git repo %s commit: %s' % (self.name, self.commit))

        self.tag = self.params.get('%s_tag' % config_prefix)
        if self.tag is None:
            logging.debug('Git repo %s tag is not set' % self.name)
        else:
            logging.debug('Git repo %s tag: %s' % (self.name, self.tag))

        self.key_file = None
        tag_signed = self.params.get('%s_tag_signed' % config_prefix)
        if tag_signed is None:
            logging.warning('Git repo %s tag is not signed' % self.name)
            logging.warning('This means we will not verify if the key was '
                            'made by whomever claims to have made it '
                            '(dangerous)')
        else:
            self.key_file = os.path.join(data_dir.get_data_dir(), 'gpg',
                                         tag_signed)
            if os.path.isfile(self.key_file):
                logging.debug('Git repo %s tag %s will be verified with public '
                              'key file %s', self.name, self.tag, self.key_file)
            else:
                raise error.TestError('GPG public key file %s not found, will '
                                      'not proceed with testing' %
                                      self.key_file)

        self.cmd = os_dep.command('git')

        self.recursive = self.params.get('%s_recursive', 'yes')
Esempio n. 14
0
    delay = int(params.get("virsh_migrate_delay", 10))
    status_error = params.get("status_error", 'no')
    libvirtd_state = params.get("virsh_migrate_libvirtd_state", 'on')
    src_state = params.get("virsh_migrate_src_state", "running")
    new_nic_mac = "ff:ff:ff:ff:ff:ff"
    dest_xmlfile = ""

    exception = False
    try:
        # Confirm VM can be accessed through network.
        time.sleep(delay)
        vm_ip = vm.get_address()
        s_ping, o_ping = utils_test.ping(vm_ip, count=2, timeout=delay)
        logging.info(o_ping)
        if s_ping != 0:
            raise error.TestError("%s did not respond after %d sec."
                                  % (vm.name, delay))

        # Prepare for --xml.
        logging.debug("Preparing new xml file for --xml option.")
        if options.count("xml") or extra.count("xml"):
            dest_xmlfile = params.get("virsh_migrate_xml", "")
            if dest_xmlfile:
                ret_attach = vm.attach_interface("--type bridge --source "
                                                 "virbr0 --mac %s" % new_nic_mac, True, True)
                if not ret_attach:
                    exception = True
                    raise error.TestError(
                        "Attaching nic to %s failed." % vm.name)
                vm_xml_new = vm.get_xml()
                logging.debug("Xml file on source: %s" % vm_xml_new)
                f = codecs.open(dest_xmlfile, 'wb', encoding='utf-8')
Esempio n. 15
0
        try:
            utils.run("service libvirtd %s" % action)
            logging.debug("%s libvirtd successfuly", action)
            return True
        except error.CmdError, detail:
            logging.error("Failed to %s libvirtd:\n%s", action, detail)
            return False
    elif action == "status":
        cmd_result = utils.run("service libvirtd status", ignore_status=True)
        if re.search("pid", cmd_result.stdout.strip()):
            logging.info("Libvirtd service is running")
            return True
        else:
            return False
    else:
        raise error.TestError("Unknown action: %s" % action)


def normalize_connect_uri(connect_uri):
    """
    Processes connect_uri Cartesian into something virsh can use

    @param: connect_uri: Cartesian Params setting
    @return: Normalized connect_uri
    """
    if connect_uri == 'default':
        return None
    else: # Validate and canonicalize uri early to catch problems
        return virsh.canonical_uri(uri=connect_uri)

Esempio n. 16
0
def run(test, params, env):
    """
    Test command: virsh update-device.

    Update device from an XML <file>.
    1.Prepare test environment, adding a cdrom/floppy to VM.
    2.Perform virsh update-device operation.
    3.Recover test environment.
    4.Confirm the test result.
    """

    # Before doing anything - let's be sure we can support this test
    # Parse flag list, skip testing early if flag is not supported
    # NOTE: "".split("--") returns [''] which messes up later empty test
    flag = params.get("updatedevice_flag", "")
    flag_list = []
    if flag.count("--"):
        flag_list = flag.split("--")
    for item in flag_list:
        option = item.strip()
        if option == "":
            continue
        if not bool(virsh.has_command_help_match("update-device", option)):
            raise error.TestNAError(
                "virsh update-device doesn't support --%s" % option)

    # As per RH BZ 961443 avoid testing before behavior changes
    if 'config' in flag_list:
        # SKIP tests using --config if libvirt is 0.9.10 or earlier
        if not libvirt_version.version_compare(0, 9, 10):
            raise error.TestNAError("BZ 961443: --config behavior change "
                                    "in version 0.9.10")
    if 'persistent' in flag_list:
        # SKIP tests using --persistent if libvirt 1.0.5 or earlier
        if not libvirt_version.version_compare(1, 0, 5):
            raise error.TestNAError("BZ 961443: --persistent behavior change "
                                    "in version 1.0.5")

    # Prepare initial vm state
    vm_name = params.get("main_vm")
    vmxml = VMXML.new_from_dumpxml(vm_name, options="--inactive")
    vm = env.get_vm(vm_name)
    start_vm = "yes" == params.get("start_vm", "no")

    # Get the target bus/dev
    disk_type = params.get("disk_type", "cdrom")
    target_bus = params.get("updatedevice_target_bus", "ide")
    target_dev = params.get("updatedevice_target_dev", "hdc")
    disk_mode = params.get("disk_mode", "")
    support_mode = ['readonly', 'shareable']
    if not disk_mode and disk_mode not in support_mode:
        raise error.TestError("%s not in support mode %s" %
                              (disk_mode, support_mode))

    # Prepare tmp directory and files.
    orig_iso = os.path.join(test.virtdir, "orig.iso")
    test_iso = os.path.join(test.virtdir, "test.iso")
    test_diff_iso = os.path.join(test.virtdir, "test_diff.iso")
    update_xmlfile = os.path.join(test.tmpdir, "update.xml")
    create_attach_xml(update_xmlfile, test_iso, disk_type, target_bus,
                      target_dev, disk_mode)

    # This test needs a cdrom/floppy attached first - attach a cdrom/floppy
    # to a shutdown vm. Then decide to restart or not
    if vm.is_alive():
        vm.destroy(gracefully=False)
    create_disk(vm_name, orig_iso, disk_type, target_dev, disk_mode)
    if start_vm:
        if not vm.is_alive():
            vm.start()
        vm.wait_for_login().close()
        domid = vm.get_id()
    else:
        domid = "domid invalid; domain is shut-off"

    # Get remaining parameters for configuration.
    twice = "yes" == params.get("updatedevice_twice", "no")
    diff_iso = "yes" == params.get("updatedevice_diff_iso", "no")
    vm_ref = params.get("updatedevice_vm_ref", "")
    status_error = "yes" == params.get("status_error", "no")
    extra = params.get("updatedevice_extra", "")

    # OK let's give this a whirl...
    errmsg = ""
    try:
        if vm_ref == "id":
            vm_ref = domid
            if twice:
                # Don't pass in any flags
                ret = virsh.update_device(domainarg=domid,
                                          filearg=update_xmlfile,
                                          ignore_status=True,
                                          debug=True)
                if not status_error:
                    status = ret.exit_status
                    errmsg += ret.stderr
                    libvirt.check_exit_status(ret)
            if diff_iso:
                # Swap filename of device backing file in update.xml
                os.remove(update_xmlfile)
                create_attach_xml(update_xmlfile, test_diff_iso, disk_type,
                                  target_bus, target_dev, disk_mode)
        elif vm_ref == "uuid":
            vm_ref = vmxml.uuid
        elif vm_ref == "hex_id":
            vm_ref = hex(int(domid))
        elif vm_ref.find("updatedevice_invalid") != -1:
            vm_ref = params.get(vm_ref)
        elif vm_ref == "name":
            vm_ref = "%s %s" % (vm_name, extra)

        cmdresult = virsh.update_device(domainarg=vm_ref,
                                        filearg=update_xmlfile,
                                        flagstr=flag,
                                        ignore_status=True,
                                        debug=True)
        status = cmdresult.exit_status
        if not status_error:
            errmsg += cmdresult.stderr

        active_vmxml = VMXML.new_from_dumpxml(vm_name)
        inactive_vmxml = VMXML.new_from_dumpxml(vm_name, options="--inactive")
    finally:
        vm.destroy(gracefully=False, free_mac_addresses=False)
        vmxml.undefine()
        vmxml.restore()
        vmxml.define()
        if os.path.exists(orig_iso):
            os.remove(orig_iso)
        if os.path.exists(test_iso):
            os.remove(test_iso)
        if os.path.exists(test_diff_iso):
            os.remove(test_diff_iso)

    # Result handling logic set errmsg only on error
    if status_error:
        if status == 0:
            errmsg += "\nRun successfully with wrong command!\n"
    else:  # Normal test
        if status != 0:
            errmsg += "\nRun failed with right command\n"
        if diff_iso:  # Expect the backing file to have updated
            active_attached = is_attached(active_vmxml.devices, disk_type,
                                          test_diff_iso, target_dev)
            inactive_attached = is_attached(inactive_vmxml.devices, disk_type,
                                            test_diff_iso, target_dev)
        else:  # Expect backing file to remain the same
            active_attached = is_attached(active_vmxml.devices, disk_type,
                                          test_iso, target_dev)
            inactive_attached = is_attached(inactive_vmxml.devices, disk_type,
                                            test_iso, target_dev)

        # Check behavior of combination before individual!
        if "config" in flag_list and "live" in flag_list:
            if not active_attached:
                errmsg += ("Active domain XML not updated when "
                           "--config --live options used\n")
            if not inactive_attached:
                errmsg += ("Inactive domain XML not updated when "
                           "--config --live options used\n")

        elif "live" in flag_list and inactive_attached:
            errmsg += ("Inactive domain XML updated when "
                       "--live option used\n")

        elif "config" in flag_list and active_attached:
            errmsg += ("Active domain XML updated when "
                       "--config option used\n")

        # persistent option behavior depends on start_vm
        if "persistent" in flag_list:
            if start_vm:
                if not active_attached or not inactive_attached:
                    errmsg += ("XML not updated when --persistent "
                               "option used on active domain\n")

            else:
                if not inactive_attached:
                    errmsg += ("XML not updated when --persistent "
                               "option used on inactive domain\n")
        if len(flag_list) == 0:
            # Not specifying any flag is the same as specifying --current
            if start_vm:
                if not active_attached:
                    errmsg += "Active domain XML not updated\n"
                elif inactive_attached:
                    errmsg += ("Inactive domain XML updated when active "
                               "requested\n")

    # Log some debugging info before destroying instances
    if errmsg and not status_error:
        logging.debug("Active XML:")
        logging.debug(str(active_vmxml))
        logging.debug("Inactive XML:")
        logging.debug(str(inactive_vmxml))
        logging.debug("active_attached: %s", str(active_attached))
        logging.debug("inctive_attached: %s", str(inactive_attached))
        logging.debug("Device XML:")
        logging.debug(open(update_xmlfile, "r").read())

    # clean up tmp files
    del vmxml
    del active_vmxml
    del inactive_vmxml
    os.unlink(update_xmlfile)

    if errmsg:
        raise error.TestFail(errmsg)
Esempio n. 17
0
        def test(self):
            super(test_multihost_write, self).test()
            copy_timeout = int(params.get("copy_timeout", 480))
            self.mount_dir = params["mount_dir"]
            format_floppy_cmd = params["format_floppy_cmd"]
            check_copy_path = params["check_copy_path"]

            pid = None
            sync_id = {
                'src': self.srchost,
                'dst': self.dsthost,
                "type": "file_trasfer"
            }
            filename = "orig"

            if self.is_src:  # Starts in source
                vm = env.get_vm(self.vms[0])
                session = vm.wait_for_login(timeout=login_timeout)

                if self.mount_dir:
                    session.cmd("rm -f %s" %
                                (os.path.join(self.mount_dir, filename)))
                    session.cmd("rm -f %s" % (check_copy_path))
                # If mount_dir specified, treat guest as a Linux OS
                # Some Linux distribution does not load floppy at boot
                # and Windows needs time to load and init floppy driver
                error.context("Prepare floppy for writing.")
                if self.mount_dir:
                    lsmod = session.cmd("lsmod")
                    if not 'floppy' in lsmod:
                        session.cmd("modprobe floppy")
                else:
                    time.sleep(20)

                session.cmd(format_floppy_cmd)

                error.context("Mount and copy data")
                if self.mount_dir:
                    session.cmd("mount -t vfat %s %s" %
                                (guest_floppy_path, self.mount_dir),
                                timeout=30)

                error.context("File copying test")

                pid = lazy_copy(vm, os.path.join(self.mount_dir, filename),
                                check_copy_path, copy_timeout)

            sync = SyncData(self.mig.master_id(), self.mig.hostid,
                            self.mig.hosts, sync_id, self.mig.sync_server)

            pid = sync.sync(pid, timeout=floppy_prepare_timeout)[self.srchost]

            self.mig.migrate_wait([self.vms[0]], self.srchost, self.dsthost)

            if not self.is_src:  # Starts in destination
                vm = env.get_vm(self.vms[0])
                session = vm.wait_for_login(timeout=login_timeout)
                error.context("Wait for copy finishing.")
                status = int(
                    session.cmd_status("kill %s" % pid, timeout=copy_timeout))
                if not status in [0]:
                    raise error.TestFail("Copy process was terminatted with"
                                         " error code %s" % (status))

                session.cmd_status("kill -s SIGINT %s" % (pid),
                                   timeout=copy_timeout)

                error.context("Check floppy file checksum.")
                md5_cmd = params.get("md5_cmd")
                if md5_cmd:
                    md5_floppy = session.cmd(
                        "%s %s" % (params.get("md5_cmd"),
                                   os.path.join(self.mount_dir, filename)))
                    try:
                        md5_floppy = md5_floppy.split(" ")[0]
                    except IndexError:
                        error.TestError("Failed to get md5 from source file,"
                                        " output: '%s'" % md5_floppy)
                    md5_check = session.cmd(
                        "%s %s" % (params.get("md5_cmd"), check_copy_path))
                    try:
                        md5_check = md5_check.split(" ")[0]
                    except IndexError:
                        error.TestError("Failed to get md5 from source file,"
                                        " output: '%s'" % md5_floppy)
                    if md5_check != md5_floppy:
                        raise error.TestFail(
                            "There is mistake in copying,"
                            " it is possible to check file on vm.")

                session.cmd("rm -f %s" %
                            (os.path.join(self.mount_dir, filename)))
                session.cmd("rm -f %s" % (check_copy_path))

            self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts,
                                    'finish_floppy_test', login_timeout)
                path=device_source_path,
                size="1",
                disk_format=device_source_format)
            s_attach = virsh.attach_disk(vm_name, device_source,
                                         device_target2,
                                         "--driver qemu --config").exit_status
            if s_attach != 0:
                logging.error("Attaching device failed before testing "
                              "detach-disk test_twice")

    vm.start()
    vm.wait_for_login()

    # Add acpiphp module before testing if VM's os type is rhle5.*
    if not acpiphp_module_modprobe(vm, os_type):
        raise error.TestError("Add acpiphp module failed before test.")

    # Turn VM into certain state.
    if pre_vm_state == "paused":
        logging.info("Suspending %s..." % vm_name)
        if vm.is_alive():
            vm.pause()
    elif pre_vm_state == "shut off":
        logging.info("Shuting down %s..." % vm_name)
        if vm.is_alive():
            vm.destroy(gracefully=False)

    # Get disk count before test.
    disk_count_before_cmd = vm_xml.VMXML.get_disk_count(vm_name)

    # Test.
Esempio n. 19
0
def run(test, params, env):
    """
    Test command: virsh blockjob.

    This command can manage active block operations.
    1. Positive testing
        1.1 Query active block job for the specified disk.
        1.2 Manager the active block job(cancle/pivot).
        1.3 Adjust speed for the active block job.
    2. Negative testing
        2.1 Query active block job for a invalid disk.
        2.2 Invalid bandwith test.
        2.3 No active block job management.
    """

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    options = params.get("blockjob_options", "")
    bandwidth = params.get("blockjob_bandwidth", "")
    no_blockjob = "yes" == params.get("no_blockjob", "no")
    invalid_disk = params.get("invalid_disk")
    persistent_vm = "yes" == params.get("persistent_vm", "no")
    status_error = "yes" == params.get("status_error", "no")

    target = get_disk(vm_name)
    if not target:
        raise error.TestFail("Require target disk to copy.")

    # Prepare transient/persistent vm
    original_xml = vm.backup_xml()
    if not persistent_vm and vm.is_persistent():
        vm.undefine()
    elif persistent_vm and not vm.is_persistent():
        vm.define(original_xml)

    #Create a block job, e.g.: blockcopy
    tmp_file = time.strftime("%Y-%m-%d-%H.%M.%S.img")
    dest_path = os.path.join(data_dir.get_tmp_dir(), tmp_file)
    if not no_blockjob:
        cmd_result = virsh.blockcopy(vm_name,
                                     target,
                                     dest_path,
                                     "",
                                     ignore_status=True,
                                     debug=True)
        status = cmd_result.exit_status
        if status != 0:
            raise error.TestError("Fail to create blockcopy job.")
        # This option need blockjcopy job finish first
        if options.count("--pivot"):
            #Set default blockcopy timeout to 300 sec
            timeout = 300
            finish_job(vm_name, target, timeout)

    if len(bandwidth):
        options += "--bandwidth %s" % bandwidth

    if invalid_disk:
        target = invalid_disk

    # Run virsh blockjob command
    cmd_result = virsh.blockjob(vm_name,
                                target,
                                options,
                                ignore_status=True,
                                debug=True)
    err = cmd_result.stderr.strip()
    status = cmd_result.exit_status

    # Check result
    if not utils_libvirtd.libvirtd_is_running():
        raise error.TestFail("Libvirtd service is dead.")
    try:
        if not status_error:
            if status == 0:
                #'abort' option check
                if options.count("--abort"):
                    utl.check_blockjob(vm_name, target, "no_job", 0)
                #'pivot' option check
                if options.count("--pivot"):
                    if utl.check_blockjob(vm_name, target, "no_job", 0):
                        check_disk(vm_name, dest_path)
                #'bandwidth' option check
                if options.count("--bandwidth"):
                    utl.check_blockjob(vm_name, target, "bandwidth", bandwidth)
            else:
                raise error.TestFail(err)
        else:
            if status:
                logging.debug("Expect error: %s", err)
            else:
                raise error.TestFail("Expect fail, but run successfully.")
        #cleanup
    finally:
        try:
            if vm.exists():
                vm.destroy()
            else:
                raise error.TestFail("Domain is disappeared.")
        finally:
            vm.define(original_xml)
            if os.path.exists(dest_path):
                os.remove(dest_path)
Esempio n. 20
0
    def add_device(pci_num, queues=1):
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_%s" % (cmd_type, pci_type)]
        except Exception:
            raise error.TestError("No function for adding '%s' dev with '%s'" %
                                  (pci_type, cmd_type))
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num, queues)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output(params.get("find_pci_cmd"))
                output = map(string.strip, output.splitlines())
                ref = map(string.strip, reference.splitlines())
                output = [_ for _ in output if _ not in ref]
                output = "\n".join(output)
                if re.search(params.get("match_string"), output, re.I | re.M):
                    return True
                return False

            error.context("Start checking new added device", logging.info)
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail(
                    "No new device shown in output of command "
                    "executed inside the guest: %s" % reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail(
                    "PCI %s %s device not found in guest. "
                    "Command was: %s" %
                    (pci_model, pci_type, params.get("find_pci_cmd")))

            # Test the newly added device
            try:
                if params.get("pci_test_cmd"):
                    test_cmd = re.sub("PCI_NUM", "%s" % (pci_num + 1),
                                      params.get("pci_test_cmd"))
                    session.cmd(test_cmd)
            except aexpect.ShellError, e:
                raise error.TestFail("Check for %s device failed after PCI "
                                     "hotplug. Output: %r" %
                                     (pci_type, e.output))

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise
Esempio n. 21
0
def run(test, params, env):
    """
    Test command: virsh nodedev-reset <device>

    When `device_option` is:
    1) resettable   : Reset specified device if it is resettable.
    2) non-exist    : Try to reset specified device which doesn't exist.
    3) non-pci      : Try to reset all local non-PCI devices.
    4) active       : Try to reset specified device which is attached to VM.
    5) unresettable : Try to reset all unresettable PCI devices.
    """
    # Retrive parameters
    expect_succeed = params.get('expect_succeed', 'yes')
    device_option = params.get('device_option', 'valid')
    unspecified = 'REPLACE_WITH_TEST_DEVICE'
    specified_device = params.get('specified_device', unspecified)

    # Backup original libvirtd status and prepare libvirtd status
    logging.debug('Preparing libvirtd')
    libvirtd = utils_libvirtd.Libvirtd()
    if params.get("libvirtd", "on") == "off":
        libvirtd.stop()

    # Get whether PCI devices are resettable from sysfs.
    devices = get_pci_info()

    # Devide PCI devices into to catagories.
    resettable_nodes = []
    unresettable_nodes = []
    for device in devices:
        info = devices[device]
        if info['reset'] and info['driver']:
            resettable_nodes.append(device)
        if not info['reset'] and not info['driver']:
            unresettable_nodes.append(device)

    # Find out all non-PCI devices.
    all_devices = virsh.nodedev_list().stdout.strip().splitlines()
    non_pci_nodes = []
    for device in all_devices:
        if device not in devices:
            non_pci_nodes.append(device)

    try:
        if device_option == 'resettable':
            # Test specified resettable device.
            if specified_device != unspecified:
                if specified_device in resettable_nodes:
                    test_nodedev_reset([specified_device], expect_succeed)
                else:
                    raise error.TestNAError(
                        'Param specified_device is not set!')
            else:
                raise error.TestNAError('Param specified_device is not set!')
        elif device_option == 'non-exist':
            # Test specified non-exist device.
            if specified_device != unspecified:
                if specified_device not in all_devices:
                    test_nodedev_reset([specified_device], expect_succeed)
                else:
                    raise error.TestError('Specified device exists!')
            else:
                raise error.TestNAError('Param specified_device is not set!')
        elif device_option == 'non-pci':
            # Test all non-PCI device.
            if non_pci_nodes:
                test_nodedev_reset(non_pci_nodes, expect_succeed)
            else:
                raise error.TestNAError('No non-PCI device found!')
        elif device_option == 'active':
            # Test specified device if attached to VM.
            if specified_device != unspecified:
                vm_name = params.get('main_vm', 'virt-tests-vm1')
                vm = env.get_vm(vm_name)
                test_active_nodedev_reset(specified_device, vm, expect_succeed)
            else:
                raise error.TestNAError('Param specified_device is not set!')
        elif device_option == 'unresettable':
            # Test all unresettable device.
            if unresettable_nodes:
                test_nodedev_reset(unresettable_nodes, expect_succeed)
            else:
                raise error.TestNAError('No unresettable device found!')
        else:
            raise error.TestError('Unrecognisable device option %s!' %
                                  device_option)
    finally:
        # Restore libvirtd status
        logging.debug('Restoring libvirtd')
        if not libvirtd.is_running():
            libvirtd.start()
Esempio n. 22
0
 def verify_supported_device(dev):
     if not is_supported_device(dev):
         raise error.TestError("%s doesn't support device: %s" %
                               (cmd_type, dev))
Esempio n. 23
0
def run_cpuid(test, params, env):
    """
    Boot guest with different cpu_models and cpu flags and check if guest works correctly.

    @param test: kvm test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    qemu_binary = utils_misc.get_path('.', params.get("qemu_binary", "qemu"))

    cpu_model = params.get("cpu_model", "qemu64")

    xfail = False
    if (params.get("xfail") is not None) and (params.get("xfail") == "yes"):
        xfail = True

    class MiniSubtest(test_module.Subtest):
        """
        subtest base class for actual tests
        """
        def __new__(cls, *args, **kargs):
            self = test.__new__(cls)
            ret = None
            if args is None:
                args = []
            try:
                ret = self.test(*args, **kargs)
            finally:
                if hasattr(self, "clean"):
                    self.clean()
            return ret

        def clean(self):
            """
            cleans up running VM instance
            """
            if (hasattr(self, "vm")):
                vm = getattr(self, "vm")
                if vm.is_alive():
                    vm.pause()
                    vm.destroy(gracefully=False)

        def test(self):
            """
            stub for actual test code
            """
            raise error.TestFail("test() must be redifined in subtest")

    def print_exception(called_object):
        """
        print error including stack trace
        """
        exc_type, exc_value, exc_traceback = sys.exc_info()
        logging.error("In function (" + called_object.__name__ + "):")
        logging.error("Call from:\n" + traceback.format_stack()[-2][:-1])
        logging.error("Exception from:\n" + "".join(
            traceback.format_exception(exc_type, exc_value,
                                       exc_traceback.tb_next)))

    def cpu_models_to_test():
        """Return the list of CPU models to be tested, based on the
        cpu_models and cpu_model config options.

        Config option "cpu_model" may be used to ask a single CPU model
        to be tested. Config option "cpu_models" may be used to ask
        multiple CPU models to be tested.

        If cpu_models is "*", all CPU models reported by QEMU will be tested.
        """
        models_opt = params.get("cpu_models")
        model_opt = params.get("cpu_model")

        if (models_opt is None and model_opt is None):
            raise error.TestError("No cpu_models or cpu_model option is set")

        cpu_models = set()

        if models_opt == '*':
            cpu_models.update(utils_misc.get_qemu_cpu_models(qemu_binary))
        elif models_opt:
            cpu_models.update(models_opt.split())

        if model_opt:
            cpu_models.add(model_opt)

        return cpu_models

    class test_qemu_cpu_models_list(MiniSubtest):
        """
        check CPU models returned by <qemu> -cpu '?' are what is expected
        """
        def test(self):
            """
            test method
            """
            cpu_models = cpu_models_to_test()
            qemu_models = utils_misc.get_qemu_cpu_models(qemu_binary)
            missing = set(cpu_models) - set(qemu_models)
            if missing:
                raise error.TestFail(
                    "Some CPU models not in QEMU CPU model list: %s")
            added = set(qemu_models) - set(cpu_models)
            if added:
                logging.info("Extra CPU models in QEMU CPU listing: %s", added)

    def get_guest_cpuid(self, cpu_model, feature=None):
        test_kernel_dir = os.path.join(test.virtdir, "deps",
                                       "cpuid_test_kernel")
        os.chdir(test_kernel_dir)
        utils.make("cpuid_dump_kernel.bin")

        vm_name = params.get('main_vm')
        params_b = params.copy()
        params_b["kernel"] = os.path.join(test_kernel_dir,
                                          "cpuid_dump_kernel.bin")
        params_b["cpu_model"] = cpu_model
        params_b["cpu_model_flags"] = feature
        del params_b["images"]
        del params_b["nics"]
        env_process.preprocess_vm(self, params_b, env, vm_name)
        vm = env.get_vm(vm_name)
        vm.create()
        self.vm = vm
        vm.resume()

        timeout = float(params.get("login_timeout", 240))
        f = lambda: re.search("==END TEST==", vm.serial_console.get_output())
        if not utils_misc.wait_for(f, timeout, 1):
            raise error.TestFail("Could not get test complete message.")

        test_sig = re.compile("==START TEST==\n((?:.*\n)*)\n*==END TEST==")
        test_output = test_sig.search(vm.serial_console.get_output())
        if test_output == None:
            raise error.TestFail(
                "Test output signature not found in "
                "output:\n %s", vm.serial_console.get_output())
        self.clean()
        return test_output.group(1)

    def cpuid_regs_to_dic(level_count, cpuid_dump):
        """
            @param level_count: is CPUID level and count string in format
                                'LEVEL COUNT', where:
                                      LEVEL - CPUID level in hex format
                                            8 chracters width
                                      COUNT - input ECX value of cpuid in
                                            hex format 2 charaters width
                                example: '0x00000001 0x00'
            @cpuid_dump: string: output of 'cpuid' utility or provided with
                                 this test simple kernel that dumps cpuid
                                 in a similar format.
            @return: dictionary of register values indexed by register name
        """
        grp = '\w*=(\w*)\s*'
        regs = re.search(
            '\s+%s:.*%s%s%s%s' % (level_count, grp, grp, grp, grp), cpuid_dump)
        if regs == None:
            raise error.TestFail("Could not find %s in cpuid output:\n%s",
                                 level_count, cpuid_dump)
        return {
            'eax': int(regs.group(1), 16),
            'ebx': int(regs.group(2), 16),
            'ecx': int(regs.group(3), 16),
            'edx': int(regs.group(4), 16)
        }

    def cpuid_to_vendor(cpuid_dump, idx):
        r = cpuid_regs_to_dic(idx + ' 0x00', cpuid_dump)
        dst = []
        map(lambda i: dst.append((chr(r['ebx'] >> (8 * i) & 0xff))),
            range(0, 4))
        map(lambda i: dst.append((chr(r['edx'] >> (8 * i) & 0xff))),
            range(0, 4))
        map(lambda i: dst.append((chr(r['ecx'] >> (8 * i) & 0xff))),
            range(0, 4))
        return ''.join(dst)

    class default_vendor(MiniSubtest):
        """
        Boot qemu with specified cpu models and
        verify that CPU vendor matches requested
        """
        def test(self):
            cpu_models = cpu_models_to_test()

            vendor = params.get("vendor")
            if vendor is None or vendor == "host":
                cmd = "grep 'vendor_id' /proc/cpuinfo | head -n1 | awk '{print $3}'"
                cmd_result = utils.run(cmd, ignore_status=True)
                vendor = cmd_result.stdout.strip()

            ignore_cpus = set(params.get("ignore_cpu_models", "").split(' '))
            cpu_models = cpu_models - ignore_cpus

            for cpu_model in cpu_models:
                out = get_guest_cpuid(self, cpu_model)
                guest_vendor = cpuid_to_vendor(out, '0x00000000')
                logging.debug("Guest's vendor: " + guest_vendor)
                if guest_vendor != vendor:
                    raise error.TestFail("Guest vendor [%s], doesn't match "
                                         "required vendor [%s] for CPU [%s]" %
                                         (guest_vendor, vendor, cpu_model))

    class custom_vendor(MiniSubtest):
        """
        Boot qemu with specified vendor
        """
        def test(self):
            has_error = False
            if params.get("vendor") is None:
                raise error.TestNAError("'vendor' must be specified in config"
                                        " for this test")
            vendor = params.get("vendor")

            try:
                out = get_guest_cpuid(self, cpu_model, "vendor=" + vendor)
                guest_vendor0 = cpuid_to_vendor(out, '0x00000000')
                guest_vendor80000000 = cpuid_to_vendor(out, '0x80000000')
                logging.debug("Guest's vendor[0]: " + guest_vendor0)
                logging.debug("Guest's vendor[0x80000000]: " +
                              guest_vendor80000000)
                if guest_vendor0 != params.get("vendor"):
                    raise error.TestFail("Guest vendor[0] [%s], doesn't match "
                                         "required vendor [%s] for CPU [%s]" %
                                         (guest_vendor0, vendor, cpu_model))
                if guest_vendor80000000 != params.get("vendor"):
                    raise error.TestFail(
                        "Guest vendor[0x80000000] [%s], "
                        "doesn't match required vendor "
                        "[%s] for CPU [%s]" %
                        (guest_vendor80000000, vendor, cpu_model))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_level(cpuid_dump):
        r = cpuid_regs_to_dic('0x00000000 0x00', cpuid_dump)
        return r['eax']

    class custom_level(MiniSubtest):
        """
        Boot qemu with specified level
        """
        def test(self):
            has_error = False
            if params.get("level") is None:
                raise error.TestNAError("'level' must be specified in config"
                                        " for this test")
            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "level=" + params.get("level"))
                guest_level = str(cpuid_to_level(out))
                if guest_level != params.get("level"):
                    raise error.TestFail("Guest's level [%s], doesn't match "
                                         "required level [%s]" %
                                         (guest_level, params.get("level")))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_family(cpuid_dump):
        # Intel Processor Identification and the CPUID Instruction
        # http://www.intel.com/Assets/PDF/appnote/241618.pdf
        # 5.1.2 Feature Information (Function 01h)
        eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax']
        family = (eax >> 8) & 0xf
        if family == 0xf:
            # extract extendend family
            return family + ((eax >> 20) & 0xff)
        return family

    class custom_family(MiniSubtest):
        """
        Boot qemu with specified family
        """
        def test(self):
            has_error = False
            if params.get("family") is None:
                raise error.TestNAError("'family' must be specified in config"
                                        " for this test")
            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "family=" + params.get("family"))
                guest_family = str(cpuid_to_family(out))
                if guest_family != params.get("family"):
                    raise error.TestFail("Guest's family [%s], doesn't match "
                                         "required family [%s]" %
                                         (guest_family, params.get("family")))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_model(cpuid_dump):
        # Intel Processor Identification and the CPUID Instruction
        # http://www.intel.com/Assets/PDF/appnote/241618.pdf
        # 5.1.2 Feature Information (Function 01h)
        eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax']
        model = (eax >> 4) & 0xf
        # extended model
        model |= (eax >> 12) & 0xf0
        return model

    class custom_model(MiniSubtest):
        """
        Boot qemu with specified model
        """
        def test(self):
            has_error = False
            if params.get("model") is None:
                raise error.TestNAError("'model' must be specified in config"
                                        " for this test")
            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "model=" + params.get("model"))
                guest_model = str(cpuid_to_model(out))
                if guest_model != params.get("model"):
                    raise error.TestFail("Guest's model [%s], doesn't match "
                                         "required model [%s]" %
                                         (guest_model, params.get("model")))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_stepping(cpuid_dump):
        # Intel Processor Identification and the CPUID Instruction
        # http://www.intel.com/Assets/PDF/appnote/241618.pdf
        # 5.1.2 Feature Information (Function 01h)
        eax = cpuid_regs_to_dic('0x00000001 0x00', cpuid_dump)['eax']
        stepping = eax & 0xf
        return stepping

    class custom_stepping(MiniSubtest):
        """
        Boot qemu with specified stepping
        """
        def test(self):
            has_error = False
            if params.get("stepping") is None:
                raise error.TestNAError(
                    "'stepping' must be specified in config"
                    " for this test")
            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "stepping=" + params.get("stepping"))
                guest_stepping = str(cpuid_to_stepping(out))
                if guest_stepping != params.get("stepping"):
                    raise error.TestFail(
                        "Guest's stepping [%s], doesn't match "
                        "required stepping [%s]" %
                        (guest_stepping, params.get("stepping")))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_xlevel(cpuid_dump):
        # Intel Processor Identification and the CPUID Instruction
        # http://www.intel.com/Assets/PDF/appnote/241618.pdf
        # 5.2.1 Largest Extendend Function # (Function 80000000h)
        return cpuid_regs_to_dic('0x80000000 0x00', cpuid_dump)['eax']

    class custom_xlevel(MiniSubtest):
        """
        Boot qemu with specified xlevel
        """
        def test(self):
            has_error = False
            if params.get("xlevel") is None:
                raise error.TestNAError("'xlevel' must be specified in config"
                                        " for this test")
            xlevel = params.get("xlevel")
            if params.get("expect_xlevel") is not None:
                xlevel = params.get("expect_xlevel")

            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "xlevel=" + params.get("xlevel"))
                guest_xlevel = str(cpuid_to_xlevel(out))
                if guest_xlevel != xlevel:
                    raise error.TestFail("Guest's xlevel [%s], doesn't match "
                                         "required xlevel [%s]" %
                                         (guest_xlevel, xlevel))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_to_model_id(cpuid_dump):
        # Intel Processor Identification and the CPUID Instruction
        # http://www.intel.com/Assets/PDF/appnote/241618.pdf
        # 5.2.3 Processor Brand String (Functions 80000002h, 80000003h,
        # 80000004h)
        m_id = ""
        for idx in ('0x80000002', '0x80000003', '0x80000004'):
            regs = cpuid_regs_to_dic('%s 0x00' % idx, cpuid_dump)
            for name in ('eax', 'ebx', 'ecx', 'edx'):
                for shift in range(4):
                    c = ((regs[name] >> (shift * 8)) & 0xff)
                    if c == 0:  # drop trailing \0-s
                        break
                    m_id += chr(c)
        return m_id

    class custom_model_id(MiniSubtest):
        """
        Boot qemu with specified model_id
        """
        def test(self):
            has_error = False
            if params.get("model_id") is None:
                raise error.TestNAError(
                    "'model_id' must be specified in config"
                    " for this test")
            model_id = params.get("model_id")

            try:
                out = get_guest_cpuid(self, cpu_model,
                                      "model_id='%s'" % model_id)
                guest_model_id = cpuid_to_model_id(out)
                if guest_model_id != model_id:
                    raise error.TestFail(
                        "Guest's model_id [%s], doesn't match "
                        "required model_id [%s]" % (guest_model_id, model_id))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    def cpuid_regs_to_string(cpuid_dump, leaf, idx, regs):
        r = cpuid_regs_to_dic('%s %s' % (leaf, idx), cpuid_dump)
        signature = ""
        for i in regs:
            for shift in range(0, 4):
                c = chr((r[i] >> (shift * 8)) & 0xFF)
                if c in string.printable:
                    signature = signature + c
                else:
                    signature = "%s\\x%02x" % (signature, ord(c))
        logging.debug("(%s.%s:%s: signature: %s" %
                      (leaf, idx, str(regs), signature))
        return signature

    class cpuid_signature(MiniSubtest):
        """
        test signature in specified leaf:index:regs
        """
        def test(self):
            has_error = False
            flags = params.get("flags", "")
            leaf = params.get("leaf", "0x40000000")
            idx = params.get("index", "0x00")
            regs = params.get("regs", "ebx ecx edx").split()
            if params.get("signature") is None:
                raise error.TestNAError("'signature' must be specified in"
                                        "config for this test")
            try:
                out = get_guest_cpuid(self, cpu_model, flags)
                signature = cpuid_regs_to_string(out, leaf, idx, regs)
                if signature != params.get("signature"):
                    raise error.TestFail("Guest's signature [%s], doesn't"
                                         "match required signature [%s]" %
                                         (signature, params.get("signature")))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    class cpuid_bit_test(MiniSubtest):
        """
        test bits in specified leaf:func:reg
        """
        def test(self):
            has_error = False
            flags = params.get("flags", "")
            leaf = params.get("leaf", "0x40000000")
            idx = params.get("index", "0x00")
            reg = params.get("reg", "eax")
            if params.get("bits") is None:
                raise error.TestNAError("'bits' must be specified in"
                                        "config for this test")
            bits = params.get("bits").split()
            try:
                out = get_guest_cpuid(self, cpu_model, flags)
                r = cpuid_regs_to_dic('%s %s' % (leaf, idx), out)[reg]
                logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r))
                for i in bits:
                    if (r & (1 << int(i))) == 0:
                        raise error.TestFail("CPUID(%s.%s).%s[%s] is not set" %
                                             (leaf, idx, reg, i))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    class cpuid_reg_test(MiniSubtest):
        """
        test register value in specified leaf:index:reg
        """
        def test(self):
            has_error = False
            flags = params.get("flags", "")
            leaf = params.get("leaf")
            idx = params.get("index", "0x00")
            reg = params.get("reg", "eax")
            if params.get("value") is None:
                raise error.TestNAError("'value' must be specified in"
                                        "config for this test")
            val = int(params.get("value"))
            try:
                out = get_guest_cpuid(self, cpu_model, flags)
                r = cpuid_regs_to_dic('%s %s' % (leaf, idx), out)[reg]
                logging.debug("CPUID(%s.%s).%s=0x%08x" % (leaf, idx, reg, r))
                if r != val:
                    raise error.TestFail("CPUID(%s.%s).%s is not 0x%08x" %
                                         (leaf, idx, reg, val))
            except:
                has_error = True
                if xfail is False:
                    raise
            if (has_error is False) and (xfail is True):
                raise error.TestFail(
                    "Test was expected to fail, but it didn't")

    # subtests runner
    test_type = params.get("test_type")
    failed = []
    if test_type in locals():
        tests_group = locals()[test_type]
        try:
            tests_group()
        except:
            print_exception(tests_group)
            failed.append(test_type)
    else:
        raise error.TestError("Test group '%s' is not defined in"
                              " test" % test_type)

    if failed != []:
        raise error.TestFail("Test of cpu models %s failed." % (str(failed)))
Esempio n. 24
0
def run(test, params, env):
    """
    Test hotplug of PCI devices.

    (Elements between [] are configurable test parameters)
    1) PCI add one/multi device (NIC / block) with(or without) repeat
    2) Compare output of monitor command 'info pci'.
    3) Compare output of guest command [reference_cmd].
    4) Verify whether pci_model is shown in [pci_find_cmd].
    5) Check whether the newly added PCI device works fine.
    6) PCI delete the device, verify whether could remove the PCI device.
    7) reboot VM after guest wakeup form S3/S4 status (Optional Step).

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

    # Select an image file
    def find_image(pci_num):
        image_params = params.object_params("%s" % img_list[pci_num + 1])
        o = storage.get_image_filename(image_params, data_dir.get_data_dir())
        return o

    def pci_add_nic(pci_num):
        pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % pci_model
        return pci_add(pci_add_cmd)

    def pci_add_block(pci_num):
        image_filename = find_image(pci_num)
        pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" %
                       (image_filename, pci_model))
        return pci_add(pci_add_cmd)

    def pci_add(pci_add_cmd):
        error.context("Adding pci device with command 'pci_add'", logging.info)
        add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info.append(['', '', add_output, pci_model])

        if "OK domain" not in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        return vm.monitor.info("pci")

    def is_supported_device(dev):
        # Probe qemu to verify what is the supported syntax for PCI hotplug
        cmd_output = vm.monitor.human_monitor_cmd("?")
        if len(re.findall("\ndevice_add", cmd_output)) > 0:
            cmd_type = "device_add"
        elif len(re.findall("\npci_add", cmd_output)) > 0:
            cmd_type = "pci_add"
        else:
            raise error.TestError("Unknow version of qemu")

        # Probe qemu for a list of supported devices
        probe_output = vm.monitor.human_monitor_cmd("%s ?" % cmd_type)
        devices_supported = [
            j.strip('"') for j in re.findall('\"[a-z|0-9|\-|\_|\,|\.]*\"',
                                             probe_output, re.MULTILINE)
        ]
        logging.debug(
            "QEMU reported the following supported devices for "
            "PCI hotplug: %s", devices_supported)
        return (dev in devices_supported)

    def verify_supported_device(dev):
        if not is_supported_device(dev):
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, dev))

    def device_add_nic(pci_num, queues=1):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        pci_model = params.get("pci_model")
        if pci_model == "virtio":
            pci_model = "virtio-net-pci"
        verify_supported_device(pci_model)
        pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1],
                                                      pci_model)
        if queues > 1 and "virtio" in pci_model:
            pci_add_cmd += ",mq=on"
        return device_add(pci_num, pci_add_cmd)

    def device_add_block(pci_num, queues=1):
        device_id = pci_type + "-" + utils_misc.generate_random_id()
        pci_info.append([device_id, device_id])

        image_format = params.get("image_format_%s" % img_list[pci_num + 1])
        if not image_format:
            image_format = params.get("image_format", "qcow2")
        image_filename = find_image(pci_num)

        pci_model = params.get("pci_model")
        controller_model = None
        if pci_model == "virtio":
            pci_model = "virtio-blk-pci"

        if pci_model == "scsi" or pci_model == "scsi-hd":
            if pci_model == "scsi":
                pci_model = "scsi-disk"
                if arch.ARCH == 'ppc64':
                    controller_model = "spapr-vscsi"
                else:
                    controller_model = "lsi53c895a"
            if pci_model == "scsi-hd":
                controller_model = "virtio-scsi-pci"
            verify_supported_device(controller_model)
            controller_id = "controller-" + device_id
            if vm.monitor.protocol == "human":
                controller_add_cmd = ("device_add %s,id=%s" %
                                      (controller_model, controller_id))
            else:
                controller_add_cmd = ("device_add driver=%s,id=%s" %
                                      (controller_model, controller_id))
            error.context("Adding SCSI controller.", logging.info)
            vm.monitor.send_args_cmd(controller_add_cmd, convert=False)

        verify_supported_device(pci_model)
        if drive_cmd_type == "drive_add":
            driver_add_cmd = ("%s auto file=%s,if=none,format=%s,id=%s" %
                              (drive_cmd_type, image_filename, image_format,
                               pci_info[pci_num][0]))
        elif drive_cmd_type == "__com.redhat_drive_add":
            driver_add_cmd = ("%s file=%s,format=%s,id=%s" %
                              (drive_cmd_type, image_filename, image_format,
                               pci_info[pci_num][0]))
        # add block device to vm device container
        image_name = img_list[pci_num + 1]
        image_params = params.object_params(image_name)
        image_name = pci_info[pci_num][0]
        blk_insert = vm.devices.images_define_by_params(
            image_name, image_params, 'disk')
        vm.devices.insert(blk_insert)
        env.register_vm(vm.name, vm)

        # add driver.
        error.context("Adding driver.", logging.info)
        vm.monitor.send_args_cmd(driver_add_cmd, convert=False)

        pci_add_cmd = ("device_add id=%s,driver=%s,drive=%s" %
                       (pci_info[pci_num][1], pci_model, pci_info[pci_num][0]))
        return device_add(pci_num, pci_add_cmd)

    def device_add(pci_num, pci_add_cmd):
        error.context("Adding pci device with command 'device_add'",
                      logging.info)
        if vm.monitor.protocol == 'qmp':
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        else:
            add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False)
        pci_info[pci_num].append(add_output)
        pci_info[pci_num].append(pci_model)

        after_add = vm.monitor.info("pci")
        if pci_info[pci_num][1] not in str(after_add):
            logging.error("Could not find matched id in monitor:"
                          " %s" % pci_info[pci_num][1])
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))
        return after_add

    # Hot add a pci device
    def add_device(pci_num, queues=1):
        info_pci_ref = vm.monitor.info("pci")
        reference = session.cmd_output(reference_cmd)

        try:
            # get function for adding device.
            add_fuction = local_functions["%s_%s" % (cmd_type, pci_type)]
        except Exception:
            raise error.TestError("No function for adding '%s' dev with '%s'" %
                                  (pci_type, cmd_type))
        after_add = None
        if add_fuction:
            # Do add pci device.
            after_add = add_fuction(pci_num, queues)

        try:
            # Define a helper function to compare the output
            def _new_shown():
                o = session.cmd_output(reference_cmd)
                return o != reference

            # Define a helper function to catch PCI device string
            def _find_pci():
                output = session.cmd_output(params.get("find_pci_cmd"))
                output = map(string.strip, output.splitlines())
                ref = map(string.strip, reference.splitlines())
                output = [_ for _ in output if _ not in ref]
                output = "\n".join(output)
                if re.search(params.get("match_string"), output, re.I | re.M):
                    return True
                return False

            error.context("Start checking new added device", logging.info)
            # Compare the output of 'info pci'
            if after_add == info_pci_ref:
                raise error.TestFail("No new PCI device shown after executing "
                                     "monitor command: 'info pci'")

            secs = int(params.get("wait_secs_for_hook_up"))
            if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3):
                raise error.TestFail(
                    "No new device shown in output of command "
                    "executed inside the guest: %s" % reference_cmd)

            if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3):
                raise error.TestFail(
                    "PCI %s %s device not found in guest. "
                    "Command was: %s" %
                    (pci_model, pci_type, params.get("find_pci_cmd")))

            # Test the newly added device
            try:
                if params.get("pci_test_cmd"):
                    test_cmd = re.sub("PCI_NUM", "%s" % (pci_num + 1),
                                      params.get("pci_test_cmd"))
                    session.cmd(test_cmd)
            except aexpect.ShellError, e:
                raise error.TestFail("Check for %s device failed after PCI "
                                     "hotplug. Output: %r" %
                                     (pci_type, e.output))

        except Exception:
            pci_del(pci_num, ignore_failure=True)
            raise

    # Hot delete a pci device
    def pci_del(pci_num, ignore_failure=False):
        def _device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != before_del

        before_del = vm.monitor.info("pci")
        if cmd_type == "pci_add":
            slot_id = int(pci_info[pci_num][2].split(",")[2].split()[1])
            cmd = "pci_del pci_addr=%s" % hex(slot_id)
            vm.monitor.send_args_cmd(cmd, convert=False)
        elif cmd_type == "device_add":
            if vm.monitor.protocol == "human":
                cmd = "device_del %s" % pci_info[pci_num][1]
            else:
                cmd = "device_del id=%s" % pci_info[pci_num][1]
            vm.monitor.send_args_cmd(cmd, convert=False)
            pci_model = params.get("pci_model")
            if pci_model == "scsi" or pci_model == "scsi-hd":
                controller_id = "controller-" + pci_info[pci_num][0]
                if vm.monitor.protocol == "human":
                    controller_del_cmd = "device_del %s" % controller_id
                else:
                    controller_del_cmd = "device_del id=%s" % controller_id
                error.context("Deleting SCSI controller.", logging.info)
                vm.monitor.send_args_cmd(controller_del_cmd, convert=False)

        if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1)
                and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (pci_info[pci_num][3], cmd))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    test_timeout = int(params.get("hotplug_timeout", 360))
    reference_cmd = params["reference_cmd"]
    # Test if it is nic or block
    pci_type = params["pci_type"]
    pci_model = params["pci_model"]

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        session.cmd("modprobe %s" % module)

    # check monitor type
    qemu_binary = utils_misc.get_qemu_binary(params)
    qemu_binary = utils_misc.get_path(test.bindir, qemu_binary)
    # Probe qemu to verify what is the supported syntax for PCI hotplug
    if vm.monitor.protocol == 'qmp':
        cmd_output = vm.monitor.info("commands")
    else:
        cmd_output = vm.monitor.human_monitor_cmd("help", debug=False)

    cmd_type = utils_misc.find_substring(str(cmd_output), "device_add",
                                         "pci_add")
    if not cmd_output:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " device in this version of qemu")

    # Determine syntax of drive hotplug
    # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6
    # drive_add == qemu-kvm-0.13 onwards
    drive_cmd_type = utils_misc.find_substring(str(cmd_output),
                                               "__com.redhat_drive_add",
                                               "drive_add")
    if not drive_cmd_type:
        raise error.TestError("Could find a suitable method for hotplugging"
                              " drive in this version of qemu")

    local_functions = locals()

    pci_num_range = int(params.get("pci_num"))
    queues = int(params.get("queues", 1))
    rp_times = int(params.get("repeat_times"))
    img_list = params.get("images").split()
    context_msg = "Running sub test '%s' %s"
    for j in range(rp_times):
        # pci_info is a list of list.
        # each element 'i' has 4 members:
        # pci_info[i][0] == device drive id, only used for device_add
        # pci_info[i][1] == device id, only used for device_add
        # pci_info[i][2] == output of device add command
        # pci_info[i][3] == device module name.
        pci_info = []
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("Start hot-adding pci device, repeat %d" % j,
                          logging.info)
            add_device(pci_num, queues)

            sub_type = params.get("sub_type_after_plug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)
        for pci_num in xrange(pci_num_range):
            sub_type = params.get("sub_type_before_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "before hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

            error.context("start hot-deleting pci device, repeat %d" % j,
                          logging.info)
            pci_del(-(pci_num + 1))

            sub_type = params.get("sub_type_after_unplug")
            if sub_type:
                error.context(context_msg % (sub_type, "after hotunplug"),
                              logging.info)
                utils_test.run_virt_sub_test(test, params, env, sub_type)

    if params.get("reboot_vm", "no") == "yes":
        vm.reboot()
Esempio n. 25
0
def run(test, params, env):
    """
    Timer device check TSC synchronity for long time test:

    1) Check for an appropriate clocksource on host.
    2) Check host has more than one cpu socket.
    3) Boot the guest with specified cpu socket.
    4) Copy time-warp-test.c to guest.
    5) Compile the time-warp-test.c.
    6) Run time-warp-test for minimum 4 hours.

    :param test: QEMU test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    error.context("Check for an appropriate clocksource on host", logging.info)
    host_cmd = "cat /sys/devices/system/clocksource/"
    host_cmd += "clocksource0/current_clocksource"
    if "tsc" not in utils.system_output(host_cmd):
        raise error.TestNAError("Host must use 'tsc' clocksource")

    error.context("Check host has more than one cpu socket", logging.info)
    host_socket_cnt_cmd = params["host_socket_cnt_cmd"]
    if utils.system_output(host_socket_cnt_cmd).strip() == "1":
        raise error.TestNAError("Host must have more than 1 socket")

    error.context("Boot the guest with one cpu socket", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    error.context("Copy time-warp-test.c to guest", logging.info)
    src_file_name = os.path.join(data_dir.get_root_dir(), "shared", "deps",
                                 "time-warp-test.c")
    vm.copy_files_to(src_file_name, "/tmp")

    error.context("Compile the time-warp-test.c", logging.info)
    cmd = "cd /tmp/;"
    cmd += " yum install -y popt-devel;"
    cmd += " rm -f time-warp-test;"
    cmd += " gcc -Wall -o time-warp-test time-warp-test.c -lrt"
    session.cmd(cmd)

    error.context("Run time-warp-test for minimum 4 hours", logging.info)
    test_run_timeout = int(params.get("test_run_timeout", 14400))
    session.sendline("$(sleep %d; pkill time-warp-test) &" % test_run_timeout)
    cmd = "/tmp/time-warp-test"
    _, output = session.cmd_status_output(cmd, timeout=(test_run_timeout + 60))

    re_str = "fail:(\d+).*?fail:(\d+).*fail:(\d+)"
    fail_cnt = re.findall(re_str, output)
    if not fail_cnt:
        raise error.TestError("Could not get correct test output."
                              " Output: '%s'" % output)

    tsc_cnt, tod_cnt, clk_cnt = [int(_) for _ in fail_cnt[-1]]
    if tsc_cnt or tod_cnt or clk_cnt:
        msg = output.splitlines()[-5:]
        raise error.TestFail("Get error when running time-warp-test."
                             " Output (last 5 lines): '%s'" % msg)
Esempio n. 26
0
def run(test, params, env):
    """
    Test hdparm setting on linux guest os. This case will:
    1) Set/record parameters value of hard disk to low performance status.
    2) Perform device/cache read timings then record the results.
    3) Set/record parameters value of hard disk to high performance status.
    4) Perform device/cache read timings then compare two results.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def check_setting_result(set_cmd, timeout):
        params = re.findall("(-[a-zA-Z])([0-9]*)", set_cmd)
        disk = re.findall("(\/+[a-z]*\/[a-z]*$)", set_cmd)[0]
        unsupport_param = 0
        for (param, value) in params:
            check_value = True
            cmd = "hdparm %s %s" % (param, disk)
            (s, output) = session.cmd_status_output(cmd, timeout)
            failed_count = len(re.findall("failed:", output))
            ignore_count = len(re.findall(ignore_string, output))
            if failed_count > ignore_count:
                raise error.TestError("Fail to get %s parameter value. "
                                      "Output is:\n%s" %
                                      (param, output.strip()))
            else:
                check_value = False
                unsupport_param += 1
                logging.warn("Disk %s not support parameter %s" %
                             (disk, param))
            if check_value and value not in output:
                raise error.TestFail("Fail to set %s parameter to value: %s" %
                                     (param, value))
        if len(params) == unsupport_param:
            raise error.TestNAError("All parameters are not supported."
                                    " Skip the test")

    def perform_read_timing(disk, timeout, num=5):
        results = 0
        for i in range(num):
            cmd = params["device_cache_read_cmd"] % disk
            (s, output) = session.cmd_status_output(cmd, timeout)
            if s != 0:
                raise error.TestFail("Fail to perform device/cache read"
                                     " timings \nOutput is: %s\n" % output)
            logging.info(
                "Output of device/cache read timing check (%s of %s):" %
                (i + 1, num))
            for line in output.strip().splitlines():
                logging.info(line)
            (result, unit) = re.findall("= *([0-9]*.+[0-9]*) ([a-zA-Z]*)",
                                        output)[1]
            if unit == "kB":
                result = float(result) / 1024.0
            results += float(result)
        return results / num

    ignore_string = params.get("ignore_string")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    try:
        timeout = float(params.get("cmd_timeout", 60))
        cmd = params["get_disk_cmd"]
        output = session.cmd(cmd)
        disk = output.strip()

        error.context("Setting hard disk to lower performance")
        cmd = params["low_status_cmd"] % disk
        try:
            session.cmd(cmd, timeout)
        except aexpect.ShellCmdError, err:
            failed_count = len(re.findall("failed:", err.output))
            ignore_count = len(re.findall(ignore_string, err.output))
            if failed_count > ignore_count:
                raise error.TestError(
                    "Fail to setting hard disk to lower "
                    "performance. Output is:%s", err.output)

        error.context("Checking hard disk keyval under lower performance "
                      "settings")
        check_setting_result(cmd, timeout)
        low_result = perform_read_timing(disk, timeout)
        logging.info("Average buffered disk read speed under low performance "
                     "settings: %.2f MB/sec" % low_result)

        error.context("Setting hard disk to higher performance")
        cmd = params["high_status_cmd"] % disk
        try:
            session.cmd(cmd, timeout)
        except aexpect.ShellCmdError, err:
            failed_count = len(re.findall("failed:", err.output))
            ignore_count = len(re.findall(ignore_string, err.output))
            if failed_count > ignore_count:
                raise error.TestError(
                    "Fail to setting hard disk to higher "
                    "performance. Output is:%s", err.output)
Esempio n. 27
0
def run(test, params, env):
    """
    This test virsh domtime command and its options.

    1) Start a guest with/without guest agent configured;
    2) Record guest times;
    3) Do some operation to stop VM;
    4) Run virsh domtime command with different options;
    5) Check the command result;
    6) Check the guest times against expectation;
    7) Cleanup test environment.
    """
    epoch = datetime.datetime(1970, 1, 1, 0, 0, 0)
    # Max time can be set with domtime successfully in newer qemu-ga
    time_max_1 = 3155731199
    # Max time can be set with domtime successfully in older qemu-ga
    time_max_2 = 3155759999
    # Max time can be set with domtime bug failed to set RTC in older qemu-ga
    time_max_3 = 9223372035

    def init_time(session):
        """
        Initialize guest RTC time to epoch + 1234567890 and system time
        one day latter.

        :param session: Session from which to access guest
        """
        res = virsh.domtime(vm_name, time=1234567890)
        if res.exit_status:
            logging.debug("Failed to init time to 1234567890:\n%s", res)
        status, output = session.cmd_status_output('date -s "1 day"')
        if status:
            raise error.TestError("Failed to set guest time:\n%s" % output)

    def get_host_utc_time():
        """
        Get host UTC time from date command.
        """
        res = utils.run("date -u")
        # Strip timezone info from output
        # e.g. 'Sun Feb 15 07:31:40 CST 2009' -> 'Sun Feb 15 07:31:40 2009'
        time_str = re.sub(r'\S+ (?=\S+$)', '', res.stdout.strip())
        return datetime.datetime.strptime(time_str, r"%a %b %d %H:%M:%S %Y")

    def run_cmd(session, cmd):
        """
        Run a command in a session and record duration of call.
        """
        start = time.time()
        output = session.cmd_output(cmd)
        duration = time.time() - start
        logging.info('Result of command "%s". Duration: %s. Output:%s', cmd,
                     duration, output.strip())
        return output, duration

    def get_guest_times(session):
        """
        Retrieve different guest time as a dict for checking.
        Keys:
            local_hw: Guest RTC time in local timezone
            local_sys: Guest system time in local timezone
            utc_sys: Guest system time in UTC
            domtime: Guest system time in UTC got from virsh domtime command

        :param session: Session from which to access guest
        """
        times = {}
        get_begin = time.time()
        # Guest RTC local timezone time
        output, _ = run_cmd(session, 'hwclock')
        time_str, _ = re.search(r"(.+)  (\S+ seconds)", output).groups()

        try:
            # output format 1: Tue 01 Mar 2016 01:53:46 PM CST
            # Remove timezone info from output
            new_str = re.sub(r'\S+$', '', time_str)
            times['local_hw'] = datetime.datetime.strptime(
                new_str, r"%a %d %b %Y %I:%M:%S %p")
        except ValueError:
            # There are two possible output format for `hwclock`
            # output format 2: Sat Feb 14 07:31:33 2009
            times['local_hw'] = datetime.datetime.strptime(
                time_str, r"%a %b %d %H:%M:%S %Y")
        delta = time.time() - get_begin
        times['local_hw'] -= datetime.timedelta(seconds=delta)

        # Guest system local timezone time
        output, _ = run_cmd(session, 'date')
        # Strip timezone info from output
        # e.g. 'Sun Feb 15 07:31:40 CST 2009' -> 'Sun Feb 15 07:31:40 2009'
        time_str = re.sub(r'\S+ (?=\S+$)', '', output.strip())
        times['local_sys'] = datetime.datetime.strptime(
            time_str, r"%a %b %d %H:%M:%S %Y")
        delta = time.time() - get_begin
        times['local_sys'] -= datetime.timedelta(seconds=delta)

        # Guest system UTC timezone time
        output, _ = run_cmd(session, 'date -u')
        # Strip timezone info from output
        # e.g. 'Sun Feb 15 07:31:40 CST 2009' -> 'Sun Feb 15 07:31:40 2009'
        time_str = re.sub(r'\S+ (?=\S+$)', '', output.strip())
        times['utc_sys'] = datetime.datetime.strptime(time_str,
                                                      r"%a %b %d %H:%M:%S %Y")
        delta = time.time() - get_begin
        times['utc_sys'] -= datetime.timedelta(seconds=delta)

        # Guest UTC time from virsh domtime
        res = virsh.domtime(vm_name, pretty=True, ignore_status=True)
        if not res.exit_status:
            logging.info('Result of "domtime". Duration: %s. Output:%s',
                         res.duration, res.stdout.strip())
            _, time_str = res.stdout.split(" ", 1)
            times['domtime'] = datetime.datetime.strptime(
                time_str.strip(), r"%Y-%m-%d %H:%M:%S")
            delta = time.time() - get_begin
            times['domtime'] -= datetime.timedelta(seconds=delta)
        else:
            logging.debug("Unable to get domain time:\n%s", res)
            times['domtime'] = None

        return times, time.time() - get_begin

    def check_get_success(expected_times):
        """
        Check virsh command get result against expected times

        :param expected_times: Expected time for checking
        """
        _, time_str = res.stdout.split(" ", 1)
        if pretty:
            # Time: 2015-01-13 06:29:18
            domtime = datetime.datetime.strptime(time_str.strip(),
                                                 r"%Y-%m-%d %H:%M:%S")
        else:
            # Time: 1421130740
            domtime = epoch + datetime.timedelta(seconds=int(time_str))
        time_shift = time.time() - start
        logging.debug("Time shift is %s", time_shift)
        result_diff = (domtime - expected_times['domtime']).total_seconds()
        if abs(result_diff) > 2.0:
            raise error.TestFail("Expect get time %s, but got %s, time "
                                 "diff: %s" %
                                 (org_times['domtime'], domtime, result_diff))

    def check_guest_times(expected_times, cur_times):
        """
        Check guest times after test against expected times

        :param expected_times: Expected time for checking
        """
        time_shift = time.time() - start
        logging.debug("Time shift is %s", time_shift)

        error_msgs = []
        for key in cur_times:
            if cur_times[key] is not None:
                cur = cur_times[key]
                expect = expected_times[key]

                diff = (cur - expect).total_seconds()
                msg = "For %s, expect get time %s, got %s, time diff: %s" % (
                    key, expect, cur, diff)
                logging.debug(msg)
                if abs(diff) > 2.0:
                    error_msgs.append(msg)
        if error_msgs:
            raise error.TestFail('\n'.join(error_msgs))

    def check_time(result, org_times, cur_times):
        """
        Check whether domain time has been change accordingly.

        :param result: virsh domtime CmdResult instance
        :param org_times: Original guest times
        """
        action = "get"
        if now or sync or (set_time is not None):
            action = "set"

        tz_diff = org_times['local_sys'] - org_times['utc_sys']
        logging.debug("Timezone diff on guest is %d hours.",
                      (tz_diff.total_seconds() / 3600))

        # Hardware time will never stop
        logging.info('Add %ss to expected guest time', interval)
        if action == 'get':
            expected_times = org_times
        elif action == 'set':
            if result.exit_status:
                # Time not change if domtime fails
                expected_times = org_times
            else:
                # Time change accordingly if succeed.
                if now:
                    utc_time = org_host_time
                    local_time = utc_time + tz_diff
                elif sync:
                    local_time = org_times["local_hw"]
                    utc_time = local_time - tz_diff
                elif set_time is not None:
                    utc_time = epoch + datetime.timedelta(
                        seconds=(int(set_time) - guest_duration))
                    local_time = utc_time + tz_diff
                expected_times = {}
                expected_times['local_hw'] = local_time
                expected_times['local_sys'] = local_time
                expected_times["utc_sys"] = utc_time
                expected_times["domtime"] = utc_time

        # Add interval between two checks of guest time
        for key in expected_times:
            if expected_times[key] is not None:
                expected_times[key] += interval

        # Hardware time will never stop
        # Software time will stop if suspended or managed-saved
        if suspend or managedsave:
            logging.info('Remove %ss from expected guest software time',
                         stop_time)
            expected_times["domtime"] -= stop_time
            expected_times["local_sys"] -= stop_time
            expected_times["utc_sys"] -= stop_time

        # Check guest time if domtime succeeded
        check_guest_times(expected_times, cur_times)

        # Check if output of domtime is correct
        if action == 'get' and not result.exit_status:
            check_get_success(expected_times)

    def prepare_fail_patts():
        """
        Predict fail pattern from test parameters.
        """
        fail_patts = []
        if not channel:
            fail_patts.append(r"QEMU guest agent is not configured")
        if not agent:
            # For older version
            fail_patts.append(r"Guest agent not available for now")
            # For newer version
            fail_patts.append(r"Guest agent is not responding")
        if int(now) + int(sync) + int(bool(set_time)) > 1:
            fail_patts.append(r"Options \S+ and \S+ are mutually exclusive")
        if shutdown:
            fail_patts.append(r"domain is not running")

        if set_time is not None:
            if int(set_time) < 0:
                fail_patts.append(r"Invalid argument")
            elif time_max_1 < int(set_time) <= time_max_2:
                fail_patts.append(r"Invalid time")
            elif time_max_2 < int(set_time) <= time_max_3:
                fail_patts.append(r"Invalid time")
            elif time_max_3 < int(set_time):
                fail_patts.append(r"too big for guest agent")
        return fail_patts

    def stop_vm():
        """
        Suspend, managedsave, pmsuspend or shutdown a VM for a period of time
        """
        stop_start = time.time()
        if suspend:
            vm.pause()
            time.sleep(10)
            vm.resume()
        elif managedsave:
            vm.managedsave()
            time.sleep(10)
            vm.start()
            vm.wait_for_login()
        elif pmsuspend:
            vm.pmsuspend()
            time.sleep(10)
            vm.pmwakeup()
            vm.wait_for_login()
        elif shutdown:
            vm.destroy()

        # Check real guest stop time
        stop_seconds = time.time() - stop_start
        stop_time = datetime.timedelta(seconds=stop_seconds)
        logging.debug("Guest stopped: %s", stop_time)
        return stop_time

    # Check availability of virsh command domtime
    if not virsh.has_help_command('domtime'):
        raise error.TestNAError("This version of libvirt does not support "
                                "the domtime test")

    channel = (params.get("prepare_channel", "yes") == 'yes')
    agent = (params.get("start_agent", "yes") == 'yes')
    pretty = (params.get("domtime_pretty", "no") == 'yes')
    now = (params.get("domtime_now", "no") == 'yes')
    sync = (params.get("domtime_sync", "no") == 'yes')
    set_time = params.get("domtime_time", None)

    shutdown = (params.get("shutdown_vm", "no") == 'yes')
    suspend = (params.get("suspend_vm", "no") == 'yes')
    managedsave = (params.get("managedsave_vm", "no") == 'yes')
    pmsuspend = (params.get("pmsuspend_vm", "no") == 'yes')

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)

    # Backup domain XML
    xml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    try:
        if pmsuspend:
            vm_xml.VMXML.set_pm_suspend(vm_name)
        # Add or remove qemu-agent from guest before test
        vm.prepare_guest_agent(channel=channel, start=agent)
        session = vm.wait_for_login()
        try:
            if channel and agent:
                init_time(session)

            # Expected fail message patterns
            fail_patts = prepare_fail_patts()

            # Message patterns test should skip when met
            skip_patts = [
                r'The command \S+ has not been found',
            ]

            # Record start time
            start = time.time()

            # Record host time before testing
            org_host_time = get_host_utc_time()
            # Get original guest times
            org_times, guest_duration = get_guest_times(session)

            # Run some operations to stop guest system
            stop_time = stop_vm()

            # Run command with specified options.
            res = virsh.domtime(vm_name,
                                now=now,
                                pretty=pretty,
                                sync=sync,
                                time=set_time)
            libvirt.check_result(res, fail_patts, skip_patts)

            # Check interval between two check of guest time
            interval = datetime.timedelta(seconds=(time.time() - start))
            logging.debug("Interval between guest checking: %s", interval)

            if not shutdown:
                # Get current guest times
                cur_times, _ = get_guest_times(session)

                check_time(res, org_times, cur_times)
        finally:
            # Sync guest time with host
            if channel and agent and not shutdown:
                res = virsh.domtime(vm_name, now=True)
                if res.exit_status:
                    session.close()
                    raise error.TestError("Failed to recover guest time:\n%s" %
                                          res)
            session.close()
    finally:
        # Restore VM XML
        xml_backup.sync()
Esempio n. 28
0
def run(test, params, env):
    """
    Qemu guest irqbalance inactive/active test:
    1) Setup host for sr-iov test.
    2) Boot VM with sr-iov vf/pf assigned and multi vcpu.
    3) Update irqbalance service status in guest. stop/start this server
       according to request.
    4) Get available network interface name in guest.
    5) Start background network stress in guest.
    6) Get irq number assigned to attached vfs/pfs.
    7) Get the cpu number the irq running.
    8) Check specified IRQ count grow on specified cpu.
    9) Repeat step 7 for every 10s.
    10) Balance IRQs generated by vfs/pfs to different vcpus (optional)
       e.g.
       echo 4 > /proc/irq/num/smp_affinity
    11) Repeat step 6, 7
    12) Check that specified IRQ count grow on every cpu. (optional)

    :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 = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)
    irqbalance_check_count = int(params.get("irqbalance_check_count", 36))
    nic_interface_filter = params["nic_interface_filter"]

    error.context("Make sure that guest have at least 2 vCPUs.", logging.info)
    cpu_count = vm.get_cpu_count()
    if cpu_count < 2:
        raise error.TestNAError("Test requires at least 2 vCPUs.")

    msg = "Update irqbalance service status in guest if not match request."
    error.context(msg, logging.info)
    irqbalance_status = params.get("irqbalance_status", "active")
    status = get_guest_service_status(session=session, service="irqbalance")
    service_cmd = ""
    if status == "active" and irqbalance_status == "inactive":
        service_cmd = "service irqbalance stop"
    elif status == "inactive" and irqbalance_status == "active":
        service_cmd = "service irqbalance start"
    if service_cmd:
        status, output = session.cmd_status_output(service_cmd)
        if status:
            msg = "Fail to update irqbalance service status in guest."
            msg += " Command output in guest: %s" % output
            raise error.TestError(msg)

    error.context("Get first network interface name in guest.", logging.info)
    devname = get_first_network_devname(session, nic_interface_filter)

    error.context("Start background network stress in guest.", logging.info)
    host_ip = utils_net.get_ip_address_by_interface(params.get('netdst'))
    ping_cmd = "ping %s  -f -q" % host_ip
    ping_timeout = irqbalance_check_count * 10 + 100
    ping_session = vm.wait_for_login(timeout=timeout)
    bg_stress = utils.InterruptedThread(utils_test.raw_ping,
                                        kwargs={
                                            'command': ping_cmd,
                                            'timeout': ping_timeout,
                                            'session': ping_session,
                                            'output_func': None
                                        })
    bg_stress.start()
    try:
        error.context("Get irq number assigned to attached VF/PF in guest",
                      logging.info)
        irq_nums_dict = get_guest_irq_info(session, devname, cpu_count)
        if irq_nums_dict:
            irqs = irq_nums_dict.keys()

        msg = "Check specified IRQ count grow on specified cpu."
        error.context(msg, logging.info)
        check_irqbalance(session, devname, cpu_count, irqs)
        irq_cpus_dict = {}
        for irq in irqs:
            cpus = get_irq_smp_affinity(session, irq)
            irq_cpus_dict[irq] = cpus

        if irqbalance_status == "inactive":
            msg = "balance IRQs generated by vfs/pfs to different vcpus."
            error.context(msg, logging.info)
            post_irq_cpus_dict = {}
            for irq in irq_cpus_dict:
                balance_cpu_count = 1
                cpus = []
                for cpu in xrange(cpu_count):
                    if cpu not in irq_cpus_dict[irq]:
                        cpus.append(cpu)
                        if len(cpus) == balance_cpu_count:
                            break
                set_irq_smp_affinity(session, irq, cpus)
                post_irq_cpus_dict[irq] = cpus

            for irq in irqs:
                cpus = get_irq_smp_affinity(session, irq)
                msg = "Fail to balance IRQs generated by vf/pf to different cpu"
                if cpus != post_irq_cpus_dict[irq]:
                    raise error.TestFail(msg)

        msg = "Check specified IRQ count grow on specified cpu."
        error.context(msg, logging.info)
        check_irqbalance(session,
                         devname,
                         cpu_count,
                         irqs,
                         count=irqbalance_check_count)

        if irqbalance_status == "active":
            msg = "Check that specified IRQ count grow on every cpu."
            error.context(msg, logging.info)
            post_irq_nums_dict = get_guest_irq_info(session, devname,
                                                    cpu_count)

            for irq in irqs:
                if irq not in post_irq_nums_dict.keys():
                    post_irqs = post_irq_nums_dict.keys()
                    msg = "Different irq detected: '%s' and '%s'." % (
                        irqs, post_irqs)
                    raise error.TestError(msg)
                for cpu in xrange(cpu_count):
                    if (int(irq_nums_dict[irq][cpu]) >= int(
                            post_irq_nums_dict[irq][cpu])):
                        msg = "'Cpu%s' did not handle more interrupt" % cpu
                        msg += "for irq '%s'." % irq
                        msg += "IRQ balance information for IRQ '%s'\n" % irq
                        msg += "First time: %s\n" % irq_nums_dict
                        msg += "Just now: %s" % post_irq_nums_dict
                        raise error.TestFail(msg)
    finally:
        if bg_stress.isAlive():
            bg_stress.join(suppress_exception=True)
        else:
            logging.warn("Background stress test already finished")
Esempio n. 29
0
 def postprocess(self):
     if self.nfail != 0:
         logging.info('\n nfails is non-zero')
         raise error.TestError('\nTest failed')
     else:
         logging.info('\n Test completed successfully ')
Esempio n. 30
0
    # Direct migration is supported only for Xen in libvirt
    if options.count("direct") or extra.count("direct"):
        if params.get("driver_type") is not "xen":
            raise error.TestNAError("Direct migration is supported only for "
                                    "Xen in libvirt.")

    # Add migrateuri if exists and check for default example
    if migrate_uri:
        if migrate_uri.count("EXAMPLE"):
            raise error.TestNAError("Set up the migrate_uri.")
        extra = ("%s --migrateuri=%s" % (extra, migrate_uri))

    # To migrate you need to have a shared disk between hosts
    if shared_storage is None:
        raise error.TestError("For migration you need to have a shared "
                              "storage.")

    exception = False
    try:
        # Change the disk of the vm to shared disk
        if vm.is_alive():
            vm.destroy(gracefully=False)

        devices = vm.get_blk_devices()
        for device in devices:
            s_detach = virsh.detach_disk(vm_name,
                                         device,
                                         "--config",
                                         debug=True)
            if not s_detach:
                logging.error("Detach vda failed before test.")