예제 #1
0
def run(test, params, env):
    """
    Test blkdevio tuning

    Positive test has covered the following combination.
    -------------------------
    | total | read  | write |
    -------------------------
    |   0   |   0   |   0   |
    | non-0 |   0   |   0   |
    |   0   | non-0 | non-0 |
    |   0   | non-0 |  0    |
    |   0   |   0   | non-0 |
    -------------------------

    Negative test has covered unsupported combination and
    invalid command arguments.

    NB: only qemu-kvm-rhev supports block I/O throttling on >= RHEL6.5,
    the qemu-kvm is okay for block I/O throttling on >= RHEL7.0.
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    start_vm = params.get("start_vm", "yes")
    change_parameters = params.get("change_parameters", "no")
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Used for default device of blkdeviotune
    device = params.get("blkdevio_device", "vmblk")
    sys_image_target = vm.get_first_disk_devices()["target"]

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm and vm.is_alive():
        vm.destroy()

    # Recover previous running guest
    if vm and not vm.is_alive() and start_vm == "yes":
        vm.start()

    test_dict = dict(params)
    test_dict['vm'] = vm
    if device == "vmblk":
        test_dict['blkdevio_device'] = sys_image_target

    # Make sure libvirtd service is running
    if not utils_libvirtd.libvirtd_is_running():
        raise error.TestNAError("libvirt service is not running!")

    ########## positive and negative testing #########

    try:
        if change_parameters == "no":
            get_blkdevio_parameter(test_dict)
        else:
            set_blkdevio_parameter(test_dict)
    finally:
        # Restore guest
        original_vm_xml.sync()
예제 #2
0
def run(test, params, env):
    """
    Test blkdevio tuning

    Positive test has covered the following combination.
    -------------------------
    | total | read  | write |
    -------------------------
    |   0   |   0   |   0   |
    | non-0 |   0   |   0   |
    |   0   | non-0 | non-0 |
    |   0   | non-0 |  0    |
    |   0   |   0   | non-0 |
    -------------------------

    Negative test has covered unsupported combination and
    invalid command arguments.

    NB: only qemu-kvm-rhev supports block I/O throttling on >= RHEL6.5,
    the qemu-kvm is okay for block I/O throttling on >= RHEL7.0.
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    start_vm = params.get("start_vm", "yes")
    change_parameters = params.get("change_parameters", "no")
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Used for default device of blkdeviotune
    device = params.get("blkdevio_device", "vmblk")
    sys_image_target = vm.get_first_disk_devices()["target"]

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm and vm.is_alive():
        vm.destroy()

    # Recover previous running guest
    if vm and not vm.is_alive() and start_vm == "yes":
        vm.start()

    test_dict = dict(params)
    test_dict['vm'] = vm
    if device == "vmblk":
        test_dict['blkdevio_device'] = sys_image_target

    # Make sure libvirtd service is running
    if not utils_libvirtd.libvirtd_is_running():
        raise error.TestNAError("libvirt service is not running!")

    # Positive and negative testing
    try:
        if change_parameters == "no":
            get_blkdevio_parameter(test_dict)
        else:
            set_blkdevio_parameter(test_dict)
    finally:
        # Restore guest
        original_vm_xml.sync()
예제 #3
0
def check_libvirtd_process_id(ori_pid_libvirtd, test):
    """
    Check libvirtd process id not change

    :param params: original libvirtd process id
    :param test: test assert object
    """
    if not utils_split_daemons.is_modular_daemon():
        aft_pid_libvirtd = process.getoutput("pidof libvirtd")
        if not utils_libvirtd.libvirtd_is_running() or ori_pid_libvirtd != aft_pid_libvirtd:
            test.fail("Libvirtd crash after attaching ccw addr devices")
예제 #4
0
            options1 = "--wait --raw --finish --verbose"
            cmd_result = virsh.blockcopy(vm_name, target, dest_path, options1,
                                         ignore_status=True, debug=True)
            status = cmd_result.exit_status
            if status != 0:
                raise error.TestFail("Run blockcopy command fail.")
            elif not os.path.exists(dest_path):
                raise error.TestFail("Cannot find the created copy.")

        cmd_result = virsh.blockcopy(vm_name, target, dest_path, options,
                                     ignore_status=True, debug=True)
        status = cmd_result.exit_status
    except Exception, detail:
        logging.error(detail)

    if not utils_libvirtd.libvirtd_is_running():
        raise error.TestFail("Libvirtd service is dead.")
    # Check_result
    try:
        try:
            if not status_error:
                if status == 0:
                    check_xml(vm_name, target, dest_path, options)
                    if options.count("--bandwidth"):
                        utl.check_blockjob(vm_name, target, "bandwidth", bandwidth)
                    if options.count("--pivot") + options.count("--finish") == 0:
                        finish_job(vm_name, target, default_timeout)
                    if options.count("--raw"):
                        check_format(dest_path, "raw")
                else:
                    raise error.TestFail(cmd_result.stderr)
예제 #5
0
def run(test, params, env):
    """
    Test command: virsh dump.

    This command can dump the core of a domain to a file for analysis.
    1. Positive testing
        1.1 Dump domain with valid options.
        1.2 Avoid file system cache when dumping.
        1.3 Compress the dump images to valid/invalid formats.
    2. Negative testing
        2.1 Dump domain to a non-exist directory.
        2.2 Dump domain with invalid option.
        2.3 Dump a shut-off domain.
    """

    vm_name = params.get("main_vm", "vm1")
    vm = env.get_vm(vm_name)
    options = params.get("dump_options")
    dump_file = params.get("dump_file", "vm.core")
    if os.path.dirname(dump_file) is "":
        dump_file = os.path.join(test.tmpdir, dump_file)
    dump_image_format = params.get("dump_image_format")
    start_vm = params.get("start_vm") == "yes"
    paused_after_start_vm = params.get("paused_after_start_vm") == "yes"
    status_error = params.get("status_error", "no") == "yes"
    timeout = int(params.get("timeout", "5"))
    qemu_conf = "/etc/libvirt/qemu.conf"

    def check_domstate(actual, options):
        """
        Check the domain status according to dump options.
        """

        if options.find('live') >= 0:
            domstate = "running"
            if options.find('crash') >= 0 or options.find('reset') > 0:
                domstate = "running"
            if paused_after_start_vm:
                domstate = "paused"
        elif options.find('crash') >= 0:
            domstate = "shut off"
            if options.find('reset') >= 0:
                domstate = "running"
        elif options.find('reset') >= 0:
            domstate = "running"
            if paused_after_start_vm:
                domstate = "paused"
        else:
            domstate = "running"
            if paused_after_start_vm:
                domstate = "paused"

        if not start_vm:
            domstate = "shut off"

        logging.debug("Domain should %s after run dump %s", domstate, options)

        return (domstate == actual)

    def check_dump_format(dump_image_format, dump_file):
        """
        Check the format of dumped file.

        If 'dump_image_format' is not specified or invalid in qemu.conf, then
        the file shoule be normal raw file, otherwise it shoud be compress to
        specified format, the supported compress format including: lzop, gzip,
        bzip2, and xz.
        """

        valid_format = ["lzop", "gzip", "bzip2", "xz"]
        if len(dump_image_format) == 0 or dump_image_format not in valid_format:
            logging.debug("No need check the dumped file format")
            return True
        else:
            file_cmd = "file %s" % dump_file
            (status, output) = commands.getstatusoutput(file_cmd)
            if status:
                logging.error("Fail to check dumped file %s", dump_file)
                return False
            logging.debug("Run file %s output: %s", dump_file, output)
            actual_format = output.split(" ")[1]
            if actual_format.lower() != dump_image_format.lower():
                logging.error("Compress dumped file to %s fail: %s" %
                              (dump_image_format, actual_format))
                return False
            else:
                return True

    # Configure dump_image_format in /etc/libvirt/qemu.conf.
    if len(dump_image_format):
        conf_cmd = ("echo dump_image_format = \\\"%s\\\" >> %s" %
                    (dump_image_format, qemu_conf))
        if os.system(conf_cmd):
            logging.error("Config dump_image_format to %s fail",
                          dump_image_format)
        utils_libvirtd.libvirtd_restart()
        if not utils_libvirtd.libvirtd_is_running():
            raise error.TestNAError("libvirt service is not running!")

    # Deal with bypass-cache option
    child_pid = 0
    if options.find('bypass-cache') >= 0:
        pid = os.fork()
        if pid:
            # Guarantee check_bypass function has run before dump
            child_pid = pid
            try:
                wait_pid_active(pid, timeout)
            finally:
                os.kill(child_pid, signal.SIGUSR1)
        else:
            check_bypass(dump_file)
            # Wait for parent process over
            while True:
                time.sleep(1)

    # Run virsh command
    cmd_result = virsh.dump(vm_name, dump_file, options,
                            ignore_status=True, debug=True)
    status = cmd_result.exit_status

    try:
        logging.info("Start check result")
        if not check_domstate(vm.state(), options):
            raise error.TestFail("Domain status check fail.")
        if status_error:
            if not status:
                raise error.TestFail("Expect fail, but run successfully")
        else:
            if status:
                raise error.TestFail("Expect succeed, but run fail")
            if not os.path.exists(dump_file):
                raise error.TestFail("Fail to find domain dumped file.")
            if check_dump_format(dump_image_format, dump_file):
                logging.info("Successfully dump domain to %s", dump_file)
            else:
                raise error.TestFail("The format of dumped file is wrong.")
    finally:
        if child_pid:
            os.kill(child_pid, signal.SIGUSR1)
        if os.path.isfile(dump_file):
            os.remove(dump_file)
        if len(dump_image_format):
            clean_qemu_conf = "sed -i '$d' %s " % qemu_conf
            if os.system(clean_qemu_conf):
                raise error.TestFail("Fail to recover %s", qemu_conf)
예제 #6
0
            if status != 0:
                raise error.TestFail("Run blockcopy command fail.")
            elif not os.path.exists(dest_path):
                raise error.TestFail("Cannot find the created copy.")

        cmd_result = virsh.blockcopy(vm_name,
                                     target,
                                     dest_path,
                                     options,
                                     ignore_status=True,
                                     debug=True)
        status = cmd_result.exit_status
    except Exception, detail:
        logging.error(detail)

    if not utils_libvirtd.libvirtd_is_running():
        raise error.TestFail("Libvirtd service is dead.")
    # Check_result
    try:
        try:
            if not status_error:
                if status == 0:
                    check_xml(vm_name, target, dest_path, options)
                    if options.count("--bandwidth"):
                        utl.check_blockjob(vm_name, target, "bandwidth",
                                           bandwidth)
                    if options.count("--pivot") + options.count(
                            "--finish") == 0:
                        finish_job(vm_name, target, default_timeout)
                    if options.count("--raw"):
                        check_format(dest_path, dest_extension, dest_format)
