def _verify_string(regex_str, string, expect_result, search_opt=0): """ Verify USB storage device in monitor @params regex_str: regex for checking command output, search option, and expected string. """ error.context("Finding matched sub-string with regex pattern %s" % regex_str) m = re.findall(regex_str, string, search_opt) if not m: logging.debug(string) raise error.TestError("Could not find matched sub-string") error.context("Verify matched string is same as expected") fail_log = [] if isinstance(m[0], tuple): for i in xrange(len(expect_result)): if m[0][i] != expect_result[i]: fail_log.append("Expected: '%s', Actual: '%s'" % (expect_result[i], m[0][i])) else: if m[0] != expect_result[0]: fail_log.append("Expected: '%s', Actual: '%s'" % (expect_result[0], m[0])) if fail_log: logging.debug(string) raise error.TestFail("Could not find expected string:\n %s" % ("\n".join(fail_log)))
def setup_url(self): """ Download the vmlinuz and initrd.img from URL. """ # it's only necessary to download kernel/initrd if running bare qemu if self.vm_type == 'kvm': error.context("downloading vmlinuz/initrd.img from %s" % self.url) os.chdir(self.image_path) kernel_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.kernel)) initrd_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.initrd)) if os.path.exists(self.kernel): os.remove(self.kernel) if os.path.exists(self.initrd): os.remove(self.initrd) utils.run(kernel_cmd, verbose=DEBUG) utils.run(initrd_cmd, verbose=DEBUG) elif self.vm_type == 'libvirt': logging.info("Not downloading vmlinuz/initrd.img from %s, " "letting virt-install do it instead") else: logging.info("No action defined/needed for the current virt " "type: '%s'" % self.vm_type)
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @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() install_timeout = int(params.get("timeout", 3000)) post_install_delay = int(params.get("post_install_delay", 0)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info( "Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60 ) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: vm.verify_alive() client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((vm.get_address(), port)) if client.recv(1024) == "done": break except (socket.error, kvm_vm.VMAddressError): pass if migrate_background: # Drop the params which may break the migration # Better method is to use dnsmasq to do the # unattended installation if vm.params.get("initrd"): vm.params["initrd"] = None if vm.params.get("kernel"): vm.params["kernel"] = None if vm.params.get("extra_params"): vm.params["extra_params"] = re.sub("--append '.*'", "", vm.params["extra_params"]) vm.migrate(timeout=mig_timeout, protocol=mig_protocol) else: time.sleep(1) client.close() else: raise error.TestFail("Timeout elapsed while waiting for install to " "finish") time_elapsed = time.time() - start_time logging.info("Guest reported successful installation after %d s (%d min)", time_elapsed, time_elapsed / 60) if post_install_delay: logging.debug("Post install delay specified, waiting %s s...", post_install_delay) time.sleep(post_install_delay)
def cleanup(self): error.context("performing enospc cleanup") if os.path.isfile(self.lvtest_device): utils.run("fuser -k %s" % self.lvtest_device) 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 setup(self): logging.debug("Starting enospc setup") error.context("performing enospc setup") 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, e: self.cleanup() raise
def cmd_output(self, command, timeout=60): """ Get output from shell session. If the create flag is True, init the shell session and set the create flag to False. @param command: command to execute in qemu-io @param timeout: timeout for execute the command """ qemu_io_cmd = self.qemu_io_cmd prompt = self.prompt output_func = self.output_func output_params = self.output_params output_prefix = self.output_prefix if self.create_session: error.context("Running command: %s" % qemu_io_cmd, logging.info) self.session = aexpect.ShellSession(qemu_io_cmd, echo=True, prompt=prompt, output_func=output_func, output_params=output_params, output_prefix=output_prefix) # Record the command line in log file params = self.output_params + (qemu_io_cmd, ) self.output_func(*params) self.create_session = False # Get the reaction from session self.session.cmd_output("\n") error.context("Executing command: %s" % command, logging.info) return self.session.cmd_output(command, timeout=timeout)
def setup(self): logging.debug("Starting enospc setup") error.context("performing enospc setup") virt_utils.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, e: self.cleanup() raise
def setup_cdrom(self): """ Mount cdrom and copy vmlinuz and initrd.img. """ error.context("Copying vmlinuz and initrd.img from install cdrom %s" % self.cdrom_cd1) m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' % (self.cdrom_cd1, self.cdrom_cd1_mount)) utils.run(m_cmd, verbose=DEBUG) try: if not os.path.isdir(self.image_path): os.makedirs(self.image_path) kernel_fetch_cmd = ("cp %s/%s/%s %s" % (self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.kernel), self.kernel)) utils.run(kernel_fetch_cmd, verbose=DEBUG) initrd_fetch_cmd = ("cp %s/%s/%s %s" % (self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.initrd), self.initrd)) utils.run(initrd_fetch_cmd, verbose=DEBUG) if self.unattended_file.endswith('.preseed'): self.preseed_initrd() # Virtinstall command needs files named "vmlinuz" and "initrd.img" elif self.params.get("vm_type") == "libvirt": os.chdir(self.image_path) base_kernel = os.path.basename(self.kernel) base_initrd = os.path.basename(self.initrd) if base_kernel != 'vmlinuz': utils.run("mv %s vmlinuz" % base_kernel, verbose=DEBUG) if base_initrd != 'initrd.img': utils.run("mv %s initrd.img" % base_initrd, verbose=DEBUG) finally: cleanup(self.cdrom_cd1_mount)
def setup_cdrom(self): """ Mount cdrom and copy vmlinuz and initrd.img. """ error.context("Copying vmlinuz and initrd.img from install cdrom %s" % self.cdrom_cd1) m_cmd = "mount -t iso9660 -v -o loop,ro %s %s" % (self.cdrom_cd1, self.cdrom_cd1_mount) utils.run(m_cmd) try: if not os.path.isdir(self.image_path): os.makedirs(self.image_path) kernel_fetch_cmd = "cp %s/%s/%s %s" % ( self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.kernel), self.kernel, ) utils.run(kernel_fetch_cmd) initrd_fetch_cmd = "cp %s/%s/%s %s" % ( self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.initrd), self.initrd, ) utils.run(initrd_fetch_cmd) if self.unattended_file.endswith(".preseed"): self.preseed_initrd() finally: cleanup(self.cdrom_cd1_mount)
def login(self, nic_index=0, timeout=LOGIN_TIMEOUT): """ Log into the guest via SSH/Telnet/Netcat. If timeout expires while waiting for output from the guest (e.g. a password prompt or a shell prompt) -- fail. @param nic_index: The index of the NIC to connect to. @param timeout: Time (seconds) before giving up logging into the guest. @return: A ShellSession object. """ error.context("logging into '%s'" % self.name) username = self.params.get("username", "") password = self.params.get("password", "") prompt = self.params.get("shell_prompt", "[\#\$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) client = self.params.get("shell_client") address = self.get_address(nic_index) port = self.get_port(int(self.params.get("shell_port"))) log_filename = ("session-%s-%s.log" % (self.name, virt_utils.generate_random_string(4))) session = virt_utils.remote_login(client, address, port, username, password, prompt, linesep, log_filename, timeout) session.set_status_test_command( self.params.get("status_test_command", "")) return session
def copy_files_from(self, guest_path, host_path, nic_index=0, verbose=False, timeout=COPY_FILES_TIMEOUT): """ Transfer files from the guest. @param host_path: Guest path @param guest_path: Host path @param nic_index: The index of the NIC to connect to. @param verbose: If True, log some stats using logging.debug (RSS only) @param timeout: Time (seconds) before giving up on doing the remote copy. """ error.context("receiving file(s) from '%s'" % self.name) username = self.params.get("username", "") password = self.params.get("password", "") client = self.params.get("file_transfer_client") address = self.get_address(nic_index) port = self.get_port(int(self.params.get("file_transfer_port"))) log_filename = ( "transfer-%s-from-%s-%s.log" % (self.name, address, virt_utils.generate_random_string(4))) virt_utils.copy_files_from(address, client, username, password, port, guest_path, host_path, log_filename, verbose, timeout)
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 setup_cdrom(self): """ Mount cdrom and copy vmlinuz and initrd.img. """ error.context("Copying vmlinuz and initrd.img from install cdrom %s" % self.cdrom_cd1) m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' % (self.cdrom_cd1, self.cdrom_cd1_mount)) utils.run(m_cmd) try: if not os.path.isdir(self.image_path): os.makedirs(self.image_path) kernel_fetch_cmd = ("cp %s/%s/%s %s" % (self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.kernel), self.kernel)) utils.run(kernel_fetch_cmd) initrd_fetch_cmd = ("cp %s/%s/%s %s" % (self.cdrom_cd1_mount, self.boot_path, os.path.basename(self.initrd), self.initrd)) utils.run(initrd_fetch_cmd) if self.unattended_file.endswith('.preseed'): self.preseed_initrd() # Virtinstall command needs files named "vmlinuz" and "initrd.img" elif self.params.get("vm_type") == "libvirt": os.chdir(self.image_path) base_kernel = os.path.basename(self.kernel) base_initrd = os.path.basename(self.initrd) if base_kernel != 'vmlinuz': utils.run("mv %s vmlinuz" % base_kernel) if base_initrd != 'initrd.img': utils.run("mv %s initrd.img" % base_initrd) finally: cleanup(self.cdrom_cd1_mount)
def serial_login(self, timeout=LOGIN_TIMEOUT): """ Log into the guest via the serial console. If timeout expires while waiting for output from the guest (e.g. a password prompt or a shell prompt) -- fail. @param timeout: Time (seconds) before giving up logging into the guest. @return: ShellSession object on success and None on failure. """ error.context("logging into '%s' via serial console" % self.name) username = self.params.get("username", "") password = self.params.get("password", "") prompt = self.params.get("shell_prompt", "[\#\$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) status_test_command = self.params.get("status_test_command", "") self.serial_console.set_linesep(linesep) self.serial_console.set_status_test_command(status_test_command) # Try to get a login prompt self.serial_console.sendline() virt_utils._remote_login(self.serial_console, username, password, prompt, timeout) return self.serial_console
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) 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) 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) finally: cleanup(self.nfs_mount)
def login(self, nic_index=0, timeout=10): """ Log into the guest via SSH/Telnet/Netcat. If timeout expires while waiting for output from the guest (e.g. a password prompt or a shell prompt) -- fail. @param nic_index: The index of the NIC to connect to. @param timeout: Time (seconds) before giving up logging into the guest. @return: A ShellSession object. """ error.context("logging into '%s'" % self.name) username = self.params.get("username", "") password = self.params.get("password", "") prompt = self.params.get("shell_prompt", "[\#\$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) client = self.params.get("shell_client") address = self.get_address(nic_index) port = self.get_port(int(self.params.get("shell_port"))) log_filename = ("session-%s-%s.log" % (self.name, virt_utils.generate_random_string(4))) session = virt_utils.remote_login(client, address, port, username, password, prompt, linesep, log_filename, timeout) session.set_status_test_command(self.params.get("status_test_command", "")) return session
def serial_login(self, timeout=10): """ Log into the guest via the serial console. If timeout expires while waiting for output from the guest (e.g. a password prompt or a shell prompt) -- fail. @param timeout: Time (seconds) before giving up logging into the guest. @return: ShellSession object on success and None on failure. """ error.context("logging into '%s' via serial console" % self.name) username = self.params.get("username", "") password = self.params.get("password", "") prompt = self.params.get("shell_prompt", "[\#\$]") linesep = eval("'%s'" % self.params.get("shell_linesep", r"\n")) status_test_command = self.params.get("status_test_command", "") self.serial_console.set_linesep(linesep) self.serial_console.set_status_test_command(status_test_command) # Try to get a login prompt self.serial_console.sendline() virt_utils._remote_login(self.serial_console, username, password, prompt, timeout) return self.serial_console
def cleanup(self): error.context("trying to dealocate hugepage memory") try: utils.system("umount %s" % self.hugepage_path) except error.CmdError: return utils.system("echo 0 > %s" % self.kernel_hp_file) logging.debug("Hugepage memory successfuly dealocated")
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @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"]) unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() # params passed explicitly, because they may have been updated by # unattended install config code, such as when params['url'] == auto vm.create(params=params) post_finish_str = params.get("post_finish_str", "Post set up finished") install_timeout = int(params.get("timeout", 3000)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info("Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: try: vm.verify_alive() # Due to a race condition, sometimes we might get a MonitorError # before the VM gracefully shuts down, so let's capture MonitorErrors. except (virt_vm.VMDeadError, kvm_monitor.MonitorError), e: if params.get("wait_no_ack", "no") == "yes": break else: raise e vm.verify_kernel_crash() finish_signal = vm.serial_console.get_output() if (params.get("wait_no_ack", "no") == "no" and (post_finish_str in finish_signal)): break # Due to libvirt automatically start guest after import # we only need to wait for successful login. if params.get("medium") == "import": try: vm.login() break except (virt_utils.LoginError, Exception), e: pass
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @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"]) unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() # params passed explicitly, because they may have been updated by # unattended install config code, such as when params['url'] == auto vm.create(params=params) install_timeout = int(params.get("timeout", 3000)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info("Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: try: vm.verify_alive() # Due to a race condition, sometimes we might get a MonitorError # before the VM gracefully shuts down, so let's capture MonitorErrors. except (virt_vm.VMDeadError, kvm_monitor.MonitorError), e: if params.get("wait_no_ack", "no") == "yes": break else: raise e vm.verify_kernel_crash() if params.get("wait_no_ack", "no") == "no": client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((vm.get_address(), port)) if client.recv(1024) == "done": break except (socket.error, virt_vm.VMAddressError): pass if migrate_background: vm.migrate(timeout=mig_timeout, protocol=mig_protocol) else: time.sleep(1) if params.get("wait_no_ack", "no") == "no": client.close()
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @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"]) unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() # params passed explicitly, because they may have been updated by # unattended install config code, such as when params['url'] == auto vm.create(params=params) install_timeout = int(params.get("timeout", 3000)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info( "Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: try: vm.verify_alive() except virt_vm.VMDeadError, e: if params.get("wait_no_ack", "no") == "yes": break else: raise e vm.verify_kernel_crash() if params.get("wait_no_ack", "no") == "no": client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((vm.get_address(), port)) if client.recv(1024) == "done": break except (socket.error, virt_vm.VMAddressError): pass if migrate_background: vm.migrate(timeout=mig_timeout, protocol=mig_protocol) else: time.sleep(1) if params.get("wait_no_ack", "no") == "no": client.close()
def master_cdroms(params): error.context("creating test cdrom") os.chdir(test.tmpdir) cdrom_cd1 = params.get("cdrom_cd1") cdrom_dir = os.path.dirname(cdrom_cd1) utils.run("dd if=/dev/urandom of=orig bs=10M count=1") utils.run("dd if=/dev/urandom of=new bs=10M count=1") utils.run("mkisofs -o %s/orig.iso orig" % cdrom_dir) utils.run("mkisofs -o %s/new.iso new" % cdrom_dir) return "%s/new.iso" % cdrom_dir
def _restart_vm(options): if vm.is_alive(): vm.destroy() new_params = params.copy() for option, value in options.iteritems(): new_params[option] = value error.context("Restarting VM") vm.create(params=new_params) vm.verify_alive()
def run_nmi_watchdog(test, params, env): """ Test the function of nmi injection and verify the response of guest 1) Log in the guest 2) Add 'watchdog=1' to boot option 2) Check if guest's NMI counter augment after injecting nmi @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) get_nmi_cmd = params.get("get_nmi_cmd") kernel_version = session.get_command_output("uname -r").strip() nmi_watchdog_type = int(params.get("nmi_watchdog_type")) update_kernel_cmd = ("grubby --update-kernel=/boot/vmlinuz-%s " "--args='nmi_watchdog=%d'" % (kernel_version, nmi_watchdog_type)) error.context("Add 'nmi_watchdog=%d' to guest kernel cmdline and reboot" % nmi_watchdog_type) session.cmd(update_kernel_cmd) time.sleep(int(params.get("sleep_before_reset", 10))) session = vm.reboot(session, method='shell', timeout=timeout) try: error.context("Getting guest's number of vcpus") guest_cpu_num = session.cmd(params.get("cpu_chk_cmd")) error.context("Getting guest's NMI counter") output = session.cmd(get_nmi_cmd) logging.debug(output.strip()) nmi_counter1 = output.split()[1:] logging.info("Waiting 60 seconds to see if guest's NMI counter " "increases") time.sleep(60) error.context("Getting guest's NMI counter 2nd time") output = session.cmd(get_nmi_cmd) logging.debug(output.strip()) nmi_counter2 = output.split()[1:] error.context("") for i in range(int(guest_cpu_num)): logging.info("vcpu: %s, nmi_counter1: %s, nmi_counter2: %s" % (i, nmi_counter1[i], nmi_counter2[i])) if int(nmi_counter2[i]) <= int(nmi_counter1[i]): raise error.TestFail("Guest's NMI counter did not increase " "after 60 seconds") finally: session.close()
def run_nmi_watchdog(test, params, env): """ Test the function of nmi injection and verify the response of guest 1) Log in the guest 2) Add 'watchdog=1' to boot option 2) Check if guest's NMI counter augment after injecting nmi @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) get_nmi_cmd= params.get("get_nmi_cmd") kernel_version = session.get_command_output("uname -r").strip() nmi_watchdog_type = int(params.get("nmi_watchdog_type")) update_kernel_cmd = ("grubby --update-kernel=/boot/vmlinuz-%s " "--args='nmi_watchdog=%d'" % (kernel_version, nmi_watchdog_type)) error.context("Add 'nmi_watchdog=%d' to guest kernel cmdline and reboot" % nmi_watchdog_type) session.cmd(update_kernel_cmd) time.sleep(int(params.get("sleep_before_reset", 10))) session = vm.reboot(session, method='shell', timeout=timeout) try: error.context("Getting guest's number of vcpus") guest_cpu_num = session.cmd(params.get("cpu_chk_cmd")) error.context("Getting guest's NMI counter") output = session.cmd(get_nmi_cmd) logging.debug(output.strip()) nmi_counter1 = output.split()[1:] logging.info("Waiting 60 seconds to see if guest's NMI counter " "increases") time.sleep(60) error.context("Getting guest's NMI counter 2nd time") output = session.cmd(get_nmi_cmd) logging.debug(output.strip()) nmi_counter2 = output.split()[1:] error.context("") for i in range(int(guest_cpu_num)): logging.info("vcpu: %s, nmi_counter1: %s, nmi_counter2: %s" % (i, nmi_counter1[i], nmi_counter2[i])) if int(nmi_counter2[i]) <= int(nmi_counter1[i]): raise error.TestFail("Guest's NMI counter did not increase " "after 60 seconds") finally: session.close()
def close(self): error.context("Creating unattended install CD image %s" % self.path) g_cmd = ('mkisofs -o %s -max-iso9660-filenames ' '-relaxed-filenames -D --input-charset iso8859-1 ' '%s' % (self.path, self.mount)) utils.run(g_cmd, verbose=DEBUG) os.chmod(self.path, 0755) cleanup(self.mount) logging.debug("unattended install CD image %s successfuly created", self.path)
def install_ntttcp(session): """ Install ntttcp through a remote session """ logging.info("Installing NTttcp ...") try: # Don't install ntttcp if it's already installed error.context("NTttcp directory already exists") session.cmd(params.get("check_ntttcp_cmd")) except aexpect.ShellCmdError, e: ntttcp_install_cmd = params.get("ntttcp_install_cmd") error.context("Installing NTttcp on guest") session.cmd(ntttcp_install_cmd % (platform, platform), timeout=200)
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ unattended_install_config = UnattendedInstallConfig(test, params) unattended_install_config.setup() vm = env.get_vm(params["main_vm"]) vm.create() install_timeout = int(params.get("timeout", 3000)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info( "Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60 ) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: try: vm.verify_alive() except virt_vm.VMDeadError, e: if params.get("wait_no_ack", "no") == "yes": break else: raise e vm.verify_kernel_crash() if params.get("wait_no_ack", "no") == "no": client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((vm.get_address(), port)) if client.recv(1024) == "done": break except (socket.error, virt_vm.VMAddressError): pass if migrate_background: vm.migrate(timeout=mig_timeout, protocol=mig_protocol) else: time.sleep(1) if params.get("wait_no_ack", "no") == "no": client.close()
def run_unattended_install(test, params, env): """ Unattended install test: 1) Starts a VM with an appropriated setup to start an unattended OS install. 2) Wait until the install reports to the install watcher its end. @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"]) unattended_install_config = UnattendedInstallConfig(test, params, vm) unattended_install_config.setup() # params passed explicitly, because they may have been updated by # unattended install config code, such as when params['url'] == auto vm.create(params=params) post_finish_str = params.get("post_finish_str", "Post set up finished") install_timeout = int(params.get("timeout", 3000)) port = vm.get_port(int(params.get("guest_port_unattended_install"))) migrate_background = params.get("migrate_background") == "yes" if migrate_background: mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") logging.info( "Waiting for installation to finish. Timeout set to %d s " "(%d min)", install_timeout, install_timeout / 60) error.context("waiting for installation to finish") start_time = time.time() while (time.time() - start_time) < install_timeout: try: vm.verify_alive() # Due to a race condition, sometimes we might get a MonitorError # before the VM gracefully shuts down, so let's capture MonitorErrors. except (virt_vm.VMDeadError, kvm_monitor.MonitorError), e: if params.get("wait_no_ack", "no") == "yes": break else: raise e vm.verify_kernel_crash() finish_signal = vm.serial_console.get_output() if params.get("wait_no_ack", "no") == "no" and\ post_finish_str in finish_signal: break if migrate_background: vm.migrate(timeout=mig_timeout, protocol=mig_protocol) else: time.sleep(1)
def mount_hugepage_fs(self): """ Verify if there's a hugetlbfs mount set. If there's none, will set up a hugetlbfs mount using the class attribute that defines the mount point. """ error.context("mounting hugepages path") if not os.path.ismount(self.hugepage_path): if not os.path.isdir(self.hugepage_path): os.makedirs(self.hugepage_path) cmd = "mount -t hugetlbfs none %s" % self.hugepage_path utils.system(cmd)
def cleanup(dir): """ If dir is a mountpoint, do what is possible to unmount it. Afterwards, try to remove it. @param dir: Directory to be cleaned up. """ error.context("cleaning up unattended install directory %s" % dir) if os.path.ismount(dir): utils.run("fuser -k %s" % dir, ignore_status=True) utils.run("umount %s" % dir) if os.path.isdir(dir): shutil.rmtree(dir)
def cleanup(dir): """ If dir is a mountpoint, do what is possible to unmount it. Afterwards, try to remove it. @param dir: Directory to be cleaned up. """ error.context("cleaning up unattended install directory %s" % dir) if os.path.ismount(dir): utils.run('fuser -k %s' % dir, ignore_status=True, verbose=DEBUG) utils.run('umount %s' % dir, verbose=DEBUG) if os.path.isdir(dir): shutil.rmtree(dir)
def reboot(self, session=None, method="shell", nic_index=0, timeout=240): """ Reboot the VM and wait for it to come back up by trying to log in until timeout expires. @param session: A shell session object or None. @param method: Reboot method. Can be "shell" (send a shell reboot command). @param nic_index: Index of NIC to access in the VM, when logging in after rebooting. @param timeout: Time to wait for login to succeed (after rebooting). @return: A new shell session object. """ error.base_context("rebooting '%s'" % self.name, logging.info) error.context("before reboot") session = session or self.login() error.context() if method == "shell": session.sendline(self.params.get("reboot_command")) else: raise virt_vm.VMRebootError("Unknown reboot method: %s" % method) error.context("waiting for guest to go down", logging.info) if not virt_utils.wait_for(lambda: not session.is_responsive(timeout=30), 120, 0, 1): raise virt_vm.VMRebootError("Guest refuses to go down") session.close() error.context("logging in after reboot", logging.info) return self.wait_for_login(nic_index, timeout=timeout)
def reboot(self, session=None, method="shell", nic_index=0, timeout=240): """ Reboot the VM and wait for it to come back up by trying to log in until timeout expires. @param session: A shell session object or None. @param method: Reboot method. Can be "shell" (send a shell reboot command). @param nic_index: Index of NIC to access in the VM, when logging in after rebooting. @param timeout: Time to wait for login to succeed (after rebooting). @return: A new shell session object. """ error.base_context("rebooting '%s'" % self.name, logging.info) error.context("before reboot") session = session or self.login() error.context() if method == "shell": session.sendline(self.params.get("reboot_command")) else: raise virt_vm.VMRebootError("Unknown reboot method: %s" % method) error.context("waiting for guest to go down", logging.info) if not virt_utils.wait_for( lambda: not session.is_responsive(timeout=30), 120, 0, 1): raise virt_vm.VMRebootError("Guest refuses to go down") session.close() error.context("logging in after reboot", logging.info) return self.wait_for_login(nic_index, timeout=timeout)
def close(self): error.context("Creating unattended install CD image %s" % self.path) f = open(os.path.join(self.mount, 'isolinux', 'isolinux.cfg'), 'w') f.write('default /isolinux/vmlinuz append initrd=/isolinux/initrd.img ' '%s\n' % self.extra_params) f.close() m_cmd = ('mkisofs -o %s -b isolinux/isolinux.bin -c isolinux/boot.cat ' '-no-emul-boot -boot-load-size 4 -boot-info-table -f -R -J ' '-V -T %s' % (self.path, self.mount)) utils.run(m_cmd) os.chmod(self.path, 0755) cleanup(self.mount) cleanup(self.source_cdrom) logging.debug("unattended install CD image %s successfully created", self.path)
def clean_old_image(image): """ Clean a leftover image file from previous processes. If it contains a mounted file system, do the proper cleanup procedures. @param image: Path to image to be cleaned up. """ error.context("cleaning up old leftover image %s" % image) if os.path.exists(image): mtab = open("/etc/mtab", "r") mtab_contents = mtab.read() mtab.close() if image in mtab_contents: utils.run("fuser -k %s" % image, ignore_status=True) utils.run("umount %s" % image) os.remove(image)
def setup_url(self): """ Download the vmlinuz and initrd.img from URL. """ error.context("downloading vmlinuz and initrd.img from %s" % self.url) os.chdir(self.image_path) kernel_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.kernel)) initrd_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path, os.path.basename(self.initrd)) if os.path.exists(self.kernel): os.remove(self.kernel) if os.path.exists(self.initrd): os.remove(self.initrd) utils.run(kernel_fetch_cmd) utils.run(initrd_fetch_cmd)
def clean_old_image(image): """ Clean a leftover image file from previous processes. If it contains a mounted file system, do the proper cleanup procedures. @param image: Path to image to be cleaned up. """ error.context("cleaning up old leftover image %s" % image) if os.path.exists(image): mtab = open('/etc/mtab', 'r') mtab_contents = mtab.read() mtab.close() if image in mtab_contents: utils.run('fuser -k %s' % image, ignore_status=True, verbose=DEBUG) utils.run('umount %s' % image, verbose=DEBUG) os.remove(image)
def run_stress_boot(test, params, env): """ Boots VMs until one of them becomes unresponsive, and records the maximum number of VMs successfully started: 1) boot the first vm 2) boot the second vm cloned from the first vm, check whether it boots up and all booted vms respond to shell commands 3) go on until cannot create VM anymore or cannot allocate memory for VM @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ error.base_context("waiting for the first guest to be up", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=login_timeout) num = 2 sessions = [session] # Boot the VMs try: while num <= int(params.get("max_vms")): # Clone vm according to the first one error.base_context("booting guest #%d" % num, logging.info) vm_name = "vm%d" % num vm_params = vm.params.copy() curr_vm = vm.clone(vm_name, vm_params) env.register_vm(vm_name, curr_vm) kvm_preprocessing.preprocess_vm(test, vm_params, env, vm_name) params["vms"] += " " + vm_name sessions.append(curr_vm.wait_for_login(timeout=login_timeout)) logging.info("Guest #%d booted up successfully", num) # Check whether all previous shell sessions are responsive for i, se in enumerate(sessions): error.context("checking responsiveness of guest #%d" % (i + 1), logging.debug) se.cmd(params.get("alive_test_cmd")) num += 1 finally: for se in sessions: se.close() logging.info("Total number booted: %d" % (num - 1))
def run_stress_boot(test, params, env): """ Boots VMs until one of them becomes unresponsive, and records the maximum number of VMs successfully started: 1) boot the first vm 2) boot the second vm cloned from the first vm, check whether it boots up and all booted vms respond to shell commands 3) go on until cannot create VM anymore or cannot allocate memory for VM @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ error.base_context("waiting for the first guest to be up", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=login_timeout) num = 2 sessions = [session] # Boot the VMs try: while num <= int(params.get("max_vms")): # Clone vm according to the first one error.base_context("booting guest #%d" % num, logging.info) vm_name = "vm%d" % num vm_params = vm.params.copy() curr_vm = vm.clone(vm_name, vm_params) env.register_vm(vm_name, curr_vm) virt_env_process.preprocess_vm(test, vm_params, env, vm_name) params["vms"] += " " + vm_name sessions.append(curr_vm.wait_for_login(timeout=login_timeout)) logging.info("Guest #%d booted up successfully", num) # Check whether all previous shell sessions are responsive for i, se in enumerate(sessions): error.context("checking responsiveness of guest #%d" % (i + 1), logging.debug) se.cmd(params.get("alive_test_cmd")) num += 1 finally: for se in sessions: se.close() logging.info("Total number booted: %d" % (num -1))
def run_qemu_iotests(test, params, env): """ Fetch from git and run qemu-iotests using the qemu binaries under test. 1) Fetch qemu-io from git 3) Run test for the file format detected 4) Report any errors found to autotest @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ # First, let's get qemu-io std = "git://git.kernel.org/pub/scm/linux/kernel/git/hch/qemu-iotests.git" uri = params.get("qemu_io_uri", std) branch = params.get("qemu_io_branch", 'master') lbranch = params.get("qemu_io_lbranch", 'master') commit = params.get("qemu_io_commit", None) base_uri = params.get("qemu_io_base_uri", None) destination_dir = os.path.join(test.srcdir, "qemu_io_tests") git.get_repo(uri=uri, branch=branch, lbranch=lbranch, commit=commit, destination_dir=destination_dir, base_uri=base_uri) # Then, set the qemu paths for the use of the testsuite os.environ["QEMU_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_binary", "qemu")) os.environ["QEMU_IMG_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_img_binary", "qemu-img")) os.environ["QEMU_IO_PROG"] = virt_utils.get_path( test.bindir, params.get("qemu_io_binary", "qemu-io")) os.chdir(destination_dir) image_format = params.get("qemu_io_image_format") extra_options = params.get("qemu_io_extra_options", "") cmd = './check' if extra_options: cmd += extra_options error.context("running qemu-iotests for image format %s" % image_format) utils.system("%s -%s" % (cmd, image_format))
def __init__(self, path, qemu_img_binary, tmpdir): error.context("Creating unattended install floppy image %s" % path) self.tmpdir = tmpdir self.mount = tempfile.mkdtemp(prefix='floppy_', dir=self.tmpdir) self.virtio_mount = None self.path = path clean_old_image(path) if not os.path.isdir(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) try: c_cmd = '%s create -f raw %s 1440k' % (qemu_img_binary, path) utils.run(c_cmd) f_cmd = 'mkfs.msdos -s 1 %s' % path utils.run(f_cmd) m_cmd = 'mount -o loop,rw %s %s' % (path, self.mount) utils.run(m_cmd) except error.CmdError, e: cleanup(self.mount) raise
def set_hugepages(self): """ Sets the hugepage limit to the target hugepage value calculated. """ error.context("setting hugepages limit to %s" % self.target_hugepages) hugepage_cfg = open(self.kernel_hp_file, "r+") hp = hugepage_cfg.readline() while int(hp) < self.target_hugepages: loop_hp = hp hugepage_cfg.write(str(self.target_hugepages)) hugepage_cfg.flush() hugepage_cfg.seek(0) hp = int(hugepage_cfg.readline()) if loop_hp == hp: raise ValueError("Cannot set the kernel hugepage setting " "to the target value of %d hugepages." % self.target_hugepages) hugepage_cfg.close() logging.debug("Successfuly set %s large memory pages on host ", self.target_hugepages)
def run_watchdog(test, params, env): """ Configure watchdog, crash the guest and check if watchdog_action occurs. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=timeout) relogin_timeout = int(params.get("relogin_timeout", 240)) watchdog_enable_cmd = "chkconfig watchdog on" watchdog_start_cmd = "service watchdog start" def watchdog_action_reset(): """ Trigger a crash dump through sysrq-trigger Ensure watchdog_action(reset) occur. """ session = vm.wait_for_login(timeout=timeout) logging.info("Triggering crash on vm") crash_cmd = "echo c > /proc/sysrq-trigger" session.sendline(crash_cmd) if not virt_utils.wait_for(lambda: not session.is_responsive(), 240, 0, 1): raise error.TestFail("Could not trigger crash") logging.info("Waiting for kernel watchdog_action to take place") session = vm.wait_for_login(timeout=relogin_timeout) error.context("Enabling watchdog service") session.cmd(watchdog_enable_cmd) error.context("Starting watchdog service") session.cmd(watchdog_start_cmd, timeout=320) watchdog_action_reset() # Close stablished session session.close()
def fragment_host_memory(mem_path): """ Attempt to fragment host memory. It accomplishes that goal by spawning a large number of dd processes on a tmpfs mount. @param mem_path: tmpfs mount point. """ error.context("Fragmenting host memory") try: logging.info("Prepare tmpfs in host") if not os.path.isdir(mem_path): os.makedirs(mem_path) utils.run("mount -t tmpfs none %s" % mem_path) logging.info("Start using dd to fragment memory in guest") cmd = ("for i in `seq 262144`; do dd if=/dev/urandom of=%s/$i " "bs=4K count=1 & done" % mem_path) utils.run(cmd) finally: utils.run("umount %s" % mem_path)
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) 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) 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) finally: cleanup(self.nfs_mount)