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
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
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 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)
# 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)
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 _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)