예제 #7
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)
예제 #8
0
def run(test, params, env):
    """
    Test numa tuning

    1) Positive testing
       1.1) get the current numa parameters for a running/shutoff guest
       1.2) set the current numa parameters for a running/shutoff guest
           1.2.1) set valid 'mode' parameters
           1.2.2) set valid 'nodeset' parameters
    2) Negative testing
       2.1) get numa parameters
           2.1.1) invalid options
           2.1.2) stop cgroup service
       2.2) set numa parameters
           2.2.1) invalid 'mode' parameters
           2.2.2) invalid 'nodeset' parameters
           2.2.3) change 'mode' for a running guest and 'mode' is not 'strict'
           2.2.4) change 'nodeset' for running guest with mode of 'interleave'
                  'interleave' or 'preferred' numa mode
           2.2.5) stop cgroup service
    """

    try:
        utils_misc.find_command("numactl")
    except ValueError:
        raise error.TestNAError("Command 'numactl' is missing. You must "
                                "install it.")

    # Run test case
    #vm_name = params.get("vms")
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    cg = utils_cgroup.CgconfigService()
    status_error = params.get("status_error", "no")
    libvirtd = params.get("libvirtd", "on")
    cgconfig = params.get("cgconfig", "on")
    start_vm = params.get("start_vm", "no")
    change_parameters = params.get("change_parameters", "no")

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # positive and negative testing #########

    cgstop = False
    try:
        if status_error == "no":
            if change_parameters == "no":
                get_numa_parameter(params, cgstop)
            else:
                set_numa_parameter(params, cgstop)
        if cgconfig == "off":
            # If running, then need to shutdown a running guest before
            # stopping cgconfig service and will start the guest after
            # restarting libvirtd service
            if cg.cgconfig_is_running():
                if vm.is_alive():
                    vm.destroy()
                cg.cgconfig_stop()
                cgstop = True

        # If we stopped cg, then refresh libvirtd service
        # to get latest cgconfig service change; otherwise,
        # if no cg change restart of libvirtd is pointless
        if cgstop and libvirtd == "restart":
            try:
                utils_libvirtd.libvirtd_restart()
            finally:
                # Not running is not a good thing, but it does happen
                # and it will affect other tests
                if not utils_libvirtd.libvirtd_is_running():
                    raise error.TestNAError("libvirt service is not running!")

        # Recover previous running guest
        if (cgconfig == "off" and libvirtd == "restart" and not vm.is_alive()
                and start_vm == "yes"):
            vm.start()
        if status_error == "yes":
            if change_parameters == "no":
                get_numa_parameter(params, cgstop)
            else:
                set_numa_parameter(params, cgstop)
    finally:
        # Restore guest
        original_vm_xml.sync()

        # If we stopped cg, then recover and refresh libvirtd to recognize
        if cgstop:
            cg.cgconfig_start()
            utils_libvirtd.libvirtd_restart()
예제 #9
0
def run_virsh_setmem(test, params, env):
    """
    Test command: virsh setmem.

    1) Prepare vm environment.
    2) Handle params
    3) Prepare libvirtd status.
    4) Run test command and wait for current memory's stable.
    5) Recover environment.
    4) Check result.
    TODO: support new libvirt with more options.
    """

    def vm_proc_meminfo(session):
        proc_meminfo = session.cmd_output("cat /proc/meminfo")
        # verify format and units are expected
        return int(re.search(r'MemTotal:\s+(\d+)\s+kB', proc_meminfo).group(1))

    def make_domref(domarg, vm_ref, domid, vm_name, domuuid):
        # Specify domain as argument or parameter
        if domarg == "yes":
            dom_darg_key = "domainarg"
        else:
            dom_darg_key = "domain"

        # How to reference domain
        if vm_ref == "domid":
            dom_darg_value = domid
        elif vm_ref == "domname":
            dom_darg_value = vm_name
        elif vm_ref == "domuuid":
            dom_darg_value = domuuid
        elif vm_ref == "none":
            dom_darg_value = None
        elif vm_ref == "emptystring":
            dom_darg_value = '""'
        else:  # stick in value directly
            dom_darg_value = vm_ref

        return {dom_darg_key: dom_darg_value}

    def make_sizeref(sizearg, mem_ref, original_mem):
        if sizearg == "yes":
            size_darg_key = "sizearg"
        else:
            size_darg_key = "size"

        if mem_ref == "halfless":
            size_darg_value = "%d" % (original_mem / 2)
        elif mem_ref == "halfmore":
            size_darg_value = "%d" % int(original_mem * 1.5)  # no fraction
        elif mem_ref == "same":
            size_darg_value = "%d" % original_mem
        elif mem_ref == "emptystring":
            size_darg_value = '""'
        elif mem_ref == "zero":
            size_darg_value = "0"
        elif mem_ref == "toosmall":
            size_darg_value = "1024"
        elif mem_ref == "toobig":
            size_darg_value = "1099511627776"  # (KiB) One Petabyte
        elif mem_ref == "none":
            size_darg_value = None
        else:  # stick in value directly
            size_darg_value = mem_ref

        return {size_darg_key: size_darg_value}

    def is_in_range(actual, expected, error_percent):
        deviation = 100 - (100 * (float(actual) / float(expected)))
        logging.debug("Deviation: %0.2f%%" % float(deviation))
        return float(deviation) <= float(error_percent)

    def is_old_libvirt():
        regex = r'\s+\[--size\]\s+'
        return bool(not virsh.has_command_help_match('setmem', regex))

    def print_debug_stats(original_inside_mem, original_outside_mem,
                          test_inside_mem, test_outside_mem,
                          expected_mem, delta_percentage):
        dbgmsg = ("Original inside mem  : %d KiB\n"
                  "Expected inside mem  : %d KiB\n"
                  "Actual inside mem    : %d KiB\n"
                  "Inside mem deviation : %0.2f%%\n"
                  "Original outside mem : %d KiB\n"
                  "Expected outside mem : %d KiB\n"
                  "Actual outside mem   : %d KiB\n"
                  "Outside mem deviation: %0.2f%%\n"
                  "Acceptable deviation %0.2f%%" % (
                      original_inside_mem,
                      expected_mem,
                      test_inside_mem,
                      100 -
                      (100 * (float(test_inside_mem) / float(expected_mem))),
                      original_outside_mem,
                      expected_mem,
                      test_outside_mem,
                      100 -
                      (100 * (float(test_outside_mem) / float(expected_mem))),
                      float(delta_percentage)))
        for dbgline in dbgmsg.splitlines():
            logging.debug(dbgline)

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_ref = params.get("setmem_vm_ref", "")
    mem_ref = params.get("setmem_mem_ref", "")
    flags = params.get("setmem_flags", "")
    status_error = params.get("status_error", "no")
    old_libvirt_fail = params.get("setmem_old_libvirt_fail", "no")
    quiesce_delay = int(params.get("setmem_quiesce_delay", "1"))
    domarg = params.get("setmem_domarg", "no")
    sizearg = params.get("setmem_sizearg", "no")
    libvirt = params.get("libvirt", "on")
    delta_percentage = float(params.get("setmem_delta_per", "10"))
    start_vm = params.get("start_vm", "yes")
    vm_name = params.get("main_vm")
    paused_after_start_vm = "yes" == params.get("paused_after_start_vm", "no")

    # Gather environment parameters
    vm = env.get_vm(params["main_vm"])
    if start_vm == "yes":
        if paused_after_start_vm:
            vm.resume()
        session = vm.wait_for_login()
        original_inside_mem = vm_proc_meminfo(session)
        session.close()
        if paused_after_start_vm:
            vm.pause()
    else:
        session = None
        # Retrieve known mem value, convert into kilobytes
        original_inside_mem = int(params.get("mem", "1024")) * 1024
    original_outside_mem = vm.get_used_mem()
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    uri = vm.connect_uri

    old_libvirt = is_old_libvirt()
    if old_libvirt:
        logging.info("Running test on older libvirt")
        use_kilobytes = True
    else:
        logging.info("Running test on newer libvirt")
        use_kilobytes = False

    # Argument pattern is complex, build with dargs
    dargs = {'flagstr': flags,
             'use_kilobytes': use_kilobytes,
             'uri': uri, 'ignore_status': True, "debug": True}
    dargs.update(make_domref(domarg, vm_ref, domid, vm_name, domuuid))
    dargs.update(make_sizeref(sizearg, mem_ref, original_outside_mem))

    # Prepare libvirtd status
    if libvirt == "off":
        utils_libvirtd.libvirtd_stop()
    else:
        if not utils_libvirtd.libvirtd_is_running() and \
           not utils_libvirtd.libvirtd_start():
            raise error.TestFail("Cannot start libvirtd")

    if status_error == "yes" or old_libvirt_fail == "yes":
        logging.info("Error Test: Expecting an error to occur!")

    result = virsh.setmem(**dargs)
    status = result.exit_status

    # Recover libvirtd status
    if libvirt == "off":
        utils_libvirtd.libvirtd_start()

    if status is 0:
        logging.info(
            "Waiting %d seconds for VM memory to settle", quiesce_delay)
        # It takes time for kernel to settle on new memory
        # and current clean pages is not predictable. Therefor,
        # extremely difficult to determine quiescence, so
        # sleep one second per error percent is reasonable option.
        time.sleep(quiesce_delay)

    # Gather stats if not running error test
    if status_error == "no" and old_libvirt_fail == "no":
        if vm.state() == "shut off":
            vm.start()
        # Make sure it's never paused
        vm.resume()
        session = vm.wait_for_login()

        # Actual results
        test_inside_mem = vm_proc_meminfo(session)
        session.close()
        test_outside_mem = vm.get_used_mem()

        # Expected results for both inside and outside
        if sizearg == "yes":
            expected_mem = int(dargs["sizearg"])
        else:
            expected_mem = int(dargs["size"])

        print_debug_stats(original_inside_mem, original_outside_mem,
                          test_inside_mem, test_outside_mem,
                          expected_mem, delta_percentage)

    if status is 0:  # Restore original memory
        restore_status = virsh.setmem(domainarg=vm_name,
                                      sizearg=original_outside_mem,
                                      ignore_status=True).exit_status
        if restore_status is not 0:
            logging.warning("Failed to restore VM's original memory to %s KiB"
                            % original_outside_mem)
    else:
        # virsh setmem failed, no need to restore
        pass

    # Don't care about memory comparison on error test
    if status_error == "no" and old_libvirt_fail == "no":
        outside_in_range = is_in_range(test_outside_mem, expected_mem,
                                       delta_percentage)
        inside_in_range = is_in_range(test_inside_mem, expected_mem,
                                      delta_percentage)
        if status is not 0 or not outside_in_range or not inside_in_range:
            msg = "test conditions not met: "
            if status is not 0:
                msg += "Non-zero virsh setmem exit code. "  # maybe multiple
            if not outside_in_range:                       # errors
                msg += "Outside memory deviated. "
            if not inside_in_range:
                msg += "Inside memory deviated. "
            raise error.TestFail(msg)

        return  # Normal test passed
    elif status_error == "no" and old_libvirt_fail == "yes":
        if status is 0:
            if old_libvirt:
                raise error.TestFail("Error test did not result in an error")
        else:
            if not old_libvirt:
                raise error.TestFail("Newer libvirt failed when it should not")
    else:  # Verify an error test resulted in error
        if status is 0:
            raise error.TestFail("Error test did not result in an error")
