def run_boot(test, params, env): """ KVM reboot test: 1) Log into a guest 2) Send a reboot command or a system_reset monitor command (optional) 3) Wait until the guest is up again 4) Log into the guest to verify it's up again @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = float(params.get("login_timeout", 240)) session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2) try: if not params.get("reboot_method"): return # Reboot the VM session = kvm_test_utils.reboot(vm, session, params.get("reboot_method"), float(params.get("sleep_before_reset", 10)), 0, timeout) finally: session.close()
def run_shutdown(test, params, env): """ KVM shutdown test: 1) Log into a guest 2) Send a shutdown command to the guest, or issue a system_powerdown monitor command (depending on the value of shutdown_method) 3) Wait until the guest is down @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) try: if params.get("shutdown_method") == "shell": # Send a shutdown command to the guest's shell session.sendline(vm.get_params().get("shutdown_command")) logging.info("Shutdown command sent; waiting for guest to go " "down...") elif params.get("shutdown_method") == "system_powerdown": # Sleep for a while -- give the guest a chance to finish booting time.sleep(float(params.get("sleep_before_powerdown", 10))) # Send a system_powerdown monitor command vm.monitor.cmd("system_powerdown") logging.info("system_powerdown monitor command sent; waiting for " "guest to go down...") if not kvm_utils.wait_for(vm.is_dead, 240, 0, 1): raise error.TestFail("Guest refuses to go down") logging.info("Guest is down") finally: session.close()
def run_pxe(test, params, env): """ PXE test: 1) Snoop the tftp packet in the tap device. 2) Wait for some seconds. 3) Check whether we could capture TFTP packets. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("pxe_timeout", 60)) logging.info("Try to boot from PXE") status, output = kvm_subprocess.run_fg("tcpdump -nli %s" % vm.get_ifname(), logging.debug, "(pxe capture) ", timeout) logging.info("Analyzing the tcpdump result...") if not "tftp" in output: raise error.TestFail("Couldn't find any TFTP packets after %s seconds" % timeout) logging.info("Found TFTP packet")
def run_iozone_windows(test, params, env): """ Run IOzone for windows on a windows guest: 1) Log into a guest 2) Execute the IOzone test contained in the winutils.iso 3) Get results 4) Postprocess it with the IOzone postprocessing module @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) results_path = os.path.join(test.resultsdir, 'raw_output_%s' % test.iteration) analysisdir = os.path.join(test.resultsdir, 'analysis_%s' % test.iteration) # Run IOzone and record its results c = params.get("iozone_cmd") t = int(params.get("iozone_timeout")) logging.info("Running IOzone command on guest, timeout %ss", t) results = session.cmd_output(command=c, timeout=t, print_func=logging.debug) utils.open_write_close(results_path, results) # Postprocess the results using the IOzone postprocessing module logging.info("Iteration succeed, postprocessing") a = postprocessing.IOzoneAnalyzer(list_files=[results_path], output_dir=analysisdir) a.analyze() p = postprocessing.IOzonePlotter(results_file=results_path, output_dir=analysisdir) p.plot_all()
def run_ioquit(test, params, env): """ Emulate the poweroff under IO workload(dd so far) using kill -9. @param test: Kvm test object @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm, timeout=int(params.get("login_timeout", 360))) session2 = kvm_test_utils.wait_for_login(vm, timeout=int(params.get("login_timeout", 360))) try: bg_cmd = params.get("background_cmd") logging.info("Add IO workload for guest OS.") session.cmd_output(bg_cmd, timeout=60) check_cmd = params.get("check_cmd") session2.cmd(check_cmd, timeout=60) logging.info("Sleep for a while") time.sleep(random.randrange(30,100)) session2.cmd(check_cmd, timeout=60) logging.info("Kill the virtual machine") vm.process.close() finally: session.close() session2.close()
def run_clock_getres(test, params, env): """ Verify if guests using kvm-clock as the time source have a sane clock resolution. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ t_name = "test_clock_getres" base_dir = "/tmp" deps_dir = os.path.join(test.bindir, "deps", t_name) os.chdir(deps_dir) try: utils.system("make clean") utils.system("make") except: raise error.TestError("Failed to compile %s" % t_name) test_clock = os.path.join(deps_dir, t_name) if not os.path.isfile(test_clock): raise error.TestError("Could not find %s" % t_name) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) if not vm.copy_files_to(test_clock, base_dir): raise error.TestError("Failed to copy %s to VM" % t_name) session.cmd(os.path.join(base_dir, t_name)) logging.info("PASS: Guest reported appropriate clock resolution") logging.info("guest's dmesg:") session.cmd_output("dmesg")
def run_boot_savevm(test, params, env): """ KVM boot savevm test: 1) Start guest 2) Periodically savevm/loadvm 4) Log into the guest to verify it's up, fail after timeout seconds @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) savevm_delay = float(params.get("savevm_delay")) savevm_login_delay = float(params.get("savevm_login_delay")) logging.info("savevm_delay = %f" % savevm_delay) login_expire = time.time() + savevm_login_delay end_time = time.time() + float(params.get("savevm_timeout")) while time.time() < end_time: time.sleep(savevm_delay) try: vm.monitor.cmd("stop") except kvm_monitor.MonitorError, e: logging.error(e) try: # This should be replaced by a proper monitor method call vm.monitor.cmd("savevm 1") except kvm_monitor.MonitorError, e: logging.error(e)
def run_mac_change(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Set new mac in guest and regain new IP. 3) Re-log into guest with new MAC. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", 360)) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2, serial=True) # This session will be used to assess whether the IP change worked session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2) old_mac = vm.get_mac_address(0) while True: vm.free_mac_address(0) new_mac = kvm_utils.generate_mac_address(vm.instance, 0) if old_mac != new_mac: break logging.info("The initial MAC address is %s", old_mac) interface = kvm_test_utils.get_linux_ifname(session_serial, old_mac) # Start change MAC address logging.info("Changing MAC address to %s", new_mac) change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && " "ifconfig %s up" % (interface, interface, new_mac, interface)) session_serial.cmd(change_cmd) # Verify whether MAC address was changed to the new one logging.info("Verifying the new mac address") session_serial.cmd("ifconfig | grep -i %s" % new_mac) # Restart `dhclient' to regain IP for new mac address logging.info("Restart the network to gain new IP") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) # Re-log into the guest after changing mac address if kvm_utils.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. logging.warn("The session is still responsive, settings may fail.") session.close() # Re-log into guest and check if session is responsive logging.info("Re-log into the guest") session = kvm_test_utils.wait_for_login(vm, timeout=int(params.get("login_timeout", 360))) if not session.is_responsive(): raise error.TestFail("The new session is not responsive.") session.close()
def run_autoit(test, params, env): """ A wrapper for AutoIt scripts. 1) Log into a guest. 2) Run AutoIt script. 3) Wait for script execution to complete. 4) Pass/fail according to exit status of script. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) try: logging.info("Starting script...") # Collect test parameters binary = params.get("autoit_binary") script = params.get("autoit_script") script_params = params.get("autoit_script_params", "") timeout = float(params.get("autoit_script_timeout", 600)) # Send AutoIt script to guest (this code will be replaced once we # support sending files to Windows guests) session.sendline("del script.au3") file = open(kvm_utils.get_path(test.bindir, script)) for line in file.readlines(): # Insert a '^' before each character line = "".join("^" + c for c in line.rstrip()) if line: # Append line to the file session.sendline("echo %s>>script.au3" % line) file.close() session.read_up_to_prompt() command = "cmd /c %s script.au3 %s" % (binary, script_params) logging.info("---------------- Script output ----------------") status = session.get_command_status(command, print_func=logging.info, timeout=timeout) logging.info("---------------- End of script output ----------------") if status is None: raise error.TestFail("Timeout expired before script execution " "completed (or something weird happened)") if status != 0: raise error.TestFail("Script execution failed") finally: session.close()
def run_migration_with_file_transfer(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) Reboot the VM 4) Send a migration command to the source VM and wait until it's finished. 5) Kill off the source VM. 6) Log into the destination VM after the migration is finished. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ def transfer_test(vm, host_path, guest_path, timeout=120): """ vm.copy_files_to does not raise exception, so we need a wrapper in order to make it to be used by BackgroundTest. """ if not vm.copy_files_to(host_path, guest_path, timeout=timeout): raise error.TestError("Fail to do the file transfer!") vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") guest_path = params.get("guest_path", "/tmp") file_size = params.get("file_size", "1000") transfer_timeout = int(params.get("transfer_timeout", "240")) bg = None try: utils.run("dd if=/dev/zero of=/tmp/file bs=1M count=%s" % file_size) # Transfer file from host to guest bg = kvm_test_utils.BackgroundTest(transfer_test, (vm, "/tmp/file", guest_path, transfer_timeout)) bg.start() while bg.is_alive(): logging.info("File transfer is not ended, start a round of migration ...") # Migrate the VM dest_vm = kvm_test_utils.migrate(vm, env, mig_timeout, mig_protocol, False) vm = dest_vm finally: if bg: bg.join() session.close() utils.run("rm -rf /tmp/zero")
def run_set_link(test, params, env): """ KVM guest link test: 1) Boot up guest with one nic 2) Ping guest from host 3) Disable guest link and ping guest from host 4) Re-enable guest link and ping guest from host 5) Do file transfer test @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = float(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2) ip = vm.get_address(0) linkname = vm.netdev_id[0] logging.info("Pinging guest from host") s, o = kvm_test_utils.ping(ip, count=10, timeout=20) if s != 0: raise error.TestFail("Ping failed, status: %s, output: %s" % (s, o)) ratio = kvm_test_utils.get_loss_ratio(o) if ratio != 0: raise error.TestFail("Loss ratio is %s, output: %s" % (ratio, o)) logging.info("Executing 'set link %s off'", linkname) vm.monitor.cmd("set_link %s off" % linkname) logging.info(vm.monitor.info("network")) logging.info("Pinging guest from host") s, o = kvm_test_utils.ping(ip, count=10, timeout=20) if s == 0: raise error.TestFail("Ping unexpectedly succeeded, status: %s," "output: %s" % (s, o)) ratio = kvm_test_utils.get_loss_ratio(o) if ratio != 100: raise error.TestFail("Loss ratio is not 100%%," "Loss ratio is %s" % ratio) logging.info("Executing 'set link %s on'", linkname) vm.monitor.cmd("set_link %s on" % linkname) logging.info(vm.monitor.info("network")) logging.info("Pinging guest from host") s, o = kvm_test_utils.ping(ip, count=10, timeout=20) if s != 0: raise error.TestFail("Ping failed, status: %s, output: %s" % (s, o)) ratio = kvm_test_utils.get_loss_ratio(o) if ratio != 0: raise error.TestFail("Loss ratio is %s, output: %s" % (ratio, o)) file_transfer.run_file_transfer(test, params, env) session.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. """ buf = 1024 vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) port = vm.get_port(int(params.get("guest_port_unattended_install"))) if params.get("post_install_delay"): post_install_delay = int(params.get("post_install_delay")) else: post_install_delay = 0 install_timeout = float(params.get("timeout", 3000)) logging.info("Starting unattended install watch process. " "Timeout set to %ds (%d min)", install_timeout, install_timeout/60) start_time = time.time() time_elapsed = 0 while time_elapsed < install_timeout: if not vm.is_alive(): raise error.TestError("Guest died before end of OS install") client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) addr = vm.get_address() if addr is not None: try: client.connect((addr, port)) msg = client.recv(1024) if msg == 'done': if post_install_delay: logging.debug("Post install delay specified, " "waiting %ss...", post_install_delay) time.sleep(post_install_delay) break except socket.error: pass time.sleep(1) client.close() end_time = time.time() time_elapsed = int(end_time - start_time) if time_elapsed < install_timeout: logging.info('Guest reported successful installation after %ds ' '(%d min)', time_elapsed, time_elapsed/60) else: raise error.TestFail('Timeout elapsed while waiting for install to ' 'finish.')
def run_nic_bonding(test, params, env): """ Nic bonding test in guest. 1) Start guest with four nic models. 2) Setup bond0 in guest by script bonding_setup.py. 3) Execute file transfer test between guest and host. 4) Repeatedly put down/up interfaces by set_link 5) Execute file transfer test between guest and host. @param test: Kvm test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def control_link_loop(vm, termination_event): logging.info("Repeatedly put down/up interfaces by set_link") while True: for i in range(len(params.get("nics").split())): linkname = "%s.%s" % (params.get("nic_model"), i) cmd = "set_link %s down" % linkname vm.monitor.cmd(cmd) time.sleep(1) cmd = "set_link %s up" % linkname vm.monitor.cmd(cmd) if termination_event.isSet(): break timeout = int(params.get("login_timeout", 1200)) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2, serial=True) script_path = kvm_utils.get_path(test.bindir, "scripts/bonding_setup.py") vm.copy_files_to(script_path, "/tmp/bonding_setup.py") cmd = "python /tmp/bonding_setup.py %s" % vm.get_mac_address() session_serial.cmd(cmd) termination_event = threading.Event() t = threading.Thread(target=control_link_loop, args=(vm, termination_event)) try: logging.info("Do some basic test before testing high availability") file_transfer.run_file_transfer(test, params, env) t.start() logging.info("Do file transfer testing") file_transfer.run_file_transfer(test, params, env) finally: termination_event.set() t.join(10) session_serial.close()
def run_set_link(test, params, env): """ KVM guest link test: 1) Boot up guest with one nic 2) Ping guest from host 3) Disable guest link and ping guest from host 4) Re-enable guest link and ping guest from host 5) Do file transfer test @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = float(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2) def set_link_test(linkid): """ Issue set_link commands and test its function @param linkid: id of netdev or devices to be tested """ ip = vm.get_address(0) vm.monitor.cmd("set_link %s down" % linkid) s, o = kvm_test_utils.ping(ip, count=10, timeout=20) if kvm_test_utils.get_loss_ratio(o) != 100: raise error.TestFail("Still can ping the %s after down %s" % (ip, linkid)) vm.monitor.cmd("set_link %s up" % linkid) s, o = kvm_test_utils.ping(ip, count=10, timeout=20) # we use 100% here as the notification of link status changed may be # delayed in guest driver if kvm_test_utils.get_loss_ratio(o) == 100: raise error.TestFail("Packet loss during ping %s after up %s" % (ip, linkid)) netdev_id = vm.netdev_id[0] device_id = vm.get_peer(netdev_id) logging.info("Issue set_link commands for netdevs") set_link_test(netdev_id) logging.info("Issue set_link commands for network devics") set_link_test(device_id) file_transfer.run_file_transfer(test, params, env) session.close()
def run_yum_update(test, params, env): """ Runs yum update and yum update kernel on the remote host (yum enabled hosts only). @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) internal_yum_update(session, "yum update", params.get("shell_prompt"), 600) internal_yum_update(session, "yum update kernel", params.get("shell_prompt"), 600) session.close()
def run_boot(test, params, env): """ KVM reboot test: 1) Log into a guest 2) Send a reboot command or a system_reset monitor command (optional) 3) Wait until the guest is up again 4) Log into the guest to verify it's up again @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) try: if params.get("reboot_method") == "shell": # Send a reboot command to the guest's shell session.sendline(vm.get_params().get("reboot_command")) logging.info("Reboot command sent; waiting for guest to go " "down...") elif params.get("reboot_method") == "system_reset": # Sleep for a while -- give the guest a chance to finish booting time.sleep(float(params.get("sleep_before_reset", 10))) # Send a system_reset monitor command vm.send_monitor_cmd("system_reset") logging.info("system_reset monitor command sent; waiting for " "guest to go down...") else: return # Wait for the session to become unresponsive if not kvm_utils.wait_for(lambda: not session.is_responsive(), 120, 0, 1): raise error.TestFail("Guest refuses to go down") finally: session.close() logging.info("Guest is down; waiting for it to go up again...") session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2) if not session: raise error.TestFail("Could not log into guest after reboot") session.close() logging.info("Guest is up again")
def run_autotest(test, params, env): """ Run an autotest test inside a guest. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) # Collect test parameters timeout = int(params.get("test_timeout", 300)) control_path = os.path.join(test.bindir, "autotest_control", params.get("test_control_file")) outputdir = test.outputdir kvm_test_utils.run_autotest(vm, session, control_path, timeout, outputdir)
def run_linux_s3(test, params, env): """ Suspend a guest Linux OS to memory. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) logging.info("Checking that VM supports S3") status = session.get_command_status("grep -q mem /sys/power/state") if status == None: logging.error("Failed to check if S3 exists") elif status != 0: raise error.TestFail("Guest does not support S3") logging.info("Waiting for a while for X to start") time.sleep(10) src_tty = session.get_command_output("fgconsole").strip() logging.info("Current virtual terminal is %s" % src_tty) if src_tty not in map(str, range(1,10)): raise error.TestFail("Got a strange current vt (%s)" % src_tty) dst_tty = "1" if src_tty == "1": dst_tty = "2" logging.info("Putting VM into S3") command = "chvt %s && echo mem > /sys/power/state && chvt %s" % (dst_tty, src_tty) status = session.get_command_status(command, timeout=120) if status != 0: raise error.TestFail("Suspend to mem failed") logging.info("VM resumed after S3") session.close()
def run_migration_with_reboot(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) Reboot the VM 4) Send a migration command to the source VM and wait until it's finished. 5) Kill off the source VM. 6) Log into the destination VM after the migration is finished. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_cancel = bool(params.get("mig_cancel")) bg = None try: # reboot the VM in background bg = kvm_test_utils.BackgroundTest(kvm_test_utils.reboot, (vm, session)) bg.start() while bg.is_alive(): # Migrate the VM dest_vm = kvm_test_utils.migrate(vm, env, mig_timeout, mig_protocol, False) vm = dest_vm finally: if bg: bg.join() session.close()
def run_multicast(test, params, env): """ Test multicast function of nic (rtl8139/e1000/virtio) 1) Create a VM. 2) Join guest into multicast groups. 3) Ping multicast addresses on host. 4) Flood ping test with different size of packets. 5) Final ping test and check if lose packet. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm, timeout=int(params.get("login_timeout", 360))) def run_guest(cmd): try: session.cmd(cmd) except kvm_subprocess.ShellError, e: logging.warn(e)
def run_nic_hotplug(test, params, env): """ Test hotplug of NIC devices 1) Boot up guest with one nic 2) Add a host network device through monitor cmd and check if it's added 3) Add nic device through monitor cmd and check if it's added 4) Check if new interface gets ip address 5) Disable primary link of guest 6) Ping guest new ip from host 7) Delete nic device and netdev 8) Re-enable primary link of guest @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) guest_delay = int(params.get("guest_delay", 20)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) romfile = params.get("romfile") # Modprobe the module if specified in config file module = params.get("modprobe_module") if module: session.get_command_output("modprobe %s" % module) def netdev_add(vm): netdev_id = kvm_utils.generate_random_id() attach_cmd = ("netdev_add tap,id=%s" % netdev_id) nic_script = params.get("nic_script") if nic_script: attach_cmd += ",script=%s" % kvm_utils.get_path( vm.root_dir, nic_script) netdev_extra_params = params.get("netdev_extra_params") if netdev_extra_params: attach_cmd += ",%s" % netdev_extra_params logging.info("Adding netdev through %s", attach_cmd) vm.monitor.cmd(attach_cmd) network = vm.monitor.info("network") if netdev_id not in network: logging.error(network) raise error.TestError("Fail to add netdev: %s" % netdev_id) else: return netdev_id def netdev_del(vm, n_id): vm.monitor.cmd("netdev_del %s" % n_id) network = vm.monitor.info("network") if n_id in network: logging.error(network) raise error.TestError("Fail to remove netdev %s" % n_id) def nic_add(vm, model, netdev_id, mac, rom=None): """ Add a nic to virtual machine @vm: VM object @model: nic model @netdev_id: id of netdev @mac: Mac address of new nic @rom: Rom file """ nic_id = kvm_utils.generate_random_id() if model == "virtio": model = "virtio-net-pci" device_add_cmd = "device_add %s,netdev=%s,mac=%s,id=%s" % ( model, netdev_id, mac, nic_id) if rom: device_add_cmd += ",romfile=%s" % rom logging.info("Adding nic through %s", device_add_cmd) vm.monitor.cmd(device_add_cmd) qdev = vm.monitor.info("qtree") if not nic_id in qdev: logging.error(qdev) raise error.TestFail("Device %s was not plugged into qdev" "tree" % nic_id) else: return nic_id def nic_del(vm, nic_id, wait=True): """ Remove the nic from pci tree. @vm: VM object @id: the nic id @wait: Whether need to wait for the guest to unplug the device """ nic_del_cmd = "device_del %s" % nic_id vm.monitor.cmd(nic_del_cmd) if wait: logging.info("waiting for the guest to finish the unplug") if not kvm_utils.wait_for( lambda: nic_id not in vm.monitor.info("qtree"), guest_delay, 5, 1): logging.error(vm.monitor.info("qtree")) raise error.TestError("Device is not unplugged by " "guest, please check whether the " "hotplug module was loaded in guest") logging.info("Attach a virtio nic to vm") mac = kvm_utils.generate_mac_address(vm.instance, 1) if not mac: mac = "00:00:02:00:00:02" netdev_id = netdev_add(vm) device_id = nic_add(vm, "virtio", netdev_id, mac, romfile) if "Win" not in params.get("guest_name", ""): session.sendline("dhclient %s &" % kvm_test_utils.get_linux_ifname(session, mac)) logging.info("Shutting down the primary link") vm.monitor.cmd("set_link %s down" % vm.netdev_id[0]) try: logging.info("Waiting for new nic's ip address acquisition...") if not kvm_utils.wait_for( lambda: (vm.address_cache.get(mac) is not None), 10, 1): raise error.TestFail("Could not get ip address of new nic") ip = vm.address_cache.get(mac) if not kvm_utils.verify_ip_address_ownership(ip, mac): raise error.TestFail("Could not verify the ip address of new nic") else: logging.info("Got the ip address of new nic: %s", ip) logging.info("Ping test the new nic ...") s, o = kvm_test_utils.ping(ip, 100) if s != 0: logging.error(o) raise error.TestFail("New nic failed ping test") logging.info("Detaching a virtio nic from vm") nic_del(vm, device_id) netdev_del(vm, netdev_id) finally: vm.free_mac_address(1) logging.info("Re-enabling the primary link") vm.monitor.cmd("set_link %s up" % vm.netdev_id[0])
def run_timedrift_with_stop(test, params, env): """ Time drift test with stop/continue the guest: 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Stop the running of the guest 4) Sleep for a while 5) Continue the guest running 6) Take a second time reading. 7) If the drift (in seconds) is higher than a user specified value, fail. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ login_timeout = int(params.get("login_timeout", 360)) sleep_time = int(params.get("sleep_time", 30)) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm, timeout=login_timeout) # Collect test parameters: # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") drift_threshold = float(params.get("drift_threshold", "10")) drift_threshold_single = float(params.get("drift_threshold_single", "3")) stop_iterations = int(params.get("stop_iterations", 1)) stop_time = int(params.get("stop_time", 60)) try: # Get initial time # (ht stands for host time, gt stands for guest time) (ht0, gt0) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Stop the guest for i in range(stop_iterations): # Get time before current iteration (ht0_, gt0_) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Run current iteration logging.info("Stop %s second: iteration %d of %d..." % (stop_time, i + 1, stop_iterations)) vm.monitor.cmd("stop") time.sleep(stop_time) vm.monitor.cmd("cont") # Sleep for a while to wait the interrupt to be reinjected logging.info("Waiting for the interrupt to be reinjected ...") time.sleep(sleep_time) # Get time after current iteration (ht1_, gt1_) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Report iteration results host_delta = ht1_ - ht0_ guest_delta = gt1_ - gt0_ drift = abs(host_delta - guest_delta) logging.info("Host duration (iteration %d): %.2f" % (i + 1, host_delta)) logging.info("Guest duration (iteration %d): %.2f" % (i + 1, guest_delta)) logging.info("Drift at iteration %d: %.2f seconds" % (i + 1, drift)) # Fail if necessary if drift > drift_threshold_single: raise error.TestFail("Time drift too large at iteration %d: " "%.2f seconds" % (i + 1, drift)) # Get final time (ht1, gt1) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) finally: if session: session.close() # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = abs(host_delta - guest_delta) logging.info("Host duration (%d stops): %.2f" % (stop_iterations, host_delta)) logging.info("Guest duration (%d stops): %.2f" % (stop_iterations, guest_delta)) logging.info("Drift after %d stops: %.2f seconds" % (stop_iterations, drift)) # Fail if necessary if drift > drift_threshold: raise error.TestFail("Time drift too large after %d stops: " "%.2f seconds" % (stop_iterations, drift))
def run_guest_s4(test, params, env): """ Suspend guest to disk, supports both Linux & Windows OSes. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) logging.info("Checking whether guest OS supports suspend to disk (S4)...") session.cmd(params.get("check_s4_support_cmd")) logging.info("Waiting until all guest OS services are fully started...") time.sleep(float(params.get("services_up_timeout", 30))) # Start up a program (tcpdump for linux & ping for Windows), as a flag. # If the program died after suspend, then fails this testcase. test_s4_cmd = params.get("test_s4_cmd") session.sendline(test_s4_cmd) time.sleep(5) # Get the second session to start S4 session2 = kvm_test_utils.wait_for_login(vm, timeout=timeout) # Make sure the background program is running as expected check_s4_cmd = params.get("check_s4_cmd") session2.cmd(check_s4_cmd) logging.info("Launched background command in guest: %s" % test_s4_cmd) # Suspend to disk logging.info("Starting suspend to disk now...") session2.sendline(params.get("set_s4_cmd")) # Make sure the VM goes down suspend_timeout = 240 + int(params.get("smp")) * 60 if not kvm_utils.wait_for(vm.is_dead, suspend_timeout, 2, 2): raise error.TestFail("VM refuses to go down. Suspend failed.") logging.info("VM suspended successfully. Sleeping for a while before " "resuming it.") time.sleep(10) # Start vm, and check whether the program is still running logging.info("Resuming suspended VM...") if not vm.create(): raise error.TestError("Failed to start VM after suspend to disk") # Log into the resumed VM relogin_timeout = int(params.get("relogin_timeout", 240)) logging.info("Logging into resumed VM, timeout %s", relogin_timeout) session2 = kvm_utils.wait_for(vm.remote_login, relogin_timeout, 0, 2) if not session2: raise error.TestFail("Could not log into VM after resuming from " "suspend to disk") # Check whether the test command is still alive logging.info("Checking if background command is still alive...") session2.cmd(check_s4_cmd) logging.info("VM resumed successfuly after suspend to disk") session2.cmd_output(params.get("kill_test_s4_cmd")) session.close() session2.close()
def run_timedrift_with_reboot(test, params, env): """ Time drift test with reboot: 1) Log into a guest. 2) Take a time reading from the guest and host. 3) Reboot the guest. 4) Take a second time reading. 5) If the drift (in seconds) is higher than a user specified value, fail. @param test: KVM test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout = int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) # Collect test parameters: # Command to run to get the current time time_command = params.get("time_command") # Filter which should match a string to be passed to time.strptime() time_filter_re = params.get("time_filter_re") # Time format for time.strptime() time_format = params.get("time_format") drift_threshold = float(params.get("drift_threshold", "10")) drift_threshold_single = float(params.get("drift_threshold_single", "3")) reboot_iterations = int(params.get("reboot_iterations", 1)) try: # Get initial time # (ht stands for host time, gt stands for guest time) (ht0, gt0) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Reboot for i in range(reboot_iterations): # Get time before current iteration (ht0_, gt0_) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Run current iteration logging.info("Rebooting: iteration %d of %d..." % (i + 1, reboot_iterations)) session = kvm_test_utils.reboot(vm, session) # Get time after current iteration (ht1_, gt1_) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) # Report iteration results host_delta = ht1_ - ht0_ guest_delta = gt1_ - gt0_ drift = abs(host_delta - guest_delta) logging.info("Host duration (iteration %d): %.2f" % (i + 1, host_delta)) logging.info("Guest duration (iteration %d): %.2f" % (i + 1, guest_delta)) logging.info("Drift at iteration %d: %.2f seconds" % (i + 1, drift)) # Fail if necessary if drift > drift_threshold_single: raise error.TestFail("Time drift too large at iteration %d: " "%.2f seconds" % (i + 1, drift)) # Get final time (ht1, gt1) = kvm_test_utils.get_time(session, time_command, time_filter_re, time_format) finally: if session: session.close() # Report results host_delta = ht1 - ht0 guest_delta = gt1 - gt0 drift = abs(host_delta - guest_delta) logging.info("Host duration (%d reboots): %.2f" % (reboot_iterations, host_delta)) logging.info("Guest duration (%d reboots): %.2f" % (reboot_iterations, guest_delta)) logging.info("Drift after %d reboots: %.2f seconds" % (reboot_iterations, drift)) # Fail if necessary if drift > drift_threshold: raise error.TestFail("Time drift too large after %d reboots: " "%.2f seconds" % (reboot_iterations, drift))
def run_nicdriver_unload(test, params, env): """ Test nic driver. 1) Boot a VM. 2) Get the NIC driver name. 3) Repeatedly unload/load NIC driver. 4) Multi-session TCP transfer on test interface. 5) Check whether the test interface should still work. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", 360)) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2, serial=True) ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0)) sys_path = "/sys/class/net/%s/device/driver" % (ethname) o = session.cmd("readlink -e %s" % sys_path) driver = os.path.basename(o.strip()) logging.info("driver is %s", driver) class ThreadScp(threading.Thread): def run(self): remote_file = '/tmp/' + self.getName() file_list.append(remote_file) ret = vm.copy_files_to(file_name, remote_file, timeout=scp_timeout) if ret: logging.debug("File %s was transfered successfuly", remote_file) else: logging.debug("Failed to transfer file %s", remote_file) def compare(origin_file, receive_file): check_sum1 = utils.hash_file(origin_file, method="md5") output2 = session.cmd("md5sum %s" % receive_file) check_sum2 = output2.strip().split()[0] logging.debug("original file md5: %s, received file md5: %s", check_sum1, check_sum2) if check_sum1 != check_sum2: logging.error("MD5 hash of origin and received files doesn't match") return False return True #produce sized file in host file_size = params.get("file_size") file_name = "/tmp/nicdriver_unload_file" cmd = "dd if=/dev/urandom of=%s bs=%sM count=1" utils.system(cmd % (file_name, file_size)) file_list = [] connect_time = params.get("connect_time") scp_timeout = int(params.get("scp_timeout")) thread_num = int(params.get("thread_num")) unload_load_cmd = ("sleep %s && ifconfig %s down && modprobe -r %s && " "sleep 1 && modprobe %s && sleep 4 && ifconfig %s up" % (connect_time, ethname, driver, driver, ethname)) pid = os.fork() if pid != 0: logging.info("Unload/load NIC driver repeatedly in guest...") while True: logging.debug("Try to unload/load nic drive once") try: session_serial.cmd(unload_load_cmd, timeout=120) except: session.cmd_output("rm -rf /tmp/Thread-*") raise pid, s = os.waitpid(pid, os.WNOHANG) status = os.WEXITSTATUS(s) if (pid, status) != (0, 0): logging.debug("Child process ending") break else: logging.info("Multi-session TCP data transfer") threads = [] for i in range(thread_num): t = ThreadScp() t.start() threads.append(t) for t in threads: t.join(timeout = scp_timeout) os._exit(0) try: logging.info("Check MD5 hash for received files in multi-session") for f in file_list: if not compare(file_name, f): raise error.TestFail("Fail to compare (guest) file %s" % f) logging.info("Test nic function after load/unload") if not vm.copy_files_to(file_name, file_name): raise error.TestFail("Fail to copy file from host to guest") if not compare(file_name, file_name): raise error.TestFail("Test nic function after load/unload fail") finally: session.cmd_output("rm -rf /tmp/Thread-*") session.close()
def run_file_transfer(test, params, env): """ Test ethrnet device function by ethtool 1) Boot up a VM. 2) Create a large file by dd on host. 3) Copy this file from host to guest. 4) Copy this file from guest to host. 5) Check if file transfers ended good. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) timeout=int(params.get("login_timeout", 360)) session = kvm_test_utils.wait_for_login(vm, timeout=timeout) if not session: raise error.TestFail("Could not log into guest '%s'" % vm.name) dir_name = test.tmpdir transfer_timeout = int(params.get("transfer_timeout")) transfer_type = params.get("transfer_type") tmp_dir = params.get("tmp_dir", "/tmp/") clean_cmd = params.get("clean_cmd", "rm -f") filesize = int(params.get("filesize", 4000)) count = int(filesize / 10) if count == 0: count = 1 cmd = "dd if=/dev/zero of=%s/a.out bs=10M count=%d" % (dir_name, count) guest_path = tmp_dir + "b.out" try: logging.info("Creating %dMB file on host", filesize) utils.run(cmd) if transfer_type == "remote": logging.info("Transfering file host -> guest, timeout: %ss", transfer_timeout) t_begin = time.time() success = vm.copy_files_to("%s/a.out" % dir_name, guest_path, timeout=transfer_timeout) t_end = time.time() throughput = filesize / (t_end - t_begin) if not success: raise error.TestFail("Fail to transfer file from host to guest") logging.info("File transfer host -> guest succeed, " "estimated throughput: %.2fMB/s", throughput) logging.info("Transfering file guest -> host, timeout: %ss", transfer_timeout) t_begin = time.time() success = vm.copy_files_from(guest_path, "%s/c.out" % dir_name, timeout=transfer_timeout) t_end = time.time() throughput = filesize / (t_end - t_begin) if not success: raise error.TestFail("Fail to transfer file from guest to host") logging.info("File transfer guest -> host succeed, " "estimated throughput: %.2fMB/s", throughput) else: raise error.TestError("Unknown test file transfer mode %s" % transfer_type) for f in ['a.out', 'c.out']: p = os.path.join(dir_name, f) size = os.path.getsize(p) logging.debug('Size of %s: %sB', f, size) md5_orig = utils.hash_file("%s/a.out" % dir_name, method="md5") md5_new = utils.hash_file("%s/c.out" % dir_name, method="md5") if md5_orig != md5_new: raise error.TestFail("File changed after transfer host -> guest " "and guest -> host") finally: logging.info('Cleaning temp file on guest') clean_cmd += " %s" % guest_path session.cmd(clean_cmd) logging.info('Cleaning temp files on host') try: os.remove('%s/a.out' % dir_name) os.remove('%s/c.out' % dir_name) except OSError: pass session.close()
def run_vlan(test, params, env): """ Test 802.1Q vlan of NIC, config it by vconfig command. 1) Create two VMs. 2) Setup guests in 10 different vlans by vconfig and using hard-coded ip address. 3) Test by ping between same and different vlans of two VMs. 4) Test by TCP data transfer, floop ping between same vlan of two VMs. 5) Test maximal plumb/unplumb vlans. 6) Recover the vlan config. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = [] session = [] ifname = [] vm_ip = [] digest_origin = [] vlan_ip = ['', ''] ip_unit = ['1', '2'] subnet = params.get("subnet") vlan_num = int(params.get("vlan_num")) maximal = int(params.get("maximal")) file_size = params.get("file_size") vm.append(kvm_test_utils.get_living_vm(env, params.get("main_vm"))) vm.append(kvm_test_utils.get_living_vm(env, "vm2")) def add_vlan(session, id, iface="eth0"): session.cmd("vconfig add %s %s" % (iface, id)) def set_ip_vlan(session, id, ip, iface="eth0"): iface = "%s.%s" % (iface, id) session.cmd("ifconfig %s %s" % (iface, ip)) def set_arp_ignore(session, iface="eth0"): ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore" session.cmd(ignore_cmd) def rem_vlan(session, id, iface="eth0"): rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi" iface = "%s.%s" % (iface, id) return session.cmd_status(rem_vlan_cmd % (iface, iface)) def nc_transfer(src, dst): nc_port = kvm_utils.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 kvm_subprocess.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 transfered differ from origin") session[dst].cmd_output("rm -f receive") for i in range(2): session.append(kvm_test_utils.wait_for_login(vm[i], timeout=int(params.get("login_timeout", 360)))) if not session[i] : raise error.TestError("Could not log into guest(vm%d)" % i) logging.info("Logged in") ifname.append(kvm_test_utils.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_output("/etc/init.d/iptables stop") #load 8021q module for vconfig session[i].cmd("modprobe 8021q") try: for i in range(2): for vlan_i in range(1, vlan_num+1): add_vlan(session[i], vlan_i, ifname[i]) set_ip_vlan(session[i], vlan_i, "%s.%s.%s" % (subnet, vlan_i, ip_unit[i]), ifname[i]) set_arp_ignore(session[i], ifname[i]) for vlan in range(1, vlan_num+1): logging.info("Test for vlan %s" % vlan) logging.info("Ping between vlans") 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 = kvm_test_utils.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] logging.info("Flood ping") def flood_ping(src, dst): # we must use a dedicated session becuase the kvm_subprocess # does not have the other method to interrupt the process in # the guest rather than close the session. session_flood = kvm_test_utils.wait_for_login(vm[src], timeout = 60) kvm_test_utils.ping(vlan_ip[dst], flood=True, interface=ifname[src], session=session_flood, timeout=10) session_flood.close() flood_ping(0,1) flood_ping(1,0) logging.info("Transfering data through nc") nc_transfer(0, 1) nc_transfer(1, 0) finally: for vlan in range(1, vlan_num+1): rem_vlan(session[0], vlan, ifname[0]) rem_vlan(session[1], vlan, ifname[1]) logging.info("rem vlan: %s" % vlan) # Plumb/unplumb maximal unber of vlan interfaces i = 1 s = 0 try: logging.info("Testing the plumb of vlan interface") for i in range (1, maximal+1): add_vlan(session[0], i, ifname[0]) finally: for j in range (1, i+1): s = s or rem_vlan(session[0], j, ifname[0]) 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 run_ping(test, params, env): """ Ping the guest with different size of packets. Packet Loss Test: 1) Ping the guest with different size/interval of packets. Stress Test: 1) Flood ping the guest. 2) Check if the network is still usable. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) counts = params.get("ping_counts", 100) flood_minutes = float(params.get("flood_minutes", 10)) nics = params.get("nics").split() strict_check = params.get("strict_check", "no") == "yes" packet_size = [0, 1, 4, 48, 512, 1440, 1500, 1505, 4054, 4055, 4096, 4192, 8878, 9000, 32767, 65507] try: for i, nic in enumerate(nics): ip = vm.get_address(i) if not ip: logging.error("Could not get the ip of nic index %d", i) continue for size in packet_size: logging.info("Ping with packet size %s", size) status, output = kvm_test_utils.ping(ip, 10, packetsize=size, timeout=20) if strict_check: ratio = kvm_test_utils.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 failed, status: %s," " output: %s" % (status, output)) logging.info("Flood ping test") kvm_test_utils.ping(ip, None, flood=True, output_func=None, timeout=flood_minutes * 60) logging.info("Final ping test") status, output = kvm_test_utils.ping(ip, counts, timeout=float(counts) * 1.5) if strict_check: ratio = kvm_test_utils.get_loss_ratio(output) if ratio != 0: raise error.TestFail("Ping failed, status: %s," " output: %s" % (status, output)) else: if status != 0: raise error.TestFail("Ping returns non-zero value %s" % output) finally: session.close()
logging.debug("Session is not responsive") if vm.process.is_alive(): logging.debug("VM is alive, try to re-login") try: session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2) except: logging.debug("Could not re-login, reboot the guest") session = kvm_test_utils.reboot(vm, session, method = "system_reset") else: raise error.TestFail("VM has quit abnormally during %s", (op, operand)) login_timeout = float(params.get("login_timeout", 240)) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm, 0, login_timeout, 0, 2) try: ports = {} r = random.SystemRandom() logging.info("Enumerate guest devices through /proc/ioports") ioports = session.cmd_output("cat /proc/ioports") logging.debug(ioports) devices = re.findall("(\w+)-(\w+)\ : (.*)", ioports) skip_devices = params.get("skip_devices","") fuzz_count = int(params.get("fuzz_count", 10)) for (beg, end, name) in devices:
def run_autotest(test, params, env): """ Run an autotest test inside a guest. @param test: kvm test object. @param params: Dictionary with test parameters. @param env: Dictionary with the test environment. """ # Helper functions def copy_if_size_differs(vm, local_path, remote_path): """ Copy a file to a guest if it doesn't exist or if its size differs. @param vm: VM object @param local_path: Local path @param remote_path: Remote path """ copy = False output = session.get_command_output("ls -l %s" % remote_path) if ("such file" in output or int(output.split()[4]) != os.path.getsize(local_path)): basename = os.path.basename(local_path) logging.info("Copying %s to guest (file is missing or has a " "different size)..." % basename) if not vm.copy_files_to(local_path, remote_path): raise error.TestFail("Could not copy %s to guest" % basename) def extract(vm, remote_path, dest_dir="."): """ Extract a .tar.bz2 file on the guest. @param vm: VM object @param remote_path: Remote file path @param dest_dir: Destination dir for the contents """ basename = os.path.basename(remote_path) logging.info("Extracting %s..." % basename) status = session.get_command_status("tar xfj %s -C %s" % (remote_path, dest_dir)) if status != 0: raise error.TestFail("Could not extract %s" % basename) vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) # Collect test parameters test_name = params.get("test_name") test_timeout = int(params.get("test_timeout", 300)) test_control_file = params.get("test_control_file", "control") tarred_autotest_path = "/tmp/autotest.tar.bz2" tarred_test_path = "/tmp/%s.tar.bz2" % test_name # tar the contents of bindir/autotest cmd = "cd %s; tar cvjf %s autotest/*" cmd += " --exclude=autotest/tests" cmd += " --exclude=autotest/results" cmd += " --exclude=autotest/tmp" cmd += " --exclude=autotest/control" cmd += " --exclude=*.pyc" cmd += " --exclude=*.svn" cmd += " --exclude=*.git" kvm_subprocess.run_fg(cmd % (test.bindir, tarred_autotest_path), timeout=30) # tar the contents of bindir/autotest/tests/<test_name> cmd = "cd %s; tar cvjf %s %s/*" cmd += " --exclude=*.pyc" cmd += " --exclude=*.svn" cmd += " --exclude=*.git" kvm_subprocess.run_fg(cmd % (os.path.join(test.bindir, "autotest", "tests"), tarred_test_path, test_name), timeout=30) # Copy autotest.tar.bz2 copy_if_size_differs(vm, tarred_autotest_path, "autotest.tar.bz2") # Copy <test_name>.tar.bz2 copy_if_size_differs(vm, tarred_test_path, test_name + ".tar.bz2") # Extract autotest.tar.bz2 extract(vm, "autotest.tar.bz2") # mkdir autotest/tests session.sendline("mkdir autotest/tests") # Extract <test_name>.tar.bz2 into autotest/tests extract(vm, test_name + ".tar.bz2", "autotest/tests") # Copy the selected control file (located inside # test.bindir/autotest_control) to the autotest dir control_file_path = os.path.join(test.bindir, "autotest_control", test_control_file) if not vm.copy_files_to(control_file_path, "autotest/control"): raise error.TestFail("Could not copy the test control file to guest") # Run the test logging.info("Running test '%s'..." % test_name) session.sendline("cd autotest") session.sendline("rm -f control.state") session.sendline("rm -rf results/*") session.read_up_to_prompt() logging.info("---------------- Test output ----------------") status = session.get_command_status("bin/autotest control", timeout=test_timeout, print_func=logging.info) logging.info("---------------- End of test output ----------------") if status is None: raise error.TestFail("Timeout elapsed while waiting for test to " "complete") # Get the results generated by autotest output = session.get_command_output("cat results/*/status") results = scan_results.parse_results(output) session.close # Copy test results to the local bindir/guest_results logging.info("Copying results back from guest...") guest_results_dir = os.path.join(test.outputdir, "guest_results") if not os.path.exists(guest_results_dir): os.mkdir(guest_results_dir) if not vm.copy_files_from("autotest/results/default/*", guest_results_dir): logging.error("Could not copy results back from guest") # Report test results logging.info("Results (test, status, duration, info):") for result in results: logging.info(str(result)) # Make a list of FAIL/ERROR/ABORT results (make sure FAIL results appear # before ERROR results, and ERROR results appear before ABORT results) bad_results = [r for r in results if r[1] == "FAIL"] bad_results += [r for r in results if r[1] == "ERROR"] bad_results += [r for r in results if r[1] == "ABORT"] # Fail the test if necessary if not results: raise error.TestFail("Test '%s' did not produce any recognizable " "results" % test_name) if bad_results: result = bad_results[0] raise error.TestFail("Test '%s' ended with %s (reason: '%s')" % (result[0], result[1], result[3]))
def run_jumbo(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. @param test: KVM test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) session = kvm_test_utils.wait_for_login(vm) mtu = params.get("mtu", "1500") flood_time = params.get("flood_time", "300") max_icmp_pkt_size = int(mtu) - 28 ifname = vm.get_ifname(0) ip = vm.get_address(0) if ip is None: raise error.TestError("Could not get the IP address") try: # Environment preparation ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0)) logging.info("Changing the MTU of guest ...") guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu) session.cmd(guest_mtu_cmd) logging.info("Chaning the MTU of host tap ...") host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu) utils.run(host_mtu_cmd) logging.info("Add a temporary static ARP entry ...") arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_mac_address(0), ifname) utils.run(arp_add_cmd) def is_mtu_ok(): s, o = kvm_test_utils.ping(ip, 1, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return s == 0 def verify_mtu(): logging.info("Verify the path MTU") s, o = kvm_test_utils.ping(ip, 10, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if s != 0 : logging.error(o) raise error.TestFail("Path MTU is not as expected") if kvm_test_utils.get_loss_ratio(o) != 0: logging.error(o) raise error.TestFail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") kvm_test_utils.ping(ip, interface=ifname, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") s, o = kvm_test_utils.ping(ip, count, interface=ifname, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = kvm_test_utils.get_loss_ratio(o) if ratio != 0: raise error.TestFail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s" % (ip, size)) s, o = kvm_test_utils.ping(ip, 1, interface=ifname, packetsize=size, hint="do", timeout=1) if s != 0: s, o = kvm_test_utils.ping(ip, 10, interface=ifname, packetsize=size, adaptive=True, hint="do", timeout=20) if kvm_test_utils.get_loss_ratio(o) > int(params.get( "fail_ratio", 50)): raise error.TestFail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not kvm_utils.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug(commands.getoutput("ifconfig -a")) raise error.TestError("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean session.close() logging.info("Removing the temporary ARP entry") utils.run("arp -d %s -i %s" % (ip, ifname))