def check_bandwidth(params):
        """
        Check migration bandwidth

        :param params: the parameters used
        :raise: test.fail if migration bandwidth does not match expected values
        """
        exp_migrate_speed = eval(params.get('exp_migrate_speed', '{}'))
        migrate_postcopy_cmd = "yes" == params.get("migrate_postcopy_cmd",
                                                   "yes")
        if extra.count("bandwidth"):
            get_speed(exp_migrate_speed)
        if params.get("set_postcopy_in_precopy_phase"):
            virsh.migrate_setspeed(vm_name,
                                   params.get("set_postcopy_in_precopy_phase"),
                                   "--postcopy", **virsh_args)
            get_speed(exp_migrate_speed)

        params.update({
            'compare_to_value':
            exp_migrate_speed.get("precopy_speed", "8796093022207")
        })

        if exp_migrate_speed.get("precopy_speed", "0") == "8796093022207":
            params.update({'domjob_ignore_status': True})
        libvirt_domjobinfo.check_domjobinfo(vm, params)

        if migrate_postcopy_cmd:
            if not utils_misc.wait_for(
                    lambda: not virsh.migrate_postcopy(vm_name, **virsh_args).
                    exit_status, 5):
                test.fail("Failed to set migration postcopy.")

            if params.get("set_postcopy_in_postcopy_phase"):
                virsh.migrate_setspeed(
                    vm_name, params.get("set_postcopy_in_postcopy_phase"),
                    "--postcopy", **virsh_args)
                get_speed(exp_migrate_speed)
            time.sleep(5)

            if exp_migrate_speed.get("postcopy_speed"):
                params.update(
                    {'compare_to_value': exp_migrate_speed["postcopy_speed"]})
                params.update({'domjob_ignore_status': False})
            libvirt_domjobinfo.check_domjobinfo(vm, params)
    def get_subprocess(action, vm_name, file, remote_uri=None):
        """
        Execute background virsh command, return subprocess w/o waiting for exit()

        :param cmd : virsh command.
        :param guest_name : VM's name
        :param file_source : virsh command's file option.
        """
        if action == "managedsave":
            file = ""
        elif action == "migrate":
            # Slow down migration for domjobabort
            virsh.migrate_setspeed(vm_name, "1")
            file = remote_uri
        command = "virsh %s %s %s --unsafe" % (action, vm_name, file)
        logging.debug("Action: %s", command)
        p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        return p