예제 #10
0
def run_virsh_dump(test, params, env):
    """
    Test command: virsh dump.

    This command can dump the core of a domain to a file for analysis.
    1. Positive testing
        1.1 Dump domain with valid options.
        1.2 Avoid file system cache when dumping.
        1.3 Compress the dump images to valid/invalid formats.
    2. Negative testing
        2.1 Dump domain to a non-exist directory.
        2.2 Dump domain with invalid option.
        2.3 Dump a shut-off domain.
    """

    vm_name = params.get("main_vm", "vm1")
    vm = env.get_vm(params["main_vm"])
    options = params.get("dump_options")
    dump_file = params.get("dump_file", "vm.core")
    if os.path.dirname(dump_file) is "":
        dump_file = os.path.join(test.tmpdir, dump_file)
    dump_image_format = params.get("dump_image_format")
    start_vm = params.get("start_vm")
    status_error = params.get("status_error", "no")
    qemu_conf = "/etc/libvirt/qemu.conf"

    # prepare the vm state
    if vm.is_alive() and start_vm == "no":
        vm.destroy()

    if vm.is_dead() and start_vm == "yes":
        vm.start()

    def check_domstate(actual, options):
        """
        Check the domain status according to dump options.
        """

        if options.find('live') >= 0:
            domstate = "running"
            if options.find('crash') >= 0 or options.find('reset') > 0:
                domstate = "running"
        elif options.find('crash') >= 0:
            domstate = "shut off"
            if options.find('reset') >= 0:
                domstate = "running"
        elif options.find('reset') >= 0:
            domstate = "running"
        else:
            domstate = "running"

        if start_vm == "no":
            domstate = "shut off"

        logging.debug("Domain should %s after run dump %s", domstate, options)

        if domstate == actual:
            return True
        else:
            return False

    def check_dump_format(dump_image_format, dump_file):
        """
        Check the format of dumped file.

        If 'dump_image_format' is not specified or invalid in qemu.conf, then
        the file shoule be normal raw file, otherwise it shoud be compress to
        specified format, the supported compress format including: lzop, gzip,
        bzip2, and xz.
        """

        valid_format = ["lzop", "gzip", "bzip2", "xz"]
        if len(dump_image_format
               ) == 0 or dump_image_format not in valid_format:
            logging.debug("No need check the dumped file format")
            return True
        else:
            file_cmd = "file %s" % dump_file
            (status, output) = commands.getstatusoutput(file_cmd)
            if status == 0:
                logging.debug("Run file %s output: %s", dump_file, output)
                actual_format = output.split(" ")[1]
                if actual_format == dump_image_format:
                    if dump_image_format in valid_format:
                        logging.info("Compress dumped file to %s successfully",
                                     dump_image_format)
                    return True
                else:
                    logging.error("Compress dumped file to %s fail",
                                  dump_image_format)
                    return False
            else:
                logging.error("Fail to check dumped file %s", dump_file)
                return False

    # Configure dump_image_format in /etc/libvirt/qemu.conf.
    if len(dump_image_format) != 0:
        conf_cmd = ("echo dump_image_format = \\\"%s\\\" >> %s" %
                    (dump_image_format, qemu_conf))
        if os.system(conf_cmd):
            logging.error("Config dump_image_format to %s fail",
                          dump_image_format)
        utils_libvirtd.libvirtd_restart()

    # Deal with bypass-cache option
    if options.find('bypass-cache') >= 0:
        thread.start_new_thread(check_bypass, (dump_file, ))
        # Guarantee check_bypass function has run before dump
        time.sleep(5)

    # Run virsh command
    cmd_result = virsh.dump(vm_name,
                            dump_file,
                            options,
                            ignore_status=True,
                            debug=True)
    status = cmd_result.exit_status

    # Check libvirtd status
    if utils_libvirtd.libvirtd_is_running():
        if check_domstate(vm.state(), options):
            if status_error == "yes":
                if status == 0:
                    raise error.TestFail("Expect fail, but run successfully")
            if status_error == "no":
                if status != 0:
                    raise error.TestFail("Expect succeed, but run fail")
                else:
                    if os.path.exists(dump_file):
                        if check_dump_format(dump_image_format, dump_file):
                            logging.info("Successfully dump domain to %s",
                                         dump_file)
                        else:
                            raise error.TestFail("The format of dumped file "
                                                 "is wrong.")
                    else:
                        raise error.TestFail(
                            "Fail to find domain dumped file.")

        else:
            raise error.TestFail("Domain status check fail.")
    else:
        raise error.TestFail("Libvirtd service is dead.")

    if os.path.isfile(dump_file):
        os.remove(dump_file)

    if len(dump_image_format) != 0:
        clean_qemu_conf = "sed -i '$d' %s " % qemu_conf
        if os.system(clean_qemu_conf):
            raise error.TestFail("Fail to recover %s", qemu_conf)
예제 #11
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 = params.get("libvirtd", "on")
    libvirtd_status = utils_libvirtd.libvirtd_is_running()
    if libvirtd == "off" and libvirtd_status:
        utils_libvirtd.libvirtd_stop()
    elif libvirtd == "on" and not libvirtd_status:
        utils_libvirtd.libvirtd_start()

    # 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)
        else:
            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')
        current_libvirtd_status = utils_libvirtd.libvirtd_is_running()
        if current_libvirtd_status and not libvirtd_status:
            utils_libvirtd.libvirtd_stop()
        elif not current_libvirtd_status and libvirtd_status:
            utils_libvirtd.libvirtd_start()
예제 #12
0
def run(test, params, env):
    """
    Test blkio tuning

    1) Positive testing
       1.1) get the current blkio parameters for a running/shutoff guest
       1.2) set the current blkio parameters for a running/shutoff guest
    2) Negative testing
       2.1) get blkio parameters for a running/shutoff guest
       2.2) set blkio parameters running/shutoff guest
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    cg = utils_cgroup.CgconfigService()
    cgconfig = params.get("cgconfig", "on")
    libvirtd = params.get("libvirtd", "on")
    start_vm = params.get("start_vm", "yes")
    status_error = params.get("status_error", "no")
    change_parameters = params.get("change_parameters", "no")
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm and vm.is_alive():
        vm.destroy()

    test_dict = prepare_scheduler(params, test, vm)

    # positive and negative testing
    cgstop = False
    try:
        if start_vm == "yes" and not vm.is_alive():
            vm.start()
            vm.wait_for_login()
        if status_error == "no":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
        if cgconfig == "off":
            # If running, then need to shutdown a running guest before
            # stopping cgconfig service and will start the guest after
            # restarting libvirtd service
            if cg.cgconfig_is_running():
                if vm.is_alive():
                    vm.destroy()
                cg.cgconfig_stop()
                cgstop = True

        # If we stopped cg, then refresh libvirtd service
        # to get latest cgconfig service change; otherwise,
        # if no cg change restart of libvirtd is pointless
        if cgstop and libvirtd == "restart":
            try:
                utils_libvirtd.libvirtd_restart()
            finally:
                # Not running is not a good thing, but it does happen
                # and it will affect other tests
                if not utils_libvirtd.libvirtd_is_running():
                    test.fail("libvirt service is not running!")

        # Recover previous running guest
        if (cgconfig == "off" and libvirtd == "restart" and not vm.is_alive()
                and start_vm == "yes"):
            vm.start()
        if status_error == "yes":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
    finally:
        # Restore guest
        original_vm_xml.sync()

        with open(schedulerfd, 'w') as scf:
            scf.write(test_dict['oldmode'])

        # If we stopped cg, then recover and refresh libvirtd to recognize
        if cgstop:
            cg.cgconfig_start()
            utils_libvirtd.libvirtd_restart()
예제 #13
0
def run(test, params, env):
    """
    Test blkio tuning

    1) Positive testing
       1.1) get the current blkio parameters for a running/shutoff guest
       1.2) set the current blkio parameters for a running/shutoff guest
    2) Negative testing
       2.1) get blkio parameters for a running/shutoff guest
       2.2) set blkio parameters running/shutoff guest
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    cg = utils_cgroup.CgconfigService()
    cgconfig = params.get("cgconfig", "on")
    libvirtd = params.get("libvirtd", "on")
    start_vm = params.get("start_vm", "yes")
    status_error = params.get("status_error", "no")
    change_parameters = params.get("change_parameters", "no")
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm and vm.is_alive():
        vm.destroy()

    cmd = "cat /sys/block/sda/queue/scheduler"
    iosche = results_stdout_52lts(process.run(cmd, shell=True))
    logging.debug("iosche value is:%s", iosche)
    oldmode = re.findall("\[(.*?)\]", iosche)[0]
    with open('/sys/block/sda/queue/scheduler', 'w') as scf:
        if 'cfq' in iosche:
            scf.write('cfq')
        elif 'bfq' in iosche:
            scf.write('bfq')
        else:
            test.fail('Unknown scheduler in "/sys/block/sda/queue/scheduler"')

    test_dict = dict(params)
    test_dict['vm'] = vm

    # positive and negative testing

    cgstop = False
    try:
        if start_vm == "yes" and not vm.is_alive():
            vm.start()
            vm.wait_for_login()
        if status_error == "no":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
        if cgconfig == "off":
            # If running, then need to shutdown a running guest before
            # stopping cgconfig service and will start the guest after
            # restarting libvirtd service
            if cg.cgconfig_is_running():
                if vm.is_alive():
                    vm.destroy()
                cg.cgconfig_stop()
                cgstop = True

        # If we stopped cg, then refresh libvirtd service
        # to get latest cgconfig service change; otherwise,
        # if no cg change restart of libvirtd is pointless
        if cgstop and libvirtd == "restart":
            try:
                utils_libvirtd.libvirtd_restart()
            finally:
                # Not running is not a good thing, but it does happen
                # and it will affect other tests
                if not utils_libvirtd.libvirtd_is_running():
                    test.fail("libvirt service is not running!")

        # Recover previous running guest
        if (cgconfig == "off" and libvirtd == "restart" and not vm.is_alive()
                and start_vm == "yes"):
            vm.start()
        if status_error == "yes":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
    finally:
        # Restore guest
        original_vm_xml.sync()

        with open('/sys/block/sda/queue/scheduler', 'w') as scf:
            scf.write(oldmode)

        # If we stopped cg, then recover and refresh libvirtd to recognize
        if cgstop:
            cg.cgconfig_start()
            utils_libvirtd.libvirtd_restart()
