def run_nic_promisc(test, params, env): """ Test nic driver in promisc mode: 1) Boot up a VM. 2) Repeatedly enable/disable promiscuous mode in guest. 3) Transfer file from host to guest, and from guest to host in the same time @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_serial = vm.wait_for_serial_login(timeout=timeout) ethname = virt_test_utils.get_linux_ifname(session_serial, vm.get_mac_address(0)) try: transfer_thread = virt_utils.Thread(file_transfer.run_file_transfer, (test, params, env)) transfer_thread.start() while transfer_thread.isAlive(): session_serial.cmd("ip link set %s promisc on" % ethname) session_serial.cmd("ip link set %s promisc off" % ethname) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join()
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 nic_bonding_guest.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. """ timeout = int(params.get("login_timeout", 1200)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session_serial = vm.wait_for_serial_login(timeout=timeout) # get params of bonding modprobe_cmd = "modprobe bonding" bonding_params = params.get("bonding_params") if bonding_params: modprobe_cmd += " %s" % bonding_params session_serial.cmd(modprobe_cmd) session_serial.cmd("ifconfig bond0 up") ifnames = [ virt_test_utils.get_linux_ifname(session_serial, vm.get_mac_address(vlan)) for vlan, nic in enumerate(params.get("nics").split()) ] setup_cmd = "ifenslave bond0 " + " ".join(ifnames) session_serial.cmd(setup_cmd) session_serial.cmd("dhclient bond0") try: logging.info("Test file transfering:") file_transfer.run_file_transfer(test, params, env) logging.info("Failover test with file transfer") transfer_thread = virt_utils.Thread(file_transfer.run_file_transfer, (test, params, env)) try: transfer_thread.start() while transfer_thread.isAlive(): for vlan, nic in enumerate(params.get("nics").split()): device_id = vm.get_peer(vm.netdev_id[vlan]) vm.monitor.cmd("set_link %s down" % device_id) time.sleep(1) vm.monitor.cmd("set_link %s up" % device_id) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join() finally: session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames)) session_serial.sendline("kill -9 `pgrep dhclient`")
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 = env.get_vm(params["main_vm"]) vm.verify_alive() session_serial = vm.wait_for_serial_login(timeout=timeout) ethname = virt_test_utils.get_linux_ifname(session_serial, vm.get_mac_address(0)) # get ethernet driver from '/sys' directory. # ethtool can do the same thing and doesn't care about os type. # if we make sure all guests have ethtool, we can make a change here. sys_path = params.get("sys_path") % (ethname) # readlink in RHEL4.8 doesn't have '-e' param, should use '-f' in RHEL4.8. readlink_cmd = params.get("readlink_command", "readlink -e") driver = os.path.basename( session_serial.cmd("%s %s" % (readlink_cmd, sys_path)).strip()) logging.info("driver is %s", driver) try: threads = [] for t in range(int(params.get("sessions_num", "10"))): thread = virt_utils.Thread(file_transfer.run_file_transfer, (test, params, env)) thread.start() threads.append(thread) time.sleep(10) while threads[0].isAlive(): session_serial.cmd("sleep 10") session_serial.cmd("ifconfig %s down" % ethname) session_serial.cmd("modprobe -r %s" % driver) session_serial.cmd("modprobe %s" % driver) session_serial.cmd("ifconfig %s up" % ethname) except: for thread in threads: thread.join(suppress_exception=True) raise else: for thread in threads: thread.join()
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 = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2 try: # Reboot the VM in the background bg = virt_utils.Thread(vm.reboot, (session, )) bg.start() try: while bg.isAlive(): vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay) except Exception: # If something bad happened in the main thread, ignore exceptions # raised in the background thread bg.join(suppress_exception=True) raise else: session = bg.join() 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) Transfer file from host to guest. 4) Repeatedly migrate VM and wait until transfer's finished. 5) Transfer file from guest back to host. 6) Repeatedly migrate VM and wait until transfer's finished. @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() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) mig_timeout = float(params.get("mig_timeout", "3600")) mig_protocol = params.get("migration_protocol", "tcp") mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2 host_path = "/tmp/file-%s" % virt_utils.generate_random_string(6) host_path_returned = "%s-returned" % host_path guest_path = params.get("guest_path", "/tmp/file") file_size = params.get("file_size", "500") transfer_timeout = int(params.get("transfer_timeout", "240")) try: utils.run("dd if=/dev/urandom of=%s bs=1M count=%s" % (host_path, file_size)) def run_and_migrate(bg): bg.start() try: while bg.isAlive(): logging.info( "File transfer not ended, starting a round of " "migration...") vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay) except: # If something bad happened in the main thread, ignore # exceptions raised in the background thread bg.join(suppress_exception=True) raise else: bg.join() error.context("transferring file to guest while migrating", logging.info) bg = virt_utils.Thread(vm.copy_files_to, (host_path, guest_path), dict(verbose=True, timeout=transfer_timeout)) run_and_migrate(bg) error.context("transferring file back to host while migrating", logging.info) bg = virt_utils.Thread(vm.copy_files_from, (guest_path, host_path_returned), dict(verbose=True, timeout=transfer_timeout)) run_and_migrate(bg) # Make sure the returned file is identical to the original one error.context("comparing hashes", logging.info) orig_hash = client_utils.hash_file(host_path) returned_hash = client_utils.hash_file(host_path_returned) if orig_hash != returned_hash: raise error.TestFail("Returned file hash (%s) differs from " "original one (%s)" % (returned_hash, orig_hash)) error.context() finally: session.close() if os.path.isfile(host_path): os.remove(host_path) if os.path.isfile(host_path_returned): os.remove(host_path_returned)
def run_netperf(test, params, env): """ Network stress test with netperf. 1) Boot up a VM with multiple nics. 2) Launch netserver on guest. 3) Execute multiple netperf clients on host in parallel with different protocols. 4) Output the test result. @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() login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) session.close() session_serial = vm.wait_for_serial_login(timeout=login_timeout) netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2") setup_cmd = params.get("setup_cmd") firewall_flush = "iptables -F" session_serial.cmd_output(firewall_flush) try: utils.run("iptables -F") except: pass for i in params.get("netperf_files").split(): vm.copy_files_to(os.path.join(netperf_dir, i), "/tmp") try: session_serial.cmd(firewall_flush) except aexpect.ShellError: logging.warning("Could not flush firewall rules on guest") session_serial.cmd(setup_cmd % "/tmp", timeout=200) session_serial.cmd(params.get("netserver_cmd") % "/tmp") if "tcpdump" in env and env["tcpdump"].is_alive(): # Stop the background tcpdump process try: logging.debug("Stopping the background tcpdump") env["tcpdump"].close() except: pass def netperf(i=0): guest_ip = vm.get_address(i) logging.info("Netperf_%s: netserver %s" % (i, guest_ip)) result_file = os.path.join(test.resultsdir, "output_%s_%s" % (test.iteration, i)) list_fail = [] result = open(result_file, "w") result.write("Netperf test results\n") for p in params.get("protocols").split(): packet_size = params.get("packet_size", "1500") for size in packet_size.split(): cmd = params.get("netperf_cmd") % (netperf_dir, p, guest_ip, size) logging.info("Netperf_%s: protocol %s" % (i, p)) try: netperf_output = utils.system_output(cmd, retain_output=True) result.write("%s\n" % netperf_output) except: logging.error("Test of protocol %s failed", p) list_fail.append(p) result.close() if list_fail: raise error.TestFail("Some netperf tests failed: %s" % ", ".join(list_fail)) try: logging.info("Setup and run netperf clients on host") utils.run(setup_cmd % netperf_dir) bg = [] nic_num = len(params.get("nics").split()) for i in range(nic_num): bg.append(virt_utils.Thread(netperf, (i, ))) bg[i].start() completed = False while not completed: completed = True for b in bg: if b.isAlive(): completed = False finally: try: for b in bg: if b: b.join() finally: session_serial.cmd_output("killall netserver")
def run_vmstop(test, params, env): """ KVM guest stop test: 1) Log into a guest 2) Copy a file into guest 3) Stop guest 4) Check the status through monitor 5) Check the session 6) Migrat the vm to a file twice and compare them. @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 = float(params.get("login_timeout", 240)) session = vm.wait_for_login(timeout=timeout) save_path = params.get("save_path", "/tmp") clean_save = params.get("clean_save") == "yes" save1 = os.path.join(save_path, "save1") save2 = os.path.join(save_path, "save2") guest_path = params.get("guest_path", "/tmp") file_size = params.get("file_size", "1000") try: utils.run("dd if=/dev/zero of=/tmp/file bs=1M count=%s" % file_size) # Transfer file from host to guest, we didn't expect the finish of # transfer, we just let it to be a kind of stress in guest. bg = virt_utils.Thread(vm.copy_files_to, ("/tmp/file", guest_path), dict(verbose=True, timeout=60)) logging.info("Start the background transfer") bg.start() try: # wait for the transfer start time.sleep(5) logging.info("Stop the VM") vm.monitor.cmd("stop") # check with monitor logging.info("Check the status through monitor") if "paused" not in vm.monitor.info("status"): raise error.TestFail("Guest did not pause after sending stop") # check through session logging.info("Check the session") if session.is_responsive(): raise error.TestFail("Session still alive after sending stop") # Check with the migration file logging.info("Save and check the state files") for p in [save1, save2]: vm.save_to_file(p) time.sleep(1) if not os.path.isfile(p): raise error.TestFail("VM failed to save state file %s" % p) # Fail if we see deltas md5_save1 = utils.hash_file(save1) md5_save2 = utils.hash_file(save2) if md5_save1 != md5_save2: raise error.TestFail("The produced state files differ") finally: bg.join(suppress_exception=True) finally: session.close() if clean_save: logging.debug("Clean the state files") if os.path.isfile(save1): os.remove(save1) if os.path.isfile(save2): os.remove(save2) vm.monitor.cmd("cont")