def run_subtest(sub_test): """ Run subtest(e.g. rng_bat,reboot,shutdown) when it's not None :param sub_test: subtest name """ error_context.context("Run %s subtest" % sub_test) utils_test.run_virt_sub_test(test, params, env, sub_test)
def run(test, params, env): """ Verify if guests using kvm-clock as the time source have a sane clock resolution. :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ source_name = "clock_getres/clock_getres.c" source_name = os.path.join(data_dir.get_deps_dir(), source_name) dest_name = "/tmp/clock_getres.c" bin_name = "/tmp/clock_getres" if not os.path.isfile(source_name): raise error.TestError("Could not find %s" % source_name) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) vm.copy_files_to(source_name, dest_name) session.cmd("gcc -lrt -o %s %s" % (bin_name, dest_name)) session.cmd(bin_name) logging.info("PASS: Guest reported appropriate clock resolution") sub_test = params.get("sub_test") if sub_test: error.context( "Run sub test '%s' after checking" " clock resolution" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test)
def run_video(): """ Run video in background """ while True: utils_test.run_virt_sub_test(test, params, env, params.get("video_test"))
def run(test, params, env): """ Run Iometer for Windows on a Windows guest: 1) Boot guest with additional disk 2) Format the additional disk 3) Install and register Iometer 4) Perpare icf to Iometer.exe 5) Run Iometer.exe with icf 6) Copy result to host :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # format the target disk utils_test.run_virt_sub_test(test, params, env, "format_disk") error_context.context("Install Iometer", logging.info) cmd_timeout = int(params.get("cmd_timeout", 360)) ins_cmd = params["install_cmd"] vol_utils = utils_misc.get_winutils_vol(session) if not vol_utils: raise exceptions.TestError("WIN_UTILS CDROM not found") ins_cmd = re.sub("WIN_UTILS", vol_utils, ins_cmd) session.cmd(cmd=ins_cmd, timeout=cmd_timeout) time.sleep(0.5) error_context.context("Register Iometer", logging.info) reg_cmd = params["register_cmd"] reg_cmd = re.sub("WIN_UTILS", vol_utils, reg_cmd) session.cmd_output(cmd=reg_cmd, timeout=cmd_timeout) error_context.context("Prepare icf for Iometer", logging.info) icf_name = params["icf_name"] ins_path = params["install_path"] res_file = params["result_file"] icf_file = os.path.join(data_dir.get_deps_dir(), "iometer", icf_name) vm.copy_files_to(icf_file, "%s\\%s" % (ins_path, icf_name)) # Run Iometer error_context.context("Start Iometer", logging.info) session.cmd("cd %s" % ins_path) logging.info("Change dir to: %s" % ins_path) run_cmd = params["run_cmd"] run_timeout = int(params.get("run_timeout", 1000)) logging.info("Set Timeout: %ss" % run_timeout) run_cmd = run_cmd % (icf_name, res_file) logging.info("Execute Command: %s" % run_cmd) s, o = session.cmd_status_output(cmd=run_cmd, timeout=run_timeout) error_context.context("Copy result '%s' to host" % res_file, logging.info) vm.copy_files_from(res_file, test.resultsdir) if s != 0: raise exceptions.TestFail("iometer test failed. {}".format(o))
def run_clock_getres(test, params, env): """ Verify if guests using kvm-clock as the time source have a sane clock resolution. :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ source_name = "test_clock_getres/test_clock_getres.c" source_name = os.path.join(test.virtdir, "deps", source_name) dest_name = "/tmp/test_clock_getres.c" bin_name = "/tmp/test_clock_getres" if not os.path.isfile(source_name): raise error.TestError("Could not find %s" % source_name) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) vm.copy_files_to(source_name, dest_name) session.cmd("gcc -lrt -o %s %s" % (bin_name, dest_name)) session.cmd(bin_name) logging.info("PASS: Guest reported appropriate clock resolution") sub_test = params.get("sub_test") if sub_test: error.context("Run sub test '%s' after checking" " clock resolution" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test)
def run_migration_multi_host(test, params, env): """ KVM multi-host migration test: Migration execution progress is described in documentation for migrate method in class MultihostMigration. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) sub_test = params.get("sub_test") mig_protocol = params.get("mig_protocol", "tcp") mig_type = utils_test.MultihostMigration if mig_protocol == "fd": mig_type = utils_test.MultihostMigrationFd if mig_protocol == "exec": mig_type = utils_test.MultihostMigrationExec vms = params.get("vms").split(" ") srchost = params["hosts"][0] dsthost = params["hosts"][1] is_src = params["hostid"] == srchost mig = mig_type(test, params, env, False) mig.migrate_wait([vms[0]], srchost, dsthost) if not is_src: #is destination if sub_test: error.context( "Run sub test '%s' after checking" " clock resolution" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test)
def run_migration_multi_host(test, params, env): """ KVM multi-host migration test: Migration execution progress is described in documentation for migrate method in class MultihostMigration. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) sub_test = params.get("sub_test") mig_protocol = params.get("mig_protocol", "tcp") mig_type = utils_test.MultihostMigration if mig_protocol == "fd": mig_type = utils_test.MultihostMigrationFd if mig_protocol == "exec": mig_type = utils_test.MultihostMigrationExec vms = params.get("vms").split(" ") srchost = params["hosts"][0] dsthost = params["hosts"][1] is_src = params["hostid"] == srchost mig = mig_type(test, params, env, False) mig.migrate_wait([vms[0]], srchost, dsthost) if not is_src: #is destination if sub_test: error.context("Run sub test '%s' after checking" " clock resolution" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test)
def run_subtest(sub_type): """ Run sub test. e.g. reboot / system_reset... :params: sub_type: Sub test. """ utils_test.run_virt_sub_test(test, params, env, sub_type)
def run_balloon_sub_test(self, test, params, env, test_tag): """ Run subtest after ballooned memory. Set up the related parameters according to the subtest. :param test: QEMU test object :type test: object :param params: Dictionary with the test parameters :type param: dict :param env: Dictionary with test environment. :type env: dict :return: if qemu-kvm process quit after test. There are three status for this variable. -1 means the process will not quit. 0 means the process will quit but already restart in sub test. 1 means the process quit after sub test. :rtype: int """ utils_test.run_virt_sub_test(test, params, env, sub_type=test_tag) qemu_quit_after_test = -1 if "shutdown" in test_tag: logging.info("Guest shutdown normally after balloon") qemu_quit_after_test = 1 if params.get("session_need_update", "no") == "yes": timeout = int(self.params.get("login_timeout", 360)) self.session = self.vm.wait_for_login(timeout=timeout) if params.get("qemu_quit_after_sub_case", "no") == "yes": self.current_mmem = self.ori_mem self.current_gmem = self.ori_gmem qemu_quit_after_test = 0 return qemu_quit_after_test
def run(test, params, env): """ Run Iometer for Windows on a Windows guest: 1) Boot guest with additional disk 2) Format the additional disk 3) Install and register Iometer 4) Perpare icf to Iometer.exe 5) Run Iometer.exe with icf 6) Copy result to host :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) # format the target disk utils_test.run_virt_sub_test(test, params, env, "format_disk") error_context.context("Install Iometer", logging.info) cmd_timeout = int(params.get("cmd_timeout", 360)) ins_cmd = params["install_cmd"] vol_utils = utils_misc.get_winutils_vol(session) if not vol_utils: raise exceptions.TestError("WIN_UTILS CDROM not found") ins_cmd = re.sub("WIN_UTILS", vol_utils, ins_cmd) session.cmd(cmd=ins_cmd, timeout=cmd_timeout) time.sleep(0.5) error_context.context("Register Iometer", logging.info) reg_cmd = params["register_cmd"] reg_cmd = re.sub("WIN_UTILS", vol_utils, reg_cmd) session.cmd_output(cmd=reg_cmd, timeout=cmd_timeout) error_context.context("Prepare icf for Iometer", logging.info) icf_name = params["icf_name"] ins_path = params["install_path"] res_file = params["result_file"] icf_file = os.path.join(data_dir.get_deps_dir(), "iometer", icf_name) vm.copy_files_to(icf_file, "%s\\%s" % (ins_path, icf_name)) # Run Iometer error_context.context("Start Iometer", logging.info) session.cmd("cd %s" % ins_path) logging.info("Change dir to: %s" % ins_path) run_cmd = params["run_cmd"] run_timeout = int(params.get("run_timeout", 1000)) logging.info("Set Timeout: %ss" % run_timeout) run_cmd = run_cmd % (icf_name, res_file) logging.info("Execute Command: %s" % run_cmd) s, o = session.cmd_status_output(cmd=run_cmd, timeout=100) error_context.context("Copy result '%s' to host" % res_file, logging.info) vm.copy_files_from(res_file, test.resultsdir) if s != 0: raise exceptions.TestFail("iometer test failed. {}".format(o))
def run(test, params, env): """ Test hotplug/unplug of rng device 1) Boot up w/o rng device 2) Hotplug one or more rng devices 3) Run random read test after hotplug 4) Unplug rng devices 5) Repeat step 2 ~ step4 (option) :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ login_timeout = int(params.get("login_timeout", 360)) repeat_times = int(params.get("repeat_times", 1)) rng_num = int(params.get("rng_num", 1)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() vm.wait_for_login(timeout=login_timeout) for i in xrange(repeat_times): dev_list = [] logging.info("Hotplug/unplug rng devices the %sth times", (i+1)) for num in xrange(rng_num): vm.devices.set_dirty() new_dev = qdevices.QDevice("virtio-rng-pci", {'id': 'virtio-rng-pci-%d' % num}) dev_list.append(new_dev) error_context.context("Hotplug %s" % new_dev, logging.info) output = new_dev.hotplug(vm.monitor) time.sleep(2) error_context.context("Check %sfrom qtree after hotplug" % new_dev, logging.info) qtree_output = new_dev.verify_hotplug(output, vm.monitor) if not qtree_output: msg = "no % device in qtree after hotplug" msg += "the %sth time" % (new_dev, i) raise exceptions.TestFail(msg) logging.info("virtio-rng-pci-%d is hotpluged successfully" % num) sub_test = params.get("sub_test_after_hotplug") if sub_test: utils_test.run_virt_sub_test(test, params, env, sub_test) for dev in dev_list: error_context.context("Unplug %s" % dev, logging.info) output = dev.unplug(vm.monitor) time.sleep(2) error_context.context("Check rng device from qtree after unplug", logging.info) qtree_output = dev.verify_unplug(output, vm.monitor) if not qtree_output: msg = "Still get %s in qtree after unplug %s times" % (dev, i) raise exceptions.TestFail(msg) logging.info("%s is unpluged successfully" % dev)
def run_block_stream_with_stress(test, params, env): """ block_stream_with_stress test: 1). boot guest 2). make guest under heavyload status 3). create live snpshot file and start block stream job 4). wait for it done correctly @param test: Kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) image_filename = storage.get_image_filename(params, data_dir.get_data_dir()) device_id = vm.get_block({"file": image_filename}) snapshot_file = os.path.splitext(image_filename)[0] + "-snp" sub_test = params.get("pre_test") start_cmd = params.get("start_cmd") def is_job_done(): """ Query block job status to check is job finished """ job = vm.monitor.query_block_job(device_id) if job: processed = float(job["offset"]) / job["len"] * 100 logging.debug("%s, rocessed: %.2f" % (job["type"], processed)) return False logging.info("block stream job done") return True try: utils_test.run_virt_sub_test(test, params, env, sub_type=sub_test) error.context("Heavy load in guest ...", logging.info) if start_cmd.startswith("stress"): cpu = int(params.get("smp", 1)) mem = int(params.get("mem", 1024)) start_cmd = start_cmd.format(cpu=cpu, vm=cpu * 2, mem=(mem - 512) / cpu) session.sendline(start_cmd) error.context("Creating live snapshot", logging.info) if vm.monitor.live_snapshot(device_id, snapshot_file): raise error.TestFail("Fail to create live snapshot") error.context("Start block device stream job", logging.info) if vm.monitor.block_stream(device_id): raise error.TestFail("Fail to start block stream job") if not utils_misc.wait_for(is_job_done, timeout=int(params.get("job_timeout", 2400)), text="wait job done, it will take long time"): raise error.TestFail("Wait job finish timeout") finally: if session: session.close() if os.path.isfile(snapshot_file): os.remove(snapshot_file)
def run(test, params, env): """ [pci-bridge]Check stress when 31 block devices attached to 1 pci-bridge, this case will: 1) Attach one pci-bridge to guest. 2) Create 31 disks to this pci-bridge. 3) Start the guest. 4) Check 'info block'. 5) Read and write data on disks under pci bridge. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context("Modify params!", logging.info) image_parent_bus = params.get("image_parent_bus") image_num = int(params.get("image_num", 0)) if image_num != 0: for index in range(image_num): image = "stg%s" % index params["images"] = ' '.join([params["images"], image]) params["disk_pci_bus_%s" % image] = image_parent_bus params["image_name_%s" % image] = "images/%s" % image params["image_size_%s" % image] = "100M" params["force_create_image_%s" % image] = "yes" params["remove_image_%s" % image] = "yes" params["blk_extra_params_%s" % image] = "serial=TARGET_DISK%s" % index env_process.process_images(env_process.preprocess_image, test, params) env_process.preprocess_vm(test, params, env, params["main_vm"]) error_context.context("Get the main VM!", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) error_context.context("Check 'info block'!", logging.info) monitor_info_block = vm.monitor.info_block(False) if image_num + 1 != len(monitor_info_block.keys()): test.fail("Check 'info block' failed!") logging.info("Check 'info block' succeed!") error_context.context("Read and write data on all disks!", logging.info) sub_test_type = params.get("sub_test_type", "dd_test") images = params["images"] images = images.split() images.pop(0) for image in images: if params.get("dd_if") == "ZERO": params["dd_of"] = image else: params["dd_if"] = image utils_test.run_virt_sub_test(test, params, env, sub_test_type) logging.info("Read and write data on all disks succeed!") session.close()
def check_data_disks(test, params, env, vm, session): """ Check guest data disks (except image1) :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. :param vm: VM object :param session: VM session """ image_list = params.objects("images") del image_list[0] image_num = len(image_list) error_context.context("Check data disks in monitor!", logging.info) monitor_info_block = vm.monitor.info_block(False) blocks = ','.join(monitor_info_block.keys()) for image in image_list: if image not in blocks: test.fail("drive_%s is missed: %s!" % (image, blocks)) error_context.context("Read and write on data disks!", logging.info) os_type = params["os_type"] if os_type == "linux": sub_test_type = params.get("sub_test_type", "dd_test") for image in image_list: params["dd_if"] = "ZERO" params["dd_of"] = image utils_test.run_virt_sub_test(test, params, env, sub_test_type) params["dd_if"] = image params["dd_of"] = "NULL" utils_test.run_virt_sub_test(test, params, env, sub_test_type) elif os_type == "windows": iozone_cmd = params["iozone_cmd"] iozone_cmd = utils_misc.set_winutils_letter(session, iozone_cmd) data_image_size = params["data_image_size"] disks = utils_disk.get_windows_disks_index(session, data_image_size) disk_num = len(disks) if disk_num < image_num: err_msg = "set disk num: %d" % image_num err_msg += ", get in guest: %d" % disk_num test.fail("Fail to list all the volumes, %s" % err_msg) if not utils_disk.update_windows_disk_attributes(session, disks): test.fail("Failed to update windows disk attributes.") for disk in disks: drive_letter = utils_disk.configure_empty_disk( session, disk, data_image_size, os_type) if not drive_letter: test.fail("Fail to format disks.") iozone_cmd_disk = iozone_cmd % drive_letter[0] status, output = session.cmd_status_output(iozone_cmd_disk, timeout=3600) if status: test.fail("Check block device '%s' failed! Output: %s" % (drive_letter[0], output)) utils_disk.clean_partition(session, disk, os_type) else: test.cancel("Unsupported OS type '%s'" % os_type)
def run(test, params, env): """ Test hotplug/unplug of rng device 1) Boot up w/o rng device 2) Hotplug one or more rng devices 3) Run random read test after hotplug 4) Unplug rng devices 5) Repeat step 2 ~ step4 (option) :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment """ login_timeout = int(params.get("login_timeout", 360)) repeat_times = int(params.get("repeat_times", 1)) rng_num = int(params.get("rng_num", 1)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() vm.wait_for_login(timeout=login_timeout) for i in xrange(repeat_times): dev_list = [] logging.info("Hotplug/unplug rng devices the %sth times", (i + 1)) for num in xrange(rng_num): vm.devices.set_dirty() new_dev = qdevices.QDevice("virtio-rng-pci", {'id': 'virtio-rng-pci-%d' % num}) dev_list.append(new_dev) error_context.context("Hotplug %s" % new_dev, logging.info) output = new_dev.hotplug(vm.monitor) time.sleep(2) error_context.context("Check %sfrom qtree after hotplug" % new_dev, logging.info) qtree_output = new_dev.verify_hotplug(output, vm.monitor) if not qtree_output: msg = "no % device in qtree after hotplug" msg += "the %sth time" % (new_dev, i) raise exceptions.TestFail(msg) logging.info("virtio-rng-pci-%d is hotpluged successfully" % num) sub_test = params.get("sub_test_after_hotplug") if sub_test: utils_test.run_virt_sub_test(test, params, env, sub_test) for dev in dev_list: error_context.context("Unplug %s" % dev, logging.info) output = dev.unplug(vm.monitor) time.sleep(2) error_context.context("Check rng device from qtree after unplug", logging.info) qtree_output = dev.verify_unplug(output, vm.monitor) if not qtree_output: msg = "Still get %s in qtree after unplug %s times" % (dev, i) raise exceptions.TestFail(msg) logging.info("%s is unpluged successfully" % dev)
def run_post_sub_test(self): # is destination host if not self.is_src: if self.post_sub_test: error.context("Run sub test '%s' after migration on dst" % self.post_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, self.post_sub_test)
def run_migration_multi_host(test, params, env): """ KVM multi-host migration test: Migration execution progress is described in documentation for migrate method in class MultihostMigration. steps: 1) try log to VM if login_before_pre_tests == yes 2) before migration start pre_sub_test 3) migration 4) after migration start post_sub_test :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) pre_sub_test = params.get("pre_sub_test") post_sub_test = params.get("post_sub_test") pre_sub_test_timeout = int(params.get("pre_sub_test_timeout", "240")) login_before_pre_tests = params.get("login_before_pre_tests", "no") mig_protocol = params.get("mig_protocol", "tcp") mig_type = utils_test.MultihostMigration if mig_protocol == "fd": mig_type = utils_test.MultihostMigrationFd if mig_protocol == "exec": mig_type = utils_test.MultihostMigrationExec vms = params.get("vms").split(" ") srchost = params["hosts"][0] dsthost = params["hosts"][1] is_src = params["hostid"] == srchost if is_src: # is destination if pre_sub_test: if login_before_pre_tests == "yes": vm = env.get_vm(vms[0]) vm.wait_for_login(timeout=login_timeout) error.context( "Run sub test '%s' before migration on src" % pre_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, pre_sub_test) mig = mig_type(test, params, env, False) mig._hosts_barrier([srchost, dsthost], { 'src': srchost, 'dst': dsthost, "vms": vms[0] }, "sync", pre_sub_test_timeout) mig.migrate_wait([vms[0]], srchost, dsthost) if not is_src: # is destination if post_sub_test: error.context( "Run sub test '%s' after migration on dst" % post_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, post_sub_test)
def run(test, params, env): """ [pci-bridge]Check stress when 31 block devices attached to 1 pci-bridge, this case will: 1) Attach one pci-bridge to guest. 2) Create 31 disks to this pci-bridge. 3) Start the guest. 4) Check 'info block'. 5) Read and write data on disks under pci bridge. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error_context.context("Modify params!", logging.info) image_parent_bus = params.get("image_parent_bus") image_num = int(params.get("image_num", 0)) if image_num != 0: for index in xrange(image_num): image = "stg%s" % index params["images"] = ' '.join([params["images"], image]) params["disk_pci_bus_%s" % image] = image_parent_bus params["image_name_%s" % image] = "images/%s" % image params["image_size_%s" % image] = "100M" params["force_create_image_%s" % image] = "yes" params["remove_image_%s" % image] = "yes" params["blk_extra_params_%s" % image] = "serial=TARGET_DISK%s" % index env_process.process_images(env_process.preprocess_image, test, params) env_process.preprocess_vm(test, params, env, params["main_vm"]) error_context.context("Get the main VM!", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) error_context.context("Check 'info block'!", logging.info) monitor_info_block = vm.monitor.info_block(False) if image_num + 1 != len(monitor_info_block.keys()): raise error.TestFail("Check 'info block' failed!") logging.info("Check 'info block' succeed!") error_context.context("Read and write data on all disks!", logging.info) sub_test_type = params.get("sub_test_type", "dd_test") images = params["images"] images = images.split() images.pop(0) for image in images: if params.get("dd_if") == "ZERO": params["dd_of"] = image else: params["dd_if"] = image utils_test.run_virt_sub_test(test, params, env, sub_test_type) logging.info("Read and write data on all disks succeed!") session.close()
def run_migration_multi_host(test, params, env): """ KVM multi-host migration test: Migration execution progress is described in documentation for migrate method in class MultihostMigration. steps: 1) try log to VM if login_before_pre_tests == yes 2) before migration start pre_sub_test 3) migration 4) after migration start post_sub_test :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) pre_sub_test = params.get("pre_sub_test") post_sub_test = params.get("post_sub_test") pre_sub_test_timeout = int(params.get("pre_sub_test_timeout", "240")) login_before_pre_tests = params.get("login_before_pre_tests", "no") mig_protocol = params.get("mig_protocol", "tcp") mig_type = utils_test.qemu.MultihostMigration if mig_protocol == "fd": mig_type = utils_test.qemu.MultihostMigrationFd if mig_protocol == "exec": mig_type = utils_test.qemu.MultihostMigrationExec vms = params.get("vms").split(" ") srchost = params["hosts"][0] dsthost = params["hosts"][1] is_src = params["hostid"] == srchost if is_src: # is destination if pre_sub_test: if login_before_pre_tests == "yes": vm = env.get_vm(vms[0]) vm.wait_for_login(timeout=login_timeout) error.context("Run sub test '%s' before migration on src" % pre_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, pre_sub_test) if params.get("check_vm_before_migration", "yes") == "no": params['check_vm_needs_restart'] = "no" mig = mig_type(test, params, env, False) mig._hosts_barrier([srchost, dsthost], {'src': srchost, 'dst': dsthost, "vms": vms[0]}, "sync", pre_sub_test_timeout) mig.migrate_wait([vms[0]], srchost, dsthost) if not is_src: # is destination if post_sub_test: error.context("Run sub test '%s' after migration on dst" % post_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, post_sub_test)
def run_subtest(sub_type): """ Run sub test which include main test and background test. main test: e.g. reboot/shutdown/migration/stop/cont ... background test: e.g. rng_bat/balloon_test/netperf ... :params: sub_type: Sub test. """ utils_test.run_virt_sub_test(test, params, env, sub_type)
def run_sub_test(self): if self.params.get("sub_type"): step = ("Run sub test '%s' %s %s memory device" % (self.params["sub_test"], self.params["stage"], self.params["operation"])) step_engine.context(step, logging.info) args = (self.test, self.params, self.env, self.params["sub_type"]) run_virt_sub_test(*args)
def run_sub_test(self): """ Run virt sub test before/after hotplug/unplug memory device""" if self.params.get("sub_type"): step = ("Run sub test '%s' %s %s memory device" % (self.params["sub_test"], self.params["stage"], self.params["operation"])) step_engine.context(step, logging.info) args = (self.test, self.params, self.env, self.params["sub_type"]) run_virt_sub_test(*args)
def run_pm_test(pm_test, plug_type): """ Run pm(reboot/system_reset/shutdown) related test after balloon device is hot-plug or hot-unplug :param pm_test: power management test name,e.g. reboot/shutdown :param plug_type:balloon device plug operation,e.g.hot_plug or hot_unplug """ error_context.context("Run %s test after %s balloon device" % (pm_test, plug_type), logging.info) utils_test.run_virt_sub_test(test, params, env, pm_test)
def run_sub_test(self): """ Run virt sub test before/after hotplug/unplug memory device""" if self.params.get("sub_type"): step = ("Run sub test '%s' %s %s memory device" % (self.params["sub_test"], self.params["stage"], self.params["operation"])) error_context.context(step, logging.info) args = (self.test, self.params, self.env, self.params["sub_type"]) run_virt_sub_test(*args)
def run_stress(test, params, env, vm): """ Run stress in background """ while True: if params['os_type'] == 'windows': utils_test.run_virt_sub_test(test, params, env, params.get("stress_test")) else: stress_bg = utils_test.VMStress(vm, "stress", params) stress_bg.load_stress_tool()
def run_pre_sub_test(self): # is source host if self.is_src: if self.pre_sub_test: if self.login_before_pre_tests == "yes": vm = env.get_vm(params["main_vm"]) vm.wait_for_login(timeout=self.login_timeout) error.context("Run sub test '%s' before migration on src" % self.pre_sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, self.pre_sub_test)
def run(test, params, env): """ KVM driver load test: 1) Log into a guest 2) Get the driver device id(Windows) or module name(Linux) from guest 3) Unload/load the device driver 4) Check if the device still works properly(Optinal) 5) Repeat step 3-4 several times :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) # Use the last nic for send driver load/unload command nics = vm.virtnet nic_index = len(vm.virtnet) - 1 session = vm.wait_for_login(nic_index=nic_index, timeout=timeout) driver_id_cmd = params["driver_id_cmd"] driver_id_pattern = params["driver_id_pattern"] driver_load_cmd = params["driver_load_cmd"] driver_unload_cmd = params["driver_unload_cmd"] error.context("Get the driver module infor from guest.", logging.info) output = session.cmd_output(driver_id_cmd) driver_id = re.findall(driver_id_pattern, output) if not driver_id: raise error.TestError("Can not find driver module info from guest:" "%s" % output) driver_id = driver_id[0] if params["os_type"] == "windows": driver_id = '^&'.join(driver_id.split('&')) driver_load_cmd = driver_load_cmd.replace("DRIVER_ID", driver_id) driver_unload_cmd = driver_unload_cmd.replace("DRIVER_ID", driver_id) for repeat in range(0, int(params.get("repeats", "1"))): error.context("Unload and load the driver. Round %s" % repeat, logging.info) session.cmd(driver_unload_cmd) time.sleep(5) session.cmd(driver_load_cmd) time.sleep(5) if params.get("test_after_load"): test_after_load = params.get("test_after_load") utils_test.run_virt_sub_test(test, params, env, sub_type=test_after_load)
def run_driver_load(test, params, env): """ KVM driver load test: 1) Log into a guest 2) Get the driver device id(Windows) or module name(Linux) from guest 3) Unload/load the device driver 4) Check if the device still works properly(Optinal) 5) Repeat step 3-4 several times :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ error.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) # Use the last nic for send driver load/unload command nics = vm.virtnet nic_index = len(vm.virtnet) - 1 session = vm.wait_for_login(nic_index=nic_index, timeout=timeout) driver_id_cmd = params["driver_id_cmd"] driver_id_pattern = params["driver_id_pattern"] driver_load_cmd = params["driver_load_cmd"] driver_unload_cmd = params["driver_unload_cmd"] error.context("Get the driver module infor from guest.", logging.info) output = session.cmd_output(driver_id_cmd) driver_id = re.findall(driver_id_pattern, output) if not driver_id: raise error.TestError("Can not find driver module info from guest:" "%s" % output) driver_id = driver_id[0] if params["os_type"] == "windows": driver_id = '^&'.join(driver_id.split('&')) driver_load_cmd = driver_load_cmd.replace("DRIVER_ID", driver_id) driver_unload_cmd = driver_unload_cmd.replace("DRIVER_ID", driver_id) for repeat in range(0, int(params.get("repeats", "1"))): error.context("Unload and load the driver. Round %s" % repeat, logging.info) session.cmd(driver_unload_cmd) time.sleep(5) session.cmd(driver_load_cmd) time.sleep(5) if params.get("test_after_load"): test_after_load = params.get("test_after_load") utils_test.run_virt_sub_test(test, params, env, sub_type=test_after_load)
def run(test, params, env): """ boot cpu model test: steps: 1). boot guest with cpu model 2). check flags if enable_check == "yes", otherwise shutdown guest :param test: QEMU test object :param params: Dictionary with the test parameters """ cpu_vendor = utils_misc.get_cpu_vendor() host_model = utils_misc.get_host_cpu_models() model_list = params.get("cpu_model") if not model_list: if cpu_vendor == "unknow": raise error.TestError("unknow cpu vendor") else: model_list = params.get("cpu_model_%s" % cpu_vendor, host_model[-1]) extra_flags = params.get("cpu_model_flags_%s" % cpu_vendor, "") if extra_flags: cpu_flags = params.get("cpu_model_flags", "") + extra_flags params["cpu_model_flags"] = cpu_flags if model_list: model_list = model_list.split(" ") for model in model_list: if model in host_model or model == "host": params["cpu_model"] = model params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) # check guest flags if params.get("enable_check", "no") == "yes": utils_test.run_virt_sub_test(test, params, env, sub_type="flag_check") else: # log in and shutdown guest utils_test.run_virt_sub_test(test, params, env, sub_type="shutdown") logging.info("shutdown guest successfully") else: if params.get("enable_check", "no") == "yes": raise error.TestWarn("Can not test %s model on %s host, " "pls use %s host" % (model, host_model[0], model))
def run(test, params, env): """ Qemu combine test: Reuse exist simple tests to combine a more complex scenario. Also support to run some simple command in guests and host. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def exe_cmd_in_guests(subtest_tag): timeout = int(params.get("login_timeout", 240)) vms = env.get_all_vms() for vm in vms: params_vm = params.object_params(vm.name) params_vm_subtest = params_vm.object_params(subtest_tag) if params_vm_subtest.get('cmd'): error_context.context("Try to log into guest '%s'." % vm.name, logging.info) session = vm.wait_for_login(timeout=timeout) cmd_timeout = int(params_vm_subtest.get("cmd_timeout", 240)) cmd = params_vm_subtest['cmd'] session.cmd(cmd, timeout=cmd_timeout) def exe_cmd_in_host(subtest_tag): params_subtest = params.object_params(subtest_tag) cmd_timeout = int(params_subtest.get("cmd_timeout", 240)) cmd = params_subtest['cmd'] process.system(cmd, timeout=cmd_timeout, shell=True) subtests = params["subtests"].split() for subtest in subtests: params_subtest = params.object_params(subtest) error_context.context("Run test %s" % subtest, logging.info) if params_subtest.get("subtest_type") == "guests": exe_cmd_in_guests(subtest) elif params_subtest.get("subtest_type") == "host": exe_cmd_in_host(subtest) else: utils_test.run_virt_sub_test(test, params, env, subtest, subtest) if params_subtest.get("check_vm_status_after_test", "yes") == "yes": vms = env.get_all_vms() for vm in vms: error_context.context("Check %s status" % vm.name, logging.info) vm.verify_userspace_crash() vm.verify_kernel_crash() vm.verify_kvm_internal_error()
def run(test, params, env): """ Qemu virtio-rng device test: 1) boot guest with virtio-rng device 2) host read random numbers in the background 3) guest read random data at the same time during step2 4) clean host read process after test :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def host_read_start(host_read_cmd): """ Read random numbers on the host side :param host_read_cmd: host read random numbers command line :return: reture host_read_process """ host_read_process = process.SubProcess(host_read_cmd, shell=True) host_read_process.start() return host_read_process def host_read_clean(host_read_process): """ Clean host read random numbers process :param host_read_process: process of the host reading """ if host_read_process.poll() is None: host_read_process.kill() host_read_cmd = params.get("host_read_cmd") guest_rng_test = params.get("guest_rng_test") vm = env.get_vm(params["main_vm"]) vm.wait_for_login() error_context.context("Host read random numbers in the background", logging.info) host_read_process = host_read_start(host_read_cmd) try: if host_read_process.poll() is None: error_context.context("Guest begin to read random numbers", logging.info) utils_test.run_virt_sub_test(test, params, env, guest_rng_test) else: test.error("Host reading data is not alive!") finally: error_context.context("Clean host read process", logging.info) host_read_clean(host_read_process)
def netperf_vlan(client='main_vm', server='localhost', sub_type='netperf_stress'): """ Test netperf stress among guests and host. :params client: Netperf client. :params server: Netperf server. :params sub_type: Sub_type to run. """ params["netperf_client"] = client params["netperf_server"] = server error_context.context("Run netperf stress test among guests and host, " "server: %s, client: %s" % (server, client), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type)
def run_boot_cpu_model(test, params, env): """ boot cpu model test: steps: 1). boot guest with cpu model 2). check flags if enable_check == "yes", otherwise shutdown guest :param test: QEMU test object :param params: Dictionary with the test parameters """ cpu_vendor = utils_misc.get_cpu_vendor() host_model = utils_misc.get_host_cpu_models() model_list = params.get("cpu_model") if not model_list: if cpu_vendor == "unknow": raise error.TestError("unknow cpu vendor") else: model_list = params.get("cpu_model_%s" % cpu_vendor, host_model[-1]) extra_flags = params.get("cpu_model_flags_%s" % cpu_vendor, "") if extra_flags: cpu_flags = params.get("cpu_model_flags", "") + extra_flags params["cpu_model_flags"] = cpu_flags if model_list: model_list = model_list.split(" ") for model in model_list: if model in host_model or model == "host": params["cpu_model"] = model params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) # check guest flags if params.get("enable_check", "no") == "yes": utils_test.run_virt_sub_test(test, params, env, sub_type="flag_check") else: # log in and shutdown guest utils_test.run_virt_sub_test(test, params, env, sub_type="shutdown") logging.info("shutdown guest successfully") else: if params.get("enable_check", "no") == "yes": raise error.TestWarn("Can not test %s model on %s host, " "pls use %s host" % (model, host_model[0], model))
def run_bg_test_sep(sub_type): """ Run background test separately with main_test. background test: e.g. rng_bat/balloon_test/netperf ... main test: e.g. reboot/shutdown/stop/cont/driver_load ... :params: sub_type: Background test. """ if params.get("bg_stress_test_is_cmd", "no") == "yes": session = vm.wait_for_login() sub_type = utils_misc.set_winutils_letter(session, sub_type) session.cmd(sub_type, timeout=600) session.close() else: utils_test.run_virt_sub_test(test, params, env, sub_type)
def run_bg_test_sep(sub_type): """ Run background test separately with main_test. background test: e.g. rng_bat/balloon_test/netperf ... main test: e.g. reboot/shutdown/stop/cont/driver_load ... :params: sub_type: Background test. """ if params.get("bg_stress_test_is_cmd", "no") == "yes": session = vm.wait_for_login() sub_type = utils_misc.set_winutils_letter( session, sub_type) session.cmd(sub_type, timeout=600) session.close() else: utils_test.run_virt_sub_test(test, params, env, sub_type)
def run_sub_test(params, plug_tag): """ Run subtest before/after hotplug/unplug device. :param plug_tag: identify when to run subtest, ex, before_hotplug. :return: whether vm was successfully shut-down if needed """ sub_type = params.get("sub_type_%s" % plug_tag) if sub_type: error_context.context(context_msg % (sub_type, plug_tag), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if sub_type == "shutdown" and vm.is_dead(): return True return None
def run(test, params, env): vm = env.get_vm(params["main_vm"]) image_tag = params.get("image_name", "image1") image_params = params.object_params(image_tag) snapshot_test = LiveSnapshotBase(image_params, env) error_context.context("Creating snapshot", logging.info) snapshot_test.create_snapshot() error_context.context("Checking snapshot created successfully", logging.info) snapshot_test.check_snapshot() sub_type = params.get("sub_type_after_snapshot") if sub_type: error_context.context("%s after snapshot" % sub_type, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if vm.is_alive(): vm.destroy()
def run(test, params, env): """ Verify if guests using kvm-clock as the time source have a sane clock resolution. :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) getres_cmd = params.get("getres_cmd") if not getres_cmd or session.cmd_status("test -x %s" % getres_cmd): source_name = "clock_getres/clock_getres.c" source_name = os.path.join(data_dir.get_deps_dir(), source_name) getres_cmd = "/tmp/clock_getres" dest_name = "/tmp/clock_getres.c" if not os.path.isfile(source_name): test.error("Could not find %s" % source_name) vm.copy_files_to(source_name, dest_name) session.cmd("gcc -lrt -o %s %s" % (getres_cmd, dest_name)) session.cmd(getres_cmd) logging.info("PASS: Guest reported appropriate clock resolution") sub_test = params.get("sub_test") if sub_test: error_context.context("Run sub test '%s' after checking" " clock resolution" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test)
def _do_io_test_guest(session): utils_test.run_virt_sub_test(test, params, env, "format_disk")
def run(test, params, env): """ Test hotplug of PCI devices. (Elements between [] are configurable test parameters) 1) PCI add one/multi device (NIC / block) with(or without) repeat 2) Compare output of monitor command 'info pci'. 3) Compare output of guest command [reference_cmd]. 4) Verify whether pci_model is shown in [pci_find_cmd]. 5) Check whether the newly added PCI device works fine. 6) PCI delete the device, verify whether could remove the PCI device. 7) reboot VM after guest wakeup form S3/S4 status (Optional Step). :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ # Select an image file def find_image(pci_num): image_params = params.object_params("%s" % img_list[pci_num + 1]) o = storage.get_image_filename(image_params, data_dir.get_data_dir()) return o def pci_add_nic(pci_num): pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % pci_model return pci_add(pci_add_cmd) def pci_add_block(pci_num): image_filename = find_image(pci_num) pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" % (image_filename, pci_model)) return pci_add(pci_add_cmd) def pci_add(pci_add_cmd): error.context("Adding pci device with command 'pci_add'", logging.info) add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info.append(['', '', add_output, pci_model]) if "OK domain" not in add_output: raise error.TestFail("Add PCI device failed. " "Monitor command is: %s, Output: %r" % (pci_add_cmd, add_output)) return vm.monitor.info("pci") def is_supported_command(cmd1, cmd2): try: vm.monitor.verify_supported_cmd(cmd1) return cmd1 except qemu_monitor.MonitorNotSupportedCmdError: try: vm.monitor.verify_supported_cmd(cmd2) return cmd2 except qemu_monitor.MonitorNotSupportedCmdError: pass return None def is_supported_device(dev): # Probe qemu to verify what is the supported syntax for PCI hotplug cmd_type = is_supported_command("device_add", "pci_add") if not cmd_type: raise error.TestError("Unknown version of qemu") # Probe qemu for a list of supported devices probe_output = vm.monitor.human_monitor_cmd("%s ?" % cmd_type, debug=False) devices_supported = [ j.strip('"') for j in re.findall('\"[a-z|0-9|\-|\_|\,|\.]*\"', probe_output, re.MULTILINE) ] logging.debug( "QEMU reported the following supported devices for " "PCI hotplug: %s", devices_supported) return (dev in devices_supported) def verify_supported_device(dev): if not is_supported_device(dev): raise error.TestError("%s doesn't support device: %s" % (cmd_type, dev)) def device_add_nic(pci_num, queues=1): device_id = pci_type + "-" + utils_misc.generate_random_id() pci_info.append([device_id, device_id]) pci_model = params.get("pci_model") if pci_model == "virtio": pci_model = "virtio-net-pci" verify_supported_device(pci_model) pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1], pci_model) if queues > 1 and "virtio" in pci_model: pci_add_cmd += ",mq=on" return device_add(pci_num, pci_add_cmd) def device_add_block(pci_num, queues=1): device_id = pci_type + "-" + utils_misc.generate_random_id() pci_info.append([device_id, device_id]) image_format = params.get("image_format_%s" % img_list[pci_num + 1]) if not image_format: image_format = params.get("image_format", "qcow2") image_filename = find_image(pci_num) pci_model = params.get("pci_model") controller_model = None if pci_model == "virtio": pci_model = "virtio-blk-pci" if pci_model == "scsi" or pci_model == "scsi-hd": if pci_model == "scsi": pci_model = "scsi-disk" if arch.ARCH in ('ppc64', 'ppc64le'): controller_model = "spapr-vscsi" else: controller_model = "lsi53c895a" if pci_model == "scsi-hd": controller_model = "virtio-scsi-pci" verify_supported_device(controller_model) controller_id = "controller-" + device_id if vm.monitor.protocol == "human": controller_add_cmd = ("device_add %s,id=%s" % (controller_model, controller_id)) else: controller_add_cmd = ("device_add driver=%s,id=%s" % (controller_model, controller_id)) error.context("Adding SCSI controller.", logging.info) vm.monitor.send_args_cmd(controller_add_cmd, convert=False) verify_supported_device(pci_model) if drive_cmd_type == "drive_add": driver_add_cmd = ("%s auto file=%s,if=none,format=%s,id=%s" % (drive_cmd_type, image_filename, image_format, pci_info[pci_num][0])) elif drive_cmd_type == "__com.redhat_drive_add": driver_add_cmd = ("%s file=%s,format=%s,id=%s" % (drive_cmd_type, image_filename, image_format, pci_info[pci_num][0])) # add block device to vm device container image_name = img_list[pci_num + 1] image_params = params.object_params(image_name) image_name = pci_info[pci_num][0] blk_insert = vm.devices.images_define_by_params( image_name, image_params, 'disk') vm.devices.insert(blk_insert) env.register_vm(vm.name, vm) # add driver. error.context("Adding driver.", logging.info) vm.monitor.send_args_cmd(driver_add_cmd, convert=False) pci_add_cmd = ("device_add id=%s,driver=%s,drive=%s" % (pci_info[pci_num][1], pci_model, pci_info[pci_num][0])) return device_add(pci_num, pci_add_cmd) def device_add(pci_num, pci_add_cmd): error.context("Adding pci device with command 'device_add'", logging.info) if vm.monitor.protocol == 'qmp': add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) else: add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info[pci_num].append(add_output) pci_info[pci_num].append(pci_model) after_add = vm.monitor.info("pci") if pci_info[pci_num][1] not in str(after_add): logging.error("Could not find matched id in monitor:" " %s" % pci_info[pci_num][1]) raise error.TestFail("Add device failed. Monitor command is: %s" ". Output: %r" % (pci_add_cmd, add_output)) return after_add # Hot add a pci device def add_device(pci_num, queues=1): info_pci_ref = vm.monitor.info("pci") reference = session.cmd_output(reference_cmd) try: # get function for adding device. add_fuction = local_functions["%s_%s" % (cmd_type, pci_type)] except Exception: raise error.TestError("No function for adding '%s' dev with '%s'" % (pci_type, cmd_type)) after_add = None if add_fuction: # Do add pci device. after_add = add_fuction(pci_num, queues) try: # Define a helper function to compare the output def _new_shown(): o = session.cmd_output(reference_cmd) return o != reference # Define a helper function to catch PCI device string def _find_pci(): output = session.cmd_output(params.get("find_pci_cmd")) output = map(string.strip, output.splitlines()) ref = map(string.strip, reference.splitlines()) output = [_ for _ in output if _ not in ref] output = "\n".join(output) if re.search(params.get("match_string"), output, re.I | re.M): return True return False error.context("Start checking new added device", logging.info) # Compare the output of 'info pci' if after_add == info_pci_ref: raise error.TestFail("No new PCI device shown after executing " "monitor command: 'info pci'") secs = int(params.get("wait_secs_for_hook_up")) if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3): raise error.TestFail( "No new device shown in output of command " "executed inside the guest: %s" % reference_cmd) if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3): raise error.TestFail( "PCI %s %s device not found in guest. " "Command was: %s" % (pci_model, pci_type, params.get("find_pci_cmd"))) # Test the newly added device try: if params.get("pci_test_cmd"): test_cmd = re.sub("PCI_NUM", "%s" % (pci_num + 1), params.get("pci_test_cmd")) session.cmd(test_cmd, timeout=disk_op_timeout) except aexpect.ShellError, e: raise error.TestFail("Check for %s device failed after PCI " "hotplug. Output: %r" % (pci_type, e.output)) except Exception: pci_del(pci_num, ignore_failure=True) raise # Hot delete a pci device def pci_del(pci_num, ignore_failure=False): def _device_removed(): after_del = vm.monitor.info("pci") return after_del != before_del before_del = vm.monitor.info("pci") blk_removed = [] if cmd_type == "pci_add": slot_id = int(pci_info[pci_num][2].split(",")[2].split()[1]) cmd = "pci_del pci_addr=%s" % hex(slot_id) vm.monitor.send_args_cmd(cmd, convert=False) blk_removed.append(pci_info[pci_num][1]) elif cmd_type == "device_add": if vm.monitor.protocol == "human": cmd = "device_del %s" % pci_info[pci_num][1] else: cmd = "device_del id=%s" % pci_info[pci_num][1] vm.monitor.send_args_cmd(cmd, convert=False) if params.get("cmd_after_unplug_dev"): cmd = re.sub("PCI_NUM", "%s" % (pci_num + 1), params.get("cmd_after_unplug_dev")) session.cmd(cmd, timeout=disk_op_timeout) blk_removed.append(pci_info[pci_num][1]) pci_model = params.get("pci_model") if pci_model == "scsi" or pci_model == "scsi-hd": controller_id = "controller-" + pci_info[pci_num][0] if vm.monitor.protocol == "human": controller_del_cmd = "device_del %s" % controller_id else: controller_del_cmd = "device_del id=%s" % controller_id error.context("Deleting SCSI controller.", logging.info) vm.monitor.send_args_cmd(controller_del_cmd, convert=False) blk_removed.append(controller_id) if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1) and not ignore_failure): raise error.TestFail("Failed to hot remove PCI device: %s. " "Monitor command: %s" % (pci_info[pci_num][3], cmd)) # Remove the device from vm device container for device in vm.devices: if device.str_short() in blk_removed: vm.devices.remove(device) env.register_vm(vm.name, vm) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) test_timeout = int(params.get("hotplug_timeout", 360)) disk_op_timeout = int(params.get("disk_op_timeout", 360)) reference_cmd = params["reference_cmd"] # Test if it is nic or block pci_type = params["pci_type"] pci_model = params["pci_model"] # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: session.cmd("modprobe %s" % module) # check monitor type qemu_binary = utils_misc.get_qemu_binary(params) qemu_binary = utils_misc.get_path(test.bindir, qemu_binary) # Probe qemu to verify what is the supported syntax for PCI hotplug cmd_type = is_supported_command("device_add", "pci_add") if not cmd_type: raise error.TestError("Could find a suitable method for hotplugging" " device in this version of qemu") # Determine syntax of drive hotplug # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6 # drive_add == qemu-kvm-0.13 onwards drive_cmd_type = is_supported_command("drive_add", "__com.redhat_drive_add") if not drive_cmd_type: raise error.TestError("Could find a suitable method for hotplugging" " drive in this version of qemu") local_functions = locals() pci_num_range = int(params.get("pci_num")) queues = int(params.get("queues", 1)) rp_times = int(params.get("repeat_times")) img_list = params.get("images").split() context_msg = "Running sub test '%s' %s" for j in range(rp_times): # pci_info is a list of list. # each element 'i' has 4 members: # pci_info[i][0] == device drive id, only used for device_add # pci_info[i][1] == device id, only used for device_add # pci_info[i][2] == output of device add command # pci_info[i][3] == device module name. pci_info = [] for pci_num in xrange(pci_num_range): sub_type = params.get("sub_type_before_plug") if sub_type: error.context(context_msg % (sub_type, "before hotplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) error.context("Start hot-adding pci device, repeat %d" % j, logging.info) add_device(pci_num, queues) sub_type = params.get("sub_type_after_plug") if sub_type: error.context(context_msg % (sub_type, "after hotplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) for pci_num in xrange(pci_num_range): sub_type = params.get("sub_type_before_unplug") if sub_type: error.context(context_msg % (sub_type, "before hotunplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) error.context("start hot-deleting pci device, repeat %d" % j, logging.info) pci_del(-(pci_num + 1)) sub_type = params.get("sub_type_after_unplug") if sub_type: error.context(context_msg % (sub_type, "after hotunplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if params.get("reboot_vm", "no") == "yes": vm.reboot()
def run(test, params, env): """ KVM driver load test: 1) Log into a guest 2) Get the driver device id(Windows) or module name(Linux) from guest 3) Unload/load the device driver 4) Check if the device still works properly 5) Repeat step 3-4 several times :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def load_driver(cmd, driver_id): """ Load driver :param cmd: Driver load cmd :param driver_id: Driver id in windows guest """ nic_index = len(vm.virtnet) - 1 session = vm.wait_for_login(nic_index=nic_index) if params["os_type"] == "windows": cmd = cmd.replace("DRIVER_ID", driver_id) status, output = session.cmd_status_output(cmd) session.close() if status != 0: test.fail("failed to load driver, %s" % output) def unload_driver(cmd, driver_id): """ Unload driver :param cmd: Driver unload cmd :param driver_id: Driver id in windows guest """ nic_index = len(vm.virtnet) - 1 session = vm.wait_for_login(nic_index=nic_index) if params["os_type"] == "windows": cmd = cmd.replace("DRIVER_ID", driver_id) status, output = session.cmd_status_output(cmd) session.close() if status != 0: if "reboot" in output: vm.reboot() session.close() else: test.fail("failed to unload driver, %s" % output) def get_driver_id(cmd, pattern): """ Get driver id from guest :param cmd: cmd to get driver info :param pattern: pattern to filter driver id """ nic_index = len(vm.virtnet) - 1 session = vm.wait_for_login(nic_index=nic_index) output = session.cmd_output(cmd) driver_id = re.findall(pattern, output) if not driver_id: test.fail("Didn't find driver info from guest %s" % output) driver_id = driver_id[0] if params["os_type"] == "windows": driver_id = '^&'.join(driver_id.split('&')) session.close() return driver_id def service_operate(cmd, ignore_error=False): """ Stop/Start service :param cmd: cmd to stop/start service :param ignore_error: ignore the cmd error while it's True else raise the error """ session = vm.wait_for_login() session.cmd(cmd, ignore_all_errors=ignore_error) session.close() error_context.context("Try to log into guest.", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) stop_service_cmd = params.get("stop_service_cmd") start_service_cmd = params.get("start_service_cmd") driver_id_pattern = params["driver_id_pattern"] driver_id_cmd = utils_misc.set_winutils_letter( session, params["driver_id_cmd"]) driver_load_cmd = utils_misc.set_winutils_letter( session, params["driver_load_cmd"]) driver_unload_cmd = utils_misc.set_winutils_letter( session, params["driver_unload_cmd"]) session.close() if stop_service_cmd: logging.info("Stop service before driver load testing") service_operate(stop_service_cmd) try: for repeat in range(0, int(params.get("repeats", 1))): error_context.context("Unload and load the driver. Round %s" % repeat, logging.info) logging.info("Get driver info from guest") driver_id = get_driver_id(driver_id_cmd, driver_id_pattern) error_context.context("Unload the driver", logging.info) unload_driver(driver_unload_cmd, driver_id) time.sleep(5) error_context.context("Load the driver", logging.info) load_driver(driver_load_cmd, driver_id) time.sleep(5) finally: if start_service_cmd: logging.info("Restart service after driver load testing") service_operate(start_service_cmd, ignore_error=True) test_after_load = params.get("test_after_load") if test_after_load: utils_test.run_virt_sub_test(test, params, env, sub_type=test_after_load)
def test(self): self.iso_image_orig = create_iso_image(params, "orig") self.iso_image_new = create_iso_image(params, "new") self.cdrom_dir = os.path.dirname(self.iso_image_new) if params.get("not_insert_at_start") == "yes": target_cdrom = params["target_cdrom"] params[target_cdrom] = "" params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) vm = env.get_vm(params["main_vm"]) self.session = vm.wait_for_login(timeout=login_timeout) pre_cmd = params.get("pre_cmd") if pre_cmd: self.session.cmd(pre_cmd, timeout=120) self.session = vm.reboot() iso_image = self.iso_image_orig error.context("Query cdrom devices in guest") cdrom_dev_list = list_guest_cdroms(self.session) logging.debug("cdrom_dev_list: '%s'", cdrom_dev_list) if params.get('not_insert_at_start') == "yes": error.context("Locked without media present", logging.info) # XXX: The device got from monitor might not match with the guest # defice if there are multiple cdrom devices. qemu_cdrom_device = get_empty_cdrom_device(vm) guest_cdrom_device = cdrom_dev_list[-1] if vm.check_block_locked(qemu_cdrom_device): raise error.TestFail("Device should not be locked just" " after booting up") cmd = params["lock_cdrom_cmd"] % guest_cdrom_device self.session.cmd(cmd) if not vm.check_block_locked(qemu_cdrom_device): raise error.TestFail("Device is not locked as expect.") return error.context("Detecting the existence of a cdrom (guest OS side)", logging.info) cdrom_dev_list = list_guest_cdroms(self.session) try: guest_cdrom_device = cdrom_dev_list[-1] except IndexError: raise error.TestFail("Could not find a valid cdrom device") error.context("Detecting the existence of a cdrom (qemu side)", logging.info) qemu_cdrom_device = get_device(vm, iso_image) self.session.get_command_output("umount %s" % guest_cdrom_device) if params.get('cdrom_test_autounlock') == 'yes': error.context("Trying to unlock the cdrom", logging.info) _f = lambda: not vm.check_block_locked(qemu_cdrom_device) if not utils_misc.wait_for(_f, 300): raise error.TestFail("Device %s could not be" " unlocked" % (qemu_cdrom_device)) del _f max_test_times = int(params.get("cdrom_max_test_times", 100)) if params.get("cdrom_test_eject") == "yes": eject_test_via_monitor(vm, qemu_cdrom_device, guest_cdrom_device, self.iso_image_orig, self.iso_image_new, max_test_times) if params.get('cdrom_test_tray_status') == 'yes': check_tray_status_test(vm, qemu_cdrom_device, guest_cdrom_device, max_test_times) if params.get('cdrom_test_locked') == 'yes': check_tray_locked_test(vm, qemu_cdrom_device, guest_cdrom_device) error.context("Check whether the cdrom is read-only", logging.info) cmd = params["readonly_test_cmd"] % guest_cdrom_device try: self.session.cmd(cmd) raise error.TestFail("Attempt to format cdrom %s succeeded" % (guest_cdrom_device)) except aexpect.ShellError: pass sub_test = params.get("sub_test") if sub_test: error.context("Run sub test '%s' before doing file" " operation" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test) if params.get("cdrom_test_file_operation") == "yes": file_operation_test(self.session, guest_cdrom_device, max_test_times) error.context("Cleanup") # Return the self.iso_image_orig cdfile = get_cdrom_file(vm, qemu_cdrom_device) if cdfile != self.iso_image_orig: time.sleep(workaround_eject_time) self.session.cmd(params["eject_cdrom_cmd"] % guest_cdrom_device) vm.eject_cdrom(qemu_cdrom_device) if get_cdrom_file(vm, qemu_cdrom_device) is not None: raise error.TestFail("Device %s was not ejected" " in clearup stage" % qemu_cdrom_device) vm.change_media(qemu_cdrom_device, self.iso_image_orig) if get_cdrom_file(vm, qemu_cdrom_device) != self.iso_image_orig: raise error.TestFail("It wasn't possible to change" " cdrom %s" % iso_image) post_cmd = params.get("post_cmd") if post_cmd: self.session.cmd(post_cmd) if params.get("guest_suspend_type"): self.session = vm.reboot()
offset = vm_assigned_mem - guest_memory # Reduce memory to random size between Free memory # to max memory size s, o = session.cmd_status_output("cat /proc/meminfo") if s != 0: raise error.TestError("Can not get guest memory information") vm_mem_free = int(re.findall('MemFree:\s+(\d+).*', o)[0]) / 1024 new_mem = int(random.uniform(vm_assigned_mem - vm_mem_free, vm_assigned_mem)) fail += balloon_memory(new_mem, offset) # Run option test after evict memory if 'sub_balloon_test_evict' in params: balloon_test = params['sub_balloon_test_evict'] utils_test.run_virt_sub_test(test, params, env, sub_type=balloon_test) if balloon_test == "shutdown" : logging.info("Guest shutdown normally after balloon") return # Reset memory value to original memory assigned on qemu. This will ensure # we won't trigger guest OOM killer while running multiple iterations fail += balloon_memory(vm_assigned_mem, offset) # Run sub test after enlarge memory if 'sub_balloon_test_enlarge' in params: balloon_test = params['sub_balloon_test_enlarge'] utils_test.run_virt_sub_test(test, params, env, sub_type=balloon_test) if balloon_test == "shutdown" : logging.info("Guest shutdown normally after balloon") return
def run(test, params, env): """ Test hotplug of sr-iov devices. (Elements between [] are configurable test parameters) 1) Set up sr-iov test environment in host. 2) Start VM. 3) Disable the primary link(s) of guest. 4) PCI add one/multi sr-io deivce with (or without) repeat 5) Compare output of monitor command 'info pci'. 6) Compare output of guest command [reference_cmd]. 7) Verify whether pci_model is shown in [pci_find_cmd]. 8) Check whether the newly added PCI device works fine. 9) Delete the device, verify whether could remove the sr-iov device. 10) Re-enabling the primary link(s) of guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_active_network_device(session, nic_filter): devnames = [] cmd = "ifconfig -a" status, output = session.cmd_status_output(cmd) if status: msg = "Guest command '%s' fail with output: %s." % (cmd, output) raise error.TestError(msg) devnames = re.findall(nic_filter, output) return devnames def pci_add_iov(pci_num): pci_add_cmd = ("pci_add pci_addr=auto host host=%s,if=%s" % (pa_pci_ids[pci_num], pci_model)) if params.get("hotplug_params"): assign_param = params.get("hotplug_params").split() for param in assign_param: value = params.get(param) if value: pci_add_cmd += ",%s=%s" % (param, value) return pci_add(pci_add_cmd) def pci_add(pci_add_cmd): error.context("Adding pci device with command 'pci_add'") add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info.append(['', add_output]) if not "OK domain" in add_output: raise error.TestFail("Add PCI device failed. " "Monitor command is: %s, Output: %r" % (pci_add_cmd, add_output)) return vm.monitor.info("pci") def check_support_device(dev): if vm.monitor.protocol == 'qmp': devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type) else: devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type) # Check if the device is support in qemu is_support = utils_misc.find_substring(devices_supported, dev) if not is_support: raise error.TestError("%s doesn't support device: %s" % (cmd_type, dev)) def device_add_iov(pci_num): device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id() pci_info.append([device_id]) driver = params.get("device_driver", "pci-assign") check_support_device(driver) pci_add_cmd = ("device_add id=%s,driver=%s,host=%s" % (pci_info[pci_num][0], driver, pa_pci_ids[pci_num])) if params.get("hotplug_params"): assign_param = params.get("hotplug_params").split() for param in assign_param: value = params.get(param) if value: pci_add_cmd += ",%s=%s" % (param, value) return device_add(pci_num, pci_add_cmd) def device_add(pci_num, pci_add_cmd): error.context("Adding pci device with command 'device_add'") if vm.monitor.protocol == 'qmp': add_output = vm.monitor.send_args_cmd(pci_add_cmd) else: add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info[pci_num].append(add_output) after_add = vm.monitor.info("pci") if pci_info[pci_num][0] not in after_add: logging.debug("Print info pci after add the block: %s" % after_add) raise error.TestFail("Add device failed. Monitor command is: %s" ". Output: %r" % (pci_add_cmd, add_output)) return after_add # Hot add a pci device def add_device(pci_num): reference_cmd = params["reference_cmd"] find_pci_cmd = params["find_pci_cmd"] info_pci_ref = vm.monitor.info("pci") reference = session.cmd_output(reference_cmd) active_nics = get_active_network_device(session, nic_filter) try: # get function for adding device. add_fuction = local_functions["%s_iov" % cmd_type] except Exception: raise error.TestError( "No function for adding sr-iov dev with '%s'" % cmd_type) after_add = None if add_fuction: # Do add pci device. after_add = add_fuction(pci_num) try: # Define a helper function to compare the output def _new_shown(): output = session.cmd_output(reference_cmd) return output != reference # Define a helper function to make sure new nic could get ip. def _check_ip(): post_nics = get_active_network_device(session, nic_filter) return (len(active_nics) <= len(post_nics) and active_nics != post_nics) # Define a helper function to catch PCI device string def _find_pci(): output = session.cmd_output(find_pci_cmd) if re.search(match_string, output, re.IGNORECASE): return True else: return False error.context("Start checking new added device") # Compare the output of 'info pci' if after_add == info_pci_ref: raise error.TestFail("No new PCI device shown after executing " "monitor command: 'info pci'") secs = int(params["wait_secs_for_hook_up"]) if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3): raise error.TestFail("No new device shown in output of command " "executed inside the guest: %s" % reference_cmd) if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3): raise error.TestFail("New add device not found in guest. " "Command was: %s" % find_pci_cmd) # Test the newly added device if not utils_misc.wait_for(_check_ip, 30, 3, 3): ifconfig = session.cmd_output("ifconfig -a") raise error.TestFail("New hotpluged device could not get ip " "after 30s in guest. guest ifconfig " "output: \n%s" % ifconfig) try: session.cmd(params["pci_test_cmd"] % (pci_num + 1)) except aexpect.ShellError, e: raise error.TestFail("Check device failed after PCI " "hotplug. Output: %r" % e.output) except Exception: pci_del(pci_num, ignore_failure=True) raise # Hot delete a pci device def pci_del(pci_num, ignore_failure=False): def _device_removed(): after_del = vm.monitor.info("pci") return after_del != before_del before_del = vm.monitor.info("pci") if cmd_type == "pci_add": slot_id = "0" + pci_info[pci_num][1].split(",")[2].split()[1] cmd = "pci_del pci_addr=%s" % slot_id vm.monitor.send_args_cmd(cmd, convert=False) elif cmd_type == "device_add": cmd = "device_del id=%s" % pci_info[pci_num][0] vm.monitor.send_args_cmd(cmd) if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1) and not ignore_failure): raise error.TestFail("Failed to hot remove PCI device: %s. " "Monitor command: %s" % (pci_model, cmd)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_serial_login(timeout=timeout) test_timeout = int(params.get("test_timeout", 360)) # Test if it is nic or block pci_num_range = int(params.get("pci_num", 1)) rp_times = int(params.get("repeat_times", 1)) pci_model = params.get("pci_model", "pci-assign") # Need udpate match_string if you use a card other than 82576 match_string = params.get("match_string", "82576") nic_filter = params["nic_interface_filter"] devices = [] device_type = params.get("hotplug_device_type", "vf") for i in xrange(pci_num_range): device = {} device["type"] = device_type device['mac'] = utils_net.generate_mac_address_simple() if params.get("device_name"): device["name"] = params.get("device_name") devices.append(device) device_driver = params.get("device_driver", "pci-assign") if vm.pci_assignable is None: vm.pci_assignable = test_setup.PciAssignable( driver=params.get("driver"), driver_option=params.get("driver_option"), host_set_flag=params.get("host_setup_flag"), kvm_params=params.get("kvm_default"), vf_filter_re=params.get("vf_filter_re"), pf_filter_re=params.get("pf_filter_re"), device_driver=device_driver) pa_pci_ids = vm.pci_assignable.request_devs(devices) # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: error.context("modprobe the module %s" % module, logging.info) session.cmd("modprobe %s" % module) # Probe qemu to verify what is the supported syntax for PCI hotplug if vm.monitor.protocol == 'qmp': cmd_o = vm.monitor.info("commands") else: cmd_o = vm.monitor.send_args_cmd("help") cmd_type = utils_misc.find_substring(str(cmd_o), "device_add", "pci_add") if not cmd_o: raise error.TestError("Unknow version of qemu") local_functions = locals() error.context("Disable the primary link(s) of guest", logging.info) for nic in vm.virtnet: vm.set_link(nic.device_id, up=False) try: for j in range(rp_times): # pci_info is a list of list. # each element 'i' has 4 members: # pci_info[i][0] == device id, only used for device_add # pci_info[i][1] == output of device add command pci_info = [] for pci_num in xrange(pci_num_range): msg = "Start hot-adding %sth pci device," % (pci_num + 1) msg += " repeat %d" % (j + 1) error.context(msg, logging.info) add_device(pci_num) sub_type = params.get("sub_type_after_plug") if sub_type: error.context("Running sub test '%s' after hotplug" % sub_type, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if "guest_suspend" == sub_type: # Hotpluged device have been released after guest suspend, # so do not need unpluged step. break for pci_num in xrange(pci_num_range): msg = "start hot-deleting %sth pci device," % (pci_num + 1) msg += " repeat %d" % (j + 1) error.context(msg, logging.info) pci_del(-(pci_num + 1)) finally: error.context("Re-enabling the primary link(s) of guest", logging.info) for nic in vm.virtnet: vm.set_link(nic.device_id, up=True)
def run(test, params, env): """ Test hot unplug of PCI devices. 1) Set up test environment in host if test sr-iov. 2) Start VM. 3) Get the device id that want to unplug. 4) Delete the device, verify whether could remove the PCI device. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def find_pci(): output = vm.monitor.info("qtree") devices = re.findall(match_string, output) return devices # Hot delete a pci device def pci_del(device, ignore_failure=False): def _device_removed(): after_del = vm.monitor.info("pci") return after_del != before_del before_del = vm.monitor.info("pci") if cmd_type == "device_del": cmd = "device_del id=%s" % device vm.monitor.send_args_cmd(cmd) else: raise error.TestFail("device_del command is not supported") if not utils_misc.wait_for(_device_removed, test_timeout, 0, 1) and not ignore_failure: raise error.TestFail("Failed to hot remove PCI device: %s. " "Monitor command: %s" % (pci_model, cmd)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) test_timeout = int(params.get("test_timeout", 360)) # Test if it is nic or block pci_num = int(params.get("unplug_pci_num", 1)) pci_model = params.get("pci_model", "pci-assign") # Need udpate match_string if you use a card other than 82576 match_string = params.get("match_string", 'dev: %s, id "(.*)"') match_string = match_string % pci_model # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: error.context("modprobe the module %s" % module, logging.info) session.cmd("modprobe %s" % module) # check monitor type is_qmp_monitor = utils_misc.qemu_has_option("qmp") and params.get("monitor_type") == "qmp" # Probe qemu to verify what is the supported syntax for PCI hotplug if is_qmp_monitor: cmd_o = vm.monitor.info("commands") else: cmd_o = vm.monitor.send_args_cmd("help") if not cmd_o: raise error.TestError("Unknow version of qemu") cmd_type = utils_misc.find_substring(str(cmd_o), "device_del") devices = find_pci() context_msg = "Running sub test '%s' %s" sub_type = params.get("sub_type_before_unplug") if sub_type: error.context(context_msg % (sub_type, "before unplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if devices: for device in devices[:pci_num]: # (lmr) I think here is the place where pci_info should go pci_info = [] error.context("Hot unplug device %s" % device, logging.info) pci_del(device) sub_type = params.get("sub_type_after_unplug") if sub_type: error.context(context_msg % (sub_type, "after hotunplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type)
def run(test, params, env): """ Test hotplug of sr-iov devices. (Elements between [] are configurable test parameters) 1) Set up sr-iov test environment in host. 2) Start VM. 3) Disable the primary link(s) of guest. 4) PCI add one/multi sr-io deivce with (or without) repeat 5) Compare output of monitor command 'info pci'. 6) Compare output of guest command [reference_cmd]. 7) Verify whether pci_model is shown in [pci_find_cmd]. 8) Check whether the newly added PCI device works fine. 9) Delete the device, verify whether could remove the sr-iov device. 10) Re-enabling the primary link(s) of guest. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_active_network_device(session, nic_filter): devnames = [] cmd = "ifconfig -a" status, output = session.cmd_status_output(cmd) if status: msg = "Guest command '%s' fail with output: %s." % (cmd, output) raise error.TestError(msg) devnames = re.findall(nic_filter, output) return devnames def pci_add_iov(pci_num): pci_add_cmd = ("pci_add pci_addr=auto host host=%s,if=%s" % (pa_pci_ids[pci_num], pci_model)) if params.get("hotplug_params"): assign_param = params.get("hotplug_params").split() for param in assign_param: value = params.get(param) if value: pci_add_cmd += ",%s=%s" % (param, value) return pci_add(pci_add_cmd) def pci_add(pci_add_cmd): error.context("Adding pci device with command 'pci_add'") add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info.append(['', add_output]) if "OK domain" not in add_output: raise error.TestFail("Add PCI device failed. " "Monitor command is: %s, Output: %r" % (pci_add_cmd, add_output)) return vm.monitor.info("pci") def check_support_device(dev): if vm.monitor.protocol == 'qmp': devices_supported = vm.monitor.human_monitor_cmd("%s ?" % cmd_type) else: devices_supported = vm.monitor.send_args_cmd("%s ?" % cmd_type) # Check if the device is support in qemu is_support = utils_misc.find_substring(devices_supported, dev) if not is_support: raise error.TestError("%s doesn't support device: %s" % (cmd_type, dev)) def device_add_iov(pci_num): device_id = "%s" % pci_model + "-" + utils_misc.generate_random_id() pci_info.append([device_id]) driver = params.get("device_driver", "pci-assign") check_support_device(driver) pci_add_cmd = ("device_add id=%s,driver=%s,host=%s" % (pci_info[pci_num][0], driver, pa_pci_ids[pci_num])) if params.get("hotplug_params"): assign_param = params.get("hotplug_params").split() for param in assign_param: value = params.get(param) if value: pci_add_cmd += ",%s=%s" % (param, value) return device_add(pci_num, pci_add_cmd) def device_add(pci_num, pci_add_cmd): error.context("Adding pci device with command 'device_add'") if vm.monitor.protocol == 'qmp': add_output = vm.monitor.send_args_cmd(pci_add_cmd) else: add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info[pci_num].append(add_output) after_add = vm.monitor.info("pci") if pci_info[pci_num][0] not in str(after_add): logging.debug("Print info pci after add the block: %s" % after_add) raise error.TestFail("Add device failed. Monitor command is: %s" ". Output: %r" % (pci_add_cmd, add_output)) return after_add # Hot add a pci device def add_device(pci_num): reference_cmd = params["reference_cmd"] find_pci_cmd = params["find_pci_cmd"] info_pci_ref = vm.monitor.info("pci") reference = session.cmd_output(reference_cmd) active_nics = get_active_network_device(session, nic_filter) try: # get function for adding device. add_fuction = local_functions["%s_iov" % cmd_type] except Exception: raise error.TestError( "No function for adding sr-iov dev with '%s'" % cmd_type) after_add = None if add_fuction: # Do add pci device. after_add = add_fuction(pci_num) try: # Define a helper function to compare the output def _new_shown(): output = session.cmd_output(reference_cmd) return output != reference # Define a helper function to make sure new nic could get ip. def _check_ip(): post_nics = get_active_network_device(session, nic_filter) return (len(active_nics) <= len(post_nics) and active_nics != post_nics) # Define a helper function to catch PCI device string def _find_pci(): output = session.cmd_output(find_pci_cmd) if re.search(match_string, output, re.IGNORECASE): return True else: return False error.context("Start checking new added device") # Compare the output of 'info pci' if after_add == info_pci_ref: raise error.TestFail("No new PCI device shown after executing " "monitor command: 'info pci'") secs = int(params["wait_secs_for_hook_up"]) if not utils_misc.wait_for(_new_shown, test_timeout, secs, 3): raise error.TestFail( "No new device shown in output of command " "executed inside the guest: %s" % reference_cmd) if not utils_misc.wait_for(_find_pci, test_timeout, 3, 3): raise error.TestFail("New add device not found in guest. " "Command was: %s" % find_pci_cmd) # Test the newly added device if not utils_misc.wait_for(_check_ip, 120, 3, 3): ifconfig = session.cmd_output("ifconfig -a") raise error.TestFail("New hotpluged device could not get ip " "after 120s in guest. guest ifconfig " "output: \n%s" % ifconfig) try: session.cmd(params["pci_test_cmd"] % (pci_num + 1)) except aexpect.ShellError, e: raise error.TestFail("Check device failed after PCI " "hotplug. Output: %r" % e.output) except Exception: pci_del(pci_num, ignore_failure=True) raise # Hot delete a pci device def pci_del(pci_num, ignore_failure=False): def _device_removed(): after_del = vm.monitor.info("pci") return after_del != before_del before_del = vm.monitor.info("pci") if cmd_type == "pci_add": slot_id = "0" + pci_info[pci_num][1].split(",")[2].split()[1] cmd = "pci_del pci_addr=%s" % slot_id vm.monitor.send_args_cmd(cmd, convert=False) elif cmd_type == "device_add": cmd = "device_del id=%s" % pci_info[pci_num][0] vm.monitor.send_args_cmd(cmd) if (not utils_misc.wait_for(_device_removed, test_timeout, 0, 1) and not ignore_failure): raise error.TestFail("Failed to hot remove PCI device: %s. " "Monitor command: %s" % (pci_model, cmd)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_serial_login(timeout=timeout) test_timeout = int(params.get("test_timeout", 360)) # Test if it is nic or block pci_num_range = int(params.get("pci_num", 1)) rp_times = int(params.get("repeat_times", 1)) pci_model = params.get("pci_model", "pci-assign") # Need udpate match_string if you use a card other than 82576 match_string = params.get("match_string", "82576") generate_mac = params.get("generate_mac", "yes") nic_filter = params["nic_interface_filter"] devices = [] device_type = params.get("hotplug_device_type", "vf") for i in xrange(pci_num_range): device = {} device["type"] = device_type if generate_mac == "yes": device['mac'] = utils_net.generate_mac_address_simple() if params.get("device_name"): device["name"] = params.get("device_name") devices.append(device) device_driver = params.get("device_driver", "pci-assign") if vm.pci_assignable is None: vm.pci_assignable = test_setup.PciAssignable( driver=params.get("driver"), driver_option=params.get("driver_option"), host_set_flag=params.get("host_setup_flag"), kvm_params=params.get("kvm_default"), vf_filter_re=params.get("vf_filter_re"), pf_filter_re=params.get("pf_filter_re"), device_driver=device_driver) pa_pci_ids = vm.pci_assignable.request_devs(devices) # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: error.context("modprobe the module %s" % module, logging.info) session.cmd("modprobe %s" % module) # Probe qemu to verify what is the supported syntax for PCI hotplug if vm.monitor.protocol == 'qmp': cmd_o = vm.monitor.info("commands") else: cmd_o = vm.monitor.send_args_cmd("help") cmd_type = utils_misc.find_substring(str(cmd_o), "device_add", "pci_add") if not cmd_o: raise error.TestError("Unknown version of qemu") local_functions = locals() if params.get("enable_set_link" "yes") == "yes": error.context("Disable the primary link(s) of guest", logging.info) for nic in vm.virtnet: vm.set_link(nic.device_id, up=False) try: for j in range(rp_times): # pci_info is a list of list. # each element 'i' has 4 members: # pci_info[i][0] == device id, only used for device_add # pci_info[i][1] == output of device add command pci_info = [] for pci_num in xrange(pci_num_range): msg = "Start hot-adding %sth pci device," % (pci_num + 1) msg += " repeat %d" % (j + 1) error.context(msg, logging.info) add_device(pci_num) sub_type = params.get("sub_type_after_plug") if sub_type: error.context("Running sub test '%s' after hotplug" % sub_type, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) if "guest_suspend" == sub_type: # Hotpluged device have been released after guest suspend, # so do not need unpluged step. break for pci_num in xrange(pci_num_range): msg = "start hot-deleting %sth pci device," % (pci_num + 1) msg += " repeat %d" % (j + 1) error.context(msg, logging.info) pci_del(-(pci_num + 1)) finally: if params.get("enable_set_link", "yes") == "yes": error.context("Re-enabling the primary link(s) of guest", logging.info) for nic in vm.virtnet: vm.set_link(nic.device_id, up=True)
def test(self): self.iso_image_orig = create_iso_image(params, "orig") self.iso_image_new = create_iso_image(params, "new") self.cdrom_dir = os.path.dirname(self.iso_image_new) if params.get("not_insert_at_start") == "yes": target_cdrom = params["target_cdrom"] params[target_cdrom] = "" params["start_vm"] = "yes" serial_num = generate_serial_num() cdrom = params.get("cdroms", "").split()[-1] params["drive_serial_%s" % cdrom] = serial_num env_process.preprocess_vm(test, params, env, params["main_vm"]) vm = env.get_vm(params["main_vm"]) self.session = vm.wait_for_login(timeout=login_timeout) pre_cmd = params.get("pre_cmd") if pre_cmd: self.session.cmd(pre_cmd, timeout=120) self.session = vm.reboot() iso_image = self.iso_image_orig error.context("Query cdrom devices in guest") cdrom_dev_list = list_guest_cdroms(self.session) logging.debug("cdrom_dev_list: '%s'", cdrom_dev_list) if params.get('not_insert_at_start') == "yes": error.context("Locked without media present", logging.info) # XXX: The device got from monitor might not match with the guest # defice if there are multiple cdrom devices. qemu_cdrom_device = get_empty_cdrom_device(vm) guest_cdrom_device = get_testing_cdrom_device( vm, self.session, cdrom_dev_list, serial_num) if vm.check_block_locked(qemu_cdrom_device): raise error.TestFail("Device should not be locked just" " after booting up") cmd = params["lock_cdrom_cmd"] % guest_cdrom_device self.session.cmd(cmd) if not vm.check_block_locked(qemu_cdrom_device): raise error.TestFail("Device is not locked as expect.") return error.context("Detecting the existence of a cdrom (guest OS side)", logging.info) cdrom_dev_list = list_guest_cdroms(self.session) guest_cdrom_device = get_testing_cdrom_device( vm, self.session, cdrom_dev_list, serial_num) error.context("Detecting the existence of a cdrom (qemu side)", logging.info) qemu_cdrom_device = get_device(vm, iso_image) if params["os_type"] != "windows": self.session.get_command_output("umount %s" % guest_cdrom_device) if params.get('cdrom_test_autounlock') == 'yes': error.context("Trying to unlock the cdrom", logging.info) if not utils_misc.wait_for( lambda: not vm.check_block_locked(qemu_cdrom_device), 300): raise error.TestFail("Device %s could not be" " unlocked" % (qemu_cdrom_device)) max_test_times = int(params.get("cdrom_max_test_times", 100)) if params.get("cdrom_test_eject") == "yes": eject_test_via_monitor(vm, qemu_cdrom_device, guest_cdrom_device, self.iso_image_orig, self.iso_image_new, max_test_times) if params.get('cdrom_test_tray_status') == 'yes': check_tray_status_test(vm, qemu_cdrom_device, guest_cdrom_device, max_test_times, self.iso_image_new) if params.get('cdrom_test_locked') == 'yes': check_tray_locked_test(vm, qemu_cdrom_device, guest_cdrom_device) error.context("Check whether the cdrom is read-only", logging.info) cmd = params["readonly_test_cmd"] % guest_cdrom_device try: self.session.cmd(cmd) raise error.TestFail("Attempt to format cdrom %s succeeded" % (guest_cdrom_device)) except aexpect.ShellError: pass sub_test = params.get("sub_test") if sub_test: error.context( "Run sub test '%s' before doing file" " operation" % sub_test, logging.info) utils_test.run_virt_sub_test(test, params, env, sub_test) if params.get("cdrom_test_file_operation") == "yes": file_operation_test(self.session, guest_cdrom_device, max_test_times) error.context("Cleanup") # Return the self.iso_image_orig cdfile = get_cdrom_file(vm, qemu_cdrom_device) if cdfile != self.iso_image_orig: time.sleep(workaround_eject_time) self.session.cmd(params["eject_cdrom_cmd"] % guest_cdrom_device) vm.eject_cdrom(qemu_cdrom_device) if get_cdrom_file(vm, qemu_cdrom_device) is not None: raise error.TestFail("Device %s was not ejected" " in clearup stage" % qemu_cdrom_device) vm.change_media(qemu_cdrom_device, self.iso_image_orig) if get_cdrom_file(vm, qemu_cdrom_device) != self.iso_image_orig: raise error.TestFail("It wasn't possible to change" " cdrom %s" % iso_image) post_cmd = params.get("post_cmd") if post_cmd: self.session.cmd(post_cmd) if params.get("guest_suspend_type"): self.session = vm.reboot()