예제 #14
0
def run(test, params, env):
    """
    Test blkio tuning

    1) Positive testing
       1.1) get the current blkio parameters for a running/shutoff guest
       1.2) set the current blkio parameters for a running/shutoff guest
    2) Negative testing
       2.1) get blkio parameters for a running/shutoff guest
       2.2) set blkio parameters running/shutoff guest
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    cg = utils_cgroup.CgconfigService()
    cgconfig = params.get("cgconfig", "on")
    libvirtd = params.get("libvirtd", "on")
    start_vm = params.get("start_vm", "yes")
    status_error = params.get("status_error", "no")
    change_parameters = params.get("change_parameters", "no")
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm and vm.is_alive():
        vm.destroy()

    cmd = "cat /sys/block/sda/queue/scheduler"
    iosche = results_stdout_52lts(process.run(cmd, shell=True))
    logging.debug("iosche value is:%s", iosche)
    oldmode = re.findall("\[(.*?)\]", iosche)[0]
    with open('/sys/block/sda/queue/scheduler', 'w') as scf:
        if 'cfq' in iosche:
            scf.write('cfq')
        elif 'bfq' in iosche:
            scf.write('bfq')
        else:
            test.fail('Unknown scheduler in "/sys/block/sda/queue/scheduler"')

    test_dict = dict(params)
    test_dict['vm'] = vm

    # positive and negative testing

    cgstop = False
    try:
        if start_vm == "yes" and not vm.is_alive():
            vm.start()
            vm.wait_for_login()
        if status_error == "no":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
        if cgconfig == "off":
            # If running, then need to shutdown a running guest before
            # stopping cgconfig service and will start the guest after
            # restarting libvirtd service
            if cg.cgconfig_is_running():
                if vm.is_alive():
                    vm.destroy()
                cg.cgconfig_stop()
                cgstop = True

        # If we stopped cg, then refresh libvirtd service
        # to get latest cgconfig service change; otherwise,
        # if no cg change restart of libvirtd is pointless
        if cgstop and libvirtd == "restart":
            try:
                utils_libvirtd.libvirtd_restart()
            finally:
                # Not running is not a good thing, but it does happen
                # and it will affect other tests
                if not utils_libvirtd.libvirtd_is_running():
                    test.fail("libvirt service is not running!")

        # Recover previous running guest
        if (cgconfig == "off" and libvirtd == "restart" and not vm.is_alive() and start_vm == "yes"):
            vm.start()
        if status_error == "yes":
            if change_parameters == "no":
                get_blkio_parameter(test, test_dict, cgstop)
            else:
                set_blkio_parameter(test, test_dict, cgstop)
    finally:
        # Restore guest
        original_vm_xml.sync()

        with open('/sys/block/sda/queue/scheduler', 'w') as scf:
            scf.write(oldmode)

        # If we stopped cg, then recover and refresh libvirtd to recognize
        if cgstop:
            cg.cgconfig_start()
            utils_libvirtd.libvirtd_restart()
예제 #15
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, test)
    if not target:
        test.fail("Require target disk to copy.")

    # Prepare transient/persistent vm
    original_xml = vm.backup_xml()
    if not persistent_vm and vm.is_persistent():
        vm.undefine("--nvram")
    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:
            test.error("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, test)

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

    if invalid_disk:
        target = invalid_disk

    # Wait for few seconds to be more like human activity,
    # otherwise, unexpected failure may happen.
    time.sleep(3)
    # 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():
        test.fail("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, test)
                #'bandwidth' option check
                if options.count("--bandwidth"):
                    utl.check_blockjob(vm_name, target, "bandwidth", bandwidth)
            else:
                test.fail(err)
        else:
            if status:
                logging.debug("Expect error: %s", err)
            else:
                test.fail("Expect fail, but run successfully.")
        #cleanup
    finally:
        try:
            if vm.exists():
                vm.destroy()
            else:
                test.fail("Domain is disappeared.")
        finally:
            vm.define(original_xml)
            if os.path.exists(dest_path):
                os.remove(dest_path)
예제 #16
0
def run(test, params, env):
    """
    Test command: virsh setmem.

    1) Prepare vm environment.
    2) Handle params
    3) Prepare libvirtd status.
    4) Run test command and wait for current memory's stable.
    5) Recover environment.
    4) Check result.
    """
    def vm_proc_meminfo(session):
        """
        Get guest total memory
        """
        proc_meminfo = session.cmd_output("cat /proc/meminfo")
        # verify format and units are expected
        return int(re.search(r'MemTotal:\s+(\d+)\s+kB', proc_meminfo).group(1))

    def make_domref(domarg, vm_ref, domid, vm_name, domuuid):
        """
        Create domain options of command
        """
        # Specify domain as argument or parameter
        if domarg == "yes":
            dom_darg_key = "domainarg"
        else:
            dom_darg_key = "domain"

        # How to reference domain
        if vm_ref == "domid":
            dom_darg_value = domid
        elif vm_ref == "domname":
            dom_darg_value = vm_name
        elif vm_ref == "domuuid":
            dom_darg_value = domuuid
        elif vm_ref == "none":
            dom_darg_value = None
        elif vm_ref == "emptystring":
            dom_darg_value = '""'
        else:  # stick in value directly
            dom_darg_value = vm_ref

        return {dom_darg_key: dom_darg_value}

    def make_sizeref(sizearg, mem_ref, original_mem):
        """
        Create size options of command
        """
        if sizearg == "yes":
            size_darg_key = "sizearg"
        else:
            size_darg_key = "size"

        if mem_ref == "halfless":
            size_darg_value = "%d" % (original_mem / 2)
        elif mem_ref == "halfmore":
            size_darg_value = "%d" % int(original_mem * 1.5)  # no fraction
        elif mem_ref == "same":
            size_darg_value = "%d" % original_mem
        elif mem_ref == "emptystring":
            size_darg_value = '""'
        elif mem_ref == "zero":
            size_darg_value = "0"
        elif mem_ref == "toosmall":
            size_darg_value = "1024"
        elif mem_ref == "toobig":
            size_darg_value = "1099511627776"  # (KiB) One Petabyte
        elif mem_ref == "none":
            size_darg_value = None
        else:  # stick in value directly
            size_darg_value = mem_ref

        return {size_darg_key: size_darg_value}

    def is_in_range(actual, expected, error_percent):
        """
        Check if value in reasonable range
        """
        deviation = 100 - (100 * (float(actual) / float(expected)))
        logging.debug("Deviation: %0.2f%%" % float(deviation))
        return float(deviation) <= float(error_percent)

    def is_old_libvirt():
        """
        Check if libvirt is old version
        """
        regex = r'\s+\[--size\]\s+'
        return bool(not virsh.has_command_help_match('setmem', regex))

    def print_debug_stats(original_inside_mem, original_outside_mem,
                          test_inside_mem, test_outside_mem, expected_mem,
                          delta_percentage):
        """
        Print debug message for test
        """
        dbgmsg = ("Original inside mem  : %d KiB\n"
                  "Expected inside mem  : %d KiB\n"
                  "Actual inside mem    : %d KiB\n"
                  "Inside mem deviation : %0.2f%%\n"
                  "Original outside mem : %d KiB\n"
                  "Expected outside mem : %d KiB\n"
                  "Actual outside mem   : %d KiB\n"
                  "Outside mem deviation: %0.2f%%\n"
                  "Acceptable deviation %0.2f%%" %
                  (original_inside_mem, expected_mem, test_inside_mem, 100 -
                   (100 * (float(test_inside_mem) / float(expected_mem))),
                   original_outside_mem, expected_mem, test_outside_mem, 100 -
                   (100 * (float(test_outside_mem) / float(expected_mem))),
                   float(delta_percentage)))
        for dbgline in dbgmsg.splitlines():
            logging.debug(dbgline)

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_ref = params.get("setmem_vm_ref", "")
    mem_ref = params.get("setmem_mem_ref", "")
    flags = params.get("setmem_flags", "")
    status_error = params.get("status_error", "no")
    old_libvirt_fail = params.get("setmem_old_libvirt_fail", "no")
    quiesce_delay = int(params.get("setmem_quiesce_delay", "1"))
    domarg = params.get("setmem_domarg", "no")
    sizearg = params.get("setmem_sizearg", "no")
    libvirt = params.get("libvirt", "on")
    delta_percentage = float(params.get("setmem_delta_per", "10"))
    start_vm = params.get("start_vm", "yes")
    vm_name = params.get("main_vm", "virt-tests-vm1")
    paused_after_start_vm = "yes" == params.get("paused_after_start_vm", "no")

    # Gather environment parameters
    vm = env.get_vm(vm_name)
    if start_vm == "yes":
        if paused_after_start_vm:
            vm.resume()
        session = vm.wait_for_login()
        original_inside_mem = vm_proc_meminfo(session)
        session.close()
        if paused_after_start_vm:
            vm.pause()
    else:
        # Retrieve known mem value, convert into kilobytes
        original_inside_mem = int(params.get("mem", "1024")) * 1024
    original_outside_mem = vm.get_used_mem()
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    uri = vm.connect_uri

    old_libvirt = is_old_libvirt()
    if old_libvirt:
        logging.info("Running test on older libvirt")
        use_kilobytes = True
    else:
        logging.info("Running test on newer libvirt")
        use_kilobytes = False

    # Argument pattern is complex, build with dargs
    dargs = {
        'flagstr': flags,
        'use_kilobytes': use_kilobytes,
        'uri': uri,
        'ignore_status': True,
        "debug": True
    }
    dargs.update(make_domref(domarg, vm_ref, domid, vm_name, domuuid))
    dargs.update(make_sizeref(sizearg, mem_ref, original_outside_mem))

    # Prepare libvirtd status
    if libvirt == "off":
        utils_libvirtd.libvirtd_stop()
    else:
        if not utils_libvirtd.libvirtd_is_running() and \
           not utils_libvirtd.libvirtd_start():
            raise error.TestFail("Cannot start libvirtd")

    if status_error == "yes" or old_libvirt_fail == "yes":
        logging.info("Error Test: Expecting an error to occur!")

    result = virsh.setmem(**dargs)
    status = result.exit_status

    # Recover libvirtd status
    if libvirt == "off":
        utils_libvirtd.libvirtd_start()

    if status is 0:
        logging.info("Waiting %d seconds for VM memory to settle",
                     quiesce_delay)
        # It takes time for kernel to settle on new memory
        # and current clean pages is not predictable. Therefor,
        # extremely difficult to determine quiescence, so
        # sleep one second per error percent is reasonable option.
        time.sleep(quiesce_delay)

    # Gather stats if not running error test
    if status_error == "no" and old_libvirt_fail == "no":
        if start_vm == "yes":
            if vm.state() == "shut off":
                vm.start()
            # Make sure it's never paused
            vm.resume()
            session = vm.wait_for_login()

            # Actual results
            test_inside_mem = vm_proc_meminfo(session)
            session.close()
        else:
            test_inside_mem = original_inside_mem
        test_outside_mem = vm.get_used_mem()

        # Expected results for both inside and outside
        if sizearg == "yes":
            expected_mem = int(dargs["sizearg"])
        else:
            expected_mem = int(dargs["size"])

        print_debug_stats(original_inside_mem, original_outside_mem,
                          test_inside_mem, test_outside_mem, expected_mem,
                          delta_percentage)

    if status is 0:  # Restore original memory
        restore_status = virsh.setmem(domainarg=vm_name,
                                      sizearg=original_outside_mem,
                                      ignore_status=True,
                                      flagstr=flags).exit_status
        if restore_status != 0:
            logging.warning(
                "Failed to restore VM's original memory to %s KiB" %
                original_outside_mem)
    else:
        # virsh setmem failed, no need to restore
        pass

    # Don't care about memory comparison on error test
    if status_error == "no" and old_libvirt_fail == "no":
        outside_in_range = is_in_range(test_outside_mem, expected_mem,
                                       delta_percentage)
        inside_in_range = is_in_range(test_inside_mem, expected_mem,
                                      delta_percentage)
        if status is not 0 or not outside_in_range or not inside_in_range:
            msg = "test conditions not met: "
            if status is not 0:
                msg += "Non-zero virsh setmem exit code. "  # maybe multiple
            if not outside_in_range:  # errors
                msg += "Outside memory deviated. "
            if not inside_in_range:
                msg += "Inside memory deviated. "
            raise error.TestFail(msg)

        return  # Normal test passed
    elif status_error == "no" and old_libvirt_fail == "yes":
        if status is 0:
            if old_libvirt:
                raise error.TestFail("Error test did not result in an error")
        else:
            if not old_libvirt:
                raise error.TestFail("Newer libvirt failed when it should not")
    else:  # Verify an error test resulted in error
        if status is 0:
            raise error.TestFail("Error test did not result in an error")
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 = params.get("libvirtd", "on")
    libvirtd_status = utils_libvirtd.libvirtd_is_running()
    if libvirtd == "off" and libvirtd_status:
        utils_libvirtd.libvirtd_stop()
    elif libvirtd == "on" and not libvirtd_status:
        utils_libvirtd.libvirtd_start()

    # 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)
        else:
            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')
        current_libvirtd_status = utils_libvirtd.libvirtd_is_running()
        if current_libvirtd_status and not libvirtd_status:
            utils_libvirtd.libvirtd_stop()
        elif not current_libvirtd_status and libvirtd_status:
            utils_libvirtd.libvirtd_start()
예제 #18
0
def run(test, params, env):
    """
    Test blkdevio tuning

    Positive test has covered the following combination.
    -------------------------
    | total | read  | write |
    -------------------------
    |   0   |   0   |   0   |
    | non-0 |   0   |   0   |
    |   0   | non-0 | non-0 |
    |   0   | non-0 |  0    |
    |   0   |   0   | non-0 |
    -------------------------

    Negative test has covered unsupported combination and
    invalid command arguments.

    NB: only qemu-kvm-rhev supports block I/O throttling on >= RHEL6.5,
    the qemu-kvm is okay for block I/O throttling on >= RHEL7.0.
    """

    # Run test case
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    start_vm = params.get("start_vm", "yes")
    change_parameters = params.get("change_parameters", "no")
    attach_disk = "yes" == params.get("attach_disk", "no")
    attach_before_start = "yes" == params.get("attach_before_start", "yes")
    disk_type = params.get("disk_type", 'file')
    disk_format = params.get("disk_format", 'qcow2')
    disk_bus = params.get("disk_bus", 'virtio')
    disk_alias = params.get("disk_alias")
    attach_options = params.get("attach_options")

    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    # Used for default device of blkdeviotune
    device = params.get("device_name", "vmblk")
    sys_image_target = vm.get_first_disk_devices()["target"]

    # Make sure vm is down if start not requested
    if (start_vm == "no" or attach_before_start) and vm and vm.is_alive():
        vm.destroy()

    if attach_disk:
        disk_source = tempfile.mktemp(dir=data_dir.get_tmp_dir())
        libvirt.create_local_disk(disk_type, path=disk_source, size='1',
                                  disk_format=disk_format)
        attach_extra = ""
        if disk_alias:
            attach_extra += " --alias %s" % disk_alias
        if disk_bus:
            attach_extra += " --targetbus %s" % disk_bus
        if disk_format:
            attach_extra += " --subdriver %s" % disk_format
        if attach_options:
            attach_extra += " %s" % attach_options
    # Coldplug disk
    if attach_disk and attach_before_start:
        ret = virsh.attach_disk(vm_name, disk_source, device,
                                extra=attach_extra, debug=True)
        libvirt.check_exit_status(ret)
    # Recover previous running guest
    if vm and not vm.is_alive() and start_vm == "yes":
        try:
            vm.start()
            vm.wait_for_login().close()
        except (virt_vm.VMError, remote.LoginError) as detail:
            vm.destroy()
            test.fail(str(detail))
    # Hotplug disk
    if attach_disk and not attach_before_start:
        ret = virsh.attach_disk(vm_name, disk_source, device,
                                extra=attach_extra, debug=True)
        libvirt.check_exit_status(ret)

    test_dict = dict(params)
    test_dict['vm'] = vm
    if device == "vmblk":
        test_dict['device_name'] = sys_image_target

    # Make sure libvirtd service is running
    if not utils_libvirtd.libvirtd_is_running():
        test.cancel("libvirt service is not running!")

    # Positive and negative testing
    try:
        if change_parameters == "no":
            get_blkdevio_parameter(test_dict, test)
        else:
            set_blkdevio_parameter(test_dict, test)
    finally:
        # Restore guest
        original_vm_xml.sync()
예제 #19
0
def run(test, params, env):

    global flag_list, flag_list_abs, update_sec, without_sec
    global check_sec, check_without_sec, newxml

    # Basic network params
    net_name = params.get("net_update_net_name", "updatenet")
    net_section = params.get("network_section")
    update_command = params.get("update_command", "add-last")
    options = params.get("cmd_options", "")
    net_state = params.get("net_state")
    use_in_guest = params.get("use_in_guest")
    iface_type = params.get("iface_type", "network")
    ip_version = params.get("ip_version", "ipv4")
    new_start_ip = params.get("start_ip")
    new_end_ip = params.get("end_ip")
    parent_index = params.get("parent_index")
    status_error = params.get("status_error", "no")

    # dhcp host test
    new_dhcp_host_ip = params.get("new_dhcp_host_ip")
    new_dhcp_host_id = params.get("new_dhcp_host_id")
    new_dhcp_host_name = params.get("new_dhcp_host_name")
    new_dhcp_host_mac = params.get("new_dhcp_host_mac")

    # ipv4 range/host test
    ipv4_range_start = params.get("ori_ipv4_range_start")
    ipv4_range_end = params.get("ori_ipv4_range_end")
    ipv4_host_mac = params.get("ori_ipv4_host_mac")
    ipv4_host_ip = params.get("ori_ipv4_host_ip")
    ipv4_host_name = params.get("ori_ipv4_host_name")

    # ipv6 range/host test
    ipv6_range_start = params.get("ori_ipv6_range_start")
    ipv6_range_end = params.get("ori_ipv6_range_end")
    ipv6_host_id = params.get("ori_ipv6_host_id")
    ipv6_host_name = params.get("ori_ipv6_host_name")
    ipv6_host_ip = params.get("ori_ipv6_host_ip")

    # dns test
    dns_name = params.get("ori_dns_name")
    dns_value = params.get("ori_dns_value")
    new_dns_name = params.get("new_dns_name")
    new_dns_value = params.get("new_dns_value")

    # srv test
    srv_service = params.get("ori_srv_service")
    srv_protocol = params.get("ori_srv_protocol")
    srv_domain = params.get("ori_srv_domain")
    srv_target = params.get("ori_srv_target")
    srv_port = params.get("ori_srv_port")
    srv_priority = params.get("ori_srv_priority")
    srv_weight = params.get("ori_srv_weight")
    new_srv_service = params.get("new_srv_service")
    new_srv_protocol = params.get("new_srv_protocol")
    new_srv_domain = params.get("new_srv_domain")
    new_srv_target = params.get("new_srv_target")
    new_srv_port = params.get("new_srv_port")
    new_srv_priority = params.get("new_srv_priority")
    new_srv_weight = params.get("new_srv_weight")

    # dns host test
    dns_hostip = params.get("ori_dns_hostip")
    dns_hostname = params.get("ori_dns_hostname")
    dns_hostname2 = params.get("ori_dns_hostname2")

    # setting for without part
    without_ip_dhcp = params.get("without_ip_dhcp", "no")
    without_dns = params.get("without_dns", "no")
    without_dns_host = params.get("without_dns_host", "no")
    without_dns_txt = params.get("without_dns_txt", "no")
    without_dns_srv = params.get("without_dns_srv", "no")
    without_dns_forwarder = params.get("without_dns_forwarder", "no")

    # setting for update/check/without section
    update_sec = params.get("update_sec")
    check_sec = params.get("check_sec")
    without_sec = params.get("without_sec")
    check_without_sec = params.get("check_without_sec")

    # forward test
    forward_mode = params.get("forward_mode")
    forward_iface = params.get("forward_iface", "eth2")

    # other params
    error_type = params.get("error_type", "")
    vm_name = params.get("main_vm")
    loop_time = int(params.get("loop_time", 1))
    check_config_round = params.get("check_config_round", -1)
    ipv4_host_id = ipv6_host_mac = ""
    dns_enable = params.get("dns_enable", "yes")
    guest_iface_num = int(params.get("guest_iface_num", 1))
    newxml = ""

    def get_hostfile():
        """
        Get the content of hostfile
        """
        logging.info("Checking network hostfile...")
        hostfile = "/var/lib/libvirt/dnsmasq/%s.hostsfile" % net_name
        with open(hostfile) as hostfile_d:
            hostfile = hostfile_d.readlines()
        return hostfile

    def find_config(check_file, need_find):
        """
        Find configure in check_file

        :param check_file: The file that will check
        :param need_find: If need to find the item in check_file, Boolean
        """
        def _find_config(check_func):
            def __find_config(*args, **kwargs):
                logging.info("Checking content of %s", check_file)
                ret = False
                item = None
                with open(check_file) as checkfile_d:
                    while True:
                        check_line = checkfile_d.readline()
                        if not check_line:
                            break
                        (ret, item) = check_func(check_line, *args, **kwargs)
                        if ret:
                            break
                if not ret:
                    if need_find:
                        test.fail("Fail to find %s in %s" % (item, check_file))
                    else:
                        logging.info("Can not find %s in %s as expected" % (item, check_file))
            return __find_config
        return _find_config

    conf_file = "/var/lib/libvirt/dnsmasq/%s.conf" % net_name

    @find_config(conf_file, True)
    def check_item(check_line, item):
        """
        Check if the item in config file
        """
        if item in check_line:
            logging.info("Find %s in %s", item, conf_file)
            return (True, item)
        else:
            return (False, item)

    host_file = "/var/lib/libvirt/dnsmasq/%s.addnhosts" % net_name

    @find_config(host_file, True)
    def check_host(check_line, item):
        """
        Check if the item in host_file
        """
        if re.search(item, check_line):
            logging.info("Find %s in %s", item, host_file)
            return (True, item)
        else:
            return (False, item)

    @find_config(conf_file, False)
    def check_item_absent(check_line, item):
        """
        Check if the item not in config file
        """
        if item in check_line:
            test.fail("Find %s in %s" % (item, conf_file))
        else:
            return (False, item)

    @find_config(host_file, False)
    def check_host_absent(check_line, item):
        """
        Check if the item not in host_file
        """
        if re.search(item, check_line):
            test.fail("Find %s in %s" % (item, host_file))
        else:
            return (False, item)

    def section_update(ori_pre, new_pre):
        """
        Deal with update section and without section in func

        :param ori_pre: prefix of original section parameter name
        :param new_pre: prefix of new section parameter name
        """
        global flag_list, flag_list_abs, update_sec, without_sec
        global check_sec, check_without_sec, newxml

        if update_sec:
            for sec in update_sec.split(","):
                newxml = newxml.replace(names[ori_pre+sec],
                                        names[new_pre+sec])
            if update_command != "delete":
                check_sec = update_sec
        if without_sec:
            for sec_no in without_sec.split(","):
                newxml = re.sub(sec_no+"=\".*?\"", "", newxml)
            if update_command == "modify":
                check_without_sec = without_sec
        if check_sec:
            for c_sec in check_sec.split(","):
                flag_list.append(names[new_pre+c_sec])
        if check_without_sec:
            for c_sec_no in check_without_sec.split(","):
                flag_list_abs.append(names[ori_pre+c_sec_no])

    dns_host_xml = """
