def lv_take_snapshot(vg_name, lv_name, lv_snapshot_name, lv_snapshot_size): """ Take a snapshot of the original logical volume. """ error.context("Taking snapshot from original logical volume", logging.info) if not vg_check(vg_name): raise error.TestError("Volume group could not be found") if lv_check(vg_name, lv_snapshot_name): raise error.TestError("Snapshot already exists") if not lv_check(vg_name, lv_name): raise error.TestError("Snapshot's origin could not be found") cmd = ("lvcreate --size %s --snapshot --name %s /dev/%s/%s" % (lv_snapshot_size, lv_snapshot_name, vg_name, lv_name)) try: result = utils.run(cmd) except error.CmdError, ex: if ('Logical volume "%s" already exists in volume group "%s"' % (lv_snapshot_name, vg_name) in ex.result_obj.stderr and re.search(re.escape(lv_snapshot_name + " [active]"), utils.run("lvdisplay").stdout)): # the above conditions detect if merge of snapshot was postponed logging.warning(("Logical volume %s is still active! " + "Attempting to deactivate..."), lv_name) lv_reactivate(vg_name, lv_name) result = utils.run(cmd) else: raise ex
def _get_service_cmds(self): """ Figure out the commands used to control the NFS service. """ error.context("Finding out appropriate commands to handle NFS service") service = os_dep.command("service") try: systemctl = os_dep.command("systemctl") except ValueError: systemctl = None if systemctl is not None: init_script = "/etc/init.d/nfs" service_file = "/lib/systemd/system/nfs-server.service" if os.path.isfile(init_script): service_name = "nfs" elif os.path.isfile(service_file): service_name = "nfs-server" else: raise error.TestError("Files %s and %s absent, don't know " "how to set up NFS for this host" % (init_script, service_file)) start_cmd = "%s start %s.service" % (systemctl, service_name) stop_cmd = "%s stop %s.service" % (systemctl, service_name) restart_cmd = "%s restart %s.service" % (systemctl, service_name) status_cmd = "%s status %s.service" % (systemctl, service_name) else: start_cmd = "%s nfs start" % service stop_cmd = "%s nfs stop" % service restart_cmd = "%s nfs restart" % service status_cmd = "%s nfs status" % service return [start_cmd, stop_cmd, restart_cmd, status_cmd]
def run_balloon_check(test, params, env): """ Check Memory ballooning, use M when compare memory in this script: 1) Boot a guest with balloon enabled. 2) Balloon guest memory to given value and run sub test(Optional) 3) Repeat step 2 following the cfg files. 8) Reset memory back to the original value :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ if params['os_type'] == 'windows': balloon_test = BallooningTestWin(test, params, env) else: balloon_test = BallooningTestLinux(test, params, env) for tag in params.objects('test_tags'): error.context("Running %s test" % tag, logging.info) params_tag = params.object_params(tag) if params_tag.get('expect_memory'): expect_mem = int(params_tag.get('expect_memory')) elif params_tag.get('expect_memory_ratio'): expect_mem = int(balloon_test.ori_mem * float(params_tag.get('expect_memory_ratio'))) else: balloon_type = params_tag['balloon_type'] min_sz, max_sz = balloon_test.get_memory_boundary(balloon_type) expect_mem = int(random.uniform(min_sz, max_sz)) quit_after_test = balloon_test.run_ballooning_test(expect_mem, tag) if quit_after_test: return balloon_test.reset_memory()
def vg_ramdisk(vg_name, ramdisk_vg_size, ramdisk_basedir, ramdisk_sparse_filename): """ Create vg on top of ram memory to speed up lv performance. """ error.context("Creating virtual group on top of ram memory", logging.info) vg_size = ramdisk_vg_size vg_ramdisk_dir = os.path.join(ramdisk_basedir, vg_name) ramdisk_filename = os.path.join(vg_ramdisk_dir, ramdisk_sparse_filename) vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name) result = "" if not os.path.exists(vg_ramdisk_dir): os.mkdir(vg_ramdisk_dir) try: logging.info("Mounting tmpfs") result = utils.run("mount -t tmpfs tmpfs %s" % vg_ramdisk_dir) logging.info("Converting and copying /dev/zero") cmd = ("dd if=/dev/zero of=%s bs=1M count=1 seek=%s" % (ramdisk_filename, vg_size)) result = utils.run(cmd, verbose=True) logging.info("Finding free loop device") result = utils.run("losetup --find", verbose=True) except error.CmdError, ex: logging.error(ex) vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name) raise ex
def check_cluster_size(parttern, expect, csize_set): cfail = 0 fail_log = "" image_name = params.get("images") image_params = params.object_params(image_name) image = qemu_storage.QemuImg(image_params, data_dir.get_data_dir(), image_name) image.create(image_params) output = image.info() error.context("Check the cluster size from output", logging.info) cluster_size = re.findall(parttern, output) if cluster_size: if cluster_size[0] != expect: logging.error("Cluster size mismatch") logging.error("Cluster size report by command: %s" % cluster_size) logging.error("Cluster size expect: %s" % expect) cfail += 1 fail_log += "Cluster size mismatch when set it to " fail_log += "%s.\n" % csize_set else: logging.error("Can not get the cluster size from command: %s" % output) cfail += 1 fail_log += "Can not get the cluster size from command:" fail_log += " %s\n" % output return cfail, fail_log
def test(self): super(test_multihost_ejecting, self).test() if self.is_src: # Starts in source self.cdrom_new = create_iso_image(params, "new") vm = env.get_vm(self.vms[0]) session = vm.wait_for_login(timeout=login_timeout) cdrom_dev_list = list_guest_cdroms(session) logging.debug("cdrom_dev_list: %s", cdrom_dev_list) device = get_device(vm, self.cdrom_orig) cdrom = cdrom_dev_list[-1] error.context("Eject cdrom.") session.cmd(params["eject_cdrom_cmd"] % cdrom) vm.eject_cdrom(device) time.sleep(2) if get_cdrom_file(vm, device) is not None: raise error.TestFail("Device %s was not ejected" % (cdrom)) cdrom = self.cdrom_new error.context("Change cdrom.") vm.change_media(device, cdrom) if get_cdrom_file(vm, device) != cdrom: raise error.TestFail("It wasn't possible to change " "cdrom %s" % (cdrom)) time.sleep(workaround_eject_time) self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts, 'cdrom_dev', cdrom_prepare_timeout) self.mig.migrate_wait([self.vms[0]], self.srchost, self.dsthost)
def create_iso_image(params, name, prepare=True, file_size=None): """ Creates 'new' iso image with one file on it :param params: parameters for test :param name: name of new iso image file :param preapre: if True then it prepare cd images. :param file_size: Size of iso image in MB :return: path to new iso image file. """ error.context("Creating test iso image '%s'" % name, logging.info) cdrom_cd = params["target_cdrom"] cdrom_cd = params[cdrom_cd] if not os.path.isabs(cdrom_cd): cdrom_cd = utils_misc.get_path(data_dir.get_data_dir(), cdrom_cd) iso_image_dir = os.path.dirname(cdrom_cd) if file_size is None: file_size = 10 file_name = utils_misc.get_path(iso_image_dir, "%s.iso" % (name)) if prepare: cmd = "dd if=/dev/urandom of=%s bs=1M count=%d" utils.run(cmd % (name, file_size)) utils.run("mkisofs -o %s %s" % (file_name, name)) utils.run("rm -rf %s" % (name)) return file_name
def check_tray_locked_test(vm, qemu_cdrom_device, guest_cdrom_device): """ Test cdrom tray locked function. """ error.context("Check cdrom tray status after cdrom is locked", logging.info) session = vm.wait_for_login(timeout=login_timeout) tmp_is_trap_open = is_tray_opened(vm, qemu_cdrom_device, mode='mixed', dev_name=guest_cdrom_device) if tmp_is_trap_open is None: logging.warn("Tray status reporting is not supported by qemu!") logging.warn("cdrom_test_locked test is skipped...") return eject_failed = False eject_failed_msg = "Tray should be closed even in locked status" session.cmd(params["eject_cdrom_cmd"] % guest_cdrom_device) tmp_is_trap_open = is_tray_opened(vm, qemu_cdrom_device, mode='mixed', dev_name=guest_cdrom_device) if not tmp_is_trap_open: raise error.TestFail("Tray should not in closed status") session.cmd(params["lock_cdrom_cmd"] % guest_cdrom_device) try: session.cmd(params["close_cdrom_cmd"] % guest_cdrom_device) except aexpect.ShellCmdError, e: eject_failed = True eject_failed_msg += ", eject command failed: %s" % str(e)
def test(self): error.context("Preparing migration env and cdroms.") mig_protocol = params.get("mig_protocol", "tcp") self.mig_type = utils_test.qemu.MultihostMigration if mig_protocol == "fd": self.mig_type = utils_test.qemu.MultihostMigrationFd if mig_protocol == "exec": self.mig_type = utils_test.qemu.MultihostMigrationExec self.vms = params.get("vms").split(" ") self.srchost = params.get("hosts")[0] self.dsthost = params.get("hosts")[1] self.is_src = params.get("hostid") == self.srchost self.mig = self.mig_type(test, params, env, False, ) self.cdrom_size = int(params.get("cdrom_size", 10)) if self.is_src: self.cdrom_orig = create_iso_image(params, "orig", file_size=self.cdrom_size) self.cdrom_dir = os.path.dirname(self.cdrom_orig) params["start_vm"] = "yes" env_process.process(test, params, env, env_process.preprocess_image, env_process.preprocess_vm) vm = env.get_vm(self.vms[0]) vm.wait_for_login(timeout=login_timeout) else: self.cdrom_orig = create_iso_image(params, "orig", False) self.cdrom_dir = os.path.dirname(self.cdrom_orig)
def enable_multi_queues(vm): sess = vm.wait_for_serial_login(timeout=login_timeout) error.context("Enable multi queues in guest.", logging.info) for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(sess, nic.mac) queues = int(nic.queues) change_queues_number(sess, ifname, queues)
def eject_test_via_monitor(vm, qemu_cdrom_device, guest_cdrom_device, iso_image_orig, iso_image_new, max_times): """ Test cdrom eject function via qemu monitor. """ error.context("Eject the iso image in monitor %s times" % max_times, logging.info) session = vm.wait_for_login(timeout=login_timeout) iso_image = iso_image_orig for i in range(1, max_times): session.cmd(params["eject_cdrom_cmd"] % guest_cdrom_device) vm.eject_cdrom(qemu_cdrom_device) time.sleep(2) if get_cdrom_file(vm, qemu_cdrom_device) is not None: raise error.TestFail("Device %s was not ejected" " (round %s)" % (iso_image, i)) iso_image = iso_image_new # On even attempts, try to change the iso image if i % 2 == 0: iso_image = iso_image_orig vm.change_media(qemu_cdrom_device, iso_image) if get_cdrom_file(vm, qemu_cdrom_device) != iso_image: raise error.TestFail("Could not change iso image %s" " (round %s)" % (iso_image, i)) time.sleep(workaround_eject_time)
def setup(self): logging.debug("Starting enospc setup") error.context("performing enospc setup") utils_misc.display_attributes(self) # Double check if there aren't any leftovers self.cleanup() try: utils.run("%s create -f raw %s 10G" % (self.qemu_img_binary, self.raw_file_path)) # Associate a loopback device with the raw file. # Subject to race conditions, that's why try here to associate # it with the raw file as quickly as possible l_result = utils.run("losetup -f") utils.run("losetup -f %s" % self.raw_file_path) self.loopback = l_result.stdout.strip() # Add the loopback device configured to the list of pvs # recognized by LVM utils.run("pvcreate %s" % self.loopback) utils.run("vgcreate %s %s" % (self.vgtest_name, self.loopback)) # Create an lv inside the vg with starting size of 200M utils.run("lvcreate -L 200M -n %s %s" % (self.lvtest_name, self.vgtest_name)) # Create a 10GB qcow2 image in the logical volume utils.run("%s create -f qcow2 %s 10G" % (self.qemu_img_binary, self.lvtest_device)) # Let's symlink the logical volume with the image name that autotest # expects this device to have os.symlink(self.lvtest_device, self.qcow_file_path) except Exception: try: self.cleanup() except Exception, e: logging.warn(e) raise
def cleanup(self): error.context("performing enospc cleanup") if os.path.islink(self.lvtest_device): utils.run("fuser -k %s" % self.lvtest_device, ignore_status=True) time.sleep(2) l_result = utils.run("lvdisplay") # Let's remove all volumes inside the volume group created if self.lvtest_name in l_result.stdout: utils.run("lvremove -f %s" % self.lvtest_device) # Now, removing the volume group itself v_result = utils.run("vgdisplay") if self.vgtest_name in v_result.stdout: utils.run("vgremove -f %s" % self.vgtest_name) # Now, if we can, let's remove the physical volume from lvm list if self.loopback: p_result = utils.run("pvdisplay") if self.loopback in p_result.stdout: utils.run("pvremove -f %s" % self.loopback) l_result = utils.run('losetup -a') if self.loopback and (self.loopback in l_result.stdout): try: utils.run("losetup -d %s" % self.loopback) except error.CmdError: logging.error("Failed to liberate loopback %s", self.loopback) if os.path.islink(self.qcow_file_path): os.remove(self.qcow_file_path) if os.path.isfile(self.raw_file_path): os.remove(self.raw_file_path)
def get_match_cdrom(session, serial_num): """ Find the cdrom in guest which is corresponding with the CML according to the serial number. :param session: VM session. :param serial num: serial number of the cdrom. :return match_cdrom: the cdrom in guest which is corresponding with the CML according to the serial number. """ error.context("Get matching cdrom in guest", logging.info) show_serial_num = "ls -l /dev/disk/by-id" serial_num_output = session.cmd_output(show_serial_num) if serial_num_output: serial_cdrom = "" for line in serial_num_output.splitlines(): if utils_misc.find_substring(str(line), str(serial_num)): serial_cdrom = line.split(" ")[-1].split("/")[-1] break if not serial_cdrom: qtree_info = vm.monitor.info("qtree") raise error.TestFail("Could not find the device whose " "serial number %s is same in Qemu" " CML.\n Qtree info: %s" % (qtree_info, serial_num)) show_cdrom_cmd = "ls -l /dev/cdrom*" dev_cdrom_output = session.cmd_output(show_cdrom_cmd) if dev_cdrom_output: for line in dev_cdrom_output.splitlines(): if utils_misc.find_substring(str(line), str(serial_cdrom)): match_cdrom = line.split(" ")[-3] return match_cdrom raise error.TestFail("Could not find the corresponding cdrom" "in guest which is same in Qemu CML.")
def run_monitor_cmds_check(test, params, env): """ monitor_cmds_check test: 1). bootup vm with human and qmp monitor 2). check commands in black_list is unavaliable in monitor :param test: Qemu test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. Notes: Please run this test with qemu/control.kernel-version to ensure it only run when requried package installed; """ def is_supported(cmd): try: vm.monitor.verify_supported_cmd(cmd) return True except qemu_monitor.MonitorNotSupportedCmdError: return False vm = env.get_vm(params["main_vm"]) vm.verify_alive() protocol = vm.monitor.protocol black_cmds = params.get("black_cmds", "").split() error.context("Verify black commands are unavaliable in '%s' monitor" % protocol, logging.info) logging.info("Black commands: %s" % black_cmds) cmds = [cmd for cmd in black_cmds if is_supported(cmd)] if cmds: msg = "Unexpected commands %s found in %s monitor" % (cmds, protocol) raise error.TestFail(msg)
def verify_guest_clock_source(session, expected): error.context("Check the current clocksource in guest", logging.info) cmd = "cat /sys/devices/system/clocksource/" cmd += "clocksource0/current_clocksource" if expected not in session.cmd(cmd): raise error.TestFail( "Guest didn't use '%s' clocksource" % expected)
def cleanup_cdrom(path): """ Removes created iso image """ if path: error.context("Cleaning up temp iso image '%s'" % path, logging.info) if "gluster" in path: g_mount_point = tempfile.mkdtemp("gluster") g_server, v_name, f_name = path.split("/")[-3:] if ":" in g_server: g_server = g_server.split(":")[0] g_mount_link = "%s:/%s" % (g_server, v_name) mount_cmd = "mount -t glusterfs %s %s" % (g_mount_link, g_mount_point) utils.system(mount_cmd, timeout=60) path = os.path.join(g_mount_point, f_name) try: logging.debug("Remove the file with os.remove().") os.remove("%s" % path) except OSError, err: logging.warn("Fail to delete %s" % path) if "gluster" in path: try: umount_cmd = "umount %s" % g_mount_point utils.system(umount_cmd, timeout=60) os.rmdir(g_mount_point) except Exception, err: msg = "Fail to clean up %s" % g_mount_point msg += "Error message %s" % err logging.warn(msg)
def stop(self): """ stop vm and verify it is really paused; """ error.context("stop vm", logging.info) self.vm.pause() return self.vm.verify_status("paused")
def resume(self): """ resume vm and verify it is really running; """ error.context("resume vm", logging.info) self.vm.resume() return self.vm.verify_status("running")
def before_migration(self, mig_data): def do_reboot(vm): reboot_method = mig_data.params.get("reboot_method", "system_reset") reboot_timeout = float(mig_data.params.get("reboot_timeout", 30)) if self.is_src: logging.info("Do '%s' before migraion..." % reboot_method) end_time = time.time() + reboot_timeout while time.time() < end_time: vm.monitor.clear_event("RESET") vm.monitor.cmd(reboot_method) reseted = utils_misc.wait_for(lambda: vm.monitor.get_event("RESET"), timeout=self.login_timeout) if not reseted: raise error.TestFail("Not found RESET event after " "execute 'system_reset'") vm.monitor.clear_event("RESET") time.sleep(self.random_timeout) error.context("Do reboot before migraion.", logging.info) vm = env.get_vm(params["main_vm"]) bg = utils.InterruptedThread(do_reboot, (vm,)) bg.start() time.sleep(self.random_timeout)
def reboot(self, method="shell", boot_check=True): """ reboot VM, alias of vm.reboot(); """ error.context("reboot vm", logging.info) params = self.parser_test_args() timeout = params["login_timeout"] if boot_check: session = self.get_session() return self.vm.reboot(session=session, timeout=timeout, method=method) if self.vm.monitor.protocol == "qmp": error.context("reset guest via system_reset", logging.info) self.vm.monitor.clear_event("RESET") self.vm.monitor.cmd("system_reset") reseted = utils_misc.wait_for(lambda: self.vm.monitor.get_event("RESET"), timeout=timeout) if not reseted: raise error.TestFail("No RESET event received after" "execute system_reset %ss" % timeout) self.vm.monitor.clear_event("RESET") else: self.vm.monitor.cmd("system_reset") return None
def test(self): super(test_multihost_ejecting, self).test() if self.is_src: # Starts in source self.cdrom_new = create_iso_image(params, "new") vm = env.get_vm(self.vms[0]) session = vm.wait_for_login(timeout=login_timeout) output = session.get_command_output("ls /dev/cdrom*") cdrom_dev_list = re.findall("/dev/cdrom-\w+|/dev/cdrom\d*", output) logging.debug("cdrom_dev_list: %s", cdrom_dev_list) device = get_device(vm, self.cdrom_orig) cdrom = cdrom_dev_list[0] error.context("Eject cdrom.") session.cmd('eject %s' % cdrom) eject_cdrom(device, vm.monitor) time.sleep(2) if get_cdrom_file(vm, device) is not None: raise error.TestFail("Device %s was not ejected" % (cdrom)) cdrom = self.cdrom_new error.context("Change cdrom.") change_cdrom(device, cdrom, vm.monitor) if get_cdrom_file(vm, device) != cdrom: raise error.TestFail("It wasn't possible to change " "cdrom %s" % (cdrom)) time.sleep(workaround_eject_time) self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts, 'cdrom_dev', cdrom_prepare_timeout) self.mig.migrate_wait([self.vms[0]], self.srchost, self.dsthost)
def check_test(cmd): """ Subcommand 'qemu-img check' test. This tests will 'dd' to create a specified size file, and check it. Then convert it to supported image_format in each loop and check again. :param cmd: qemu-img base command. """ test_image = _get_image_filename(params["image_name_dd"], enable_gluster) create_image_cmd = params["create_image_cmd"] create_image_cmd = create_image_cmd % test_image msg = " Create image %s by command %s" % (test_image, create_image_cmd) error.context(msg, logging.info) utils.system(create_image_cmd, verbose=False) status, output = _check(cmd, test_image) if not status: raise error.TestFail("Check image '%s' failed with error: %s" % (test_image, output)) for fmt in params["supported_image_formats"].split(): output_image = test_image + ".%s" % fmt _convert(cmd, fmt, test_image, output_image) status, output = _check(cmd, output_image) if not status: raise error.TestFail("Check image '%s' got error: %s" % (output_image, output)) remove(output_image) remove(test_image)
def _convert(cmd, output_fmt, img_name, output_filename, fmt=None, compressed="no", encrypted="no"): """ Simple wrapper of 'qemu-img convert' function. :param cmd: qemu-img base command. :param output_fmt: the output format of converted image :param img_name: image name that to be converted :param output_filename: output image name that converted :param fmt: output image format :param compressed: whether output image is compressed :param encrypted: whether output image is encrypted """ cmd += " convert" if compressed == "yes": cmd += " -c" if encrypted == "yes": cmd += " -e" if fmt: cmd += " -f %s" % fmt cmd += " -O %s" % output_fmt options = params.get("qemu_img_options") if options: options = options.split() cmd += " -o " for option in options: value = params.get(option) cmd += "%s=%s," % (option, value) cmd = cmd.rstrip(",") cmd += " %s %s" % (img_name, output_filename) msg = "Converting '%s' from format '%s'" % (img_name, fmt) msg += " to '%s'" % output_fmt error.context(msg, logging.info) utils.system(cmd)
def snapshot_test(cmd): """ Subcommand 'qemu-img snapshot' test. :param cmd: qemu-img base command. """ cmd += " snapshot" for i in range(2): crtcmd = cmd sn_name = "snapshot%d" % i crtcmd += " -c %s %s" % (sn_name, image_name) msg = "Created snapshot '%s' in '%s' by command %s" % (sn_name, image_name, crtcmd) error.context(msg, logging.info) status, output = commands.getstatusoutput(crtcmd) if status != 0: raise error.TestFail("Create snapshot failed via command: %s;" "Output is: %s" % (crtcmd, output)) listcmd = cmd listcmd += " -l %s" % image_name status, out = commands.getstatusoutput(listcmd) if not ("snapshot0" in out and "snapshot1" in out and status == 0): raise error.TestFail("Snapshot created failed or missed;" "snapshot list is: \n%s" % out) for i in range(2): sn_name = "snapshot%d" % i delcmd = cmd delcmd += " -d %s %s" % (sn_name, image_name) msg = "Delete snapshot '%s' by command %s" % (sn_name, delcmd) error.context(msg, logging.info) status, output = commands.getstatusoutput(delcmd) if status != 0: raise error.TestFail("Delete snapshot '%s' failed: %s" % (sn_name, output))
def migration_scenario(self, worker=None): error.context("Migration from %s to %s over protocol %s." % (self.srchost, self.dsthost, mig_protocol), logging.info) def worker_func(mig_data): vm = mig_data.vms[0] session = vm.wait_for_login(timeout=self.login_timeout) utils_misc.install_cpuflags_util_on_vm(test, vm, self.install_path, extra_flags="-msse3 -msse2") cmd = ("nohup %s/cpuflags-test --stressmem %d,%d &" % (os.path.join(self.install_path, "test_cpu_flags"), self.vm_mem * 100, self.vm_mem / 2)) logging.debug("Sending command: %s" % (cmd)) session.sendline(cmd) time.sleep(3) if worker is None: worker = worker_func try: self.migrate_wait(self.vms, self.srchost, self.dsthost, start_work=worker) finally: self.clean_firewall()
def setup_nfs(self): """ Copy the vmlinuz and initrd.img from nfs. """ error.context("copying the vmlinuz and initrd.img from NFS share") m_cmd = ("mount %s:%s %s -o ro" % (self.nfs_server, self.nfs_dir, self.nfs_mount)) utils.run(m_cmd, verbose=DEBUG) try: kernel_fetch_cmd = ("cp %s/%s/%s %s" % (self.nfs_mount, self.boot_path, os.path.basename(self.kernel), self.image_path)) utils.run(kernel_fetch_cmd, verbose=DEBUG) initrd_fetch_cmd = ("cp %s/%s/%s %s" % (self.nfs_mount, self.boot_path, os.path.basename(self.initrd), self.image_path)) utils.run(initrd_fetch_cmd, verbose=DEBUG) finally: utils_disk.cleanup(self.nfs_mount) if 'autoyast=' in self.kernel_params: # SUSE self.kernel_params = (self.kernel_params + " ip=dhcp " "install=nfs://" + self.nfs_server + ":" + self.nfs_dir)
def check_tray_status_test(vm, qemu_cdrom_device, guest_cdrom_device, max_times): """ Test cdrom tray status reporting function. """ error.context("Copy test script to guest") tray_check_src = params.get("tray_check_src") if tray_check_src: tray_check_src = utils_misc.get_path(test.virtdir, "deps/%s" % tray_check_src) vm.copy_files_to(tray_check_src, "/tmp") if is_tray_opened(vm, qemu_cdrom_device) is None: logging.warn("Tray status reporting is not supported by qemu!") logging.warn("cdrom_test_tray_status test is skipped...") return error.context("Eject the cdrom in guest %s times" % max_times, logging.info) session = vm.wait_for_login(timeout=login_timeout) for i in range(1, max_times): session.cmd('eject %s' % guest_cdrom_device) if not is_tray_opened(vm, qemu_cdrom_device): raise error.TestFail("Monitor reports tray closed" " when ejecting (round %s)" % i) session.cmd('dd if=%s of=/dev/null count=1' % guest_cdrom_device) if is_tray_opened(vm, qemu_cdrom_device): raise error.TestFail("Monitor reports tray opened when reading" " cdrom in guest (round %s)" % i) time.sleep(workaround_eject_time)
def test(self): error.context("Preparing migration env and floppies.") mig_protocol = params.get("mig_protocol", "tcp") self.mig_type = utils_test.qemu.MultihostMigration if mig_protocol == "fd": self.mig_type = utils_test.qemu.MultihostMigrationFd if mig_protocol == "exec": self.mig_type = utils_test.qemu.MultihostMigrationExec self.vms = params.get("vms").split(" ") self.srchost = params["hosts"][0] self.dsthost = params["hosts"][1] self.is_src = params["hostid"] == self.srchost self.mig = self.mig_type(test, params, env, False, ) if self.is_src: self.floppy = create_floppy(params) self.floppy_dir = os.path.dirname(self.floppy) params["start_vm"] = "yes" env_process.process(test, params, env, env_process.preprocess_image, env_process.preprocess_vm) vm = env.get_vm(self.vms[0]) vm.wait_for_login(timeout=login_timeout) else: self.floppy = create_floppy(params, False) self.floppy_dir = os.path.dirname(self.floppy)
def check_boot_result(boot_fail_info, device_name): """ Check boot result, and logout from iscsi device if boot from iscsi. """ logging.info("Wait for display and check boot info.") infos = boot_fail_info.split(';') f = lambda: re.search(infos[0], vm.serial_console.get_output()) utils_misc.wait_for(f, timeout, 1) logging.info("Try to boot from '%s'" % device_name) try: if dev_name == "hard-drive" or (dev_name == "scsi-hd" and not params.get("image_name_stg")): error.context("Log into the guest to verify it's up", logging.info) session = vm.wait_for_login(timeout=timeout) session.close() vm.destroy() return output = vm.serial_console.get_output() for i in infos: if not re.search(i, output): raise error.TestFail("Could not boot from" " '%s'" % device_name) finally: cleanup(device_name)
def run(test, params, env): """ qemu cdrom block size check test. 1) Boot the guest with empty iso. 2) Get the cdrom's size in guest. 3) Attach a small cd iso file to the cdrom. 4) mount the cdrom in guest and check its block size. 5) umount and eject cdrom in guest. 6) Change cdrom media to another file with different size. 7) Get the cdrom's size in guest again. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def list_guest_cdroms(session): """ Get cdrom lists from guest os; :param session: ShellSession object; :param params: test params dict; :return: list of cdroms; :rtype: list """ list_cdrom_cmd = "wmic cdrom get Drive" filter_cdrom_re = "\w:" if params["os_type"] != "windows": list_cdrom_cmd = "ls /dev/cdrom*" filter_cdrom_re = r"/dev/cdrom-\w+|/dev/cdrom\d*" output = session.cmd_output(list_cdrom_cmd) return re.findall(filter_cdrom_re, output) def get_cdrom_mount_point(session, os_type="linux", drive_letter=None): """ Get default cdrom mount point; """ mount_point = "/mnt" if os_type == "windows": cmd = "wmic volume where DriveLetter='%s' " % drive_letter cmd += "get DeviceID | more +1" mount_point = session.cmd_output(cmd).strip() return mount_point def get_cdrom_device(vm): """ Get cdrom device when cdrom is not insert. """ device = None blocks = vm.monitor.info("block") if isinstance(blocks, str): for block in blocks.strip().split('\n'): if 'not inserted' in block: device = block.split(':')[0] else: for block in blocks: if 'inserted' not in block.keys(): device = block['device'] return device def create_iso_image(params, name, prepare=True, file_size=None): """ Creates 'new' iso image with one file on it :param params: parameters for test :param name: name of new iso image file. It could be the full path of cdrom. :param preapre: if True then it prepare cd images. :param file_size: Size of iso image in MB :return: path to new iso image file. """ error.context("Creating test iso image '%s'" % name, logging.info) if not os.path.isabs(name): cdrom_path = utils_misc.get_path(data_dir.get_data_dir(), name) else: cdrom_path = name if not cdrom_path.endswith(".iso"): cdrom_path = "%s.iso" % cdrom_path name = os.path.basename(cdrom_path) if file_size is None: file_size = 10 if prepare: cmd = "dd if=/dev/urandom of=%s bs=1M count=%d" utils.run(cmd % (name, file_size)) utils.run("mkisofs -o %s %s" % (cdrom_path, name)) utils.run("rm -rf %s" % (name)) return cdrom_path def check_cdrom_size(session): error.context("Get the cdrom's size in guest.", logging.info) check_cdrom_size_cmd = params["check_cdrom_size_cmd"] output = session.cmd(check_cdrom_size_cmd, timeout=60) if not output: msg = "Unable to get the cdrom's size in guest." msg += " Command: %s\nOutput: %s" % (check_cdrom_size_cmd, output) raise error.TestError(msg) size = output.strip().splitlines()[-1] try: cdrom_size = int(size) except ValueError: cdrom_size = 0 logging.info("Cdrom's size in guest %s", cdrom_size) return cdrom_size def mount_cdrom(session, guest_cdrom, mount_point, show_mount_cmd, mount_cmd): txt = "Mount the cdrom in guest and check its block size." error.context(txt, logging.info) mounted = session.cmd(show_mount_cmd) if mount_point not in mounted: mount_cmd = params.get("mount_cdrom_cmd") % (guest_cdrom, mount_point) status, output = session.cmd_status_output(mount_cmd, timeout=360) if status: msg = "Unable to mount cdrom. command: %s\n" % mount_cmd msg += " Output: %s" % output raise error.TestError(msg) cdroms = params["test_cdroms"] params["cdroms"] = cdroms params["start_vm"] = "yes" show_mount_cmd = params.get("show_mount_cmd") mount_cmd = params.get("mount_cdrom_cmd") umount_cmd = params.get("umount_cdrom_cmd") os_type = params["os_type"] error.context("Get the main VM", logging.info) main_vm = params["main_vm"] env_process.preprocess_vm(test, params, env, main_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) guest_cdrom = list_guest_cdroms(session)[-1] mount_point = get_cdrom_mount_point(session, os_type, guest_cdrom) empty_size = check_cdrom_size(session) cdrom_name = params.get("orig_cdrom", "images/orig.iso") file_size = params.get("orig_cdrom_size", 100) orig_cdrom = create_iso_image(params, cdrom_name, prepare=True, file_size=file_size) cdrom_device = get_cdrom_device(vm) error.context("Attach a small cd iso file to the cdrom.", logging.info) vm.change_media(cdrom_device, orig_cdrom) if mount_cmd: mount_cdrom(session, guest_cdrom, mount_point, show_mount_cmd, mount_cmd) orig_size = utils_misc.wait_for(lambda: check_cdrom_size(session), 60, 5, 3) if orig_size == empty_size: err = "Get same block size '%s' after new cdrom attached" % orig_size raise error.TestFail(err) if umount_cmd: error.context("umount cdrom in guest.", logging.info) umount_cmd = umount_cmd % mount_point status, output = session.cmd_status_output(umount_cmd, timeout=360) if status: msg = "Unable to umount cdrom. command: %s\n" % umount_cmd msg += "Output: %s" % output raise error.TestError(msg) error.context("eject the cdrom from monitor.", logging.info) vm.eject_cdrom(cdrom_device) cdrom_name = params.get("final_cdrom", "images/final.iso") file_size = params.get("final_cdrom_size", 1000) final_cdrom = create_iso_image(params, cdrom_name, prepare=True, file_size=file_size) error.context("Attach a bigger cd iso file to the cdrom.", logging.info) vm.change_media(cdrom_device, final_cdrom) if mount_cmd: mount_cdrom(session, guest_cdrom, mount_point, show_mount_cmd, mount_cmd) final_size = utils_misc.wait_for(lambda: check_cdrom_size(session), 60, 5, 3) if final_size == empty_size or final_size == orig_size: err = "Get same block size '%s' after new cdrom attached" % final_size raise error.TestFail(err) # Check guest's network. vm.wait_for_login(timeout=timeout)
def run(test, params, env): """ Update virtio driver: 1) Boot up guest with default devices and virtio_win iso 2) Install virtio driver 3) Check dirver info :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def reboot(vm, session=None): nic_idx = len(vm.virtnet) - 1 while nic_idx >= 0: try: return vm.reboot(session, nic_index=nic_idx) except Exception: nic_idx -= 1 if nic_idx < 0: raise logging.warn("Unable to login guest, " "try to login via nic %d" % nic_idx) def check_cdrom(timeout): cdrom_chk_cmd = "echo list volume > cmd && echo exit >>" cdrom_chk_cmd += " cmd && diskpart /s cmd" vols = [] start_time = time.time() while time.time() - start_time < timeout: vols_str = session.cmd(cdrom_chk_cmd) if len(re.findall("CDFS", vols_str)) >= cdrom_num: vols = re.findall(".*CDFS.*?\n", vols_str) break return vols if params.get("case_type") == "driver_install": error.context("Update the device type to default.", logging.info) default_drive_format = params.get("default_drive_format", "ide") default_nic_model = params.get("default_nic_model", "rtl8139") images = params.get("images") main_image = re.split("\s+", images)[0] nics = params.get("nics") main_nic = re.split("\s+", nics)[0] default_display = params.get("default_display", "vnc") default_parameters = { "default_drive_format": default_drive_format, "default_nic_model": default_nic_model, "default_display": default_display, "default_cd_format": default_drive_format } for key in default_parameters: params[key[8:]] = default_parameters[key] if params.get("prewhql_install") == "yes": error.context("Prepare the prewhql virtio_win driver iso") url_virtio_win = params.get("url_virtio_win") if os.path.isdir("/tmp/virtio_win"): utils.system("rm -rf /tmp/virtio_win") utils.system("mkdir /tmp/virtio_win") virtio_win = utils.unmap_url("/tmp/virtio_win", url_virtio_win, "/tmp/virtio_win") if re.findall("zip$", url_virtio_win): utils.system("cd /tmp/virtio_win; unzip *; rm -f *.zip") virtio_version = params.get("virtio_version", "unknown") virtio_iso = utils_misc.get_path( data_dir.get_data_dir(), params.get("cdrom_virtio", "/tmp/prewhql.iso")) utils.system("mkisofs -J -o %s /tmp/virtio_win" % virtio_iso) drivers_install = re.split(";", params.get("drivers_install")) timeout = float(params.get("login_timeout", 240)) install_cmds = {} check_str = {} check_cmds = {} op_cmds = {} setup_ps = False error.context("Fill up driver install command line", logging.info) for driver in drivers_install: params_driver = params.object_params(driver) mount_point = params_driver.get("mount_point") storage_path = params_driver.get("cdrom_virtio") re_hw_id = params_driver.get("re_hw_id", "(PCI.{14,50})\r\n") driver_install_cmd = params_driver.get("driver_install_cmd") if "hwidcmd" in driver_install_cmd: pattern_drive = params.get("pattern_drive", "\s+\w:(.[^\s]+)\s+hwidcmd") driver_path = re.findall(pattern_drive, driver_install_cmd)[0] driver_path = "/".join(driver_path.split("\\\\")[1:]) storage_path = utils_misc.get_path(data_dir.get_data_dir(), storage_path) hw_id = utils_test.get_driver_hardware_id( driver_path, mount_point=mount_point, storage_path=storage_path, re_hw_id=re_hw_id) install_cmds[driver] = re.sub("hwidcmd", hw_id, driver_install_cmd) else: install_cmds[driver] = driver_install_cmd check_str[driver] = params_driver.get("check_str") check_cmds[driver] = params_driver.get("check_cmd") if params_driver.get('op_cmd'): op_cmds[driver] = params_driver["op_cmd"].split("::") if "pecheck.py" in check_cmds[driver]: setup_ps = True if params.get("check_info") == "yes": mount_point = params.get("virtio_mount_point", "/tmp/virtio_win") iso_path = utils_misc.get_path(data_dir.get_data_dir(), params.get("cdrom_virtio")) utils.system("mount -o loop %s %s" % (iso_path, mount_point)) pattern_driver = params_driver.get("pattern_driver") driver_path = re.findall(pattern_driver, driver_install_cmd)[0] driver_path = "/".join(driver_path.split("\\\\")[1:]) storage_path = utils_misc.get_path(mount_point, driver_path) storage_path = os.path.dirname(storage_path) files = " ".join(os.listdir(storage_path)) file_name = re.findall("\s+(.*?\.inf)", files) if file_name: file_name = utils_misc.get_path(storage_path, file_name[0]) else: raise error.TestError("Can not find .inf file.") inf = open(file_name) inf_context = inf.read() inf.close() utils.system("umount %s" % mount_point) patterns_check_str = params_driver.get("check_str") check_str[driver] = {} for i in patterns_check_str.split(";"): check_n, check_p = i.split("::") check_str[driver][check_n] = re.findall(check_p, inf_context)[0] check_cmds[driver] = {} for i in params_driver.get("check_cmd").split(";"): cmd_n, cmd_c = i.split("::") cmd_c = re.sub("DRIVER_PATH", params_driver.get("sys_file_path", ""), cmd_c) cmd_c = re.sub( "DRIVER_PATTERN_%s" % cmd_n, params_driver.get("info_pattern_%s" % cmd_n, ""), cmd_c) check_cmds[driver][cmd_n] = cmd_c error.context("Boot up guest with setup parameters", logging.info) params["start_vm"] = "yes" vm_name = params['main_vm'] env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) session = vm.wait_for_login(timeout=timeout) cdroms = params.get("cdroms") cdrom_num = len(re.split("\s+", cdroms.strip())) init_timeout = int(params.get("init_timeout", "60")) driver_install_timeout = int(params.get('driver_install_timeout', 720)) error.context("Check the cdrom is available") volumes = check_cdrom(init_timeout) vol_info = [] for volume in volumes: vol_info += re.findall("Volume\s+\d+\s+(\w).*?(\d+)\s+\w+", volume) if len(volumes) > 1: if int(vol_info[0][1]) > int(vol_info[1][1]): vol_utils = vol_info[0][0] vol_virtio = vol_info[1][0] else: vol_utils = vol_info[1][0] vol_virtio = vol_info[0][0] else: vol_utils = vol_info[0][0] error.context("Install drivers", logging.info) for driver in drivers_install: error.context("Install drivers %s" % driver, logging.info) if params.get("kill_rundll", "no") == "yes": kill_cmd = 'tasklist | find /I "rundll32"' status, tasks = session.cmd_status_output(kill_cmd) if status == 0: for i in re.findall("rundll32.*?(\d+)", tasks): session.cmd('taskkill /PID %s' % i) if install_cmds: cmd = re.sub("WIN_UTILS", vol_utils, install_cmds[driver]) cmd = re.sub("WIN_VIRTIO", vol_virtio, cmd) session.cmd(cmd, timeout=driver_install_timeout) session = reboot(vm, session) if params.get("check_info") == "yes": fail_log = "Details check failed in guest." fail_log += " Please check the error_log. " else: fail_log = "Failed to install:" error_log = open("%s/error_log" % test.resultsdir, "w") fail_flag = False error.context("Check driver available in guest", logging.info) if setup_ps: setup_cmd = params.get("python_scripts") session.cmd(setup_cmd) for driver in drivers_install: error_log.write("For driver %s:\n" % driver) if isinstance(check_str[driver], dict): for i in check_str[driver]: output = session.cmd(check_cmds[driver][i]) if not re.findall(check_str[driver][i], output, re.I): fail_flag = True fail_log += " %s" % driver fail_log += "(%s) is not right; " % i error_log.write("inf:\t%s\n" % check_str[driver][i]) error_log.write("sys: \t%s\n" % output) else: output = session.cmd(check_cmds[driver]) if not re.findall(check_str[driver], output, re.I): fail_falg = True fail_log += " %s" % driver error_log.write("Check command output: %s\n" % output) if fail_flag: raise error.TestFail(fail_log) if op_cmds: error.context("Do more operates in guest to check the driver", logging.info) for driver in drivers_install: if driver not in op_cmds: continue for cmd in op_cmds[driver]: session.cmd(cmd)
def run(test, params, env): """ Install/upgrade special kernel package via brew tool or link. And we have another case 'kernel_install' can to this too, but this case has addational steps. In future, we will merge this to kernel_install case. 1) Boot the vm 2) Get latest kernel package link from brew 3) Verify the version of guest kernel 4) Compare guest kernel version and brew latest kernel version 5) Backup grub.cfg file 6) Install guest kernel firmware (Optional) 7) Install guest kernel 8) Install guest kernel debuginfo (Optional) 9) Backup grub.cfg after installing new kernel 10) Installing virtio driver (Optional) 11) Backup initrd file 12) Update initrd file 13) Make the new installed kernel as default 14) Backup grup.cfg after setting new kernel as default 15) Update the guest kernel cmdline (Optional) 16) Reboot guest after updating kernel 17) Verifying the virtio drivers (Optional) @param test: QEMU test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def get_brew_url(mnt_path, download_root): # get the url from the brew mnt path url = download_root + mnt_path[11:] logging.debug("Brew URL is %s" % url) return url def install_rpm(session, url, upgrade=False, nodeps=False, timeout=600): # install a package from brew cmd = "rpm -ivhf %s" % url if upgrade: # Upgrades or installs kernel to a newer version, then remove # old version. cmd = "rpm -Uvhf %s" % url if nodeps: cmd += " --nodeps" s, o = session.cmd_status_output(cmd, timeout=timeout) if s != 0 and ("already" not in o): raise error.TestFail("Fail to install %s:%s" % (url, o)) return True # FIXME: need to add the check for newer version def copy_and_install_rpm(session, url, upgrade=False): rpm_name = os.path.basename(url) if url.startswith("http"): download_cmd = "wget %s" % url utils.system_output(download_cmd) rpm_src = rpm_name else: rpm_src = utils_misc.get_path(test.bindir, url) vm.copy_files_to(rpm_src, "/tmp/%s" % rpm_name) install_rpm(session, "/tmp/%s" % rpm_name, upgrade) def get_kernel_rpm_link(): method = params.get("method", "link") if method not in ["link", "brew"]: raise error.TestError("Unknown installation method %s" % method) if method == "link": return (params.get("kernel_version"), params.get("kernel_rpm"), params.get("firmware_rpm")) error.context("Get latest kernel package link from brew", logging.info) # fetch the newest packages from brew # FIXME: really brain dead method to fetch the kernel version # kernel_vesion = re... + hint from configuration file # is there any smart way to fetch the `uname -r` from # brew build? rh_kernel_hint = "[\d+][^\s]+" kernel_re = params.get("kernel_re") tag = params.get("brew_tag") latest_pkg_cmd = "brew latest-pkg %s kernel" % tag o = utils.system_output(latest_pkg_cmd, timeout=360) build = re.findall("kernel[^\s]+", o)[0] logging.debug("Latest package on brew for tag %s is %s" % (tag, build)) buildinfo = utils.system_output("brew buildinfo %s" % build, timeout=360) # install kernel-firmware firmware_url = None if "firmware" in buildinfo: logging.info("Found kernel-firmware") fw_pattern = ".*firmware.*" try: fw_brew_link = re.findall(fw_pattern, buildinfo)[0] except IndexError: raise error.TestError("Could not get kernel-firmware package" " brew link matching pattern '%s'" % fw_pattern) firmware_url = get_brew_url(fw_brew_link, download_root) knl_pattern = kernel_re % rh_kernel_hint try: knl_brew_link = re.findall(knl_pattern, buildinfo, re.I)[0] except IndexError: raise error.TestError("Could not get kernel package brew link" " matching pattern '%s'" % knl_pattern) kernel_url = get_brew_url(knl_brew_link, download_root) debug_re = kernel_re % ("(%s)" % rh_kernel_hint) try: kernel_version = re.findall(debug_re, kernel_url, re.I)[0] except IndexError: raise error.TestError("Could not get kernel version matching" " pattern '%s'" % debug_re) kernel_version += "." + params.get("kernel_suffix", "") return kernel_version, kernel_url, firmware_url def get_kernel_debuginfo_rpm_link(): knl_dbginfo_re = params.get("knl_dbginfo_re") tag = params.get("brew_tag") latest_pkg_cmd = "brew latest-pkg %s kernel" % tag o = utils.system_output(latest_pkg_cmd, timeout=360) build = re.findall("kernel[^\s]+", o)[0] logging.debug("Latest package on brew for tag %s is %s" % (tag, build)) buildinfo = utils.system_output("brew buildinfo %s" % build, timeout=360) try: knl_dbginfo_links = re.findall(knl_dbginfo_re, buildinfo, re.I) except IndexError: raise error.TestError("Could not get kernel-debuginfo package " "brew link matching pattern '%s'" % knl_dbginfo_re) knl_dbginfo_urls = [] for l in knl_dbginfo_links: link = get_brew_url(l, download_root) knl_dbginfo_urls.append(link) return knl_dbginfo_urls def get_guest_kernel_version(): error.context("Verify the version of guest kernel", logging.info) s, o = session.cmd_status_output("uname -r") return o.strip() def is_kernel_debuginfo_installed(): get_kernel_debuginfo_cmd = "rpm -qa | grep %s" % knl_dbginfo_version s, o = session.cmd_status_output(get_kernel_debuginfo_cmd) if s != 0: return False if knl_dbginfo_version not in o: logging.debug("%s has not been installed." % knl_dbginfo_version) return False logging.debug("%s has already been installed." % knl_dbginfo_version) return True def is_virtio_driver_installed(): s, o = session.cmd_status_output("lsmod | grep virtio") if s != 0: return False for driver in virtio_drivers: if driver not in o: logging.debug("%s has not been installed." % driver) return False logging.debug("%s has already been installed." % driver) return True def compare_kernel_version(kernel_version, guest_version): error.context("Compare guest kernel version and brew's", logging.info) # return True: when kernel_version <= guest_version if guest_version == kernel_version: logging.info("The kernel version is matched %s" % guest_version) return True kernel_s = re.split('[.-]', kernel_version) guest_s = re.split('[.-]', guest_version) kernel_v = [int(i) for i in kernel_s if i.isdigit()] guest_v = [int(i) for i in guest_s if i.isdigit()] for i in range(min(len(kernel_v), len(guest_v))): if kernel_v[i] < guest_v[i]: logging.debug("The kernel version: '%s' is old than" " guest version %s" % (kernel_version, guest_version)) return True elif kernel_v[i] > guest_v[i]: return False if len(kernel_v) < len(guest_v): logging.debug("The kernel_version: %s is old than guest_version" " %s" % (kernel_version, guest_version)) return True return False def get_guest_pkgs(session, pkg, qformat=""): """ Query requries packages in guest which name like 'pkg'. :parm session: session object to guest. :parm pkg: package name without version and arch info. :parm qformat: display format(eg, %{NAME}, %{VERSION}). :return: list of packages. :rtype: list """ cmd = "rpm -q --whatrequires %s" % pkg if qformat: cmd += " --queryformat='%s\n'" % qformat pkgs = session.cmd_output(cmd).splitlines() pkgs.append(pkg) return pkgs def get_latest_pkgs_url(pkg, arch): """ Get url of latest packages in brewweb. :parm pkg: package name without version info. :parm brew_tag: requried in cfg file. :parm vm_arch_name: requried in cfg file. :parm latest_pkg_cmd: requried in cfg file. :return: urls for pkg in brewweb. :rtype: list """ tag = params.get("brew_tag") latest_pkg_cmd = params.get("latest_pkg_cmd", "brew latest-pkg") latest_pkg_cmd = "%s %s %s" % (latest_pkg_cmd, tag, pkg) latest_pkg_cmd = "%s --arch=%s --paths" % (latest_pkg_cmd, arch) mnt_paths = utils.system_output(latest_pkg_cmd).splitlines() return [ get_brew_url(_, download_root) for _ in mnt_paths if _.endswith(".rpm") ] def upgrade_guest_pkgs(session, pkg, arch, debuginfo=False, nodeps=True, timeout=600): """ upgrade given packages in guest os. :parm session: session object. :parm pkg: package name without version info. :parm debuginfo: bool type, if True, install debuginfo package too. :parm nodeps: bool type, if True, ignore deps when install rpm. :parm timeout: float type, timeout value when install rpm. """ error.context("Upgrade package '%s' in guest" % pkg, logging.info) pkgs = get_guest_pkgs(session, pkg, "%{NAME}") latest_pkgs_url = get_latest_pkgs_url(pkg, arch) for url in latest_pkgs_url: if "debuginfo" in url and not debuginfo: continue upgrade = bool(filter(lambda x: x in url, pkgs)) logging.info("Install packages from: %s" % url) install_rpm(session, url, upgrade, nodeps, timeout) vm = env.get_vm(params["main_vm"]) vm.verify_alive() download_root = params["download_root_url"] login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) install_virtio = params.get("install_virtio", "yes") install_knl_debuginfo = params.get("install_knl_debuginfo") verify_virtio = params.get("verify_virtio", "yes") args_removed = params.get("args_removed", "").split() args_added = params.get("args_added", "").split() restore_initrd_cmd = "" virtio_drivers = params.get("virtio_drivers_list", "").split() kernel_version, kernel_rpm, firmware_rpm = get_kernel_rpm_link() knl_dbginfo_rpm = get_kernel_debuginfo_rpm_link() knl_dbginfo_version = "kernel-debuginfo-%s" % kernel_version logging.info("Kernel version: %s" % kernel_version) logging.info("Kernel rpm : %s" % kernel_rpm) logging.info("Firmware rpm : %s" % firmware_rpm) grub_cfg_path = params.get("grub_cfg_path", "/boot/grub/grub.conf") cp_grubcf_cmd = "/bin/cp %s %s-bk" % (grub_cfg_path, grub_cfg_path) cp_grubcf_cmd = params.get("cp_grubcf_cmd", cp_grubcf_cmd) restore_grubcf_cmd = "/bin/cp %s-bk %s" % (grub_cfg_path, grub_cfg_path) restore_grubcf_cmd = params.get("restore_grubcf_cmd", restore_grubcf_cmd) count = 0 try: error.context("Backup grub.cfg file") s, o = session.cmd_status_output(cp_grubcf_cmd) if s != 0: logging.error(o) raise error.TestError("Fail to backup the grub.cfg") count = 1 # judge if need to install a new kernel ifupdatekernel = True guest_version = get_guest_kernel_version() if compare_kernel_version(kernel_version, guest_version): ifupdatekernel = False # set kernel_version to current version for later step to use kernel_version = guest_version if is_kernel_debuginfo_installed(): install_knl_debuginfo = "no" if is_virtio_driver_installed(): install_virtio = "no" else: logging.info("The guest kerenl is %s but expected is %s" % (guest_version, kernel_version)) rpm_install_func = install_rpm if params.get("install_rpm_from_local") == "yes": rpm_install_func = copy_and_install_rpm kernel_deps_pkgs = params.get("kernel_deps_pkgs", "dracut").split() if kernel_deps_pkgs: for pkg in kernel_deps_pkgs: arch = params.get("arch_%s" % pkg, params.get("vm_arch_name")) upgrade_guest_pkgs(session, pkg, arch) if firmware_rpm: error.context("Install guest kernel firmware", logging.info) rpm_install_func(session, firmware_rpm, upgrade=True) error.context("Install guest kernel", logging.info) status = rpm_install_func(session, kernel_rpm) if status: count = 2 error.context("Backup grub.cfg after installing new kernel", logging.info) s, o = session.cmd_status_output(cp_grubcf_cmd) if s != 0: msg = ("Fail to backup the grub.cfg after updating kernel," " guest output: '%s'" % o) logging.error(msg) raise error.TestError(msg) kernel_path = "/boot/vmlinuz-%s" % kernel_version if install_knl_debuginfo == "yes": error.context("Installing kernel-debuginfo packages", logging.info) links = "" for r in knl_dbginfo_rpm: links += " %s" % r install_rpm(session, links) if install_virtio == "yes": error.context("Installing virtio driver", logging.info) initrd_prob_cmd = "grubby --info=%s" % kernel_path s, o = session.cmd_status_output(initrd_prob_cmd) if s != 0: msg = ("Could not get guest kernel information," " guest output: '%s'" % o) logging.error(msg) raise error.TestError(msg) try: initrd_path = re.findall("initrd=(.*)", o)[0] except IndexError: raise error.TestError("Could not get initrd path from guest," " guest output: '%s'" % o) driver_list = ["--with=%s " % drv for drv in virtio_drivers] mkinitrd_cmd = "mkinitrd -f %s " % initrd_path mkinitrd_cmd += "".join(driver_list) mkinitrd_cmd += " %s" % kernel_version cp_initrd_cmd = "/bin/cp %s %s-bk" % (initrd_path, initrd_path) restore_initrd_cmd = "/bin/cp %s-bk %s" % (initrd_path, initrd_path) error.context("Backup initrd file") s, o = session.cmd_status_output(cp_initrd_cmd, timeout=200) if s != 0: logging.error( "Failed to backup guest initrd," " guest output: '%s'", o) error.context("Update initrd file", logging.info) s, o = session.cmd_status_output(mkinitrd_cmd, timeout=200) if s != 0: msg = "Failed to install virtio driver, guest output '%s'" % o logging.error(msg) raise error.TestFail(msg) count = 3 # make sure the newly installed kernel as default if ifupdatekernel: error.context("Make the new installed kernel as default", logging.info) make_def_cmd = "grubby --set-default=%s " % kernel_path s, o = session.cmd_status_output(make_def_cmd) if s != 0: msg = ("Fail to set %s as default kernel," " guest output: '%s'" % (kernel_path, o)) logging.error(msg) raise error.TestError(msg) count = 4 error.context( "Backup grup.cfg after setting new kernel as default") s, o = session.cmd_status_output(cp_grubcf_cmd) if s != 0: msg = ("Fail to backup the grub.cfg, guest output: '%s'" % o) logging.error(msg) raise error.TestError(msg) # remove or add the required arguments error.context("Update the guest kernel cmdline", logging.info) remove_args_list = ["--remove-args=%s " % arg for arg in args_removed] update_kernel_cmd = "grubby --update-kernel=%s " % kernel_path update_kernel_cmd += "".join(remove_args_list) update_kernel_cmd += '--args="%s"' % " ".join(args_added) s, o = session.cmd_status_output(update_kernel_cmd) if s != 0: msg = "Fail to modify the kernel cmdline, guest output: '%s'" % o logging.error(msg) raise error.TestError(msg) count = 5 # upgrade listed packages to latest version. for pkg in params.get("upgrade_pkgs", "").split(): _ = params.object_params(pkg) arch = _.get("vm_arch_name", "x86_64") nodeps = _.get("ignore_deps") == "yes" install_debuginfo = _.get("install_debuginfo") == "yes" timeout = int(_.get("install_pkg_timeout", "600")) upgrade_guest_pkgs(session, pkg, arch, install_debuginfo, nodeps, timeout) # reboot guest error.context("Reboot guest after updating kernel", logging.info) time.sleep(int(params.get("sleep_before_reset", 10))) session = vm.reboot(session, 'shell', timeout=login_timeout) # check if the guest can bootup normally after kernel update guest_version = get_guest_kernel_version() if guest_version != kernel_version: raise error.TestFail("Fail to verify the guest kernel, \n" "Expceted version %s \n" "In fact version %s \n" % (kernel_version, guest_version)) if verify_virtio == "yes": error.context("Verifying the virtio drivers", logging.info) if not is_virtio_driver_installed(): raise error.TestFail("Fail to verify the installation of" " virtio drivers") except Exception: if count in [4, 3, 1]: # restore grub.cfg s, o = session.cmd_status_output(restore_grubcf_cmd, timeout=100) if s != 0: logging.error( "Failed to execute cmd '%s' in guest," " guest output: '%s'", restore_grubcf_cmd, o) elif count == 2 and restore_initrd_cmd: # restore initrd file s, o = session.cmd_status_output(restore_initrd_cmd, timeout=200) if s != 0: logging.error( "Failed to execute cmd '%s' in guest," " guest output: '%s'", restore_initrd_cmd, o) raise
def get_guest_kernel_version(): error.context("Verify the version of guest kernel", logging.info) s, o = session.cmd_status_output("uname -r") return o.strip()
def run_migration_after_nichotplug(test, params, env): """ KVM migration test: 1) Get a live VM and clone it. 2) Verify that the source VM supports migration. If it does, proceed with the test. 3) Hotplug a nic. 4) Disable the primary link of guest. 5) Check if new interface gets ip address. 6) Ping guest's new ip from host. 7) Re-enabling the primary link. 8) Send a migration command to the source VM and wait until it's finished. 9) Disable the primary link again. 10) Ping guest's new ip from host. 11) Re-enabling the primary link. :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def set_link(nic_name, up=False): for nic in vm.virtnet: if nic.nic_name != nic_name: vm.set_link(nic.device_id, up=up) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) guest_is_not_windows = (params.get("os_type") != 'windows') run_dhclient = params.get("run_dhclient", "no") mig_timeout = float(params.get("mig_timeout", "3600")) nettype = params.get("nettype", "bridge") netdst = params.get("netdst", "virbr0") mig_protocol = params.get("migration_protocol", "tcp") mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2 pci_model = params.get("pci_model") # Modprobe the module if specified in config file module = params.get("modprobe_module") if guest_is_not_windows and module: session.cmd_output("modprobe %s" % module) if session: session.close() error.context("Add network devices through monitor cmd", logging.info) nic_name = 'hotadded' nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name, netdst=netdst, nettype=nettype, queues=params.get('queues')) nic_mac = nic_info['mac'] vm.params['nics'] += " %s" % nic_name vm.params['nic_model_%s' % nic_name] = nic_info['nic_model'] # Only run dhclient if explicitly set and guest is not running Windows. # Most modern Linux guests run NetworkManager, and thus do not need this. if run_dhclient == "yes" and guest_is_not_windows: session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = utils_net.get_linux_ifname(session, nic_mac) utils_net.restart_guest_network(session_serial, ifname) # Guest need to take quite a long time to set the ip addr, sleep a # while to wait for guest done. time.sleep(60) error.context("Disable the primary link of guest", logging.info) set_link(nic_name, up=False) error.context("Check if new interface gets ip address", logging.info) try: ip = vm.wait_for_get_address(nic_name) except virt_vm.VMIPAddressMissingError: raise error.TestFail("Could not get or verify ip address of nic") logging.info("Got the ip address of new nic: %s", ip) error.context("Ping guest's new ip from host", logging.info) s, o = utils_test.ping(ip, 10, timeout=15) if s != 0: raise error.TestFail("New nic failed ping test with output:\n %s" % o) error.context("Re-enabling the primary link", logging.info) set_link(nic_name, up=True) error.context("Migrate from source VM to Destination VM", logging.info) vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay) error.context("Disable the primary link", logging.info) set_link(nic_name, up=False) error.context("Ping guest's new ip from host", logging.info) s, o = utils_test.ping(ip, 10, timeout=15) if s != 0: raise error.TestFail("New nic failed ping test with output:\n %s" % o) error.context("Re-enabling the primary link", logging.info) set_link(nic_name, up=True)
def run(test, params, env): """ Configure watchdog, crash the guest and check if watchdog_action occurs. Test Step: 1. see every function step Params: :param test: QEMU test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ timeout = int(params.get("login_timeout", '360')) relogin_timeout = int(params.get("relogin_timeout", '240')) watchdog_device_type = params.get("watchdog_device_type", "i6300esb") watchdog_action = params.get("watchdog_action", "reset") trigger_cmd = params.get("trigger_cmd", "echo c > /dev/watchdog") # internal function def _watchdog_device_check(session, watchdog_device): """ Check the watchdog device have been found and init successfully. if not will raise error. """ # when using ib700 need modprobe it's driver manually. if watchdog_device == "ib700": session.cmd("modprobe ib700wdt") # when wDT is 6300esb need check pci info if watchdog_device == "i6300esb": error.context("checking pci info to ensure have WDT device", logging.info) o = session.cmd_output("lspci") if o: wdt_pci_info = re.findall(".*6300ESB Watchdog Timer", o) if not wdt_pci_info: raise error.TestFail("Can find watchdog pci") logging.info("Found watchdog pci device : %s" % wdt_pci_info) # checking watchdog init info using dmesg error.context("Checking watchdog init info using dmesg", logging.info) dmesg_info = params.get("dmesg_info", "(i6300ESB|ib700wdt).*init") (s, o) = session.cmd_status_output("dmesg | grep -i '%s' " % dmesg_info) if s != 0: error_msg = "Wactchdog device '%s' initialization failed " raise error.TestError(error_msg % watchdog_device) logging.info("Watchdog device '%s' add and init successfully" % watchdog_device) logging.debug("Init info : '%s'" % o) def _trigger_watchdog(session, trigger_cmd=None): """ Trigger watchdog action Params: @session: guest connect session. @trigger_cmd: cmd trigger the watchdog """ if trigger_cmd is not None: error.context("Trigger Watchdog action using:'%s'." % trigger_cmd, logging.info) session.sendline(trigger_cmd) def _action_check(session, watchdog_action): """ Check whether or not the watchdog action occurred. if the action was not occurred will raise error. """ # when watchdog action is pause, shutdown, reset, poweroff # the vm session will lost responsive response_timeout = int(params.get("response_timeout", '240')) error.context( "Check whether or not watchdog action '%s' take effect" % watchdog_action, logging.info) if not utils_misc.wait_for(lambda: not session.is_responsive(), response_timeout, 0, 1): if watchdog_action == "none" or watchdog_action == "debug": logging.info("OK, the guest session is responsive still") else: raise error.TestFail( "Oops, seems action '%s' take no effect, ", "guest is responsive" % watchdog_action) # when action is poweroff or shutdown(without no-shutdown option), the vm # will dead, and qemu exit. # The others the vm monitor still responsive, can report the vm status. if (watchdog_action == "poweroff" or (watchdog_action == "shutdown" and params.get("disable_shutdown") != "yes")): if not utils_misc.wait_for(lambda: vm.is_dead(), response_timeout, 0, 1): raise error.TestFail( "Oops, seems '%s' action take no effect, ", "guest is alive!" % watchdog_action) else: if watchdog_action == "pause": f_param = "paused" elif watchdog_action == "shutdown": f_param = "shutdown" else: f_param = "running" if not utils_misc.wait_for( lambda: vm.monitor.verify_status(f_param), response_timeout, 0, 1): logging.debug("Monitor status is:%s" % vm.monitor.get_status()) raise error.TestFail( "Oops, seems action '%s' take no effect, ", "Wrong monitor status!" % watchdog_action) # when the action is reset, need can relogin the guest. if watchdog_action == "reset": logging.info("Try to login the guest after reboot") vm.wait_for_login(timeout=relogin_timeout) logging.info("Watchdog action '%s' come into effect." % watchdog_action) # test case def check_watchdog_support(): """ check the host qemu-kvm support watchdog device Test Step: 1. Send qemu command 'qemu -watchdog ?' 2. Check the watchdog type that the host support. """ qemu_binary = utils_misc.get_qemu_binary(params) watchdog_type_check = params.get("watchdog_type_check", " -watchdog '?'") qemu_cmd = qemu_binary + watchdog_type_check # check the host support watchdog types. error.context( "Checking whether or not the host support WDT '%s'" % watchdog_device_type, logging.info) watchdog_device = utils.system_output("%s 2>&1" % qemu_cmd, retain_output=True) if watchdog_device: if re.findall(watchdog_device_type, watchdog_device, re.I): logging.info("The host support '%s' type watchdog device" % watchdog_device_type) else: raise error.TestFail( "Host not support watchdog device type %s " % watchdog_device_type) logging.info("The host support watchdog device type is: '%s'" % watchdog_device) else: raise error.TestFail("No watchdog device support in the host!") def guest_boot_with_watchdog(): """ check the guest can boot with watchdog device Test Step: 1. Boot guest with watchdog device 2. Check watchdog device have been initialized successfully in guest """ _watchdog_device_check(session, watchdog_device_type) def watchdog_action_test(): """ Watchdog action test Test Step: 1. Boot guest with watchdog device 2. Check watchdog device have been initialized successfully in guest 3.Trigger wathchdog action through open /dev/watchdog 4.Ensure watchdog_action take effect. """ _watchdog_device_check(session, watchdog_device_type) _trigger_watchdog(session, trigger_cmd) _action_check(session, watchdog_action) def magic_close_support(): """ Magic close the watchdog action. Test Step: 1. Boot guest with watchdog device 2. Check watchdog device have been initialized successfully in guest 3. Inside guest, trigger watchdog action" 4. Inside guest, before heartbeat expires, close this action" 5. Wait heartbeat timeout check the watchdog action deactive. """ response_timeout = int(params.get("response_timeout", '240')) magic_cmd = params.get("magic_close_cmd", "echo V > /dev/watchdog") _watchdog_device_check(session, watchdog_device_type) _trigger_watchdog(session, trigger_cmd) # magic close error.context("Magic close is start", logging.info) _trigger_watchdog(session, magic_cmd) if utils_misc.wait_for(lambda: not session.is_responsive(), response_timeout, 0, 1): error_msg = "Oops,Watchdog action take effect, magic close FAILED" raise error.TestFail(error_msg) logging.info("Magic close take effect.") def migration_when_wdt_timeout(): """ Migration when WDT timeout Test Step: 1. Boot guest with watchdog device 2. Check watchdog device have been initialized successfully in guest 3. Start VM with watchdog device, action reset|poweroff|pause 4. Inside RHEL guest, trigger watchdog 5. Before WDT timeout, do vm migration 6. After migration, check the watchdog action take effect """ mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2 _watchdog_device_check(session, watchdog_device_type) _trigger_watchdog(session, trigger_cmd) error.context( "Do migration(protocol:%s),Watchdog have been triggered." % mig_protocol, logging.info) vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay) _action_check(session, watchdog_action) def hotplug_unplug_watchdog_device(): """ Hotplug/unplug watchdog device Test Step: 1. Start VM with "-watchdog-action pause" CLI option 2. Add WDT via monitor 3. Trigger watchdog action in guest 4. Remove WDT device through monitor cmd "device_del" 5. Resume and relogin the guest, check the device have been removed. """ session = vm.wait_for_login(timeout=timeout) o = session.cmd_output("lspci") if o: wdt_pci_info = re.findall(".*6300ESB Watchdog Timer", o) if wdt_pci_info: raise error.TestFail("Can find watchdog pci") plug_watchdog_device = params.get("plug_watchdog_device", "i6300esb") watchdog_device_add = ("device_add driver=%s, id=%s" % (plug_watchdog_device, "watchdog")) watchdog_device_del = ("device_del id=%s" % "watchdog") error.context("Hotplug watchdog device '%s'" % plug_watchdog_device, logging.info) vm.monitor.send_args_cmd(watchdog_device_add) # wait watchdog device init time.sleep(5) _watchdog_device_check(session, plug_watchdog_device) _trigger_watchdog(session, trigger_cmd) _action_check(session, watchdog_action) error.context("Hot unplug watchdog device", logging.info) vm.monitor.send_args_cmd(watchdog_device_del) error.context("Resume the guest, check the WDT have been removed", logging.info) vm.resume() session = vm.wait_for_login(timeout=timeout) o = session.cmd_output("lspci") if o: wdt_pci_info = re.findall(".*6300ESB Watchdog Timer", o) if wdt_pci_info: raise error.TestFail("Oops, find watchdog pci, unplug failed") logging.info("The WDT remove successfully") # main procedure test_type = params.get("test_type") error.context("'%s' test starting ... " % test_type, logging.info) error.context( "Boot VM with WDT(Device:'%s', Action:'%s'),and try to login" % (watchdog_device_type, watchdog_action), logging.info) params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params.get("main_vm")) vm = env.get_vm(params["main_vm"]) session = vm.wait_for_login(timeout=timeout) if (test_type in locals()): test_running = locals()[test_type] test_running() else: raise error.TestError( "Oops test %s doesn't exist, have a check please." % test_type)
def run_hello_world(test, params, env): """ QEMU 'Hello, world!' test 1) Boot the main vm, or just grab it if it's already booted. 2) Echo "Hello, world!" in guest and get the output. 3) Compare whether the return matches our expectations. 4) Send a monitor command and log its output. 5) Verify whether the vm is running through monitor. 6) Echo "Hello, world!" in the host using shell. 7) Compare whether the return matches our expectations. 8) Get a sleep_time parameter from the config file and sleep during the specified sleep_time. This is a sample QEMU test, so people can get used to some of the test APIs. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ # Error contexts are used to give more info on what was # going on when one exception happened executing test code. error.context("Get the main VM", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() # Each test has a params dict, with lots of # key = value pairs. Values are always strings # In this case, we'll convert login_timeout to int timeout = int(params.get("login_timeout", 360)) # This represents an SSH session. You can end it calling # session.close(), but you don't need to since the framework # takes care of closing all sessions that were opened by a test. session = vm.wait_for_login(timeout=timeout) # Send command to the guest, using session command. error.context("Echo 'Hello, world!' in guest and get the output", logging.info) # Here, timeout was passed explicitly to show it can be tweaked guest_cmd = "echo 'Hello, world!'" # If you just need the output, use session.cmd(). If the command fails, # it will raise a aexpect.ShellCmdError exception guest_cmd_output = session.cmd(guest_cmd, timeout=60) # The output will contain a newline, so strip() # it for the purposes of pretty printing and comparison guest_cmd_output = guest_cmd_output.strip() logging.info("Guest cmd output: '%s'", guest_cmd_output) # Here, we will fail a test if the guest outputs something unexpected if guest_cmd_output != 'Hello, world!': raise error.TestFail("Unexpected output from guest") # Send command to the guest, using monitor command. error.context("Send a monitor command", logging.info) monitor_cmd_ouput = vm.monitor.info("status") logging.info("Monitor returns '%s'", monitor_cmd_ouput) # Verify whether the VM is running. This will throw an exception in case # it is not running, failing the test as well. vm.verify_status("running") # Send command to host error.context("Echo 'Hello, world!' in the host using shell", logging.info) # If the command fails, it will raise a error.CmdError exception host_cmd_output = utils.system_output("echo 'Hello, world!'") logging.info("Host cmd output '%s'", host_cmd_output) # Here, we will fail a test if the host outputs something unexpected if host_cmd_output != 'Hello, world!': raise error.TestFail("Unexpected output from guest") # An example of getting a required parameter from the config file error.context("Get a required parameter from the config file", logging.info) sleep_time = int(params["sleep_time"]) logging.info("Sleep for '%d' seconds", sleep_time) time.sleep(sleep_time)
err) if params.get("negative_check_pattern"): check_pattern = params.get("negative_check_pattern") if check_pattern not in str(err): raise error.TestFail("'%s' not in exception '%s'" % (check_pattern, err)) else: raise error.TestFail(err) except qemu_monitor.MonitorProtocolError, err: raise error.TestFail(err) except Exception, err: raise error.TestFail(err) # Post command if post_cmd is not None: error.context("Run post command '%s'." % post_cmd, logging.info) post_o = send_cmd(post_cmd) logging.debug("Post-command: '%s'\n Output: '%s'", post_cmd, post_o) if result_check is not None: txt = "Verify that qmp command '%s' works as designed." % qmp_cmd error.context(txt, logging.info) if result_check == 'qmp_cpu': qmp_cpu_check(output) elif result_check == "equal" or result_check == "contain": check_result(output, cmd_return_value) elif result_check == "m_format_q": check_result(output, cmd_return_value) elif 'post' in result_check: result_check = result_check.split('_', 1)[1] check_result(post_o, cmd_return_value)
def launch_client(sessions, server, server_ctl, host, clients, l, nf_args, port, params, server_cyg): """ Launch netperf clients """ netperf_version = params.get("netperf_version", "2.6.0") client_path = "/tmp/netperf-%s/src/netperf" % netperf_version server_path = "/tmp/netperf-%s/src/netserver" % netperf_version get_status_flag = params.get("get_status_in_guest", "no") == "yes" global _netserver_started # Start netserver if _netserver_started: logging.debug("Netserver already started.") else: error.context("Start Netserver on guest", logging.info) if params.get("os_type") == "windows": timeout = float(params.get("timeout", "240")) cdrom_drv = utils_misc.get_winutils_vol(server_ctl) if params.get("use_cygwin") == "yes": netserv_start_cmd = params.get("netserv_start_cmd") netperf_src = params.get("netperf_src") % cdrom_drv cygwin_root = params.get("cygwin_root") netserver_path = params.get("netserver_path") netperf_install_cmd = params.get("netperf_install_cmd") start_session = server_cyg logging.info("Start netserver with cygwin, cmd is: %s" % netserv_start_cmd) if "netserver" not in server_ctl.cmd_output("tasklist"): netperf_pack = "netperf-%s" % params.get("netperf_version") s_check_cmd = "dir %s" % netserver_path p_check_cmd = "dir %s" % cygwin_root if not ("netserver.exe" in server_ctl.cmd(s_check_cmd) and netperf_pack in server_ctl.cmd(p_check_cmd)): error.context( "Install netserver in Windows guest cygwin", logging.info) cmd = "xcopy %s %s /S /I /Y" % (netperf_src, cygwin_root) server_ctl.cmd(cmd) server_cyg.cmd_output(netperf_install_cmd, timeout=timeout) if "netserver.exe" not in server_ctl.cmd(s_check_cmd): err_msg = "Install netserver cygwin failed" raise error.TestNAError(err_msg) logging.info( "Install netserver in cygwin successfully") else: start_session = server_ctl netserv_start_cmd = params.get("netserv_start_cmd") % cdrom_drv logging.info("Start netserver without cygwin, cmd is: %s" % netserv_start_cmd) error.context("Start netserver on windows guest", logging.info) start_netserver_win(start_session, netserv_start_cmd) else: logging.info("Netserver start cmd is '%s'" % server_path) ssh_cmd(server_ctl, "pidof netserver || %s" % server_path) ncpu = ssh_cmd(server_ctl, "cat /proc/cpuinfo |grep processor |wc -l") ncpu = re.findall(r"\d+", ncpu)[-1] logging.info("Netserver start successfully") def count_interrupt(name): """ Get a list of interrut number for each queue @param name: the name of interrupt, such as "virtio0-input" """ sum = 0 intr = [] stat = ssh_cmd(server_ctl, "cat /proc/interrupts |grep %s" % name) for i in stat.strip().split("\n"): for cpu in range(int(ncpu)): sum += int(i.split()[cpu + 1]) intr.append(sum) sum = 0 return intr def get_state(): for i in ssh_cmd(server_ctl, "ifconfig").split("\n\n"): if server in i: ifname = re.findall(r"(\w+\d+)[:\s]", i)[0] path = "find /sys/devices|grep net/%s/statistics" % ifname cmd = "%s/rx_packets|xargs cat;%s/tx_packets|xargs cat;" \ "%s/rx_bytes|xargs cat;%s/tx_bytes|xargs cat" % (path, path, path, path) output = ssh_cmd(server_ctl, cmd).split()[-4:] nrx = int(output[0]) ntx = int(output[1]) nrxb = int(output[2]) ntxb = int(output[3]) nre = int( ssh_cmd(server_ctl, "grep Tcp /proc/net/snmp|tail -1").split()[12]) state_list = [ 'rx_pkts', nrx, 'tx_pkts', ntx, 'rx_byts', nrxb, 'tx_byts', ntxb, 're_pkts', nre ] try: nrx_intr = count_interrupt("virtio.-input") ntx_intr = count_interrupt("virtio.-output") sum = 0 for i in range(len(nrx_intr)): state_list.append('rx_intr_%s' % i) state_list.append(nrx_intr[i]) sum += nrx_intr[i] state_list.append('rx_intr_sum') state_list.append(sum) sum = 0 for i in range(len(ntx_intr)): state_list.append('tx_intr_%s' % i) state_list.append(ntx_intr[i]) sum += ntx_intr[i] state_list.append('tx_intr_sum') state_list.append(sum) except IndexError: ninit = count_interrupt("virtio.") state_list.append('intr') state_list.append(ninit) io_exit = int(ssh_cmd(host, "cat /sys/kernel/debug/kvm/io_exits")) irq_inj = int(ssh_cmd(host, "cat /sys/kernel/debug/kvm/irq_injections")) state_list.append('io_exit') state_list.append(io_exit) state_list.append('irq_inj') state_list.append(irq_inj) return state_list def netperf_thread(i, numa_enable, client_s, timeout): cmd = "" fname = "/tmp/netperf.%s.nf" % pid if numa_enable: output = ssh_cmd(client_s, "numactl --hardware") n = int(re.findall(r"available: (\d+) nodes", output)[0]) - 1 cmd += "numactl --cpunodebind=%s --membind=%s " % (n, n) cmd += "/tmp/netperf_agent.py %d %s -D 1 -H %s -l %s %s" % ( i, client_path, server, int(l) * 1.5, nf_args) cmd += " >> %s" % fname logging.info("Start netperf thread by cmd '%s'" % cmd) ssh_cmd(client_s, cmd) def all_clients_up(): try: content = ssh_cmd(clients[-1], "cat %s" % fname) except: content = "" return False if int(sessions) == len(re.findall("MIGRATE", content)): return True return False def parse_demo_result(fname, sessions): """ Process the demo result, remove the noise from head, and compute the final throughout. :param fname: result file name :param sessions: sessions' number """ fd = open(fname) lines = fd.readlines() fd.close() for i in range(1, len(lines) + 1): if "AF_INET" in lines[-i]: break nresult = i - 1 if nresult < int(sessions): raise error.TestError("We couldn't expect this parallism," "expect %s get %s" % (sessions, nresult)) niteration = nresult / sessions result = 0.0 for this in lines[-sessions * niteration:]: if "Interim" in this: result += float(re.findall(r"Interim result: *(\S+)", this)[0]) result = result / niteration logging.debug("niteration: %s" % niteration) return result error.context("Start netperf client threads", logging.info) pid = str(os.getpid()) fname = "/tmp/netperf.%s.nf" % pid ssh_cmd(clients[-1], "rm -f %s" % fname) numa_enable = params.get("netperf_with_numa", "yes") == "yes" timeout_netperf_start = int(l) * 0.5 client_thread = threading.Thread(target=netperf_thread, kwargs={ "i": int(sessions), "numa_enable": numa_enable, "client_s": clients[0], "timeout": timeout_netperf_start }) client_thread.start() ret = {} ret['pid'] = pid if utils_misc.wait_for(all_clients_up, timeout_netperf_start, 0.0, 0.2, "Wait until all netperf clients start to work"): logging.debug("All netperf clients start to work.") else: raise error.TestNAError("Error, not all netperf clients at work") # real & effective test starts if get_status_flag: start_state = get_state() ret['mpstat'] = ssh_cmd(host, "mpstat 1 %d |tail -n 1" % (l - 1)) finished_result = ssh_cmd(clients[-1], "cat %s" % fname) # stop netperf clients kill_cmd = "killall netperf" if params.get("os_type") == "windows": kill_cmd = "taskkill /F /IM netperf*" ssh_cmd(clients[-1], kill_cmd, ignore_status=True) # real & effective test ends if get_status_flag: end_state = get_state() if len(start_state) != len(end_state): msg = "Initial state not match end state:\n" msg += " start state: %s\n" % start_state msg += " end state: %s\n" % end_state logging.warn(msg) else: for i in range(len(end_state) / 2): ret[end_state[i * 2]] = (end_state[i * 2 + 1] - start_state[i * 2 + 1]) client_thread.join() error.context("Testing Results Treatment and Report", logging.info) f = open(fname, "w") f.write(finished_result) f.close() ret['thu'] = parse_demo_result(fname, int(sessions)) return ret
def run_qmp_command(test, params, env): """ Test qmp event notification, this case will: 1) Start VM with qmp enable. 2) Connect to qmp port then run qmp_capabilities command. 3) Initiate the qmp command defined in config (qmp_cmd) 4) Verify that qmp command works as designed. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ def check_result(qmp_o, output=None): """ Check test result with difference way accoriding to result_check. result_check = equal, will compare cmd_return_value with qmp command output. result_check = contain, will try to find cmd_return_value in qmp command output. result_check = m_equal_q, will compare key value in monitor command output and qmp command output. result_check = m_in_q, will try to find monitor command output's key value in qmp command output. result_check = m_format_q, will try to match the output's format with check pattern. :param qmp_o: output from pre_cmd, qmp_cmd or post_cmd. :param o: output from pre_cmd, qmp_cmd or post_cmd or an execpt result set in config file. """ if result_check == "equal": value = output if value != str(qmp_o): raise error.TestFail("QMP command return value does not match " "the expect result. Expect result: '%s'\n" "Actual result: '%s'" % (value, qmp_o)) elif result_check == "contain": values = output.split(';') for value in values: if value.strip() not in str(qmp_o): raise error.TestFail("QMP command output does not contain " "expect result. Expect result: '%s'\n" "Actual result: '%s'" % (value, qmp_o)) elif result_check == "not_contain": values = output.split(';') for value in values: if value in str(qmp_o): raise error.TestFail("QMP command output contains unexpect" " result. Unexpect result: '%s'\n" "Actual result: '%s'" % (value, qmp_o)) elif result_check == "m_equal_q": msg = "QMP command ouput is not equal to in human monitor command." msg += "\nQMP command output: '%s'" % qmp_o msg += "\nHuman command output: '%s'" % output res = output.splitlines(True) if type(qmp_o) != type(res): len_o = 1 else: len_o = len(qmp_o) if len(res) != len_o: raise error.TestFail(msg) re_str = r'([^ \t\n\r\f\v=]*)=([^ \t\n\r\f\v=]*)' for i in range(len(res)): if qmp_cmd == "query-version": version = qmp_o['qemu'] version = "%s.%s.%s" % (version['major'], version['minor'], version['micro']) package = qmp_o['package'] re_str = r"([0-9]+\.[0-9]+\.[0-9]+)\s*(\(\S*\))?" hmp_version, hmp_package = re.findall(re_str, res[i])[0] if not hmp_package: hmp_package = package if version != hmp_version or package != hmp_package: raise error.TestFail(msg) else: matches = re.findall(re_str, res[i]) for key, val in matches: if '0x' in val: val = long(val, 16) if val != qmp_o[i][key]: msg += "\nValue in human monitor: '%s'" % val msg += "\nValue in qmp: '%s'" % qmp_o[i][key] raise error.TestFail(msg) elif qmp_cmd == "query-block": cmp_str = "u'%s': u'%s'" % (key, val) cmp_s = "u'%s': %s" % (key, val) if '0' == val: cmp_str_b = "u'%s': False" % key elif '1' == val: cmp_str_b = "u'%s': True" % key else: cmp_str_b = cmp_str if (cmp_str not in str(qmp_o[i]) and cmp_str_b not in str(qmp_o[i]) and cmp_s not in str(qmp_o[i])): msg += ("\nCan not find '%s', '%s' or '%s' in " " QMP command output." % (cmp_s, cmp_str_b, cmp_str)) raise error.TestFail(msg) elif qmp_cmd == "query-balloon": if (int(val) * 1024 * 1024 != qmp_o[key] and val not in str(qmp_o[key])): msg += ("\n'%s' is not in QMP command output" % val) raise error.TestFail(msg) else: if (val not in str(qmp_o[i][key]) and str(bool(int(val))) not in str(qmp_o[i][key])): msg += ("\n'%s' is not in QMP command output" % val) raise error.TestFail(msg) elif result_check == "m_in_q": res = output.splitlines(True) msg = "Key value from human monitor command is not in" msg += "QMP command output.\nQMP command output: '%s'" % qmp_o msg += "\nHuman monitor command output '%s'" % output for i in range(len(res)): params = res[i].rstrip().split() for param in params: try: str_o = str(qmp_o.values()) except AttributeError: str_o = qmp_o if param.rstrip() not in str(str_o): msg += "\nKey value is '%s'" % param.rstrip() raise error.TestFail(msg) elif result_check == "m_format_q": match_flag = True for i in qmp_o: if output is None: raise error.TestError("QMP output pattern is missing") if re.match(output.strip(), str(i)) is None: match_flag = False if not match_flag: msg = "Output does not match the pattern: '%s'" % output raise error.TestFail(msg) def qmp_cpu_check(output): """ qmp_cpu test check """ last_cpu = int(params['smp']) - 1 for out in output: cpu = out.get('CPU') if cpu is None: raise error.TestFail("'CPU' index is missing in QMP output " "'%s'" % out) else: current = out.get('current') if current is None: raise error.TestFail("'current' key is missing in QMP " "output '%s'" % out) elif cpu < last_cpu: if current is False: pass else: raise error.TestFail("Attribute 'current' should be " "'False', but is '%s' instead.\n" "'%s'" % (current, out)) elif cpu == last_cpu: if current is True: pass else: raise error.TestFail("Attribute 'current' should be " "'True', but is '%s' instead.\n" "'%s'" % (current, out)) elif cpu <= last_cpu: continue else: raise error.TestFail("Incorrect CPU index '%s' (corrupted " "or higher than no_cpus).\n%s" % (cpu, out)) if not utils_misc.qemu_has_option("qmp", params['qemu_binary']): raise error.TestNAError("Host qemu does not support qmp.") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) module = params.get("modprobe_module") if module: error.context("modprobe the module %s" % module, logging.info) session.cmd("modprobe %s" % module) qmp_ports = vm.get_monitors_by_type('qmp') if qmp_ports: qmp_port = qmp_ports[0] else: raise error.TestError("Incorrect configuration, no QMP monitor found.") hmp_ports = vm.get_monitors_by_type('human') if hmp_ports: hmp_port = hmp_ports[0] else: raise error.TestError("Incorrect configuration, no QMP monitor found.") callback = {"host_cmd": utils.system_output, "guest_cmd": session.get_command_output, "monitor_cmd": hmp_port.send_args_cmd, "qmp_cmd": qmp_port.send_args_cmd} def send_cmd(cmd): """ Helper to execute command on ssh/host/monitor """ if cmd_type in callback.keys(): return callback[cmd_type](cmd) else: raise error.TestError("cmd_type is not supported") pre_cmd = params.get("pre_cmd") qmp_cmd = params.get("qmp_cmd") cmd_type = params.get("event_cmd_type") post_cmd = params.get("post_cmd") result_check = params.get("cmd_result_check") cmd_return_value = params.get("cmd_return_value") # HOOKs if result_check == 'qmp_cpu': pre_cmd = "cpu index=%d" % (int(params['smp']) - 1) # Pre command if pre_cmd is not None: error.context("Run prepare command '%s'." % pre_cmd, logging.info) pre_o = send_cmd(pre_cmd) logging.debug("Pre-command: '%s'\n Output: '%s'", pre_cmd, pre_o) try: # Testing command error.context("Run qmp command '%s'." % qmp_cmd, logging.info) output = qmp_port.send_args_cmd(qmp_cmd) logging.debug("QMP command: '%s' \n Output: '%s'", qmp_cmd, output) except qemu_monitor.QMPCmdError, err: if params.get("negative_test") == 'yes': logging.debug("Negative QMP command: '%s'\n output:'%s'", qmp_cmd, err) if params.get("negative_check_pattern"): check_pattern = params.get("negative_check_pattern") if check_pattern not in str(err): raise error.TestFail("'%s' not in exception '%s'" % (check_pattern, err)) else: raise error.TestFail(err)
file_link = os.path.join(test.virtdir, "scripts/pipetest.c") vm.copy_files_to(file_link, "/tmp/pipetest.c") build_pipetest_cmd = params.get("build_pipetest_cmd") error.context("Build pipetest script in guest.", logging.info) session.cmd(build_pipetest_cmd, timeout=180) error.context("Run pipetest script in guest.", logging.info) try: o = session.cmd(pipetest_cmd, timeout=180) except aexpect.ShellTimeoutError, e: o = e re_str = params.get("usec_re_str", "[0-9]*\.[0-9]+") val1 = get_re_average(o, re_str) session.close() vm.destroy() error.context("Boot guest without x2apic.", logging.info) params["cpu_model_flags"] += ",-x2apic" env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) if check_x2apic_cmd: error.context("Check x2apic flag in guest after reboot.", logging.info) x2apic_output = session.cmd_output(check_x2apic_cmd).strip() logging.info(x2apic_output) if x2apic_output: raise error.TestFail("Fail to disable x2apic in guest.") error.context("Run pipetest script in guest again.", logging.info) try: o = session.cmd(pipetest_cmd, timeout=180)
def run(test, params, env): """ Network stress test with netperf. 1) Boot up VM(s), setup SSH authorization between host and guest(s)/external host 2) Prepare the test environment in server/client/host 3) Execute netperf tests, collect and analyze the results :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def env_setup(session, ip, user, port, password): error.context("Setup env for %s" % ip) ssh_cmd(session, "iptables -F", ignore_status=True) ssh_cmd(session, "service iptables stop", ignore_status=True) ssh_cmd(session, "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore") download_link = params.get("netperf_download_link") download_dir = data_dir.get_download_dir() md5sum = params.get("pkg_md5sum") pkg = utils.unmap_url_cache(download_dir, download_link, md5sum) remote.scp_to_remote(ip, shell_port, username, password, pkg, "/tmp") ssh_cmd(session, params.get("setup_cmd")) agent_path = os.path.join(test.virtdir, "scripts/netperf_agent.py") remote.scp_to_remote(ip, shell_port, username, password, agent_path, "/tmp") def _pin_vm_threads(vm, node): if node: if not isinstance(node, utils_misc.NumaNode): node = utils_misc.NumaNode(int(node)) utils_test.qemu.pin_vm_threads(vm, node) return node 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) queues = int(params.get("queues", 1)) if queues > 1: if params.get("os_type") == "linux": ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) session.cmd_status_output("ethtool -L %s combined %s" % (ethname, queues)) else: logging.info("FIXME: support to enable MQ for Windows guest!") config_cmds = params.get("config_cmds") if config_cmds: for config_cmd in config_cmds.split(","): cmd = params.get(config_cmd.strip()) if cmd: s, o = session.cmd_status_output(cmd) if s: msg = "Config command %s failed. Output: %s" % (cmd, o) raise error.TestError(msg) if params.get("reboot_after_config", "yes") == "yes": session = vm.reboot(session=session, timeout=login_timeout) if params.get("rh_perf_envsetup_script"): utils_test.service_setup(vm, session, test.virtdir) session.close() server_ip = vm.wait_for_get_address(0, timeout=5) server_ctl = vm.wait_for_login(timeout=login_timeout) server_ctl_ip = server_ip if (params.get("os_type") == "windows" and params.get("use_cygwin") == "yes"): cygwin_prompt = params.get("cygwin_prompt", r"\$\s+$") cygwin_start = params.get("cygwin_start") server_cyg = vm.wait_for_login(timeout=login_timeout) server_cyg.set_prompt(cygwin_prompt) server_cyg.cmd_output(cygwin_start) else: server_cyg = None if len(params.get("nics", "").split()) > 1: vm.wait_for_login(nic_index=1, timeout=login_timeout) server_ctl_ip = vm.wait_for_get_address(1, timeout=5) logging.debug(commands.getoutput("numactl --hardware")) logging.debug(commands.getoutput("numactl --show")) # pin guest vcpus/memory/vhost threads to last numa node of host by default numa_node = _pin_vm_threads(vm, params.get("numa_node")) host = params.get("host", "localhost") host_ip = host if host != "localhost": params_host = params.object_params("host") host = remote.wait_for_login(params_host.get("shell_client"), host_ip, params_host.get("shell_port"), params_host.get("username"), params_host.get("password"), params_host.get("shell_prompt")) client = params.get("client", "localhost") client_ip = client clients = [] # client session 1 for control, session 2 for data communication for i in range(2): if client in params.get("vms"): vm_client = env.get_vm(client) tmp = vm_client.wait_for_login(timeout=login_timeout) client_ip = vm_client.wait_for_get_address(0, timeout=5) elif client != "localhost": tmp = remote.wait_for_login(params.get("shell_client_client"), client_ip, params.get("shell_port_client"), params.get("username_client"), params.get("password_client"), params.get("shell_prompt_client")) else: tmp = "localhost" clients.append(tmp) client = clients[0] vms_list = params["vms"].split() if len(vms_list) > 1: vm2 = env.get_vm(vms_list[-1]) vm2.verify_alive() session2 = vm2.wait_for_login(timeout=login_timeout) if params.get("rh_perf_envsetup_script"): utils_test.service_setup(vm2, session2, test.virtdir) client = vm2.wait_for_login(timeout=login_timeout) client_ip = vm2.get_address() session2.close() _pin_vm_threads(vm2, numa_node) error.context("Prepare env of server/client/host", logging.info) prepare_list = set([server_ctl, client, host]) tag_dict = {server_ctl: "server", client: "client", host: "host"} ip_dict = {server_ctl: server_ctl_ip, client: client_ip, host: host_ip} for i in prepare_list: params_tmp = params.object_params(tag_dict[i]) if params_tmp.get("os_type") == "linux": shell_port = int(params_tmp["shell_port"]) password = params_tmp["password"] username = params_tmp["username"] env_setup(i, ip_dict[i], username, shell_port, password) env.stop_tcpdump() error.context("Start netperf testing", logging.info) start_test(server_ip, server_ctl, host, clients, test.resultsdir, l=int(params.get('l')), sessions_rr=params.get('sessions_rr'), sessions=params.get('sessions'), sizes_rr=params.get('sizes_rr'), sizes=params.get('sizes'), protocols=params.get('protocols'), ver_cmd=params.get('ver_cmd', "rpm -q qemu-kvm"), netserver_port=params.get('netserver_port', "12865"), params=params, server_cyg=server_cyg, test=test) if params.get("log_hostinfo_script"): src = os.path.join(test.virtdir, params.get("log_hostinfo_script")) path = os.path.join(test.resultsdir, "sysinfo") utils.system_output("bash %s %s &> %s" % (src, test.resultsdir, path)) if params.get("log_guestinfo_script") and params.get("log_guestinfo_exec"): src = os.path.join(test.virtdir, params.get("log_guestinfo_script")) path = os.path.join(test.resultsdir, "sysinfo") destpath = params.get("log_guestinfo_path", "/tmp/log_guestinfo.sh") vm.copy_files_to(src, destpath) logexec = params.get("log_guestinfo_exec", "bash") output = server_ctl.cmd_output("%s %s" % (logexec, destpath)) logfile = open(path, "a+") logfile.write(output) logfile.close()
def run_check_block_size(test, params, env): """ Check physical block size and logical block size for virtio block device: 1) Install guest with a new image. 2) Verify whether physical/logical block size in guest is same as qemu parameters. TODO: This test only works on Linux guest, should make it work in windows guest. (Are there any windows tools to check block size?) @param test: QEMU test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ if params.get("need_install") == "yes": error.context("Install guest with a new image", logging.info) unattended_install.run_unattended_install(test, params, env) params["cdroms"] = "" params["unattended_file"] = "" params["cdrom_unattended"] = "" params["kernel"] = "" params["initrd"] = "" params["kernel_params"] = "" params["boot_once"] = "c" vm = env.get_vm(params["main_vm"]) try: vm.verify_alive() except virt_vm.VMDeadError: logging.info("VM is dead, creating...") vm.create(params=params) timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) try: # Get virtio block devices in guest. cmd = params.get("get_dev_list_cmd", '') dev_list = session.cmd_output(cmd).split() if dev_list: expect_physical = int(params.get("physical_block_size_stg", 0)) expect_logical = int(params.get("logical_block_size_stg", 0)) #FIXME: seems we don't have a method to check which virtio # device matches device file in guest. So we just check the # last device file in guest. Hope it will work correctly. # Yep, we need improvement here. error.context("Verify physical/Logical block size", logging.info) cmd = params.get("chk_phy_blk_cmd") % dev_list[-1] logging.debug("Physical block size get via '%s'" % cmd) out_physical = int(session.cmd_output(cmd)) cmd = params.get("chk_log_blk_cmd") % dev_list[-1] logging.debug("Logical block size get via '%s'" % cmd) out_logical = int(session.cmd_output(cmd)) if ((out_physical != expect_physical) or (out_logical != expect_logical)): msg = "Block size in guest doesn't match with qemu parameter\n" msg += "Physical block size in guest: %s, " % out_physical msg += "expect: %s" % expect_physical msg += "\nLogical block size in guest: %s, " % out_logical msg += "expect: %s" % expect_logical raise error.TestFail(msg) else: raise error.TestError("Could not find any virtio block device.") finally: if session: session.close()
def start_test(server, server_ctl, host, clients, resultsdir, l=60, sessions_rr="50 100 250 500", sessions="1 2 4", sizes_rr="64 256 512 1024 2048", sizes="64 256 512 1024 2048 4096", protocols="TCP_STREAM TCP_MAERTS TCP_RR TCP_CRR", ver_cmd=None, netserver_port=None, params={}, server_cyg=None, test=None): """ Start to test with different kind of configurations :param server: netperf server ip for data connection :param server_ctl: ip to control netperf server :param host: localhost ip :param clients: netperf clients' ip :param resultsdir: directory to restore the results :param l: test duration :param sessions_rr: sessions number list for RR test :param sessions: sessions number list :param sizes_rr: request/response sizes (TCP_RR, UDP_RR) :param sizes: send size (TCP_STREAM, UDP_STREAM) :param protocols: test type :param ver_cmd: command to check kvm version :param netserver_port: netserver listen port :param params: Dictionary with the test parameters. :param server_cyg: shell session for cygwin in windows guest """ guest_ver_cmd = params.get("guest_ver_cmd", "uname -r") fd = open("%s/netperf-result.%s.RHS" % (resultsdir, time.time()), "w") test.write_test_keyval( {'kvm-userspace-ver': commands.getoutput(ver_cmd).strip()}) test.write_test_keyval( {'guest-kernel-ver': ssh_cmd(server_ctl, guest_ver_cmd).strip()}) test.write_test_keyval({'session-length': l}) fd.write('### kvm-userspace-ver : %s\n' % commands.getoutput(ver_cmd).strip()) fd.write('### guest-kernel-ver : %s\n' % ssh_cmd(server_ctl, guest_ver_cmd).strip()) fd.write('### kvm_version : %s\n' % os.uname()[2]) fd.write('### session-length : %s\n' % l) record_list = [ 'size', 'sessions', 'throughput', 'trans.rate', 'CPU', 'thr_per_CPU', 'rx_pkts', 'tx_pkts', 'rx_byts', 'tx_byts', 're_pkts', 'irq_inj', 'io_exit', 'rpkt_per_irq', 'tpkt_per_exit' ] for i in range(int(params.get("queues", 0))): record_list.append('rx_intr_%s' % i) record_list.append('rx_intr_sum') for i in range(int(params.get("queues", 0))): record_list.append('tx_intr_%s' % i) record_list.append('tx_intr_sum') base = params.get("format_base", "12") fbase = params.get("format_fbase", "2") output = ssh_cmd(host, "mpstat 1 1 |grep CPU") mpstat_head = re.findall(r"CPU\s+.*", output)[0].split() mpstat_key = params.get("mpstat_key", "%idle") if mpstat_key in mpstat_head: mpstat_index = mpstat_head.index(mpstat_key) + 1 else: mpstat_index = 0 for protocol in protocols.split(): error.context("Testing %s protocol" % protocol, logging.info) if protocol in ("TCP_RR", "TCP_CRR"): sessions_test = sessions_rr.split() sizes_test = sizes_rr.split() protocol_log = protocol else: sessions_test = sessions.split() sizes_test = sizes.split() if protocol == "TCP_STREAM": protocol_log = protocol + " (RX)" elif protocol == "TCP_MAERTS": protocol_log = protocol + " (TX)" fd.write("Category:" + protocol_log + "\n") record_header = True for i in sizes_test: for j in sessions_test: if protocol in ("TCP_RR", "TCP_CRR"): nf_args = "-t %s -v 1 -- -r %s,%s" % (protocol, i, i) elif (protocol == "TCP_MAERTS"): nf_args = "-C -c -t %s -- -m ,%s" % (protocol, i) else: nf_args = "-C -c -t %s -- -m %s" % (protocol, i) ret = launch_client(j, server, server_ctl, host, clients, l, nf_args, netserver_port, params, server_cyg) thu = float(ret['thu']) cpu = 100 - float(ret['mpstat'].split()[mpstat_index]) normal = thu / cpu if ret.get('rx_pkts') and ret.get('irq_inj'): ret['rpkt_per_irq'] = float(ret['rx_pkts']) / float( ret['irq_inj']) if ret.get('tx_pkts') and ret.get('io_exit'): ret['tpkt_per_exit'] = float(ret['tx_pkts']) / float( ret['io_exit']) ret['size'] = int(i) ret['sessions'] = int(j) if protocol in ("TCP_RR", "TCP_CRR"): ret['trans.rate'] = thu else: ret['throughput'] = thu ret['CPU'] = cpu ret['thr_per_CPU'] = normal row, key_list = netperf_record(ret, record_list, header=record_header, base=base, fbase=fbase) if record_header: record_header = False category = row.split('\n')[0] test.write_test_keyval({'category': category}) prefix = '%s--%s--%s' % (protocol, i, j) for key in key_list: test.write_perf_keyval( {'%s--%s' % (prefix, key): ret[key]}) logging.info(row) fd.write(row + "\n") fd.flush() logging.debug("Remove temporary files") commands.getoutput("rm -f /tmp/netperf.%s.nf" % ret['pid']) logging.info("Netperf thread completed successfully") fd.close()
def run_timedrift_no_net_win(test, params, env): """ Test suspend commands in qemu guest agent. :param test: kvm test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ clock_server = params.get("clock_server", "clock.redhat.com") ntputil_install = params.get("ntputil_install", "yum install -y ntpdate") login_timeout = int(params.get("login_timeout", "240")) date_time_command = params.get("date_time_command", r"date -u +'TIME: %a %m/%d/%Y %H:%M:%S.%N'") date_time_filter_re = params.get("date_time_filter_re", r"(?:TIME: \w\w\w )(.{19})(.+)") date_time_format = params.get("date_time_format", "%m/%d/%Y %H:%M:%S") tolerance = float(params.get("time_diff_tolerance", "0.5")) sub_work = params["sub_work"] test_type = params["timedrift_sub_work"] vm_name = params.get("vms") vm = env.get_vm(vm_name) error.context("Check if ntp utils are host in system.", logging.info) try: utils_misc.find_command("ntpdate") except ValueError: error.context("Install ntp utils `%s`." % (ntputil_install), logging.info) utils.run(ntputil_install) error.context("Sync host machine with clock server %s" % (clock_server), logging.info) utils.run("ntpdate %s" % (clock_server)) session = vm.wait_for_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) before_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *before_date) session.close() if sub_work in globals(): # Try to find sub work function. globals()[sub_work](params, vm, session) else: raise error.TestNAError("Unable to found subwork %s in %s test file." % (sub_work, __file__)) vm = env.get_vm(vm_name) session = vm.wait_for_login(timeout=login_timeout) error.context("Get clock from host and guest VM using `date`", logging.info) after_date = utils_test.get_time(session, date_time_command, date_time_filter_re, date_time_format) logging.debug("date: host time=%ss guest time=%ss", *after_date) if test_type == 'guest_suspend': date_diff = time_diff(before_date, after_date) if date_diff > tolerance: raise error.TestFail("date %ss difference is" "'guest_diff_time != host_diff_time'" " out of tolerance %ss" % (date_diff[1], tolerance)) elif test_type == "guest_pause_resume": date_diff = time_diff_host_guest(before_date, after_date) if date_diff[1] > tolerance: raise error.TestFail("date %ss difference is " "'guest_time_after-guest_time_before'" " out of tolerance %ss" % (date_diff[1], tolerance))
def cleanup(self): error.context("Cleanup after test", logging.info) self.close_sessions() self.cleanup_private_network()
def run(test, params, env): """ KVM multi test: 1) Log into guests 2) Check all the nics available or not 3) Ping among guest nic and host 3.1) Ping with different packet size 3.2) Flood ping test 3.3) Final ping test 4) Transfer files among guest nics and host 4.1) Create file by dd command in guest 4.2) Transfer file between nics 4.3) Compare original file and transferred file 5) ping among different nics 5.1) Ping with different packet size 5.2) Flood ping test 5.3) Final ping test 6) Transfer files among different nics 6.1) Create file by dd command in guest 6.2) Transfer file between nics 6.3) Compare original file and transferred file 7) Repeat step 3 - 6 on every nic. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def ping(session, nic, dst_ip, strick_check, flood_minutes): d_packet_size = [1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192, 8878, 9000, 32767, 65507] packet_size = params.get("packet_size", "").split() or d_packet_size for size in packet_size: error.context("Ping with packet size %s" % size, logging.info) status, output = utils_test.ping(dst_ip, 10, interface=nic, packetsize=size, timeout=30, session=session) if strict_check: ratio = utils_test.get_loss_ratio(output) if ratio != 0: raise error.TestFail("Loss ratio is %s for packet size" " %s" % (ratio, size)) else: if status != 0: raise error.TestFail("Ping returns non-zero value %s" % output) error.context("Flood ping test", logging.info) utils_test.ping(dst_ip, None, interface=nic, flood=True, output_func=None, timeout=flood_minutes * 60, session=session) error.context("Final ping test", logging.info) counts = params.get("ping_counts", 100) status, output = utils_test.ping(dst_ip, counts, interface=nic, timeout=float(counts) * 1.5, session=session) if strick_check == "yes": ratio = utils_test.get_loss_ratio(output) if ratio != 0: raise error.TestFail("Packet loss ratio is %s after flood" % ratio) else: if status != 0: raise error.TestFail("Ping returns non-zero value %s" % output) def file_transfer(session, src, dst): username = params.get("username", "") password = params.get("password", "") src_path = "/tmp/1" dst_path = "/tmp/2" port = int(params["file_transfer_port"]) cmd = "dd if=/dev/urandom of=%s bs=100M count=1" % src_path cmd = params.get("file_create_cmd", cmd) error.context("Create file by dd command, cmd: %s" % cmd, logging.info) session.cmd(cmd) transfer_timeout = int(params.get("transfer_timeout")) log_filename = "scp-from-%s-to-%s.log" % (src, dst) error.context("Transfer file from %s to %s" % (src, dst), logging.info) remote.scp_between_remotes(src, dst, port, password, password, username, username, src_path, dst_path, log_filename=log_filename, timeout=transfer_timeout) src_path = dst_path dst_path = "/tmp/3" log_filename = "scp-from-%s-to-%s.log" % (dst, src) error.context("Transfer file from %s to %s" % (dst, src), logging.info) remote.scp_between_remotes(dst, src, port, password, password, username, username, src_path, dst_path, log_filename=log_filename, timeout=transfer_timeout) error.context("Compare original file and transferred file", logging.info) cmd1 = "md5sum /tmp/1" cmd2 = "md5sum /tmp/3" md5sum1 = session.cmd(cmd1).split()[0] md5sum2 = session.cmd(cmd2).split()[0] if md5sum1 != md5sum2: raise error.TestError("File changed after transfer") nic_interface_list = [] check_irqbalance_cmd = params.get("check_irqbalance_cmd") stop_irqbalance_cmd = params.get("stop_irqbalance_cmd") start_irqbalance_cmd = params.get("start_irqbalance_cmd") status_irqbalance = params.get("status_irqbalance") vms = params["vms"].split() host_mem = utils_memory.memtotal() / (1024 * 1024) host_cpu_count = len(utils_misc.get_cpu_processors()) vhost_count = 0 if params.get("vhost"): vhost_count = 1 if host_cpu_count < (1 + vhost_count) * len(vms): raise error.TestError("The host don't have enough cpus to start guest" "pcus: %d, minimum of vcpus and vhost: %d" % (host_cpu_count, (1 + vhost_count) * len(vms))) params['mem'] = host_mem / len(vms) * 1024 params['smp'] = host_cpu_count / len(vms) - vhost_count if params['smp'] % 2 != 0: params['vcpu_sockets'] = 1 params["start_vm"] = "yes" for vm_name in vms: env_process.preprocess_vm(test, params, env, vm_name) timeout = float(params.get("login_timeout", 360)) strict_check = params.get("strick_check", "no") host_ip = utils_net.get_ip_address_by_interface(params.get("netdst")) host_ip = params.get("srchost", host_ip) flood_minutes = float(params["flood_minutes"]) error.context("Check irqbalance service status", logging.info) o = process.system_output(check_irqbalance_cmd, ignore_status=True) check_stop_irqbalance = False if re.findall(status_irqbalance, o): logging.debug("stop irqbalance") process.run(stop_irqbalance_cmd) check_stop_irqbalance = True o = process.system_output(check_irqbalance_cmd, ignore_status=True) if re.findall(status_irqbalance, o): raise error.TestError("Can not stop irqbalance") thread_list = [] nic_interface = [] for vm_name in vms: guest_ifname = "" guest_ip = "" vm = env.get_vm(vm_name) session = vm.wait_for_login(timeout=timeout) thread_list.extend(vm.vcpu_threads) thread_list.extend(vm.vhost_threads) error.context("Check all the nics available or not", logging.info) for index, nic in enumerate(vm.virtnet): guest_ifname = utils_net.get_linux_ifname(session, nic.mac) guest_ip = vm.get_address(index) if not (guest_ifname and guest_ip): err_log = "vms %s get ip or ifname failed." % vm_name err_log = "ifname: %s, ip: %s." % (guest_ifname, guest_ip) raise error.TestFail(err_log) nic_interface = [guest_ifname, guest_ip, session] nic_interface_list.append(nic_interface) error.context("Pin vcpus and vhosts to host cpus", logging.info) host_numa_nodes = utils_misc.NumaInfo() vthread_num = 0 for numa_node_id in host_numa_nodes.nodes: numa_node = host_numa_nodes.nodes[numa_node_id] for _ in range(len(numa_node.cpus)): if vthread_num >= len(thread_list): break vcpu_tid = thread_list[vthread_num] logging.debug("pin vcpu/vhost thread(%s) to cpu(%s)" % (vcpu_tid, numa_node.pin_cpu(vcpu_tid))) vthread_num += 1 nic_interface_list_len = len(nic_interface_list) # ping and file transfer test for src_ip_index in range(nic_interface_list_len): error.context("Ping test from guest to host", logging.info) src_ip_info = nic_interface_list[src_ip_index] ping(src_ip_info[2], src_ip_info[0], host_ip, strict_check, flood_minutes) error.context("File transfer test between guest and host", logging.info) file_transfer(src_ip_info[2], src_ip_info[1], host_ip) for dst_ip in nic_interface_list[src_ip_index:]: if src_ip_info[1] == dst_ip[1]: continue txt = "Ping test between %s and %s" % (src_ip_info[1], dst_ip[1]) error.context(txt, logging.info) ping(src_ip_info[2], src_ip_info[0], dst_ip[1], strict_check, flood_minutes) txt = "File transfer test between %s " % src_ip_info[1] txt += "and %s" % dst_ip[1] error.context(txt, logging.info) file_transfer(src_ip_info[2], src_ip_info[1], dst_ip[1]) if check_stop_irqbalance: process.run(start_irqbalance_cmd)
def run_vlan(test, params, env): """ Test 802.1Q vlan of NIC, config it by vconfig/ip command. 1) Create two VMs. 2) load 8021q module in guest. 3) Setup vlans by vconfig/ip in guest and using hard-coded ip address. 4) Enable arp_ignore for all ipv4 device in guest. 5) Repeat steps 2 - 4 in every guest. 6) Test by ping between same and different vlans of two VMs. 7) Test by flood ping between same vlan of two VMs. 8) Test by TCP data transfer between same vlan of two VMs. 9) Remove the named vlan-device. 10) Test maximal plumb/unplumb vlans. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def add_vlan(session, v_id, iface="eth0", cmd_type="ip"): """ Creates a vlan-device on iface by cmd that assigned by cmd_type now only support 'ip' and 'vconfig' """ txt = "Create a vlan-device on interface %s with vlan id %s" % (iface, v_id) error.context(txt, logging.info) if cmd_type == "vconfig": cmd = "vconfig add %s %s" % (iface, v_id) elif cmd_type == "ip": v_name = "%s.%s" % (iface, v_id) cmd = "ip link add link %s %s type vlan id %s " % (iface, v_name, v_id) else: err_msg = "Unexpected vlan operation command: %s" % cmd_type err_msg += "only support 'ip' and 'vconfig' now" raise error.TestError(err_msg) session.cmd(cmd) def set_ip_vlan(session, v_id, ip, iface="eth0"): """ Set ip address of vlan interface """ iface = "%s.%s" % (iface, v_id) txt = "Set ip to '%s' for interface '%s'" % (iface, ip) error.context(txt, logging.info) session.cmd("ifconfig %s %s" % (iface, ip)) def set_arp_ignore(session): """ Enable arp_ignore for all ipv4 device in guest """ error.context("Enable arp_ignore for all ipv4 device in guest", logging.info) ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore" session.cmd(ignore_cmd) def rem_vlan(session, v_id, iface="eth0", cmd_type="ip"): """ Removes the named vlan interface(iface+v_id) """ v_iface = '%s.%s' % (iface, v_id) if cmd_type == "vconfig": rem_vlan_cmd = "vconfig rem %s" % v_iface elif cmd_type == "ip": rem_vlan_cmd = "ip link delete %s" % v_iface else: err_msg = "Unexpected vlan operation command: %s" % cmd_type err_msg += "only support 'ip' and 'vconfig' now" raise error.TestError(err_msg) send_cmd = "[ -e /proc/net/vlan/%s ] && %s" % (v_iface, rem_vlan_cmd) error.context("Remove the vlan-device '%s'." % v_iface, logging.info) return session.cmd_status(send_cmd) def nc_transfer(src, dst): nc_port = utils_misc.find_free_port(1025, 5334, vm_ip[dst]) listen_cmd = params.get("listen_cmd") send_cmd = params.get("send_cmd") #listen in dst listen_cmd = listen_cmd % (nc_port, "receive") session[dst].sendline(listen_cmd) time.sleep(2) # send file from src to dst send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file") session[src].cmd(send_cmd, timeout=60) try: session[dst].read_up_to_prompt(timeout=60) except aexpect.ExpectError: raise error.TestFail("Fail to receive file" " from vm%s to vm%s" % (src + 1, dst + 1)) # check MD5 message digest of receive file in dst output = session[dst].cmd_output("md5sum receive").strip() digest_receive = re.findall(r'(\w+)', output)[0] if digest_receive == digest_origin[src]: logging.info("file succeed received in vm %s", vlan_ip[dst]) else: logging.info("digest_origin is %s", digest_origin[src]) logging.info("digest_receive is %s", digest_receive) raise error.TestFail("File transferred differ from origin") session[dst].cmd("rm -f receive") def flood_ping(src, dst): # we must use a dedicated session because the aexpect # does not have the other method to interrupt the process in # the guest rather than close the session. error.context( "Flood ping from %s interface %s to %s" % (vm[src].name, ifname[src], vlan_ip[dst]), logging.info) session_flood = vm[src].wait_for_login(timeout=60) utils_test.ping(vlan_ip[dst], flood=True, interface=ifname[src], session=session_flood, timeout=10) session_flood.close() vm = [] session = [] ifname = [] vm_ip = [] digest_origin = [] vlan_ip = ['', ''] ip_unit = ['1', '2'] subnet = params.get("subnet", "192.168") vlan_num = int(params.get("vlan_num", 5)) maximal = int(params.get("maximal")) file_size = params.get("file_size", 4094) cmd_type = params.get("cmd_type", "ip") login_timeout = int(params.get("login_timeout", 360)) vm.append(env.get_vm(params["main_vm"])) vm.append(env.get_vm("vm2")) for vm_ in vm: vm_.verify_alive() for i in range(2): session.append(vm[i].wait_for_login(timeout=login_timeout)) if not session[i]: raise error.TestError("Could not log into guest %s" % vm[i].name) logging.info("Logged in %s successful" % vm[i].name) ifname.append( utils_net.get_linux_ifname(session[i], vm[i].get_mac_address())) # get guest ip vm_ip.append(vm[i].get_address()) # produce sized file in vm dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s" session[i].cmd(dd_cmd % file_size) # record MD5 message digest of file output = session[i].cmd("md5sum file", timeout=60) digest_origin.append(re.findall(r'(\w+)', output)[0]) # stop firewall in vm session[i].cmd("service iptables stop; true") error.context("load 8021q module in guest %s" % vm[i].name, logging.info) session[i].cmd("modprobe 8021q") try: for i in range(2): logging.info("Setup vlan environment in guest %s" % vm[i].name) for vlan_i in range(1, vlan_num + 1): add_vlan(session[i], vlan_i, ifname[i], cmd_type) v_ip = "%s.%s.%s" % (subnet, vlan_i, ip_unit[i]) set_ip_vlan(session[i], vlan_i, v_ip, ifname[i]) set_arp_ignore(session[i]) for vlan in range(1, vlan_num + 1): error.context("Test for vlan %s" % vlan, logging.info) error.context("Ping test between vlans", logging.info) interface = ifname[0] + '.' + str(vlan) for vlan2 in range(1, vlan_num + 1): for i in range(2): interface = ifname[i] + '.' + str(vlan) dest = subnet + '.' + \ str(vlan2) + '.' + ip_unit[(i + 1) % 2] s, o = utils_test.ping(dest, count=2, interface=interface, session=session[i], timeout=30) if ((vlan == vlan2) ^ (s == 0)): raise error.TestFail("%s ping %s unexpected" % (interface, dest)) vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0] vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1] flood_ping(0, 1) flood_ping(1, 0) error.context("Transferring data through nc", logging.info) nc_transfer(0, 1) nc_transfer(1, 0) finally: for vlan in range(1, vlan_num + 1): logging.info("rem vlan: %s", vlan) rem_vlan(session[0], vlan, ifname[0], cmd_type) rem_vlan(session[1], vlan, ifname[1], cmd_type) # Plumb/unplumb maximal number of vlan interfaces i = 1 s = 0 try: error.context("Testing the plumb of vlan interface", logging.info) for i in range(1, maximal + 1): add_vlan(session[0], i, ifname[0], cmd_type) finally: for j in range(1, i + 1): s = s or rem_vlan(session[0], j, ifname[0], cmd_type) if s == 0: logging.info("maximal interface plumb test done") else: logging.error("maximal interface plumb test failed") session[0].close() session[1].close()
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): return True 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.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: session.cmd(params.get("pci_test_cmd") % (pci_num + 1)) 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
logging.error("Failed to get guest cpu flags %s" % e) utils_misc.Flag.aliases = utils_misc.kvm_map_flags_aliases # Get all models' info from dump file dump_file = params.get("dump_file") default_dump_path = os.path.join(data_dir.get_deps_dir(), "cpuid") dump_path = params.get("dump_path", default_dump_path) cpuinfo_file = utils.unmap_url(dump_path, dump_file, dump_path) host_flags = utils_misc.get_cpu_flags() vm = env.get_vm(params["main_vm"]) guest_cpumodel = vm.cpuinfo.model extra_flags = params.get("cpu_model_flags", " ") error.context("Boot guest with -cpu %s,%s" % (guest_cpumodel, extra_flags), logging.info) vm.verify_alive() timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) # Get qemu model host_cpumodel = utils_misc.get_host_cpu_models() if guest_cpumodel not in host_cpumodel: qemu_model = host_cpumodel[0] else: qemu_model = guest_cpumodel error.context("Get model %s support flags" % qemu_model, logging.info) # Get flags for every reg from model's info models_info = utils.system_output("cat %s" % cpuinfo_file).split("x86") model_info = qemu_model_info(models_info, qemu_model)
def test(self): super(test_multihost_locking, self).test() error.context("Lock cdrom in VM.") if self.is_src: # Starts in source serial_num = generate_serial_num() cdrom = params.get("cdroms", "").split()[-1] params["drive_serial_%s" % cdrom] = serial_num params["start_vm"] = "yes" env_process.process(test, params, env, env_process.preprocess_image, env_process.preprocess_vm) vm = env.get_vm(self.vms[0]) session = vm.wait_for_login(timeout=login_timeout) cdrom_dev_list = list_guest_cdroms(session) guest_cdrom_device = get_testing_cdrom_device( session, cdrom_dev_list, serial_num) logging.debug("cdrom_dev_list: %s", cdrom_dev_list) device = get_device(vm, self.cdrom_orig) session.cmd(params["lock_cdrom_cmd"] % guest_cdrom_device) locked = check_cdrom_lock(vm, device) if locked: logging.debug("Cdrom device is successfully locked in VM.") else: raise error.TestFail("Cdrom device should be locked" " in VM.") self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts, 'cdrom_dev', cdrom_prepare_timeout) self.mig.migrate_wait([self.vms[0]], self.srchost, self.dsthost) if not self.is_src: # Starts in dest vm = env.get_vm(self.vms[0]) session = vm.wait_for_login(timeout=login_timeout) cdrom_dev_list = list_guest_cdroms(session) logging.debug("cdrom_dev_list: %s", cdrom_dev_list) device = get_device(vm, self.cdrom_orig) locked = check_cdrom_lock(vm, device) if locked: logging.debug("Cdrom device stayed locked after " "migration in VM.") else: raise error.TestFail("Cdrom device should stayed locked" " after migration in VM.") error.context("Unlock cdrom from VM.") if not self.is_src: # Starts in dest cdrom_dev_list = list_guest_cdroms(session) guest_cdrom_device = get_testing_cdrom_device( session, cdrom_dev_list, serial_num) session.cmd(params["unlock_cdrom_cmd"] % guest_cdrom_device) locked = check_cdrom_lock(vm, device) if not locked: logging.debug("Cdrom device is successfully unlocked" " from VM.") else: raise error.TestFail("Cdrom device should be unlocked" " in VM.") self.mig.migrate_wait([self.vms[0]], self.dsthost, self.srchost) if self.is_src: # Starts in source locked = check_cdrom_lock(vm, device) if not locked: logging.debug("Cdrom device stayed unlocked after " "migration in VM.") else: raise error.TestFail("Cdrom device should stayed unlocked" " after migration in VM.") self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts, 'Finish_cdrom_test', login_timeout)
def run_pci_hotplug(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'") add_output = vm.monitor.send_args_cmd(pci_add_cmd, convert=False) pci_info.append(['', '', add_output, pci_model]) 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 is_supported_device(dev): # Probe qemu to verify what is the supported syntax for PCI hotplug cmd_output = vm.monitor.human_monitor_cmd("?") if len(re.findall("\ndevice_add", cmd_output)) > 0: cmd_type = "device_add" elif len(re.findall("\npci_add", cmd_output)) > 0: cmd_type = "pci_add" else: raise error.TestError("Unknow version of qemu") # Probe qemu for a list of supported devices probe_output = vm.monitor.human_monitor_cmd("%s ?" % cmd_type) devices_supported = [ j.strip('"') for j in re.findall('\"[a-z|0-9|\-|\_|\,|\.]*\"', probe_output, re.MULTILINE) ] logging.debug( "QEMU reported the following supported devices for " "PCI hotplug: %s", devices_supported) return (dev in devices_supported) def verify_supported_device(dev): if not is_supported_device(dev): raise error.TestError("%s doesn't support device: %s" % (cmd_type, dev)) def device_add_nic(pci_num, queues=1): device_id = pci_type + "-" + utils_misc.generate_random_id() pci_info.append([device_id, device_id]) pci_model = params.get("pci_model") if pci_model == "virtio": pci_model = "virtio-net-pci" verify_supported_device(pci_model) pci_add_cmd = "device_add id=%s,driver=%s" % (pci_info[pci_num][1], pci_model) if queues > 1 and "virtio" in pci_model: pci_add_cmd += ",mq=on" return device_add(pci_num, pci_add_cmd) def device_add_block(pci_num, queues=1): device_id = pci_type + "-" + utils_misc.generate_random_id() pci_info.append([device_id, device_id]) image_format = params.get("image_format_%s" % img_list[pci_num + 1]) if not image_format: image_format = params.get("image_format", "qcow2") image_filename = find_image(pci_num) pci_model = params.get("pci_model") controller_model = None if pci_model == "virtio": pci_model = "virtio-blk-pci" if pci_model == "scsi": pci_model = "scsi-disk" if arch.ARCH == 'ppc64': controller_model = "spapr-vscsi" else: controller_model = "lsi53c895a" verify_supported_device(controller_model) controller_id = "controller-" + device_id controller_add_cmd = ("device_add %s,id=%s" % (controller_model, controller_id)) error.context("Adding SCSI controller.") vm.monitor.send_args_cmd(controller_add_cmd) 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 driver. error.context("Adding driver.") 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'") 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) pci_info[pci_num].append(pci_model) after_add = vm.monitor.info("pci") if pci_info[pci_num][1] not in 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): return True 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.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: session.cmd(params.get("pci_test_cmd") % (pci_num + 1)) except aexpect.ShellError, e: raise error.TestFail("Check for %s device failed after PCI " "hotplug. Output: %r" % (pci_type, e.output)) except Exception: pci_del(pci_num, ignore_failure=True) raise # Hot delete a pci device def pci_del(pci_num, ignore_failure=False): def _device_removed(): after_del = vm.monitor.info("pci") return after_del != before_del before_del = vm.monitor.info("pci") if cmd_type == "pci_add": slot_id = int(pci_info[pci_num][2].split(",")[2].split()[1]) cmd = "pci_del pci_addr=%s" % hex(slot_id) vm.monitor.send_args_cmd(cmd, convert=False) elif cmd_type == "device_add": cmd = "device_del id=%s" % pci_info[pci_num][1] 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_info[pci_num][3], cmd)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) test_timeout = int(params.get("hotplug_timeout", 360)) reference_cmd = params["reference_cmd"] # Test if it is nic or block pci_type = params["pci_type"] pci_model = params["pci_model"] # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: session.cmd("modprobe %s" % module) # check monitor type qemu_binary = params.get("qemu_binary", "/usr/libexec/qemu-kvm") qemu_binary = utils_misc.get_path(test.bindir, qemu_binary) # Probe qemu to verify what is the supported syntax for PCI hotplug if vm.monitor.protocol == 'qmp': cmd_output = vm.monitor.info("commands") else: cmd_output = vm.monitor.human_monitor_cmd("help", debug=False) cmd_type = utils_misc.find_substring(str(cmd_output), "device_add", "pci_add") if not cmd_output: raise error.TestError("Could find a suitable method for hotplugging" " device in this version of qemu") # Determine syntax of drive hotplug # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6 # drive_add == qemu-kvm-0.13 onwards drive_cmd_type = utils_misc.find_substring(str(cmd_output), "__com.redhat_drive_add", "drive_add") if not drive_cmd_type: raise error.TestError("Could find a suitable method for hotplugging" " drive in this version of qemu") local_functions = locals() pci_num_range = int(params.get("pci_num")) queues = int(params.get("queues", 1)) rp_times = int(params.get("repeat_times")) img_list = params.get("images").split() context_msg = "Running sub test '%s' %s" for j in range(rp_times): # pci_info is a list of list. # each element 'i' has 4 members: # pci_info[i][0] == device drive id, only used for device_add # pci_info[i][1] == device id, only used for device_add # pci_info[i][2] == output of device add command # pci_info[i][3] == device module name. pci_info = [] for pci_num in xrange(pci_num_range): sub_type = params.get("sub_type_before_plug") if sub_type: error.context(context_msg % (sub_type, "before hotplug"), logging.info) utils_test.run_virt_sub_test(test, params, env, sub_type) error.context("Start hot-adding pci device, repeat %d" % j) 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) 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_smbios_table(test, params, env): """ Check smbios table : 1) Boot a guest with smbios options 2) verify if host bios options have been emulated @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vendor_cmd = "dmidecode --type 0 | grep Vendor | awk '{print $2}'" date_cmd = "dmidecode --type 0 | grep Date | awk '{print $3}'" version_cmd = "dmidecode --type 0 | grep Version | awk '{print $2}'" error.context("getting smbios table on host") host_vendor = utils.system_output(vendor_cmd) host_date = utils.system_output(date_cmd) host_version = utils.system_output(version_cmd) smbios = (" -smbios type=0,vendor=%s,version=%s,date=%s" % (host_vendor, host_version, host_date)) extra_params = params.get("extra_params", "") params["extra_params"] = extra_params + smbios logging.debug("Booting guest %s", params.get("main_vm")) env_process.preprocess_vm(test, params, env, params.get("main_vm")) vm = env.get_vm(params["main_vm"]) vm.create() login_timeout = float(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) error.context("getting smbios table on guest") guest_vendor = session.cmd(vendor_cmd).strip() guest_date = session.cmd(date_cmd).strip() guest_version = session.cmd(version_cmd).strip() failures = [] if host_vendor != guest_vendor: e_msg = ("Vendor str mismatch -> host: %s guest: %s" % (guest_vendor, host_vendor)) logging.error(e_msg) failures.append(e_msg) if host_date != guest_date: e_msg = ("Date str mismatch -> host: %s guest: %s" % (guest_date, host_date)) logging.error(e_msg) failures.append(e_msg) if host_version != guest_version: e_msg = ("Version str mismatch -> host: %s guest: %s" % (guest_version, host_version)) logging.error(e_msg) failures.append(e_msg) error.context("") if failures: raise error.TestFail("smbios table test reported %s failures:\n%s" % (len(failures), "\n".join(failures)))
def test(self): super(test_multihost_copy, self).test() copy_timeout = int(params.get("copy_timeout", 480)) checksum_timeout = int(params.get("checksum_timeout", 180)) pid = None sync_id = { 'src': self.srchost, 'dst': self.dsthost, "type": "file_trasfer" } filename = "orig" if self.is_src: # Starts in source serial_num = generate_serial_num() cdrom = params.get("cdroms", "").split()[-1] params["drive_serial_%s" % cdrom] = serial_num params["start_vm"] = "yes" env_process.process(test, params, env, env_process.preprocess_image, env_process.preprocess_vm) vm = env.get_vm(self.vms[0]) vm.monitor.migrate_set_speed("1G") session = vm.wait_for_login(timeout=login_timeout) cdrom_dev_list = list_guest_cdroms(session) logging.debug("cdrom_dev_list: %s", cdrom_dev_list) cdrom = get_testing_cdrom_device(session, cdrom_dev_list, serial_num) mount_point = get_cdrom_mount_point(session, cdrom, params) mount_cmd = params["mount_cdrom_cmd"] % (cdrom, mount_point) src_file = params["src_file"] % (mount_point, filename) dst_file = params["dst_file"] % filename copy_file_cmd = params["copy_file_cmd"] % (mount_point, filename) remove_file_cmd = params["remove_file_cmd"] % filename md5sum_cmd = params["md5sum_cmd"] if params["os_type"] != "windows": error.context("Mount and copy data") session.cmd(mount_cmd, timeout=30) error.context("File copying test") session.cmd(copy_file_cmd) pid = disk_copy(vm, src_file, dst_file, copy_timeout) sync = SyncData(self.mig.master_id(), self.mig.hostid, self.mig.hosts, sync_id, self.mig.sync_server) pid = sync.sync(pid, timeout=cdrom_prepare_timeout)[self.srchost] self.mig.migrate_wait([self.vms[0]], self.srchost, self.dsthost) if not self.is_src: # Starts in source vm = env.get_vm(self.vms[0]) session = vm.wait_for_login(timeout=login_timeout) error.context("Wait for copy finishing.") def is_copy_done(): if params["os_type"] == "windows": cmd = "tasklist /FI \"PID eq %s\"" % pid else: cmd = "ps -p %s" % pid return session.cmd_status(cmd) != 0 if utils_misc.wait_for(is_copy_done, timeout=copy_timeout) is None: raise error.TestFail("Wait for file copy finish timeout") error.context("Compare file on disk and on cdrom") f1_hash = session.cmd("%s %s" % (md5sum_cmd, dst_file), timeout=checksum_timeout).split()[0] f2_hash = session.cmd("%s %s" % (md5sum_cmd, src_file), timeout=checksum_timeout).split()[0] if f1_hash.strip() != f2_hash.strip(): raise error.TestFail("On disk and on cdrom files are" " different, md5 mismatch") session.cmd(remove_file_cmd) self.mig._hosts_barrier(self.mig.hosts, self.mig.hosts, 'Finish_cdrom_test', login_timeout)
def run_iometer_windows(test, params, env): """ Run Iometer for Windows on a Windows guest: 1) Boot guest with additional disk 2) Install Iometer 3) Execute the Iometer test contained in the winutils.iso 4) Copy result to host @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def check_cdrom(timeout): cdrom_chk_cmd = "echo list volume > cmd && echo exit >>" cdrom_chk_cmd += " cmd && diskpart /s cmd" vols = [] start_time = time.time() while time.time() - start_time < timeout: vols_str = session.cmd(cdrom_chk_cmd) logging.info("vols_str is %s" % vols_str) if len(re.findall("CDFS.*CD-ROM", vols_str)) >= 1: vols = re.findall(".*CDFS.*?CD-ROM.*\n", vols_str) logging.info("vols is %s" % vols) break return vols vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) cmd_timeout = int(params.get("cmd_timeout", 1200)) logging.info("Sleep 120 seconds, and create a partition on second disk") time.sleep(120) error.context("Creating partition") create_partition_cmd = params.get("create_partition_cmd") session.cmd_output(cmd=create_partition_cmd, timeout=cmd_timeout) # Format the disk format_cmd = params.get("format_cmd") error.context("Formating second disk") session.cmd_output(cmd=format_cmd, timeout=cmd_timeout) logging.info("Disk is formated") # Install Iometer init_timeout = int(params.get("init_timeout", "60")) volumes = check_cdrom(init_timeout) vol_utils = re.findall("Volume\s+\d+\s+(\w).*?\d+\s+\w+", volumes[0])[0] install_iometer_cmd = params.get("iometer_installation_cmd") install_iometer_cmd = re.sub("WIN_UTILS", vol_utils, install_iometer_cmd) error.context("Installing iometer") session.cmd_output(cmd=install_iometer_cmd, timeout=cmd_timeout) logging.info("Iometer is installed") # Run Iometer cmd_reg = params.get("iometer_reg") cmd_run = params.get("iometer_run") t = int(params.get("iometer_timeout", 1000)) cmd_reg = re.sub("WIN_UTILS", vol_utils, cmd_reg) cmd_run = re.sub("WIN_UTILS", vol_utils, cmd_run) error.context("Registering Iometer on guest, timeout %ss" % cmd_timeout) session.cmd_output(cmd=cmd_reg, timeout=cmd_timeout) logging.info("Iometer is registered") error.context("Running Iometer command on guest, timeout %ss" % cmd_timeout) session.cmd_output(cmd=cmd_run, timeout=t) logging.info("Iometer testing completed") guest_path = params.get("guest_path") error.context("Copying result '%s' to host" % guest_path) vm.copy_files_from(guest_path, test.resultsdir) session.close()
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( 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( 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()
def mount_lv(lv_path, session): error.context("mounting ext3 filesystem made on logical volume %s" % os.path.basename(lv_path)) session.cmd("mkdir -p /mnt/kvm_test_lvm") session.cmd("mount %s /mnt/kvm_test_lvm" % lv_path)
def run(test, params, env): """ QEMU 'Windows virtio-serial data transfer' test 1) Start guest with one virtio-serial-pci and two virtio-serial-port. 2) Make sure vioser.sys verifier enabled in guest. 3) Transfering data from host to guest via virtio-serial-port in a loop. 4) Reboot guest. 5) Repeat step 3. 6) Reboot guest by system_reset qmp command. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_virtio_port_host_file(vm, port_name): """ Returns separated virtserialports :param vm: VM object :return: All virtserialports """ for port in vm.virtio_ports: if isinstance(port, qemu_virtio_port.VirtioSerial): if port.name == port_name: return port.hostfile def receive_data(session, serial_receive_cmd, data_file): output = session.cmd_output(serial_receive_cmd, timeout=30) ori_data = file(data_file, "r").read() if ori_data.strip() != output.strip(): err = "Data lost during transfer. Origin data is:\n%s" % ori_data err += "Guest receive data:\n%s" % output raise error.TestFail(err) def transfer_data(session, receive_cmd, send_cmd, data_file, n_time): txt = "Transfer data betwwen guest and host for %s times" % n_time error.context(txt, logging.info) for num in xrange(n_time): logging.info("Data transfer repeat %s/%s." % (num + 1, n_time)) try: args = (session, receive_cmd, data_file) guest_receive = utils.InterruptedThread(receive_data, args) guest_receive.start() utils.system(send_cmd, timeout=30) finally: if guest_receive: guest_receive.join(10) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) check_cmd = params.get("check_vioser_status_cmd", "verifier /querysettings") output = session.cmd(check_cmd, timeout=360) error.context("Make sure vioser.sys verifier enabled in guest.", logging.info) if "vioser.sys" not in output: verify_cmd = params.get("vioser_verify_cmd", "verifier.exe /standard /driver vioser.sys") session.cmd(verify_cmd, timeout=360, ok_status=[0, 2]) session = vm.reboot(session=session, timeout=timeout) output = session.cmd(check_cmd, timeout=360) if "vioser.sys" not in output: error.TestError("Fail to veirfy vioser.sys driver.") guest_scripts = params["guest_scripts"] guest_path = params.get("guest_script_folder", "C:\\") error.context("Copy test scripts to guest.", logging.info) for script in guest_scripts.split(";"): link = os.path.join(data_dir.get_deps_dir("win_serial"), script) vm.copy_files_to(link, guest_path, timeout=60) port_name = params["virtio_ports"].split()[0] host_file = get_virtio_port_host_file(vm, port_name) data_file = params["data_file"] data_file = os.path.join(data_dir.get_deps_dir("win_serial"), data_file) send_script = params.get("host_send_script", "serial-host-send.py") send_script = os.path.join(data_dir.get_deps_dir("win_serial"), send_script) serial_send_cmd = "python %s %s %s" % (send_script, host_file, data_file) receive_script = params.get("guest_receive_script", "VirtIoChannel_guest_recieve.py") receive_script = "%s%s" % (guest_path, receive_script) serial_receive_cmd = "python %s %s " % (receive_script, port_name) n_time = int(params.get("repeat_times", 20)) transfer_data(session, serial_receive_cmd, serial_send_cmd, data_file, n_time) error.context("Reboot guest.", logging.info) session = vm.reboot(session=session, timeout=timeout) transfer_data(session, serial_receive_cmd, serial_send_cmd, data_file, n_time) error.context("Reboot guest by system_reset qmp command.", logging.info) session = vm.reboot(session=session, method="system_reset", timeout=timeout) if session: session.close()
def run_lvm(test, params, env): """ KVM reboot test: 1) Log into a guest 2) Create a volume group and add both disks as pv to the Group 3) Create a logical volume on the VG 5) `fsck' to check the partition that LV locates @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) vg_name = "vg_kvm_test" lv_name = "lv_kvm_test" lv_path = "/dev/%s/%s" % (vg_name, lv_name) disks = params.get("disks", "/dev/hdb /dev/hdc") clean = params.get("clean", "yes") timeout = params.get("lvm_timeout", "600") try: error.context("adding physical volumes %s" % disks) session.cmd("pvcreate %s" % disks) error.context("creating a volume group out of %s" % disks) session.cmd("vgcreate %s %s" % (vg_name, disks)) error.context("activating volume group %s" % vg_name) session.cmd("vgchange -ay %s" % vg_name) error.context("creating logical volume on volume group %s" % vg_name) session.cmd("lvcreate -L2000 -n %s %s" % (lv_name, vg_name)) error.context("creating ext3 filesystem on logical volume %s" % lv_name) session.cmd("yes | mkfs.ext3 %s" % lv_path, timeout=int(timeout)) mount_lv(lv_path, session) umount_lv(lv_path, session) error.context("checking ext3 filesystem made on logical volume %s" % lv_name) session.cmd("fsck %s" % lv_path, timeout=int(timeout)) if clean == "no": mount_lv(lv_path, session) finally: if clean == "yes": umount_lv(lv_path, session) error.context("removing logical volume %s" % lv_name) session.cmd("lvremove %s" % lv_name) error.context("disabling volume group %s" % vg_name) session.cmd("vgchange -a n %s" % vg_name) error.context("removing volume group %s" % vg_name) session.cmd("vgremove -f %s" % vg_name)
def migration_scenario(self): error.context( "Migration from %s to %s over protocol %s." % (self.srchost, self.dsthost, mig_protocol), logging.info) sync = SyncData(self.master_id(), self.hostid, self.hosts, self.id, self.sync_server) address_cache = env.get("address_cache") def worker_cpu_mem(mig_data): vm = mig_data.vms[0] session = vm.wait_for_login(timeout=self.login_timeout) cpuflags.install_cpuflags_util_on_vm( test, vm, self.install_path, extra_flags="-msse3 -msse2") cmd = ("nohup %s/cpuflags-test --stressmem %d,32" " > %s &" % (os.path.join(self.install_path, "cpu_flags"), self.stress_memory, self.cpuflags_test_out)) logging.debug("Sending command: %s" % (cmd)) session.sendline(cmd) if session.cmd_status("killall -s 0 cpuflags-test") != 0: cpu_flags_out = ( "\n cpuflags_test_output: \n" + session.cmd_output("cat %s" % (self.cpuflags_test_out))) raise error.TestFail("Something wrong happened" " during migration cpuflags-test" " should be running all time" " during this test.\n%s" % (cpu_flags_out)) def worker_disk(mig_data): vm = mig_data.vms[0] session = vm.wait_for_login(timeout=self.login_timeout) utils_misc.install_disktest_on_vm(test, vm, self.disk_srcdir, self.install_path) cmd = ("nohup %s/disktest -m %s -L -S > %s &" % (os.path.join(self.install_path, "disktest", "src"), self.disk_usage, self.disktest_out)) logging.debug("Sending command: %s" % (cmd)) session.sendline(cmd) if session.cmd_status("killall -s 0 disktest") != 0: disk_out = ("\n cpuflags_test_output: \n" + session.cmd_output("cat %s" % (self.disktest_out))) raise error.TestFail("Something wrong happened" " during migration disktest" " should be running all time" " during this test.\n%s" % (disk_out)) def worker_all(mig_data): worker_cpu_mem(mig_data) worker_disk(mig_data) self.worker = None if self.stress_type == "cpu_memory": self.worker = worker_cpu_mem elif self.stress_type == "disk": if (self.hostid == self.master_id()): self.install_disktest() self.worker = worker_disk elif self.stress_type == "all": if (self.hostid == self.master_id()): self.install_disktest() self.worker = worker_all if (self.hostid == self.master_id()): self.vm_addr = self._prepare_vm(self.vm).get_address() self._hosts_barrier(self.hosts, self.id, "befor_mig", 120) sync.sync(address_cache, timeout=120) else: self._hosts_barrier(self.hosts, self.id, "befor_mig", 260) address_cache.update(sync.sync(timeout=120)[self.master_id()]) self.migrate_wait([self.vm], self.srchost, self.dsthost, start_work=self.worker) sync.sync(True, timeout=self.migration_timeout) tmp = self.dsthost self.dsthost = self.srchost self.srchost = tmp self.ping_pong_migrate(sync, self.worker)