Exemple #3
0
        def _set_speed(extra_option=''):
            """
            Inner function to set migration speed

            :param extra_option: str, it might include '--postcopy' or not
            """
            virsh_args = {"ignore_status": False}
            old_speed = virsh.migrate_getspeed(vm_name,
                                               extra=extra_option,
                                               **virsh_args)
            logging.debug("Current %s migration speed is %s "
                          "MiB/s\n", extra_option,
                          old_speed.stdout_text.strip())
            logging.debug("Set %s migration speed to %d "
                          "MiB/s\n", extra_option, to_speed)
            virsh.migrate_setspeed(vm_name,
                                   to_speed,
                                   extra=extra_option,
                                   **virsh_args)
    def get_subprocess(action, vm_name, file, remote_uri=None):
        """
        Execute background virsh command, return subprocess w/o waiting for exit()

        :param cmd : virsh command.
        :param guest_name : VM's name
        :param file_source : virsh command's file option.
        """
        if action == "managedsave":
            file = ""
        elif action == "migrate":
            # Slow down migration for domjobabort
            virsh.migrate_setspeed(vm_name, "1")
            file = remote_uri
        command = "virsh %s %s %s" % (action, vm_name, file)
        logging.debug("Action: %s", command)
        p = subprocess.Popen(command,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        return p
Exemple #5
0
    def control_migrate_speed(to_speed=1, opts=""):
        """
        Control migration duration

        :param to_speed: the speed value in Mbps to be set for migration
        :return int: the new migration speed after setting
        """
        virsh_args.update({"ignore_status": False})
        old_speed = virsh.migrate_getspeed(vm_name, extra=opts, **virsh_args)
        logging.debug("Current migration speed is %s MiB/s\n", old_speed.stdout.strip())
        logging.debug("Set migration speed to %d MiB/s\n", to_speed)
        cmd_result = virsh.migrate_setspeed(vm_name, to_speed, extra=opts, **virsh_args)
        actual_speed = virsh.migrate_getspeed(vm_name, extra=opts, **virsh_args)
        logging.debug("New migration speed is %s MiB/s\n", actual_speed.stdout.strip())
        return int(actual_speed.stdout.strip())
    def control_migrate_speed(to_speed=1):
        """
        Control migration duration

        :param to_speed: the speed value in Mbps to be set for migration
        :return int: the new migration speed after setting
        """
        virsh_args.update({"ignore_status": False})
        old_speed = virsh.migrate_getspeed(vm_name, **virsh_args)
        logging.debug("Current migration speed is %s MiB/s\n", old_speed.stdout.strip())
        logging.debug("Set migration speed to %d MiB/s\n", to_speed)
        cmd_result = virsh.migrate_setspeed(vm_name, to_speed, "", **virsh_args)
        actual_speed = virsh.migrate_getspeed(vm_name, **virsh_args)
        logging.debug("New migration speed is %s MiB/s\n", actual_speed.stdout.strip())
        return int(actual_speed.stdout.strip())
    def set_get_speed(vm_name,
                      expected_value,
                      status_error=False,
                      options_extra="",
                      **virsh_dargs):
        """Set speed and check its result"""
        result = virsh.migrate_setspeed(vm_name, expected_value, options_extra,
                                        **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                # Without code for bz1083483 applied, this will succeed
                # when it shouldn't be succeeding.
                if bz1083483 and not libvirt_version.version_compare(1, 2, 4):
                    raise error.TestNAError("bz1083483 should result in fail")
                else:
                    raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s" %
                     (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")
    def set_get_speed(vm_name, expected_value, status_error=False,
                      options_extra="", **virsh_dargs):
        """Set speed and check its result"""
        result = virsh.migrate_setspeed(vm_name, expected_value,
                                        options_extra, **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                # Without code for bz1083483 applied, this will succeed
                # when it shouldn't be succeeding.
                if bz1083483 and not libvirt_version.version_compare(1, 2, 4):
                    raise error.TestNAError("bz1083483 should result in fail")
                else:
                    raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s"
                     % (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")
def run(test, params, env):
    """
    Test command: virsh domjobabort.

    The command can abort the currently running domain job.
    1.Prepare test environment,destroy or suspend a VM.
    2.Do action to get a subprocess(dump, save, managedsave).
    3.Perform virsh domjobabort operation to abort VM's job.
    4.Recover the VM's status and wait for the subprocess over.
    5.Confirm the test result.
    """

    vm_name = params.get("main_vm", "vm1")
    vm = env.get_vm(vm_name)
    start_vm = params.get("start_vm")
    pre_vm_state = params.get("pre_vm_state", "start")
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # Instead of "paused_after_start_vm", use "pre_vm_state".
    # After start the VM, wait for some time to make sure the job
    # can be created on this domain.
    if start_vm == "yes":
        vm.wait_for_login()
        if params.get("pre_vm_state") == "suspend":
            vm.pause()

    domid = vm.get_id()
    domuuid = vm.get_uuid()
    original_speed = virsh.migrate_getspeed(vm_name).stdout.strip()

    def get_subprocess(action, vm_name, file, remote_uri=None):
        """
        Execute background virsh command, return subprocess w/o waiting for exit()

        :param cmd : virsh command.
        :param guest_name : VM's name
        :param file_source : virsh command's file option.
        """
        if action == "managedsave":
            file = ""
        elif action == "migrate":
            # Slow down migration for domjobabort
            virsh.migrate_setspeed(vm_name, "1")
            file = remote_uri
        command = "virsh %s %s %s --unsafe" % (action, vm_name, file)
        logging.debug("Action: %s", command)
        p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        return p

    action = params.get("jobabort_action", "dump")
    status_error = params.get("status_error", "no")
    job = params.get("jobabort_job", "yes")
    tmp_file = os.path.join(test.tmpdir, "domjobabort.tmp")
    tmp_pipe = os.path.join(test.tmpdir, "domjobabort.fifo")
    vm_ref = params.get("jobabort_vm_ref")
    remote_uri = params.get("jobabort_remote_uri")
    remote_host = params.get("migrate_dest_host")
    remote_user = params.get("migrate_dest_user", "root")
    remote_pwd = params.get("migrate_dest_pwd")
    saved_data = None

    if action == "managedsave":
        tmp_pipe = '/var/lib/libvirt/qemu/save/%s.save' % vm.name

    if action == "restore":
        virsh.save(vm_name, tmp_file, ignore_status=True)

    if action == "migrate":
        if remote_host.count("EXAMPLE"):
            raise error.TestNAError("Remote host should be configured "
                                    "for migrate.")
        else:
            # Config ssh autologin for remote host
            ssh_key.setup_ssh_key(remote_host, remote_user,
                                  remote_pwd, port=22)

    if vm_ref == "id":
        vm_ref = domid
    elif vm_ref == "hex_id":
        vm_ref = hex(int(domid))
    elif vm_ref == "uuid":
        vm_ref = domuuid
    elif vm_ref.find("invalid") != -1:
        vm_ref = params.get(vm_ref)
    elif vm_ref == "name":
        vm_ref = vm_name

    # Get the subprocess of VM.
    # The command's effect is to abort the currently running domain job.
    # So before do "domjobabort" action, we must create a job on the domain.
    process = None
    if job == "yes" and start_vm == "yes" and status_error == "no":
        if os.path.exists(tmp_pipe):
            os.unlink(tmp_pipe)
        os.mkfifo(tmp_pipe)

        process = get_subprocess(action, vm_name, tmp_pipe, remote_uri)

        saved_data = None
        if action == "restore":
            saved_data = file(tmp_file, 'r').read(10 * 1024 * 1024)
            f = open(tmp_pipe, 'w')
            f.write(saved_data[:1024 * 1024])
        elif action == "migrate":
            f = None
        else:
            f = open(tmp_pipe, 'r')
            dummy = f.read(1024 * 1024)

    # Give enough time for starting job
    t = 0
    while t < 5:
        jobtype = vm.get_job_type()
        if "None" == jobtype:
            t += 1
            time.sleep(1)
            continue
        elif jobtype is False:
            logging.error("Get job type failed.")
            break
        else:
            logging.debug("Job started: %s", jobtype)
            break
    ret = virsh.domjobabort(vm_ref, ignore_status=True, debug=True)
    status = ret.exit_status

    if process and f:
        if saved_data:
            f.write(saved_data[1024 * 1024:])
        else:
            dummy = f.read()
        f.close()

        if os.path.exists(tmp_pipe):
            os.unlink(tmp_pipe)
        if os.path.exists(tmp_file):
            os.unlink(tmp_file)

    # Recover the environment.
    if pre_vm_state == "suspend":
        vm.resume()
    if process:
        if process.poll():
            try:
                process.kill()
            except OSError:
                pass

    if action == "migrate":
        # Recover migration speed
        virsh.migrate_setspeed(vm_name, original_speed)
        utlv.MigrationTest().cleanup_dest_vm(vm, None, remote_uri)

    # check status_error
    if status_error == "yes":
        if status == 0:
            raise error.TestFail("Run successfully with wrong command!")
    elif status_error == "no":
        if status != 0:
            raise error.TestFail("Run failed with right command")
def run(test, params, env):
    """
    Test command: virsh domjobabort.

    The command can abort the currently running domain job.
    1.Prepare test environment,destroy or suspend a VM.
    2.Do action to get a subprocess(dump, save, managedsave).
    3.Perform virsh domjobabort operation to abort VM's job.
    4.Recover the VM's status and wait for the subprocess over.
    5.Confirm the test result.
    """

    vm_name = params.get("main_vm", "vm1")
    vm = env.get_vm(vm_name)
    start_vm = params.get("start_vm")
    pre_vm_state = params.get("pre_vm_state", "start")
    if start_vm == "no" and vm.is_alive():
        vm.destroy()

    # Instead of "paused_after_start_vm", use "pre_vm_state".
    # After start the VM, wait for some time to make sure the job
    # can be created on this domain.
    if start_vm == "yes":
        vm.wait_for_login()
        if params.get("pre_vm_state") == "suspend":
            vm.pause()

    domid = vm.get_id()
    domuuid = vm.get_uuid()
    original_speed = virsh.migrate_getspeed(vm_name).stdout.strip()

    def get_subprocess(action, vm_name, file, remote_uri=None):
        """
        Execute background virsh command, return subprocess w/o waiting for exit()

        :param cmd : virsh command.
        :param guest_name : VM's name
        :param file_source : virsh command's file option.
        """
        args = ""
        if action == "managedsave":
            file = ""
        elif action == "migrate":
            # Slow down migration for domjobabort
            virsh.migrate_setspeed(vm_name, "1")
            file = remote_uri
            args = "--unsafe"
        command = "virsh %s %s %s %s" % (action, vm_name, file, args)
        logging.debug("Action: %s", command)
        p = subprocess.Popen(command,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        return p

    action = params.get("jobabort_action", "dump")
    dump_opt = params.get("dump_opt", None)
    status_error = params.get("status_error", "no")
    job = params.get("jobabort_job", "yes")
    tmp_file = os.path.join(data_dir.get_tmp_dir(), "domjobabort.tmp")
    tmp_pipe = os.path.join(data_dir.get_tmp_dir(), "domjobabort.fifo")
    vm_ref = params.get("jobabort_vm_ref")
    remote_uri = params.get("jobabort_remote_uri")
    remote_host = params.get("migrate_dest_host")
    remote_user = params.get("migrate_dest_user", "root")
    remote_pwd = params.get("migrate_dest_pwd")
    saved_data = None

    # Build job action
    if dump_opt:
        action = "dump --crash"

    if action == "managedsave":
        tmp_pipe = '/var/lib/libvirt/qemu/save/%s.save' % vm.name

    if action == "restore":
        virsh.save(vm_name, tmp_file, ignore_status=True)

    if action == "migrate":
        if remote_host.count("EXAMPLE"):
            test.cancel("Remote host should be configured " "for migrate.")
        else:
            # Config ssh autologin for remote host
            ssh_key.setup_ssh_key(remote_host,
                                  remote_user,
                                  remote_pwd,
                                  port=22)

    if vm_ref == "id":
        vm_ref = domid
    elif vm_ref == "hex_id":
        vm_ref = hex(int(domid))
    elif vm_ref == "uuid":
        vm_ref = domuuid
    elif vm_ref.find("invalid") != -1:
        vm_ref = params.get(vm_ref)
    elif vm_ref == "name":
        vm_ref = vm_name

    # Get the subprocess of VM.
    # The command's effect is to abort the currently running domain job.
    # So before do "domjobabort" action, we must create a job on the domain.
    process = None
    if job == "yes" and start_vm == "yes" and status_error == "no":
        if os.path.exists(tmp_pipe):
            os.unlink(tmp_pipe)
        os.mkfifo(tmp_pipe)

        process = get_subprocess(action, vm_name, tmp_pipe, remote_uri)

        saved_data = None
        if action == "restore":
            with open(tmp_file, 'r') as tmp_f:
                saved_data = tmp_f.read(10 * 1024 * 1024)
            f = open(tmp_pipe, 'w')
            f.write(saved_data[:1024 * 1024])
        elif action == "migrate":
            f = None
        else:
            f = open(tmp_pipe, 'rb')
            dummy = f.read(1024 * 1024).decode(locale.getpreferredencoding(),
                                               'ignore')

    # Give enough time for starting job
    t = 0
    while t < 5:
        jobtype = vm.get_job_type()
        if "None" == jobtype:
            t += 1
            time.sleep(1)
            continue
        elif jobtype is False:
            logging.error("Get job type failed.")
            break
        else:
            logging.debug("Job started: %s", jobtype)
            break
    ret = virsh.domjobabort(vm_ref, ignore_status=True, debug=True)
    status = ret.exit_status

    if process and f:
        if saved_data:
            f.write(saved_data[1024 * 1024:])
        else:
            dummy = f.read()
        f.close()

        try:
            os.unlink(tmp_pipe)
        except OSError as detail:
            logging.info("Can't remove %s: %s", tmp_pipe, detail)
        try:
            os.unlink(tmp_file)
        except OSError as detail:
            logging.info("Cant' remove %s: %s", tmp_file, detail)

    # Recover the environment.
    if pre_vm_state == "suspend":
        vm.resume()
    if process:
        if process.poll():
            try:
                process.kill()
            except OSError:
                pass

    if action == "migrate":
        # Recover migration speed
        virsh.migrate_setspeed(vm_name, original_speed)
        utlv.MigrationTest().cleanup_dest_vm(vm, None, remote_uri)

    # check status_error
    if status_error == "yes":
        if status == 0:
            test.fail("Run successfully with wrong command!")
    elif status_error == "no":
        if status != 0:
            test.fail("Run failed with right command")
def run(test, params, env):
    """
    Test command: virsh migrate-setspeed <domain> <bandwidth>
                  virsh migrate-getspeed <domain>.

    1) Prepare test environment.
    2) Try to set the maximum migration bandwidth (in MiB/s)
       for a domain through valid and invalid command.
    3) Recover test environment.
    4) Check result.
    """

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_name = params.get("main_vm")
    bandwidth = params.get("bandwidth", "default")
    options_extra = params.get("options_extra", "")
    status_error = "yes" == params.get("status_error", "yes")
    virsh_dargs = {'debug': True}
    # Checking uris for migration
    twice_migration = "yes" == params.get("twice_migration", "no")
    if twice_migration:
        src_uri = params.get("migrate_src_uri",
                             "qemu+ssh://EXAMPLE/system")
        dest_uri = params.get("migrate_dest_uri",
                              "qemu+ssh://EXAMPLE/system")
        if src_uri.count('///') or src_uri.count('EXAMPLE'):
            raise error.TestNAError("The src_uri '%s' is invalid"
                                    % src_uri)
        if dest_uri.count('///') or dest_uri.count('EXAMPLE'):
            raise error.TestNAError("The dest_uri '%s' is invalid"
                                    % dest_uri)

    bz1083483 = False
    if bandwidth == "zero":
        expected_value = 0
    elif bandwidth == "one":
        expected_value = 1
    elif bandwidth == "negative":
        expected_value = -1
        bz1083483 = True
    elif bandwidth == "default":
        expected_value = DEFAULT
    elif bandwidth == "UINT32_MAX":
        expected_value = UINT32_MiB
    elif bandwidth == "INT64_MAX":
        expected_value = INT64_MiB
    elif bandwidth == "UINT64_MAX":
        expected_value = UINT64_MiB
        bz1083483 = True
    elif bandwidth == "INVALID_VALUE":
        expected_value = INT64_MiB + 1
        bz1083483 = True
    else:
        expected_value = bandwidth

    orig_value = virsh.migrate_getspeed(vm_name).stdout.strip()

    def set_get_speed(vm_name, expected_value, status_error=False,
                      options_extra="", **virsh_dargs):
        """Set speed and check its result"""
        result = virsh.migrate_setspeed(vm_name, expected_value,
                                        options_extra, **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                # Without code for bz1083483 applied, this will succeed
                # when it shouldn't be succeeding.
                if bz1083483 and not libvirt_version.version_compare(1, 2, 4):
                    raise error.TestNAError("bz1083483 should result in fail")
                else:
                    raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s"
                     % (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")

    def verify_migration_speed(test, params, env):
        """
        Check if migration speed is effective with twice migration.
        """
        vms = env.get_all_vms()
        src_uri = params.get("migrate_src_uri", "qemu+ssh://EXAMPLE/system")
        dest_uri = params.get("migrate_dest_uri", "qemu+ssh://EXAMPLE/system")

        if src_uri.count('///') or src_uri.count('EXAMPLE'):
            raise error.TestNAError("The src_uri '%s' is invalid", src_uri)

        if dest_uri.count('///') or dest_uri.count('EXAMPLE'):
            raise error.TestNAError("The dest_uri '%s' is invalid", dest_uri)

        remote_host = params.get("migrate_dest_host")
        username = params.get("migrate_dest_user", "root")
        password = params.get("migrate_dest_pwd")
        # Config ssh autologin for remote host
        ssh_key.setup_ssh_key(remote_host, username, password, port=22)

        # Check migrated vms' state
        for vm in vms:
            if vm.is_dead():
                vm.start()

        load_vm_names = params.get("load_vms").split()
        # vms for load
        load_vms = []
        for vm_name in load_vm_names:
            load_vms.append(libvirt_vm.VM(vm_name, params, test.bindir,
                                          env.get("address_cache")))

        bandwidth = int(params.get("bandwidth", "4"))
        stress_type = params.get("stress_type", "load_vms_booting")
        migration_type = params.get("migration_type", "orderly")
        thread_timeout = int(params.get("thread_timeout", "60"))
        delta = float(params.get("allowed_delta", "0.1"))
        virsh_migrate_timeout = int(params.get("virsh_migrate_timeout", 60))
        # virsh migrate options
        virsh_migrate_options = "--live --timeout %s", virsh_migrate_timeout
        # Migrate vms to remote host
        mig_first = utlv.MigrationTest()
        virsh_dargs = {"debug": True}
        for vm in vms:
            set_get_speed(vm.name, bandwidth, virsh_dargs=virsh_dargs)
            vm.wait_for_login()
        utils_test.load_stress(stress_type, vms, params)
        mig_first.do_migration(vms, src_uri, dest_uri, migration_type,
                               options=virsh_migrate_options, thread_timeout=thread_timeout)
        for vm in vms:
            mig_first.cleanup_dest_vm(vm, None, dest_uri)
            # Keep it clean for second migration
            if vm.is_alive():
                vm.destroy()

        # Migrate vms again with new bandwidth
        second_bandwidth = params.get("second_bandwidth", "times")
        if second_bandwidth == "half":
            second_bandwidth = bandwidth / 2
            speed_times = 2
        elif second_bandwidth == "times":
            second_bandwidth = bandwidth * 2
            speed_times = 0.5
        elif second_bandwidth == "same":
            second_bandwidth = bandwidth
            speed_times = 1

        # Migrate again
        for vm in vms:
            if vm.is_dead():
                vm.start()
            vm.wait_for_login()
            set_get_speed(vm.name, second_bandwidth, virsh_dargs=virsh_dargs)
        utils_test.load_stress(stress_type, vms, params)
        mig_second = utlv.MigrationTest()
        mig_second.do_migration(vms, src_uri, dest_uri, migration_type,
                                options="--live", thread_timeout=thread_timeout)
        for vm in vms:
            mig_second.cleanup_dest_vm(vm, None, dest_uri)

        fail_info = []
        # Check whether migration failed
        if len(fail_info):
            raise error.TestFail(fail_info)

        for vm in vms:
            first_time = mig_first.mig_time[vm.name]
            second_time = mig_second.mig_time[vm.name]
            logging.debug("Migration time for %s:\n"
                          "Time with Bandwidth '%s' first: %s\n"
                          "Time with Bandwidth '%s' second: %s", vm.name,
                          bandwidth, first_time, second_bandwidth, second_time)
            shift = float(abs(first_time * speed_times - second_time)) / float(second_time)
            logging.debug("Shift:%s", shift)
            if delta < shift:
                fail_info.append("Spent time for migrating %s is intolerable." % vm.name)

        # Check again for speed result
        if len(fail_info):
            raise error.TestFail(fail_info)

    # Run test case
    try:
        set_get_speed(vm_name, expected_value, status_error,
                      options_extra, **virsh_dargs)
        if twice_migration:
            verify_migration_speed(test, params, env)
        else:
            set_get_speed(vm_name, expected_value, status_error,
                          options_extra, **virsh_dargs)
    finally:
        #restore bandwidth to default
        virsh.migrate_setspeed(vm_name, orig_value)
        if twice_migration:
            for vm in env.get_all_vms():
                utlv.MigrationTest().cleanup_dest_vm(vm, src_uri, dest_uri)
                if vm.is_alive():
                    vm.destroy(gracefully=False)
Exemple #12
0
        # Case for option '--timeout --timeout-suspend'
        # 1. Start the guest
        # 2. Set migration speed to a small value. Ensure the migration
        #    duration is much larger than the timeout value
        # 3. Start the migration
        # 4. When the eclipse time reaches the timeout value, check the guest
        #    state to be paused on both source host and target host
        # 5. Wait for the migration done. Check the guest state to be shutoff
        #    on source host and running on target host
        if extra.count("--timeout-suspend"):
            asynch_migration = True
            speed = int(params.get("migrate_speed", 1))
            timeout = int(params.get("timeout_before_suspend", 5))
            logging.debug("Set migration speed to %sM", speed)
            virsh.migrate_setspeed(vm_name, speed, debug=True)
            migration_test = libvirt.MigrationTest()
            migrate_options = "%s %s" % (options, extra)
            vms = [vm]
            params["vm_migration"] = vm
            migration_test.do_migration(vms, None, dest_uri, 'orderly',
                                        migrate_options, thread_timeout=900,
                                        ignore_status=True,
                                        func=check_migration_timeout_suspend,
                                        func_params=params)
            ret_migrate = migration_test.RET_MIGRATION
        if postcopy_cmd != "":
            asynch_migration = True
            vms = []
            vms.append(vm)
            obj_migration = libvirt.MigrationTest()
def run(test, params, env):
    """
    Test migration with specified max bandwidth
    1) Set both precopy and postcopy bandwidth by virsh migrate parameter
    2) Set bandwidth before migration starts by migrate parameter --postcopy-bandwidth
    3) Set bandwidth when migration is in post-copy phase
    4) Set bandwidth when migration is in pre-copy phase
    5) Set bandwidth when guest is running and before migration starts
    6) Set bandwidth before migration starts by migrate parameter --bandwidth
    7) Set bandwidth when guest is running and before migration starts
    8) Set bandwidth when guest is shutoff
    9) Do live migration with default max bandwidth

    :param test: test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def get_speed(exp_migrate_speed):
        """
        Get migration speed and compare with value in exp_migrate_speed

        :params exp_migrate_speed: the dict of expected migration speed
        :raise: test.fail if speed does not match
        """
        if exp_migrate_speed.get("precopy_speed"):
            output = virsh.migrate_getspeed(vm_name,
                                            **virsh_args).stdout_text.strip()
            if exp_migrate_speed['precopy_speed'] != output:
                virsh.migrate_getspeed(vm_name,
                                       extra="--postcopy",
                                       **virsh_args)
                test.fail("Migration speed is expected to be '%s MiB/s', but "
                          "'%s MiB/s' found!" %
                          (exp_migrate_speed['precopy_speed'], output))
        if exp_migrate_speed.get("postcopy_speed"):
            output = virsh.migrate_getspeed(vm_name,
                                            extra="--postcopy",
                                            **virsh_args).stdout_text.strip()
            if exp_migrate_speed['postcopy_speed'] != output:
                test.fail("Prostcopy migration speed is expected to be '%s "
                          "MiB/s', but '%s MiB/s' found!" %
                          (exp_migrate_speed['postcopy_speed'], output))

    def check_bandwidth(params):
        """
        Check migration bandwidth

        :param params: the parameters used
        :raise: test.fail if migration bandwidth does not match expected values
        """
        exp_migrate_speed = eval(params.get('exp_migrate_speed', '{}'))
        migrate_postcopy_cmd = "yes" == params.get("migrate_postcopy_cmd",
                                                   "yes")
        if extra.count("bandwidth"):
            get_speed(exp_migrate_speed)
        if params.get("set_postcopy_in_precopy_phase"):
            virsh.migrate_setspeed(vm_name,
                                   params.get("set_postcopy_in_precopy_phase"),
                                   "--postcopy", **virsh_args)
            get_speed(exp_migrate_speed)

        params.update({
            'compare_to_value':
            exp_migrate_speed.get("precopy_speed", "8796093022207")
        })

        if exp_migrate_speed.get("precopy_speed", "0") == "8796093022207":
            params.update({'domjob_ignore_status': True})
        libvirt_domjobinfo.check_domjobinfo(vm, params)

        if migrate_postcopy_cmd:
            if not utils_misc.wait_for(
                    lambda: not virsh.migrate_postcopy(vm_name, **virsh_args).
                    exit_status, 5):
                test.fail("Failed to set migration postcopy.")

            if params.get("set_postcopy_in_postcopy_phase"):
                virsh.migrate_setspeed(
                    vm_name, params.get("set_postcopy_in_postcopy_phase"),
                    "--postcopy", **virsh_args)
                get_speed(exp_migrate_speed)
            time.sleep(5)

            if exp_migrate_speed.get("postcopy_speed"):
                params.update(
                    {'compare_to_value': exp_migrate_speed["postcopy_speed"]})
                params.update({'domjob_ignore_status': False})
            libvirt_domjobinfo.check_domjobinfo(vm, params)

    migration_test = migration.MigrationTest()
    migration_test.check_parameters(params)

    # Params for NFS shared storage
    shared_storage = params.get("migrate_shared_storage", "")
    if shared_storage == "":
        default_guest_asset = defaults.get_default_guest_os_info()['asset']
        default_guest_asset = "%s.qcow2" % default_guest_asset
        shared_storage = os.path.join(params.get("nfs_mount_dir"),
                                      default_guest_asset)
        logging.debug("shared_storage:%s", shared_storage)

    # Params to update disk using shared storage
    params["disk_type"] = "file"
    params["disk_source_protocol"] = "netfs"
    params["mnt_path_name"] = params.get("nfs_mount_dir")

    # Local variables
    server_ip = params.get("server_ip")
    server_user = params.get("server_user", "root")
    server_pwd = params.get("server_pwd")
    virsh_args = {"debug": True}
    virsh_options = params.get("virsh_options", "")
    extra = params.get("virsh_migrate_extra")
    options = params.get("virsh_migrate_options", "--live --verbose")
    jobinfo_item = params.get("jobinfo_item", 'Memory bandwidth:')
    set_postcopy_speed_before_mig = params.get("set_postcopy_speed_before_mig")
    set_precopy_speed_before_mig = params.get("set_precopy_speed_before_mig")
    set_precopy_speed_before_vm_start = params.get(
        "set_precopy_speed_before_vm_start")
    stress_package = params.get("stress_package")
    exp_migrate_speed = eval(params.get('exp_migrate_speed', '{}'))
    log_file = params.get("log_outputs",
                          "/var/log/libvirt/libvirt_daemons.log")
    check_str_local_log = params.get("check_str_local_log", "")
    libvirtd_conf_dict = eval(params.get("libvirtd_conf_dict", '{}'))
    action_during_mig = check_bandwidth
    params.update({"action_during_mig_params_exists": "yes"})
    extra_args = migration_test.update_virsh_migrate_extra_args(params)

    libvirtd_conf = None
    mig_result = None
    remove_dict = {}
    src_libvirt_file = None

    if not libvirt_version.version_compare(6, 0, 0):
        test.cancel("This libvirt version doesn't support "
                    "postcopy migration bandwidth function.")

    # params for migration connection
    params["virsh_migrate_desturi"] = libvirt_vm.complete_uri(
        params.get("migrate_dest_host"))
    dest_uri = params.get("virsh_migrate_desturi")

    vm_name = params.get("migrate_main_vm")
    vm = env.get_vm(vm_name)
    vm.verify_alive()

    postcopy_options = params.get("postcopy_options")
    if postcopy_options:
        extra = "%s %s" % (extra, postcopy_options)

    # For safety reasons, we'd better back up  xmlfile.
    new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    orig_config_xml = new_xml.copy()

    try:
        # Change the disk of the vm
        libvirt.set_vm_disk(vm, params)

        # Update libvirtd configuration
        if libvirtd_conf_dict:
            if os.path.exists(log_file):
                logging.debug("Delete local libvirt log file '%s'", log_file)
                os.remove(log_file)
            logging.debug("Update libvirtd configuration file")
            conf_type = "libvirtd"
            if utils_split_daemons.is_modular_daemon():
                conf_type = "virtqemud"
            libvirtd_conf = libvirt.customize_libvirt_config(
                libvirtd_conf_dict,
                conf_type,
            )

        if set_precopy_speed_before_vm_start:
            if vm.is_alive():
                vm.destroy()
            virsh.migrate_setspeed(vm_name, set_precopy_speed_before_vm_start,
                                   **virsh_args)

        if not vm.is_alive():
            vm.start()

        logging.debug("Guest xml after starting:\n%s",
                      vm_xml.VMXML.new_from_dumpxml(vm_name))

        # Check local guest network connection before migration
        vm.wait_for_login(restart_network=True).close()
        migration_test.ping_vm(vm, params)

        remove_dict = {"do_search": '{"%s": "ssh:/"}' % dest_uri}
        src_libvirt_file = libvirt_config.remove_key_for_modular_daemon(
            remove_dict)

        if any([set_precopy_speed_before_mig, set_postcopy_speed_before_mig]):
            if set_precopy_speed_before_mig:
                virsh.migrate_setspeed(vm_name, set_precopy_speed_before_mig,
                                       **virsh_args)

            if set_postcopy_speed_before_mig:
                virsh.migrate_setspeed(vm_name, set_postcopy_speed_before_mig,
                                       "--postcopy", **virsh_args)
            get_speed(exp_migrate_speed)

        if stress_package:
            migration_test.run_stress_in_vm(vm, params)

        # Execute migration process
        vms = [vm]

        migration_test.do_migration(vms,
                                    None,
                                    dest_uri,
                                    'orderly',
                                    options,
                                    thread_timeout=900,
                                    ignore_status=True,
                                    virsh_opt=virsh_options,
                                    func=action_during_mig,
                                    extra_opts=extra,
                                    **extra_args)

        if int(migration_test.ret.exit_status) == 0:
            migration_test.ping_vm(vm, params, uri=dest_uri)

        if check_str_local_log:
            libvirt.check_logfile(check_str_local_log, log_file)

    finally:
        logging.debug("Recover test environment")
        # Clean VM on destination and source
        migration_test.cleanup_vm(vm, dest_uri)

        logging.info("Recover VM XML configuration")
        orig_config_xml.sync()

        if libvirtd_conf:
            logging.debug("Recover the configurations")
            libvirt.customize_libvirt_config(None,
                                             is_recover=True,
                                             config_object=libvirtd_conf)
        if src_libvirt_file:
            src_libvirt_file.restore()

        logging.info("Remove local NFS image")
        source_file = params.get("source_file")
        libvirt.delete_local_disk("file", path=source_file)
def run(test, params, env):
    """
    Test command: virsh migrate-setspeed <domain> <bandwidth>
                  virsh migrate-getspeed <domain>.

    1) Prepare test environment.
    2) Try to set the maximum migration bandwidth (in MiB/s)
       for a domain through valid and invalid command.
    3) Recover test environment.
    4) Check result.
    """

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_name = params.get("migrate_main_vm")
    bandwidth = params.get("bandwidth", "default")
    options_extra = params.get("options_extra", "")
    status_error = "yes" == params.get("status_error", "yes")
    virsh_dargs = {'debug': True}
    # Checking uris for migration
    twice_migration = "yes" == params.get("twice_migration", "no")
    if twice_migration:
        src_uri = params.get("migrate_src_uri", "qemu+ssh://EXAMPLE/system")
        dest_uri = params.get("migrate_dest_uri", "qemu+ssh://EXAMPLE/system")
        if src_uri.count('///') or src_uri.count('EXAMPLE'):
            raise error.TestNAError("The src_uri '%s' is invalid" % src_uri)
        if dest_uri.count('///') or dest_uri.count('EXAMPLE'):
            raise error.TestNAError("The dest_uri '%s' is invalid" % dest_uri)

    bz1083483 = False
    if bandwidth == "zero":
        expected_value = 0
    elif bandwidth == "one":
        expected_value = 1
    elif bandwidth == "negative":
        expected_value = -1
        bz1083483 = True
    elif bandwidth == "default":
        expected_value = DEFAULT
    elif bandwidth == "UINT32_MAX":
        expected_value = UINT32_MiB
    elif bandwidth == "INT64_MAX":
        expected_value = INT64_MiB
    elif bandwidth == "UINT64_MAX":
        expected_value = UINT64_MiB
        bz1083483 = True
    elif bandwidth == "INVALID_VALUE":
        expected_value = INT64_MiB + 1
        bz1083483 = True
    else:
        expected_value = bandwidth

    orig_value = virsh.migrate_getspeed(vm_name).stdout.strip()

    def set_get_speed(vm_name,
                      expected_value,
                      status_error=False,
                      options_extra="",
                      **virsh_dargs):
        """Set speed and check its result"""
        result = virsh.migrate_setspeed(vm_name, expected_value, options_extra,
                                        **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                # Without code for bz1083483 applied, this will succeed
                # when it shouldn't be succeeding.
                if bz1083483 and not libvirt_version.version_compare(1, 2, 4):
                    raise error.TestNAError("bz1083483 should result in fail")
                else:
                    raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s" %
                     (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")

    def verify_migration_speed(test, params, env):
        """
        Check if migration speed is effective with twice migration.
        """
        vms = env.get_all_vms()
        src_uri = params.get("migrate_src_uri", "qemu+ssh://EXAMPLE/system")
        dest_uri = params.get("migrate_dest_uri", "qemu+ssh://EXAMPLE/system")

        if not len(vms):
            raise error.TestNAError("Please provide migrate_vms for test.")

        if src_uri.count('///') or src_uri.count('EXAMPLE'):
            raise error.TestNAError("The src_uri '%s' is invalid" % src_uri)

        if dest_uri.count('///') or dest_uri.count('EXAMPLE'):
            raise error.TestNAError("The dest_uri '%s' is invalid" % dest_uri)

        remote_host = params.get("migrate_dest_host")
        username = params.get("migrate_dest_user", "root")
        password = params.get("migrate_dest_pwd")
        # Config ssh autologin for remote host
        ssh_key.setup_ssh_key(remote_host, username, password, port=22)

        # Check migrated vms' state
        for vm in vms:
            if vm.is_dead():
                vm.start()

        load_vm_names = params.get("load_vms").split()
        # vms for load
        load_vms = []
        for vm_name in load_vm_names:
            load_vms.append(
                libvirt_vm.VM(vm_name, params, test.bindir,
                              env.get("address_cache")))
        params["load_vms"] = load_vms

        bandwidth = int(params.get("bandwidth", "4"))
        stress_type = params.get("stress_type", "load_vms_booting")
        migration_type = params.get("migration_type", "orderly")
        thread_timeout = int(params.get("thread_timeout", "60"))
        delta = float(params.get("allowed_delta", "0.1"))
        virsh_migrate_timeout = int(params.get("virsh_migrate_timeout", "60"))
        # virsh migrate options
        virsh_migrate_options = "--live --unsafe --timeout %s" % virsh_migrate_timeout
        # Migrate vms to remote host
        mig_first = utlv.MigrationTest()
        virsh_dargs = {"debug": True}
        for vm in vms:
            set_get_speed(vm.name, bandwidth, virsh_dargs=virsh_dargs)
            vm.wait_for_login()
        utils_test.load_stress(stress_type, vms, params)
        mig_first.do_migration(vms,
                               src_uri,
                               dest_uri,
                               migration_type,
                               options=virsh_migrate_options,
                               thread_timeout=thread_timeout)
        for vm in vms:
            mig_first.cleanup_dest_vm(vm, None, dest_uri)
            # Keep it clean for second migration
            if vm.is_alive():
                vm.destroy()

        # Migrate vms again with new bandwidth
        second_bandwidth = params.get("second_bandwidth", "times")
        if second_bandwidth == "half":
            second_bandwidth = bandwidth / 2
            speed_times = 2
        elif second_bandwidth == "times":
            second_bandwidth = bandwidth * 2
            speed_times = 0.5
        elif second_bandwidth == "same":
            second_bandwidth = bandwidth
            speed_times = 1

        # Migrate again
        for vm in vms:
            if vm.is_dead():
                vm.start()
            vm.wait_for_login()
            set_get_speed(vm.name, second_bandwidth, virsh_dargs=virsh_dargs)
        utils_test.load_stress(stress_type, vms, params)
        mig_second = utlv.MigrationTest()
        mig_second.do_migration(vms,
                                src_uri,
                                dest_uri,
                                migration_type,
                                options=virsh_migrate_options,
                                thread_timeout=thread_timeout)
        for vm in vms:
            mig_second.cleanup_dest_vm(vm, None, dest_uri)

        fail_info = []
        # Check whether migration failed
        if len(fail_info):
            raise error.TestFail(fail_info)

        for vm in vms:
            first_time = mig_first.mig_time[vm.name]
            second_time = mig_second.mig_time[vm.name]
            logging.debug(
                "Migration time for %s:\n"
                "Time with Bandwidth '%s' first: %s\n"
                "Time with Bandwidth '%s' second: %s", vm.name, bandwidth,
                first_time, second_bandwidth, second_time)
            shift = float(abs(first_time * speed_times -
                              second_time)) / float(second_time)
            logging.debug("Shift:%s", shift)
            if delta < shift:
                fail_info.append(
                    "Spent time for migrating %s is intolerable." % vm.name)

        # Check again for speed result
        if len(fail_info):
            raise error.TestFail(fail_info)

    # Run test case
    try:
        set_get_speed(vm_name, expected_value, status_error, options_extra,
                      **virsh_dargs)
        if twice_migration:
            verify_migration_speed(test, params, env)
        else:
            set_get_speed(vm_name, expected_value, status_error, options_extra,
                          **virsh_dargs)
    finally:
        #restore bandwidth to default
        virsh.migrate_setspeed(vm_name, orig_value)
        if twice_migration:
            for vm in env.get_all_vms():
                utlv.MigrationTest().cleanup_dest_vm(vm, src_uri, dest_uri)
                if vm.is_alive():
                    vm.destroy(gracefully=False)
Exemple #15
0
def run(test, params, env):
    """
    Test command: virsh migrate-setspeed <domain> <bandwidth>
                  virsh migrate-getspeed <domain>.

    1) Prepare test environment.
    2) Try to set the maximum migration bandwidth (in MiB/s)
       for a domain through valid and invalid command.
    3) Recover test environment.
    4) Check result.
    """

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_name = params.get("main_vm")
    bandwidth = params.get("bandwidth", "default")
    options_extra = params.get("options_extra", "")
    status_error = "yes" == params.get("status_error", "yes")
    virsh_dargs = {'debug': True}

    if bandwidth == "zero":
        expected_value = 0
    elif bandwidth == "one":
        expected_value = 1
    elif bandwidth == "default":
        expected_value = DEFAULT
    elif bandwidth == "UINT32_MAX":
        expected_value = UINT32_MAX
    elif bandwidth == "INT64_MAX":
        expected_value = INT64_MAX
    elif bandwidth == "UINT64_MAX":
        expected_value = UINT64_MAX
    elif bandwidth == "INVALID_VALUE":
        expected_value = UINT64_MAX + 1
    else:
        expected_value = bandwidth

    orig_value = virsh.migrate_getspeed(vm_name).stdout.strip()

    # Run test case
    try:
        result = virsh.migrate_setspeed(vm_name, expected_value, options_extra,
                                        **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s" %
                     (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")
    finally:
        #restore bandwidth to default
        virsh.migrate_setspeed(vm_name, orig_value)
        # Case for option '--timeout --timeout-suspend'
        # 1. Start the guest
        # 2. Set migration speed to a small value. Ensure the migration
        #    duration is much larger than the timeout value
        # 3. Start the migration
        # 4. When the eclipse time reaches the timeout value, check the guest
        #    state to be paused on both source host and target host
        # 5. Wait for the migration done. Check the guest state to be shutoff
        #    on source host and running on target host
        if extra.count("--timeout-suspend"):
            asynch_migration = True
            speed = int(params.get("migrate_speed", 1))
            timeout = int(params.get("timeout_before_suspend", 5))
            logging.debug("Set migration speed to %sM", speed)
            virsh.migrate_setspeed(vm_name, speed, debug=True)
            migration_test = libvirt.MigrationTest()
            migrate_options = "%s %s" % (options, extra)
            vms = [vm]
            params["vm_migration"] = vm
            migration_test.do_migration(vms,
                                        None,
                                        dest_uri,
                                        'orderly',
                                        migrate_options,
                                        thread_timeout=900,
                                        ignore_status=True,
                                        func=check_migration_timeout_suspend,
                                        func_params=params)
            ret_migrate = migration_test.RET_MIGRATION
        if postcopy_cmd != "":
def run(test, params, env):
    """
    Test command: virsh migrate-setspeed <domain> <bandwidth>
                  virsh migrate-getspeed <domain>.

    1) Prepare test environment.
    2) Try to set the maximum migration bandwidth (in MiB/s)
       for a domain through valid and invalid command.
    3) Recover test environment.
    4) Check result.
    """

    # MAIN TEST CODE ###
    # Process cartesian parameters
    vm_name = params.get("main_vm")
    bandwidth = params.get("bandwidth", "default")
    options_extra = params.get("options_extra", "")
    status_error = "yes" == params.get("status_error", "yes")
    virsh_dargs = {'debug': True}

    if bandwidth == "zero":
        expected_value = 0
    elif bandwidth == "one":
        expected_value = 1
    elif bandwidth == "default":
        expected_value = DEFAULT
    elif bandwidth == "UINT32_MAX":
        expected_value = UINT32_MAX
    elif bandwidth == "INT64_MAX":
        expected_value = INT64_MAX
    elif bandwidth == "UINT64_MAX":
        expected_value = UINT64_MAX
    elif bandwidth == "INVALID_VALUE":
        expected_value = UINT64_MAX + 1
    else:
        expected_value = bandwidth

    orig_value = virsh.migrate_getspeed(vm_name).stdout.strip()

    # Run test case
    try:
        result = virsh.migrate_setspeed(vm_name, expected_value,
                                        options_extra, **virsh_dargs)
        status = result.exit_status
        err = result.stderr.strip()

        # Check status_error
        if status_error:
            if status == 0 or err == "":
                raise error.TestFail("Expect fail, but run successfully!")

            # no need to perform getspeed if status_error is true
            return
        else:
            if status != 0 or err != "":
                raise error.TestFail("Run failed with right "
                                     "virsh migrate-setspeed command")

        result = virsh.migrate_getspeed(vm_name, **virsh_dargs)
        status = result.exit_status
        actual_value = result.stdout.strip()
        err = result.stderr.strip()

        if status != 0 or err != "":
            raise error.TestFail("Run failed with virsh migrate-getspeed")

        logging.info("The expected bandwidth is %s MiB/s, "
                     "the actual bandwidth is %s MiB/s"
                     % (expected_value, actual_value))

        if int(actual_value) != int(expected_value):
            raise error.TestFail("Bandwidth value from getspeed "
                                 "is different from expected value "
                                 "set by setspeed")
    finally:
        #restore bandwidth to default
        virsh.migrate_setspeed(vm_name, orig_value)
    def _migrate(self):
        """
        1.Set selinux state
        2.Record vm uptime
        3.For postcopy migration:
            1) Set migration speed to low value
            2) Monitor postcopy event
        4.Do live migration
        5.Check migration result: succeed or fail with expected error
        6.For postcopy migration: check postcopy event
        7.Do post migration check: check vm state, uptime, network
        """
        # Set selinux state before migration
        # NOTE: if selinux state is set too early, it may be changed
        # in other methods unexpectedly, so set it just before migration
        logging.debug("Set selinux to enforcing before migration")
        utils_selinux.set_status(self.selinux_state)
        # TODO: Set selinux on migrate_dest_host

        # Check vm uptime before migration
        logging.debug("Check vm uptime before migration")
        self.uptime = {}
        for vm in self.vms:
            self.uptime[vm.name] = vm.uptime(connect_uri=vm.connect_uri)

        # Do postcopy/precopy related operations/setting
        if self.migrate_flags & VIR_MIGRATE_POSTCOPY:
            # Set migration speed to low value in case it finished too early
            # before postcopy mode starts
            for vm in self.vms:
                virsh.migrate_setspeed(vm.name, 1, uri=vm.connect_uri)

            # Monitor event "Suspended Post-copy" for postcopy migration
            logging.debug("Monitor the event for postcopy migration")
            virsh_session = virsh.VirshSession(virsh_exec=virsh.VIRSH_EXEC,
                                               auto_close=True)
            self.objs_list.append(virsh_session)
            cmd = "event %s --loop --all --timestamp" % self.main_vm.name
            virsh_session.sendline(cmd)

            # Set func to be executed during postcopy migration
            func = virsh.migrate_postcopy
        else:
            # Set func to be executed during precopy migration
            func = None

        # Start to do migration
        logging.debug("Start to do migration")
        thread_timeout = self.migrate_thread_timeout
        self.obj_migration.do_migration(self.vms,
                                        self.src_uri,
                                        self.dest_uri,
                                        "orderly",
                                        options=self.virsh_migrate_options,
                                        thread_timeout=thread_timeout,
                                        ignore_status=True,
                                        virsh_uri=self.src_uri,
                                        func=func,
                                        shell=True)

        logging.info("Check migration result: succeed or"
                     " fail with expected error")
        self.obj_migration.check_result(self.obj_migration.ret, self.params)

        # Check "suspended post-copy" event after postcopy migration
        if self.migrate_flags & VIR_MIGRATE_POSTCOPY:
            logging.debug("Check event after postcopy migration")
            virsh_session.send_ctrl("^c")
            events_output = virsh_session.get_stripped_output()
            logging.debug("Events_output are %s", events_output)
            pattern = "Suspended Post-copy"
            if pattern not in events_output:
                self.test.error("Migration didn't switch to postcopy mode")

        logging.debug("Do post migration check after migrate to dest")
        self.params["migrate_options"] = self.virsh_migrate_options
        self.obj_migration.post_migration_check(self.vms,
                                                self.params,
                                                self.uptime,
                                                uri=self.dest_uri)