<host ip='%s'>
 <hostname>%s</hostname>
 <hostname>%s</hostname>
</host>
""" % (dns_hostip, dns_hostname, dns_hostname2)

    virtual_net = """
<network>
  <name>%s</name>
  <forward mode='nat'/>
  <bridge name='%s' stp='on' delay='0' />
  <mac address='52:54:00:03:78:6c'/>
  <domain name="example.com" localOnly="no"/>
  <mtu size="9000"/>
  <dns enable='%s'>
     <forwarder domain='example.com' addr="8.8.4.4"/>
      <txt name='%s' value='%s'/>
      <srv service='%s' protocol='%s' domain='%s' target='%s' port='%s' priority='%s' weight='%s'/>
      %s
  </dns>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='%s' end='%s' />
      <host mac='%s' ip='%s' name='%s' />
    </dhcp>
  </ip>
  <ip family='ipv6' address='2001:db8:ca2:2::1' prefix='64'>
    <dhcp>
      <range start='%s' end='%s'/>
      <host id='%s' name='%s' ip='%s'/>
    </dhcp>
  </ip>
  <route family='ipv6' address='2001:db8:ca2:2::' prefix='64' gateway='2001:db8:ca2:2::4'/>
  <ip address='192.168.101.1' netmask='255.255.255.0'/>
  <ip family='ipv6' address='2001:db8:ca2:3::1' prefix='64' />
</network>
""" % (net_name, net_name, dns_enable, dns_name, dns_value, srv_service, srv_protocol,
       srv_domain, srv_target, srv_port, srv_priority, srv_weight, dns_host_xml,
       ipv4_range_start, ipv4_range_end, ipv4_host_mac, ipv4_host_ip, ipv4_host_name,
       ipv6_range_start, ipv6_range_end, ipv6_host_id, ipv6_host_name, ipv6_host_ip)

    port_group = """
<portgroup name='engineering' default='no'>
  <virtualport type='802.1Qbh'>
    <parameters profileid='test'/>
  </virtualport>
  <bandwidth>
    <inbound average='1000' peak='5000' burst='5120'/>
    <outbound average='1000' peak='5000' burst='5120'/>
  </bandwidth>
</portgroup>
"""

    if use_in_guest == "yes":
        vm = env.get_vm(vm_name)
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        vmxml_backup = vmxml.copy()

    backup_files = []
    try:
        for loop in range(loop_time):
            if loop_time > 1:
                logging.info("Round %s:", loop+1)
                update_command = params.get("update_command").split(",")[loop]
                if net_section == "ip-dhcp-host":
                    new_dhcp_host_ip = params.get("new_dhcp_host_ip").split(",")[loop]
                    new_dhcp_host_name = params.get("new_dhcp_host_name").split(",")[loop]
                    new_dhcp_host_mac = params.get("new_dhcp_host_mac").split(",")[loop]
                    status_error = params.get("status_error").split(",")[loop]
                elif net_section == "dns-txt":
                    net_state = params.get("net_state").split(",")[loop]

            # Get a tmp_dir.
            tmp_dir = data_dir.get_tmp_dir()

            # Write new xml into a tempfile
            tmp_file = tempfile.NamedTemporaryFile(prefix=("new_xml_"),
                                                   dir=tmp_dir)
            xmlfile = tmp_file.name
            tmp_file.close()

            # Generate testxml
            test_xml = network_xml.NetworkXML(network_name=net_name)
            test_xml.xml = virtual_net

            names = locals()

            if net_section == "portgroup":
                portgroup_xml = network_xml.PortgroupXML()
                portgroup_xml.xml = port_group
                test_xml.portgroup = portgroup_xml
            elif net_section == "forward-interface":
                if forward_mode == "bridge":
                    forward_iface = utils_net.get_net_if(state="UP")[0]
                test_xml.forward = {'mode': forward_mode}
                test_xml.forward_interface = [{'dev': forward_iface}]
                del test_xml.bridge
                del test_xml.mac
                for ip_num in range(4):
                    del test_xml.ip
                del test_xml.routes
                del test_xml.dns
                del test_xml.mtu
                del test_xml.domain_name

            section_index = 0
            if ip_version == "ipv6":
                section_index = 1
            element = "/%s" % net_section.replace('-', '/')
            try:
                section_xml = test_xml.get_section_string(xpath=element, index=section_index)
            except xcepts.LibvirtXMLNotFoundError:
                newxml = section_xml = test_xml.get_section_string(xpath="/ip/dhcp/range")

            newxml = section_xml
            logging.debug("section xml is %s", newxml)

            flag_list = []
            flag_list_abs = []

            if (update_command == "delete" and
                    error_type not in ["host-mismatch", "range-mismatch"] and
                    not without_sec and not update_sec):
                logging.info("The delete xml is %s", newxml)
            else:
                if net_section == "bridge":
                    new_bridge_name = net_name + "_new"
                    flag_list.append(new_bridge_name)
                    newxml = section_xml.replace(net_name, new_bridge_name)
                    logging.info("The new bridge xml is %s", newxml)
                elif net_section == "forward":
                    new_mode = "route"
                    flag_list.append(new_mode)
                    newxml = section_xml.replace("nat", new_mode)
                    logging.info("The new forward xml is %s", newxml)
                elif net_section == "ip":
                    new_netmask = "255.255.0.0"
                    flag_list.append(new_netmask)
                    newxml = section_xml.replace("255.255.255.0", new_netmask)
                elif net_section == "ip-dhcp-range":
                    newxml = section_xml.replace(names[ip_version+"_range_start"], new_start_ip)
                    newxml = newxml.replace(names[ip_version+"_range_end"], new_end_ip)
                    for location in ["end", "start"]:
                        if names["new_"+location+"_ip"] == "":
                            newxml = newxml.replace(location+"=\"\"", "")
                        else:
                            flag_list.append(names["new_"+location+"_ip"])
                elif net_section == "portgroup":
                    new_inbound_average = "2000"
                    flag_list.append(new_inbound_average)
                    newxml = section_xml.replace("1000", new_inbound_average)
                    newxml = newxml.replace("default=\"no\"", "default=\"yes\"")
                    flag_list.append("default=('|\")yes")
                    if update_command in ['add-first', 'add-last', 'add']:
                        newxml = newxml.replace("engineering", "sales")
                        flag_list.append("sales")
                    if update_command == "modify" and status_error == "yes":
                        newxml = newxml.replace("engineering", "")
                elif net_section == "forward-interface":
                    new_forward_iface = params.get("new_forward_iface")
                    if error_type != "interface-duplicate":
                        find_iface = 0
                        if not new_forward_iface and forward_mode == "bridge":
                            new_iface_list = utils_net.get_net_if(qdisc="(mq|pfifo_fast)",
                                                                  state="(UP|DOWN)",
                                                                  optional="MULTICAST,UP")
                            logging.info("new_iface_list is %s", new_iface_list)
                            for iface in new_iface_list:
                                if iface[0] != forward_iface:
                                    new_forward_iface = iface[0]
                                    find_iface = 1
                                    break
                            if not find_iface:
                                test.cancel("Can not find another physical interface to attach")
                    else:
                        new_forward_iface = forward_iface
                    flag_list.append(new_forward_iface)
                    newxml = section_xml.replace(forward_iface, new_forward_iface)
                elif net_section == "ip-dhcp-host":
                    if (update_sec is None and
                            update_command not in ['modify', 'delete']):
                        if ip_version == "ipv4":
                            update_sec = "ip,mac,name"
                        elif ip_version == "ipv6":
                            update_sec = "ip,id,name"
                    section_update(ip_version+"_host_", "new_dhcp_host_")
                elif net_section == "dns-txt":
                    section_update("dns_", "new_dns_")
                elif net_section == "dns-srv":
                    section_update("srv_", "new_srv_")
                elif net_section == "dns-host":
                    if without_sec == "hostname":
                        newxml = re.sub("<hostname>.*</hostname>\n", "", newxml)
                    if status_error == 'no':
                        flag_list.append("ip=.*?"+dns_hostip)
                        flag_list.append(dns_hostname)
                        flag_list.append(dns_hostname2)
                # for negative test may have net_section do not match issues
                elif status_error == "no":
                    test.fail("Unknown network section")
                logging.info("The new xml of %s is %s", net_section, newxml)

            with open(xmlfile, 'w') as xmlfile_d:
                xmlfile_d.write(newxml)

            if without_ip_dhcp == "yes":
                test_xml.del_element(element="/ip/dhcp")
                test_xml.del_element(element="/ip/dhcp")

            if without_dns == "yes":
                test_xml.del_element(element='/dns')
            if without_dns_host == "yes":
                test_xml.del_element(element='/dns/host')
            if without_dns_txt == "yes":
                test_xml.del_element(element='/dns/txt')
            if without_dns_srv == "yes":
                test_xml.del_element(element='/dns/srv')
            if without_dns_forwarder == "yes":
                test_xml.del_element(element='/dns/forwarder')
            # Only do net define/start in first loop

            if (net_section == "ip-dhcp-range" and use_in_guest == "yes" and
                    without_ip_dhcp == "no"):
                test_xml.del_element(element="/ip/dhcp", index=section_index)

            if loop == 0:
                try:
                    # Define and start network
                    test_xml.debug_xml()
                    test_xml.define()
                    ori_net_xml = virsh.net_dumpxml(net_name).stdout.strip()
                    if "ipv6" in ori_net_xml:
                        host_ifaces = utils_net.get_net_if(state="UP")
                        backup_files.append(
                            remote.RemoteFile(address='127.0.0.1',
                                              client='scp',
                                              username=params.get('username'),
                                              password=params.get('password'),
                                              port='22',
                                              remote_path='/proc/sys/net/ipv6/'
                                                          'conf/all/accept_ra'))
                        process.run("echo 2 > /proc/sys/net/ipv6/conf/all/accept_ra",
                                    shell=True)
                        for host_iface in host_ifaces:
                            backup_files.append(
                                remote.RemoteFile(address='127.0.0.1',
                                                  client='scp',
                                                  username=params.get('username'),
                                                  password=params.get('password'),
                                                  port='22',
                                                  remote_path='/proc/sys/net/ipv6/'
                                                              'conf/%s/accept_ra'
                                                              % host_iface))
                            process.run("echo 2 > /proc/sys/net/ipv6/conf/%s/accept_ra"
                                        % host_iface, shell=True)
                            process.run("cat /proc/sys/net/ipv6/conf/%s/accept_ra"
                                        % host_iface)
                    if net_state == "active" or net_state == "transient":
                        test_xml.start()
                    if net_state == "transient":
                        test_xml.del_defined()
                    list_result = virsh.net_list("--all --name").stdout.strip()
                    if net_name not in list_result:
                        test.fail("Can not find %s in net-list" % net_name)
                except xcepts.LibvirtXMLError as detail:
                    test.error("Failed to define a test network.\n"
                               "Detail: %s." % detail)
            else:
                # setting net status for following loops
                if net_state == "active":
                    test_xml.set_active(True)
                elif net_state == "inactive":
                    test_xml.set_active(False)

            # get hostfile before update
            if without_ip_dhcp == "yes" and net_state == "active":
                hostfile_before = get_hostfile()
                if hostfile_before != []:
                    test.fail("hostfile is not empty before update: %s"
                              % hostfile_before)
                logging.info("hostfile is empty before update")

            # Get dnsmasq pid before update
            check_dnsmasq = ((update_command == "add" or update_command == "delete") and
                             net_section == "ip-dhcp-range" and status_error == "no" and
                             net_state == "active" and options != "--config")
            if check_dnsmasq:
                cmd = "ps aux|grep dnsmasq|grep -v grep|grep %s|awk '{print $2}'" % net_name
                pid_list_bef = process.run(cmd, shell=True).stdout_text.strip().split('\n')

            if parent_index:
                options += " --parent-index %s" % parent_index

            # Check config before update
            if net_state == "active":
                dns_txt = dns_srv = dns_host_str = None
                try:
                    dns_txt = test_xml.get_section_string(xpath="/dns/txt")
                    dns_srv = test_xml.get_section_string(xpath="/dns/srv")
                    dns_host_str = test_xml.get_section_string(xpath="/dns/host")
                except xcepts.LibvirtXMLNotFoundError:
                    pass

                txt_record = "txt-record=%s,%s" % (dns_name, dns_value)
                srv_host = "srv-host=_%s._%s.%s,%s,%s,%s,%s" % (srv_service, srv_protocol,
                                                                srv_domain, srv_target, srv_port,
                                                                srv_priority, srv_weight)
                hostline = "%s.*%s.*%s" % (dns_hostip, dns_hostname, dns_hostname2)
                if dns_txt:
                    check_item(txt_record)
                if dns_srv:
                    check_item(srv_host)
                if dns_host_str:
                    check_host(hostline)

            # check libvirtd should not crash during the net-update
            ori_pid_libvirtd = process.getoutput("pidof libvirtd")
            # Do net-update operation
            cmd_result = virsh.net_update(net_name,
                                          update_command,
                                          net_section,
                                          xmlfile, options, debug=True)
            aft_pid_libvirtd = process.getoutput("pidof libvirtd")
            if not utils_libvirtd.libvirtd_is_running() or ori_pid_libvirtd != aft_pid_libvirtd:
                test.fail("Libvirtd crash after net-update operation")

            if cmd_result.exit_status:
                err = cmd_result.stderr.strip()
                if status_error == "yes":
                    # index-mismatch error info and judgement
                    index_err1 = "the address family of a host entry IP must match the" + \
                                 " address family of the dhcp element's parent"
                    index_err2 = "XML error: Invalid to specify MAC address.* in network" + \
                                 ".* IPv6 static host definition"
                    index_err3 = "mismatch of address family in range.* for network"
                    mismatch_expect = (error_type == "index-mismatch" and
                                       (re.search(index_err1, err) or
                                        re.search(index_err2, err) or
                                        re.search(index_err3, err)))
                    err_dic = {}
                    # multi-host error info
                    err_dic["multi-hosts"] = "dhcp is supported only for a single.*" + \
                                             " address on each network"
                    # range-mismatch error info
                    err_dic["range-mismatch"] = "couldn't locate a matching dhcp " + \
                                                "range entry in network "
                    # host-mismatch error info
                    err_dic["host-mismatch"] = "couldn't locate a matching dhcp " + \
                                               "host entry in network "
                    # dns-mismatch error info
                    err_dic["dns-mismatch"] = "couldn't locate a matching DNS TXT " + \
                                              "record in network "
                    # range-duplicate error info
                    err_dic["range-duplicate"] = "there is an existing dhcp range" + \
                                                 " entry in network.* that matches"
                    # host-duplicate error info
                    err_dic["host-duplicate"] = "there is an existing dhcp host" + \
                                                " entry in network.* that matches"
                    # out_of_range error info
                    err_dic["out-of-range"] = "range.* is not entirely within network"
                    # no end for range error
                    err_dic["range-no-end"] = "Missing 'end' attribute in dhcp " + \
                                              "range for network"
                    # no match item for host modify err
                    err_dic["no-match-item"] = "couldn't locate an existing dhcp" + \
                                               " host entry with.* in network"
                    # no host name and mac for modify err
                    err_dic["host-no-name-mac"] = "Static host definition in IPv4 network" + \
                                                  ".* must have mac or name attribute"
                    # no host ip for modify err
                    err_dic["host-no-ip"] = "Missing IP address in static host " + \
                                            "definition for network"
                    # wrong command name
                    err_dic["wrong-command-name"] = "unrecognized command name"
                    # wrong section name
                    err_dic["wrong-section-name"] = "unrecognized section name"
                    # delete with only id
                    err_dic["only-id"] = "At least one of name, mac, or ip attribute must be" + \
                                         " specified for static host definition in network"
                    # options exclusive
                    err_dic["opt-exclusive"] = "Options --current and.* are mutually exclusive"
                    # range_reverse error info
                    if ip_version == "ipv4":
                        err_dic["range-reverse"] = "range.* is reversed"
                    elif ip_version == "ipv6":
                        err_dic["range-reverse"] = "range.*start larger than end"
                    # --live with inactive net
                    err_dic["invalid-state"] = "network is not running"
                    err_dic["transient"] = "cannot change persistent config of a transient network"
                    err_dic["dns-disable"] = "Extra data in disabled network"
                    err_dic["modify"] = "cannot be modified, only added or deleted"
                    err_dic["not-support"] = "can't update.*section of network"
                    err_dic["unrecognized"] = "unrecognized section name"
                    err_dic["interface-duplicate"] = "there is an existing interface entry " + \
                                                     "in network.* that matches"
                    err_dic["XML error"] = "XML error: Missing required name attribute in portgroup"

                    if (error_type in list(err_dic.keys()) and
                            re.search(err_dic[error_type], err) or mismatch_expect):
                        logging.debug("Get expect error: %s", err)
                    else:
                        test.fail("Do not get expect err msg: %s, %s"
                                  % (error_type, err_dic))
                else:
                    test.fail("Failed to execute net-update command")
            elif status_error == "yes":
                test.fail("Expect fail, but succeed")

            # Get dnsmasq pid after update
            if check_dnsmasq:
                pid_list_aft = process.run(cmd, shell=True).stdout_text.strip().split('\n')
                for pid in pid_list_aft:
                    if pid in pid_list_bef:
                        test.fail("dnsmasq do not updated")

            # Check the actual xml
            cmd_result = virsh.net_dumpxml(net_name)
            actual_net_xml = cmd_result.stdout.strip()
            new_xml_obj = network_xml.NetworkXML.new_from_net_dumpxml(net_name)
            logging.info("After net-update, the actual net xml is %s",
                         actual_net_xml)

            if "ip-dhcp" in net_section:
                if ip_version == "ipv6":
                    new_xml_obj.del_element(element="/ip", index=0)
                if ip_version == "ipv4":
                    new_xml_obj.del_element(element="/ip", index=1)

            config_not_work = ("--config" in options and net_state == "active" and
                               "--live" not in options)
            if config_not_work:
                if update_command != "delete":
                    flag_list_abs = flag_list
                    flag_list = []
                else:
                    flag_list = flag_list_abs
                    flag_list_abs = []

            logging.info("The check list is %s, absent list is %s", flag_list, flag_list_abs)

            if (update_command == "delete" and status_error == "no" and
                    not config_not_work and loop_time == 1):
                try:
                    section_str = new_xml_obj.get_section_string(xpath=element)
                except xcepts.LibvirtXMLNotFoundError:
                    section_str = None
                    logging.info("Can not find section %s in xml after delete", element)
                if section_str is not None:
                    test.fail("The actual net xml is not expected,"
                              "element still exists")
            elif ("duplicate" not in error_type and error_type != "range-mismatch" and
                    error_type != "host-mismatch" and error_type != "not-support"):
                # check xml should exists
                for flag_string in flag_list:
                    logging.info("checking %s should in xml in positive test,"
                                 "and absent in negative test", flag_string)
                    if not re.search(flag_string, actual_net_xml):
                        if ((status_error == "no" and update_command != "delete") or
                                (update_command == "delete" and status_error == "yes")):
                            test.fail("The actual net xml failed to update,"
                                      "or expect delete fail but xml missing"
                                      ":%s" % flag_string)
                    else:
                        if ((status_error == "yes" and update_command != "delete") or
                                (status_error == "no" and update_command == "delete" and
                                 not config_not_work)):
                            test.fail("Expect test fail, but find xml %s"
                                      " actual, or expect delete succeed,"
                                      "but fail in fact" % flag_string)
                # check xml should not exists
                for flag_string_abs in flag_list_abs:
                    logging.info("checking %s should NOT in xml in positive test,"
                                 "and exist in negative test", flag_string_abs)
                    if re.search(flag_string_abs, actual_net_xml):
                        if status_error == "no":
                            test.fail("Expect absent in net xml, but exists"
                                      "in fact: %s" % flag_string_abs)
                    else:
                        if status_error == "yes":
                            test.fail("Should exists in net xml, but it "
                                      "disappeared: %s" % flag_string_abs)

                # Check if add-last, add-fist works well
                if (status_error == "no" and not config_not_work and
                        update_command in ["add-last", "add", "add-first"]):
                    if update_command == "add-first":
                        find_index = 0
                    else:
                        find_index = -1
                    section_str_aft = new_xml_obj.get_section_string(xpath=element,
                                                                     index=find_index)
                    logging.info("xpath is %s, find_index is %s, section_str_aft is %s", element, find_index, section_str_aft)
                    for flag_string in flag_list:
                        logging.info("flag_string is %s", flag_string)
                        if not re.search(flag_string, section_str_aft):
                            test.fail("Can not find %s in %s" %
                                      (flag_string, section_str_aft))
                    logging.info("%s %s in right place", update_command, section_str_aft)

            # Check the positive test result
            if status_error == "no":
                # Check the network conf file
                # live update
                if ("--live" in options or "--config" not in options) and net_state == "active":
                    if net_section == "ip-dhcp-range" and update_command == "add-first":
                        ip_range = "%s,%s" % (new_start_ip, new_end_ip)
                        if ip_version == "ipv6":
                            ip_range = ip_range + ",64"
                        check_item(ip_range)
                    if "dns" in net_section:
                        if update_command == "delete" and loop == 0:
                            if net_section == "dns-srv":
                                check_item_absent(srv_host)
                            if net_section == "dns-txt":
                                check_item_absent(txt_record)
                            if net_section == "dns-host":
                                check_host_absent(dns_host_str)
                        elif "add" in update_command:
                            if net_section == "dns-srv":
                                for sec in update_sec.split(","):
                                    srv_host = srv_host.replace(names["srv_"+sec],
                                                                names["new_srv_"+sec])
                                check_item(srv_host)
                            if net_section == "dns-txt":
                                for sec in update_sec.split(","):
                                    txt_record = txt_record.replace(names["dns_"+sec],
                                                                    names["new_dns_"+sec])
                                check_item(txt_record)
                            if net_section == "dns-host":
                                check_host(hostline)

                    # Check the hostfile
                    if (net_section == "ip-dhcp-host" and update_command != "modify" and
                            update_command != "delete"):
                        dic_hostfile = {}
                        for sec in ["ip", "mac", "name", "id"]:
                            if update_sec is not None and sec in update_sec.split(","):
                                dic_hostfile[sec] = names["new_dhcp_host_"+sec]+","
                            else:
                                dic_hostfile[sec] = names[ip_version+"_host_"+sec]+","

                            if sec == "ip" and ip_version == "ipv6":
                                dic_hostfile[sec] = "[" + dic_hostfile[sec].strip(",") + "]"

                            if without_sec is not None and sec in without_sec.split(","):
                                dic_hostfile[sec] = ""

                        if ip_version == "ipv4":
                            host_info = (dic_hostfile["mac"] + dic_hostfile["ip"] +
                                         dic_hostfile["name"])
                            if dic_hostfile["mac"] == "":
                                host_info = dic_hostfile["name"] + dic_hostfile["ip"]
                        if ip_version == "ipv6":
                            host_info = ("id:" + dic_hostfile["id"] + dic_hostfile["name"] +
                                         dic_hostfile["ip"])

                        hostfile = get_hostfile()
                        host_info_patten = host_info.strip(",") + "\n"
                        if host_info_patten in hostfile:
                            logging.info("host info %s is in hostfile %s", host_info, hostfile)
                        else:
                            test.fail("Can not find %s in host file: %s"
                                      % (host_info, hostfile))

                # Check the net in guest
                if use_in_guest == "yes" and loop == 0:
                    # Detach all interfaces of vm first
                    iface_index = 0
                    mac_list = vm_xml.VMXML.get_iface_dev(vm_name)
                    for mac in mac_list:
                        iface_dict = vm_xml.VMXML.get_iface_by_mac(vm_name, mac)
                        virsh.detach_interface(vm_name,
                                               "--type %s --mac %s --config"
                                               % (iface_dict.get('type'), mac))
                        vm.free_mac_address(iface_index)
                        iface_index += 1

                    # attach new interface to guest
                    for j in range(guest_iface_num):
                        if net_section == "ip-dhcp-host" and new_dhcp_host_mac:
                            mac = new_dhcp_host_mac
                        else:
                            mac = utils_net.generate_mac_address_simple()
                        ret = virsh.attach_interface(vm_name,
                                                     "--type %s --source %s --mac %s --config"
                                                     % (iface_type, net_name, mac))
                        if ret.exit_status:
                            test.fail("Fail to attach new interface to guest: %s" %
                                      ret.stderr.strip())

                    # The sleep here is to make sure the update make effect
                    time.sleep(2)

                    # Start guest and check ip/mac/hostname...
                    vm.start()
                    logging.debug("vm xml is %s", vm.get_xml())
                    session = vm.wait_for_serial_login(internal_timeout=60)
                    if "ip-dhcp" in net_section:
                        dhclient_cmd = "(if pgrep dhclient;" \
                                       "then pkill dhclient; sleep 3; fi) " \
                                       "&& dhclient -%s -lf /dev/stdout" % ip_version[-1]
                        leases = session.cmd_output(dhclient_cmd)
                        iface_ip = utils_net.get_guest_ip_addr(session, mac,
                                                               ip_version=ip_version,
                                                               timeout=10)
                    if net_section == "ip-dhcp-range":
                        if new_start_ip <= iface_ip <= new_end_ip:
                            logging.info("getting ip %s is in range [%s ~ %s]",
                                         iface_ip, new_start_ip, new_end_ip)
                        else:
                            test.fail("getting ip %s not in range [%s ~ %s]" %
                                      (iface_ip, new_start_ip, new_end_ip))
                    if net_section == "ip-dhcp-host":
                        if iface_ip == new_dhcp_host_ip:
                            logging.info("getting ip is same with set: %s", iface_ip)
                        else:
                            test.fail("getting ip %s is not same with setting %s"
                                      % (iface_ip, new_dhcp_host_ip))
                        hostname = session.cmd_output("hostname -s").strip('\n')
                        # option host-name "redhatipv4-2"
                        dhcp_hostname = "option host-name \"%s\"" % new_dhcp_host_name.split('.')[0]
                        if hostname == new_dhcp_host_name.split('.')[0] or dhcp_hostname in leases:
                            logging.info("getting hostname same with setting: %s", new_dhcp_host_name.split('.')[0])
                        else:
                            test.fail("getting hostname %s is not same with "
                                      "setting: %s" % (hostname, new_dhcp_host_name))

                    session.close()

                # Check network connection for macvtap
                if (use_in_guest == "yes" and net_section == "forward-interface" and
                        forward_mode == "bridge"):
                    xml_obj_use = network_xml.NetworkXML.new_from_net_dumpxml(net_name)
                    net_conn = int(xml_obj_use.connection)
                    iface_conn = xml_obj_use.get_interface_connection()
                    conn_count = 0
                    for k in iface_conn:
                        conn_count = conn_count + int(k)
                    logging.info("net_conn=%s, conn_count=%s, guest_iface_num=%s"
                                 % (net_conn, conn_count, guest_iface_num))
                    if (net_conn != conn_count or
                            (loop == 1 and guest_iface_num != net_conn)):
                        test.fail("Can not get expected connection num: "
                                  "net_conn = %s, iface_conn = %s"
                                  % (net_conn, conn_count))

                #Check --config option after net destroyed
                if (int(check_config_round) == loop or
                        (loop_time == 1 and "--current" in options and net_state == "active")):
                    test_xml.set_active(False)
                    logging.info("Checking xml after net destroyed")
                    cmd_result = virsh.net_dumpxml(net_name)
                    inactive_xml = cmd_result.stdout.strip()
                    logging.info("inactive_xml is %s", inactive_xml)
                    #Check the inactive xml
                    for check_str in flag_list:
                        if update_command != "delete":
                            if "--config" in options:
                                if not re.search(check_str, inactive_xml):
                                    test.fail("Can not find xml after net destroyed")
                            if "--current" in options:
                                if re.search(check_str, inactive_xml):
                                    test.fail("XML still exists after net destroyed")
                        else:
                            if "--config" in options:
                                if re.search(check_str, inactive_xml):
                                    test.fail("XML still exists after net destroyed")
                            if "--current" in options:
                                if not re.search(check_str, inactive_xml):
                                    test.fail("Can not find xml after net destroyed")

                    logging.info("Check for net inactive PASS")

    finally:
        if test_xml.get_active():
            test_xml.del_active()
        if test_xml.get_defined():
            test_xml.del_defined()

        if os.path.exists(xmlfile):
            os.remove(xmlfile)

        if use_in_guest == "yes":
            vm = env.get_vm(vm_name)
            if vm.is_alive():
                vm.destroy(gracefully=False)
            vmxml_backup.sync()
        for config_file in backup_files:
            config_file._reset_file()
예제 #20
0
def run(test, params, env):
    """
    Test numa tuning

    1) Positive testing
       1.1) get the current numa parameters for a running/shutoff guest
       1.2) set the current numa parameters for a running/shutoff guest
           1.2.1) set valid 'mode' parameters
           1.2.2) set valid 'nodeset' parameters
    2) Negative testing
       2.1) get numa parameters
           2.1.1) invalid options
           2.1.2) stop cgroup service
       2.2) set numa parameters
           2.2.1) invalid 'mode' parameters
           2.2.2) invalid 'nodeset' parameters
           2.2.3) change 'mode' for a running guest and 'mode' is not 'strict'
           2.2.4) change 'nodeset' for running guest with mode of 'interleave'
                  'interleave' or 'preferred' numa mode
           2.2.5) stop cgroup service
    """

    try:
        utils_misc.find_command("numactl")
    except ValueError:
        raise error.TestNAError("Command 'numactl' is missing. You must "
                                "install it.")

    # Run test case
    vm_name = params.get("vms")
    vm = env.get_vm(vm_name)
    original_vm_xml = libvirt_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    cg = utils_cgroup.CgconfigService()
    status_error = params.get("status_error", "no")
    libvirtd = params.get("libvirtd", "on")
    cgconfig = params.get("cgconfig", "on")
    start_vm = params.get("start_vm", "no")
    change_parameters = params.get("change_parameters", "no")

    # Make sure vm is down if start not requested
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # positive and negative testing #########

    cgstop = False
    try:
        if status_error == "no":
            if change_parameters == "no":
                get_numa_parameter(params, cgstop)
            else:
                set_numa_parameter(params, cgstop)
        if cgconfig == "off":
            # If running, then need to shutdown a running guest before
            # stopping cgconfig service and will start the guest after
            # restarting libvirtd service
            if cg.cgconfig_is_running():
                if vm.is_alive():
                    vm.destroy()
                cg.cgconfig_stop()
                cgstop = True

        # If we stopped cg, then refresh libvirtd service
        # to get latest cgconfig service change; otherwise,
        # if no cg change restart of libvirtd is pointless
        if cgstop and libvirtd == "restart":
            try:
                utils_libvirtd.libvirtd_restart()
            finally:
                # Not running is not a good thing, but it does happen
                # and it will affect other tests
                if not utils_libvirtd.libvirtd_is_running():
                    raise error.TestNAError("libvirt service is not running!")

        # Recover previous running guest
        if (cgconfig == "off" and libvirtd == "restart" and
                not vm.is_alive() and start_vm == "yes"):
            vm.start()
        if status_error == "yes":
            if change_parameters == "no":
                get_numa_parameter(params, cgstop)
            else:
                set_numa_parameter(params, cgstop)
    finally:
        # Restore guest
        original_vm_xml.sync()

        # If we stopped cg, then recover and refresh libvirtd to recognize
        if cgstop:
            cg.cgconfig_start()
            utils_libvirtd.libvirtd_restart()
예제 #21
0
def run_virsh_dump(test, params, env):
    """
    Test command: virsh dump.

    This command can dump the core of a domain to a file for analysis.
    1. Positive testing
        1.1 Dump domain with valid options.
        1.2 Avoid file system cache when dumping.
        1.3 Compress the dump images to valid/invalid formats.
    2. Negative testing
        2.1 Dump domain to a non-exist directory.
        2.2 Dump domain with invalid option.
        2.3 Dump a shut-off domain.
    """

    vm_name = params.get("main_vm", "vm1")
    vm = env.get_vm(params["main_vm"])
    options = params.get("dump_options")
    dump_file = params.get("dump_file", "vm.core")
    if os.path.dirname(dump_file) is "":
        dump_file = os.path.join(test.tmpdir, dump_file)
    dump_image_format = params.get("dump_image_format")
    start_vm = params.get("start_vm")
    status_error = params.get("status_error", "no")
    qemu_conf = "/etc/libvirt/qemu.conf"

    # prepare the vm state
    if vm.is_alive() and start_vm == "no":
        vm.destroy()

    if vm.is_dead() and start_vm == "yes":
        vm.start()

    def check_domstate(actual, options):
        """
        Check the domain status according to dump options.
        """

        if options.find('live') >= 0:
            domstate = "running"
            if options.find('crash') >= 0 or options.find('reset') >0:
                domstate = "running"
        elif options.find('crash') >=0:
            domstate = "shut off"
            if options.find('reset') >= 0:
                domstate = "running"
        elif options.find('reset') >= 0:
            domstate = "running"
        else:
            domstate = "running"

        if start_vm == "no":
            domstate = "shut off"

        logging.debug("Domain should %s after run dump %s", domstate, options)

        if domstate == actual:
            return True
        else:
            return False

    def check_dump_format(dump_image_format, dump_file):
        """
        Check the format of dumped file.

        If 'dump_image_format' is not specified or invalid in qemu.conf, then
        the file shoule be normal raw file, otherwise it shoud be compress to
        specified format, the supported compress format including: lzop, gzip,
        bzip2, and xz.
        """

        valid_format = ["lzop", "gzip", "bzip2", "xz"]
        if len(dump_image_format) == 0 or dump_image_format not in valid_format:
            logging.debug("No need check the dumped file format")
            return True
        else:
            file_cmd = "file %s" % dump_file
            (status, output) = commands.getstatusoutput(file_cmd)
            if status == 0:
                logging.debug("Run file %s output: %s", dump_file, output)
                actual_format = output.split(" ")[1]
                if actual_format == dump_image_format:
                    if dump_image_format in valid_format:
                        logging.info("Compress dumped file to %s successfully",
                                     dump_image_format)
                    return True
                else:
                    logging.error("Compress dumped file to %s fail",
                                  dump_image_format)
                    return False
            else:
                logging.error("Fail to check dumped file %s", dump_file)
                return False


    # Configure dump_image_format in /etc/libvirt/qemu.conf.
    if len(dump_image_format) != 0:
        conf_cmd = ("echo dump_image_format = \\\"%s\\\" >> %s" %
                    (dump_image_format, qemu_conf))
        if os.system(conf_cmd):
            logging.error("Config dump_image_format to %s fail",
                          dump_image_format)
        utils_libvirtd.libvirtd_restart()

    # Deal with bypass-cache option
    if options.find('bypass-cache') >= 0:
        thread.start_new_thread(check_bypass,(dump_file,))
        # Guarantee check_bypass function has run before dump
        time.sleep(5)

    # Run virsh command
    cmd_result = virsh.dump(vm_name, dump_file, options,
                            ignore_status=True, debug=True)
    status = cmd_result.exit_status

    # Check libvirtd status
    if utils_libvirtd.libvirtd_is_running():
        if check_domstate(vm.state(), options):
            if status_error == "yes":
                if status == 0:
                    raise error.TestFail("Expect fail, but run successfully")
            if status_error == "no":
                if status != 0:
                    raise error.TestFail("Expect succeed, but run fail")
                else:
                    if os.path.exists(dump_file):
                        if check_dump_format(dump_image_format, dump_file):
                            logging.info("Successfully dump domain to %s",
                                         dump_file)
                        else:
                            raise error.TestFail("The format of dumped file "
                                                 "is wrong.")
                    else:
                        raise error.TestFail("Fail to find domain dumped file.")

        else:
            raise error.TestFail("Domain status check fail.")
    else:
        raise error.TestFail("Libvirtd service is dead.")

    if os.path.isfile(dump_file):
        os.remove(dump_file)

    if len(dump_image_format) != 0:
        clean_qemu_conf = "sed -i '$d' %s " % qemu_conf
        if os.system(clean_qemu_conf):
            raise error.TestFail("Fail to recover %s", qemu_conf)