From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lucas Meneghel Rodrigues Subject: [PATCH 7/7] KVM test: Moving generic tests to common tests area Date: Wed, 9 Mar 2011 06:21:10 -0300 Message-ID: <1299662470-3017-8-git-send-email-lmr@redhat.com> References: <1299662470-3017-1-git-send-email-lmr@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org To: autotest@test.kernel.org Return-path: In-Reply-To: <1299662470-3017-1-git-send-email-lmr@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: autotest-bounces@test.kernel.org Errors-To: autotest-bounces@test.kernel.org List-Id: kvm.vger.kernel.org So other virt tests can benefit from them. The tests that don't depend on any KVM VM specific features (ie, monitors) were moved. As soon as we abstract some of the monitor functionality, the KVM specific tests can be rewritten on a virt tech agnostic way and then be moved. Signed-off-by: Lucas Meneghel Rodrigues --- client/tests/kvm/tests/autotest.py | 25 --- client/tests/kvm/tests/boot.py | 26 --- client/tests/kvm/tests/clock_getres.py | 37 ---- client/tests/kvm/tests/ethtool.py | 235 --------------------- client/tests/kvm/tests/file_transfer.py | 84 -------- client/tests/kvm/tests/guest_s4.py | 76 ------- client/tests/kvm/tests/guest_test.py | 80 ------- client/tests/kvm/tests/image_copy.py | 45 ---- client/tests/kvm/tests/iofuzz.py | 136 ------------ client/tests/kvm/tests/ioquit.py | 31 --- client/tests/kvm/tests/iozone_windows.py | 40 ---- client/tests/kvm/tests/jumbo.py | 127 ------------ client/tests/kvm/tests/kdump.py | 75 ------- client/tests/kvm/tests/linux_s3.py | 41 ---- client/tests/kvm/tests/mac_change.py | 60 ------ client/tests/kvm/tests/multicast.py | 90 -------- client/tests/kvm/tests/netperf.py | 90 -------- client/tests/kvm/tests/nic_promisc.py | 39 ---- client/tests/kvm/tests/nicdriver_unload.py | 56 ----- client/tests/kvm/tests/ping.py | 73 ------- client/tests/kvm/tests/pxe.py | 29 --- client/tests/kvm/tests/shutdown.py | 43 ---- client/tests/kvm/tests/stress_boot.py | 53 ----- client/tests/kvm/tests/vlan.py | 175 ---------------- client/tests/kvm/tests/whql_client_install.py | 136 ------------ client/tests/kvm/tests/whql_submission.py | 275 ------------------------- client/tests/kvm/tests/yum_update.py | 49 ----- client/virt/tests/autotest.py | 25 +++ client/virt/tests/boot.py | 26 +++ client/virt/tests/clock_getres.py | 37 ++++ client/virt/tests/ethtool.py | 235 +++++++++++++++++++++ client/virt/tests/file_transfer.py | 84 ++++++++ client/virt/tests/guest_s4.py | 76 +++++++ client/virt/tests/guest_test.py | 80 +++++++ client/virt/tests/image_copy.py | 45 ++++ client/virt/tests/iofuzz.py | 136 ++++++++++++ client/virt/tests/ioquit.py | 31 +++ client/virt/tests/iozone_windows.py | 40 ++++ client/virt/tests/jumbo.py | 127 ++++++++++++ client/virt/tests/kdump.py | 75 +++++++ client/virt/tests/linux_s3.py | 41 ++++ client/virt/tests/mac_change.py | 60 ++++++ client/virt/tests/multicast.py | 90 ++++++++ client/virt/tests/netperf.py | 90 ++++++++ client/virt/tests/nic_promisc.py | 39 ++++ client/virt/tests/nicdriver_unload.py | 56 +++++ client/virt/tests/ping.py | 73 +++++++ client/virt/tests/pxe.py | 29 +++ client/virt/tests/shutdown.py | 43 ++++ client/virt/tests/stress_boot.py | 53 +++++ client/virt/tests/vlan.py | 175 ++++++++++++++++ client/virt/tests/whql_client_install.py | 136 ++++++++++++ client/virt/tests/whql_submission.py | 275 +++++++++++++++++++++++++ client/virt/tests/yum_update.py | 49 +++++ 54 files changed, 2226 insertions(+), 2226 deletions(-) delete mode 100644 client/tests/kvm/tests/autotest.py delete mode 100644 client/tests/kvm/tests/boot.py delete mode 100644 client/tests/kvm/tests/clock_getres.py delete mode 100644 client/tests/kvm/tests/ethtool.py delete mode 100644 client/tests/kvm/tests/file_transfer.py delete mode 100644 client/tests/kvm/tests/guest_s4.py delete mode 100644 client/tests/kvm/tests/guest_test.py delete mode 100644 client/tests/kvm/tests/image_copy.py delete mode 100644 client/tests/kvm/tests/iofuzz.py delete mode 100644 client/tests/kvm/tests/ioquit.py delete mode 100644 client/tests/kvm/tests/iozone_windows.py delete mode 100644 client/tests/kvm/tests/jumbo.py delete mode 100644 client/tests/kvm/tests/kdump.py delete mode 100644 client/tests/kvm/tests/linux_s3.py delete mode 100644 client/tests/kvm/tests/mac_change.py delete mode 100644 client/tests/kvm/tests/multicast.py delete mode 100644 client/tests/kvm/tests/netperf.py delete mode 100644 client/tests/kvm/tests/nic_promisc.py delete mode 100644 client/tests/kvm/tests/nicdriver_unload.py delete mode 100644 client/tests/kvm/tests/ping.py delete mode 100644 client/tests/kvm/tests/pxe.py delete mode 100644 client/tests/kvm/tests/shutdown.py delete mode 100644 client/tests/kvm/tests/stress_boot.py delete mode 100644 client/tests/kvm/tests/vlan.py delete mode 100644 client/tests/kvm/tests/whql_client_install.py delete mode 100644 client/tests/kvm/tests/whql_submission.py delete mode 100644 client/tests/kvm/tests/yum_update.py create mode 100644 client/virt/tests/autotest.py create mode 100644 client/virt/tests/boot.py create mode 100644 client/virt/tests/clock_getres.py create mode 100644 client/virt/tests/ethtool.py create mode 100644 client/virt/tests/file_transfer.py create mode 100644 client/virt/tests/guest_s4.py create mode 100644 client/virt/tests/guest_test.py create mode 100644 client/virt/tests/image_copy.py create mode 100644 client/virt/tests/iofuzz.py create mode 100644 client/virt/tests/ioquit.py create mode 100644 client/virt/tests/iozone_windows.py create mode 100644 client/virt/tests/jumbo.py create mode 100644 client/virt/tests/kdump.py create mode 100644 client/virt/tests/linux_s3.py create mode 100644 client/virt/tests/mac_change.py create mode 100644 client/virt/tests/multicast.py create mode 100644 client/virt/tests/netperf.py create mode 100644 client/virt/tests/nic_promisc.py create mode 100644 client/virt/tests/nicdriver_unload.py create mode 100644 client/virt/tests/ping.py create mode 100644 client/virt/tests/pxe.py create mode 100644 client/virt/tests/shutdown.py create mode 100644 client/virt/tests/stress_boot.py create mode 100644 client/virt/tests/vlan.py create mode 100644 client/virt/tests/whql_client_install.py create mode 100644 client/virt/tests/whql_submission.py create mode 100644 client/virt/tests/yum_update.py diff --git a/client/tests/kvm/tests/autotest.py b/client/tests/kvm/tests/autotest.py deleted file mode 100644 index cdea31a..0000000 --- a/client/tests/kvm/tests/autotest.py +++ /dev/null @@ -1,25 +0,0 @@ -import os -from autotest_lib.client.virt import virt_test_utils - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(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 - - virt_test_utils.run_autotest(vm, session, control_path, timeout, outputdir, - params) diff --git a/client/tests/kvm/tests/boot.py b/client/tests/kvm/tests/boot.py deleted file mode 100644 index 4fabcd5..0000000 --- a/client/tests/kvm/tests/boot.py +++ /dev/null @@ -1,26 +0,0 @@ -import time - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = float(params.get("login_timeout", 240)) - session = vm.wait_for_login(timeout=timeout) - - if params.get("reboot_method"): - if params["reboot_method"] == "system_reset": - time.sleep(int(params.get("sleep_before_reset", 10))) - session = vm.reboot(session, params["reboot_method"], 0, timeout) - - session.close() diff --git a/client/tests/kvm/tests/clock_getres.py b/client/tests/kvm/tests/clock_getres.py deleted file mode 100644 index d1baf88..0000000 --- a/client/tests/kvm/tests/clock_getres.py +++ /dev/null @@ -1,37 +0,0 @@ -import logging, os -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - vm.copy_files_to(test_clock, base_dir) - session.cmd(os.path.join(base_dir, t_name)) - logging.info("PASS: Guest reported appropriate clock resolution") - logging.info("Guest's dmesg:\n%s", session.cmd_output("dmesg").strip()) diff --git a/client/tests/kvm/tests/ethtool.py b/client/tests/kvm/tests/ethtool.py deleted file mode 100644 index 1152f00..0000000 --- a/client/tests/kvm/tests/ethtool.py +++ /dev/null @@ -1,235 +0,0 @@ -import logging, re -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import virt_test_utils, virt_utils, aexpect - - -def run_ethtool(test, params, env): - """ - Test offload functions of ethernet device by ethtool - - 1) Log into a guest. - 2) Initialize the callback of sub functions. - 3) Enable/disable sub function of NIC. - 4) Execute callback function. - 5) Check the return value. - 6) Restore original configuration. - - @param test: KVM test object. - @param params: Dictionary with the test parameters. - @param env: Dictionary with test environment. - - @todo: Not all guests have ethtool installed, so - find a way to get it installed using yum/apt-get/ - whatever - """ - def ethtool_get(f_type): - feature_pattern = { - 'tx': 'tx.*checksumming', - 'rx': 'rx.*checksumming', - 'sg': 'scatter.*gather', - 'tso': 'tcp.*segmentation.*offload', - 'gso': 'generic.*segmentation.*offload', - 'gro': 'generic.*receive.*offload', - 'lro': 'large.*receive.*offload', - } - o = session.cmd("ethtool -k %s" % ethname) - try: - return re.findall("%s: (.*)" % feature_pattern.get(f_type), o)[0] - except IndexError: - logging.debug("Could not get %s status", f_type) - - - def ethtool_set(f_type, status): - """ - Set ethernet device offload status - - @param f_type: Offload type name - @param status: New status will be changed to - """ - logging.info("Try to set %s %s", f_type, status) - if status not in ["off", "on"]: - return False - cmd = "ethtool -K %s %s %s" % (ethname, f_type, status) - if ethtool_get(f_type) != status: - try: - session.cmd(cmd) - return True - except: - return False - if ethtool_get(f_type) != status: - logging.error("Fail to set %s %s", f_type, status) - return False - return True - - - def ethtool_save_params(): - logging.info("Save ethtool configuration") - for i in supported_features: - feature_status[i] = ethtool_get(i) - - - def ethtool_restore_params(): - logging.info("Restore ethtool configuration") - for i in supported_features: - ethtool_set(i, feature_status[i]) - - - def compare_md5sum(name): - logging.info("Compare md5sum of the files on guest and host") - host_result = utils.hash_file(name, method="md5") - try: - o = session.cmd_output("md5sum %s" % name) - guest_result = re.findall("\w+", o)[0] - except IndexError: - logging.error("Could not get file md5sum in guest") - return False - logging.debug("md5sum: guest(%s), host(%s)", guest_result, host_result) - return guest_result == host_result - - - def transfer_file(src="guest"): - """ - Transfer file by scp, use tcpdump to capture packets, then check the - return string. - - @param src: Source host of transfer file - @return: Tuple (status, error msg/tcpdump result) - """ - session2.cmd_output("rm -rf %s" % filename) - dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" % - (filename, params.get("filesize"))) - failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd) - logging.info("Creating file in source host, cmd: %s", dd_cmd) - tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh" - if src == "guest": - tcpdump_cmd += " and src %s" % guest_ip - copy_files_from = vm.copy_files_from - try: - session.cmd_output(dd_cmd, timeout=360) - except aexpect.ShellCmdError, e: - return failure - else: - tcpdump_cmd += " and dst %s" % guest_ip - copy_files_from = vm.copy_files_to - try: - utils.system(dd_cmd) - except error.CmdError, e: - return failure - - # only capture the new tcp port after offload setup - original_tcp_ports = re.findall("tcp.*:(\d+).*%s" % guest_ip, - utils.system_output("/bin/netstat -nap")) - for i in original_tcp_ports: - tcpdump_cmd += " and not port %s" % i - logging.debug("Listen using command: %s", tcpdump_cmd) - session2.sendline(tcpdump_cmd) - if not virt_utils.wait_for( - lambda:session.cmd_status("pgrep tcpdump") == 0, 30): - return (False, "Tcpdump process wasn't launched") - - logging.info("Start to transfer file") - try: - copy_files_from(filename, filename) - except virt_utils.SCPError, e: - return (False, "File transfer failed (%s)" % e) - logging.info("Transfer file completed") - session.cmd("killall tcpdump") - try: - tcpdump_string = session2.read_up_to_prompt(timeout=60) - except aexpect.ExpectError: - return (False, "Fail to read tcpdump's output") - - if not compare_md5sum(filename): - return (False, "Files' md5sum mismatched") - return (True, tcpdump_string) - - - def tx_callback(status="on"): - s, o = transfer_file(src="guest") - if not s: - logging.error(o) - return False - return True - - - def rx_callback(status="on"): - s, o = transfer_file(src="host") - if not s: - logging.error(o) - return False - return True - - - def so_callback(status="on"): - s, o = transfer_file(src="guest") - if not s: - logging.error(o) - return False - logging.info("Check if contained large frame") - # MTU: default IPv4 MTU is 1500 Bytes, ethernet header is 14 Bytes - return (status == "on") ^ (len([i for i in re.findall( - "length (\d*):", o) if int(i) > mtu]) == 0) - - - def ro_callback(status="on"): - s, o = transfer_file(src="host") - if not s: - logging.error(o) - return False - return True - - - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() - session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - # Let's just error the test if we identify that there's no ethtool installed - session.cmd("ethtool -h") - session2 = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - mtu = 1514 - feature_status = {} - filename = "/tmp/ethtool.dd" - guest_ip = vm.get_address() - ethname = virt_test_utils.get_linux_ifname(session, vm.get_mac_address(0)) - supported_features = params.get("supported_features") - if supported_features: - supported_features = supported_features.split() - else: - supported_features = [] - test_matrix = { - # type:(callback, (dependence), (exclude) - "tx": (tx_callback, (), ()), - "rx": (rx_callback, (), ()), - "sg": (tx_callback, ("tx",), ()), - "tso": (so_callback, ("tx", "sg",), ("gso",)), - "gso": (so_callback, (), ("tso",)), - "gro": (ro_callback, ("rx",), ("lro",)), - "lro": (rx_callback, (), ("gro",)), - } - ethtool_save_params() - success = True - try: - for f_type in supported_features: - callback = test_matrix[f_type][0] - for i in test_matrix[f_type][2]: - if not ethtool_set(i, "off"): - logging.error("Fail to disable %s", i) - success = False - for i in [f for f in test_matrix[f_type][1]] + [f_type]: - if not ethtool_set(i, "on"): - logging.error("Fail to enable %s", i) - success = False - if not callback(): - raise error.TestFail("Test failed, %s: on", f_type) - - if not ethtool_set(f_type, "off"): - logging.error("Fail to disable %s", f_type) - success = False - if not callback(status="off"): - raise error.TestFail("Test failed, %s: off", f_type) - if not success: - raise error.TestError("Enable/disable offload function fail") - finally: - ethtool_restore_params() - session.close() - session2.close() diff --git a/client/tests/kvm/tests/file_transfer.py b/client/tests/kvm/tests/file_transfer.py deleted file mode 100644 index 5f6672d..0000000 --- a/client/tests/kvm/tests/file_transfer.py +++ /dev/null @@ -1,84 +0,0 @@ -import logging, time, os -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import virt_utils - - -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 = 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) - - 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 - - host_path = os.path.join(dir_name, "tmp-%s" % - virt_utils.generate_random_string(8)) - host_path2 = host_path + ".2" - cmd = "dd if=/dev/zero of=%s bs=10M count=%d" % (host_path, count) - guest_path = (tmp_dir + "file_transfer-%s" % - virt_utils.generate_random_string(8)) - - 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() - vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout) - t_end = time.time() - throughput = filesize / (t_end - t_begin) - 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() - vm.copy_files_from(guest_path, host_path2, timeout=transfer_timeout) - t_end = time.time() - throughput = filesize / (t_end - t_begin) - logging.info("File transfer guest -> host succeed, " - "estimated throughput: %.2fMB/s", throughput) - else: - raise error.TestError("Unknown test file transfer mode %s" % - transfer_type) - - if (utils.hash_file(host_path, method="md5") != - utils.hash_file(host_path2, method="md5")): - raise error.TestFail("File changed after transfer host -> guest " - "and guest -> host") - - finally: - logging.info('Cleaning temp file on guest') - session.cmd("rm -rf %s" % guest_path) - logging.info('Cleaning temp files on host') - try: - os.remove(host_path) - os.remove(host_path2) - except OSError: - pass - session.close() diff --git a/client/tests/kvm/tests/guest_s4.py b/client/tests/kvm/tests/guest_s4.py deleted file mode 100644 index 5b5708d..0000000 --- a/client/tests/kvm/tests/guest_s4.py +++ /dev/null @@ -1,76 +0,0 @@ -import logging, time -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils - - -@error.context_aware -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. - """ - error.base_context("before S4") - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - - error.context("checking whether guest OS supports S4", logging.info) - session.cmd(params.get("check_s4_support_cmd")) - error.context() - - 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 = vm.wait_for_login(timeout=timeout) - - # Make sure the background program is running as expected - error.context("making sure background program is running") - check_s4_cmd = params.get("check_s4_cmd") - session2.cmd(check_s4_cmd) - logging.info("Launched background command in guest: %s", test_s4_cmd) - error.context() - error.base_context() - - # Suspend to disk - logging.info("Starting suspend to disk now...") - session2.sendline(params.get("set_s4_cmd")) - - # Make sure the VM goes down - error.base_context("after S4") - suspend_timeout = 240 + int(params.get("smp")) * 60 - if not virt_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...") - vm.create() - - # Log into the resumed VM - relogin_timeout = int(params.get("relogin_timeout", 240)) - logging.info("Logging into resumed VM, timeout %s", relogin_timeout) - session2 = vm.wait_for_login(timeout=relogin_timeout) - - # Check whether the test command is still alive - error.context("making sure background program is still running", - logging.info) - session2.cmd(check_s4_cmd) - error.context() - - logging.info("VM resumed successfuly after suspend to disk") - session2.cmd_output(params.get("kill_test_s4_cmd")) - session.close() - session2.close() diff --git a/client/tests/kvm/tests/guest_test.py b/client/tests/kvm/tests/guest_test.py deleted file mode 100644 index 3bc7da7..0000000 --- a/client/tests/kvm/tests/guest_test.py +++ /dev/null @@ -1,80 +0,0 @@ -import os, logging -from autotest_lib.client.virt import virt_utils - - -def run_guest_test(test, params, env): - """ - A wrapper for running customized tests in guests. - - 1) Log into a guest. - 2) Run 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. - """ - login_timeout = int(params.get("login_timeout", 360)) - reboot = params.get("reboot", "no") - - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() - if params.get("serial_login") == "yes": - session = vm.wait_for_serial_login(timeout=login_timeout) - else: - session = vm.wait_for_login(timeout=login_timeout) - - if reboot == "yes": - logging.debug("Rebooting guest before test ...") - session = vm.reboot(session, timeout=login_timeout) - - try: - logging.info("Starting script...") - - # Collect test parameters - interpreter = params.get("interpreter") - script = params.get("guest_script") - dst_rsc_path = params.get("dst_rsc_path", "script.au3") - script_params = params.get("script_params", "") - test_timeout = float(params.get("test_timeout", 600)) - - logging.debug("Starting preparing resouce files...") - # Download the script resource from a remote server, or - # prepare the script using rss? - if params.get("download") == "yes": - download_cmd = params.get("download_cmd") - rsc_server = params.get("rsc_server") - rsc_dir = os.path.basename(rsc_server) - dst_rsc_dir = params.get("dst_rsc_dir") - - # Change dir to dst_rsc_dir, and remove the guest script dir there - rm_cmd = "cd %s && (rmdir /s /q %s || del /s /q %s)" % \ - (dst_rsc_dir, rsc_dir, rsc_dir) - session.cmd(rm_cmd, timeout=test_timeout) - logging.debug("Clean directory succeeded.") - - # then download the resource. - rsc_cmd = "cd %s && %s %s" % (dst_rsc_dir, download_cmd, rsc_server) - session.cmd(rsc_cmd, timeout=test_timeout) - logging.info("Download resource finished.") - else: - session.cmd_output("del %s" % dst_rsc_path, internal_timeout=0) - script_path = virt_utils.get_path(test.bindir, script) - vm.copy_files_to(script_path, dst_rsc_path, timeout=60) - - cmd = "%s %s %s" % (interpreter, dst_rsc_path, script_params) - - try: - logging.info("------------ Script output ------------") - session.cmd(cmd, print_func=logging.info, timeout=test_timeout) - finally: - logging.info("------------ End of script output ------------") - - if reboot == "yes": - logging.debug("Rebooting guest after test ...") - session = vm.reboot(session, timeout=login_timeout) - - logging.debug("guest test PASSED.") - finally: - session.close() diff --git a/client/tests/kvm/tests/image_copy.py b/client/tests/kvm/tests/image_copy.py deleted file mode 100644 index cc921ab..0000000 --- a/client/tests/kvm/tests/image_copy.py +++ /dev/null @@ -1,45 +0,0 @@ -import os, logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import virt_utils - - -def run_image_copy(test, params, env): - """ - Copy guest images from nfs server. - 1) Mount the NFS share directory - 2) Check the existence of source image - 3) If it exists, copy the image from NFS - - @param test: kvm test object - @param params: Dictionary with the test parameters - @param env: Dictionary with test environment. - """ - mount_dest_dir = params.get('dst_dir', '/mnt/images') - if not os.path.exists(mount_dest_dir): - try: - os.makedirs(mount_dest_dir) - except OSError, err: - logging.warning('mkdir %s error:\n%s', mount_dest_dir, err) - - if not os.path.exists(mount_dest_dir): - raise error.TestError('Failed to create NFS share dir %s' % - mount_dest_dir) - - src = params.get('images_good') - image = '%s.%s' % (os.path.split(params['image_name'])[1], - params['image_format']) - src_path = os.path.join(mount_dest_dir, image) - dst_path = '%s.%s' % (params['image_name'], params['image_format']) - cmd = 'cp %s %s' % (src_path, dst_path) - - if not virt_utils.mount(src, mount_dest_dir, 'nfs', 'ro'): - raise error.TestError('Could not mount NFS share %s to %s' % - (src, mount_dest_dir)) - - # Check the existence of source image - if not os.path.exists(src_path): - raise error.TestError('Could not find %s in NFS share' % src_path) - - logging.debug('Copying image %s...', image) - utils.system(cmd) diff --git a/client/tests/kvm/tests/iofuzz.py b/client/tests/kvm/tests/iofuzz.py deleted file mode 100644 index d244012..0000000 --- a/client/tests/kvm/tests/iofuzz.py +++ /dev/null @@ -1,136 +0,0 @@ -import logging, re, random -from autotest_lib.client.common_lib import error, aexpect -from autotest_lib.client.virt import aexpect - - -def run_iofuzz(test, params, env): - """ - KVM iofuzz test: - 1) Log into a guest - 2) Enumerate all IO port ranges through /proc/ioports - 3) On each port of the range: - * Read it - * Write 0 to it - * Write a random value to a random port on a random order - - If the guest SSH session hangs, the test detects the hang and the guest - is then rebooted. The test fails if we detect the qemu process to terminate - while executing the process. - - @param test: kvm test object - @param params: Dictionary with the test parameters - @param env: Dictionary with test environment. - """ - def outb(session, port, data): - """ - Write data to a given port. - - @param session: SSH session stablished to a VM - @param port: Port where we'll write the data - @param data: Integer value that will be written on the port. This - value will be converted to octal before its written. - """ - logging.debug("outb(0x%x, 0x%x)", port, data) - outb_cmd = ("echo -e '\\%s' | dd of=/dev/port seek=%d bs=1 count=1" % - (oct(data), port)) - try: - session.cmd(outb_cmd) - except aexpect.ShellError, e: - logging.debug(e) - - - def inb(session, port): - """ - Read from a given port. - - @param session: SSH session stablished to a VM - @param port: Port where we'll read data - """ - logging.debug("inb(0x%x)", port) - inb_cmd = "dd if=/dev/port seek=%d of=/dev/null bs=1 count=1" % port - try: - session.cmd(inb_cmd) - except aexpect.ShellError, e: - logging.debug(e) - - - def fuzz(session, inst_list): - """ - Executes a series of read/write/randwrite instructions. - - If the guest SSH session hangs, an attempt to relogin will be made. - If it fails, the guest will be reset. If during the process the VM - process abnormally ends, the test fails. - - @param inst_list: List of instructions that will be executed. - @raise error.TestFail: If the VM process dies in the middle of the - fuzzing procedure. - """ - for (op, operand) in inst_list: - if op == "read": - inb(session, operand[0]) - elif op == "write": - outb(session, operand[0], operand[1]) - else: - raise error.TestError("Unknown command %s" % op) - - if not session.is_responsive(): - logging.debug("Session is not responsive") - if vm.process.is_alive(): - logging.debug("VM is alive, try to re-login") - try: - session = vm.wait_for_login(timeout=10) - except: - logging.debug("Could not re-login, reboot the guest") - session = vm.reboot(method="system_reset") - else: - raise error.TestFail("VM has quit abnormally during %s", - (op, operand)) - - - login_timeout = float(params.get("login_timeout", 240)) - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() - session = vm.wait_for_login(timeout=login_timeout) - - 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: - ports[(int(beg, base=16), int(end, base=16))] = name.strip() - - for (beg, end) in ports.keys(): - name = ports[(beg, end)] - if name in skip_devices: - logging.info("Skipping device %s", name) - continue - - logging.info("Fuzzing %s, port range 0x%x-0x%x", name, beg, end) - inst = [] - - # Read all ports of the range - for port in range(beg, end + 1): - inst.append(("read", [port])) - - # Write 0 to all ports of the range - for port in range(beg, end + 1): - inst.append(("write", [port, 0])) - - # Write random values to random ports of the range - for seq in range(fuzz_count * (end - beg + 1)): - inst.append(("write", - [r.randint(beg, end), r.randint(0,255)])) - - fuzz(session, inst) - - finally: - session.close() diff --git a/client/tests/kvm/tests/ioquit.py b/client/tests/kvm/tests/ioquit.py deleted file mode 100644 index 34b4fb5..0000000 --- a/client/tests/kvm/tests/ioquit.py +++ /dev/null @@ -1,31 +0,0 @@ -import logging, time, random - - -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 = 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) - session2 = vm.wait_for_login(timeout=login_timeout) - 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() diff --git a/client/tests/kvm/tests/iozone_windows.py b/client/tests/kvm/tests/iozone_windows.py deleted file mode 100644 index 4046106..0000000 --- a/client/tests/kvm/tests/iozone_windows.py +++ /dev/null @@ -1,40 +0,0 @@ -import logging, os -from autotest_lib.client.bin import utils -from autotest_lib.client.tests.iozone import postprocessing - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(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(cmd=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() diff --git a/client/tests/kvm/tests/jumbo.py b/client/tests/kvm/tests/jumbo.py deleted file mode 100644 index 5108227..0000000 --- a/client/tests/kvm/tests/jumbo.py +++ /dev/null @@ -1,127 +0,0 @@ -import logging, commands, random -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import virt_utils, virt_test_utils - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - 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 = virt_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 = virt_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 = virt_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 virt_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") - virt_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 = virt_test_utils.ping(ip, count, interface=ifname, - packetsize=max_icmp_pkt_size, - timeout=float(count) * 2) - ratio = virt_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 = virt_test_utils.ping(ip, 1, interface=ifname, - packetsize=size, - hint="do", timeout=1) - if s != 0: - s, o = virt_test_utils.ping(ip, 10, interface=ifname, - packetsize=size, - adaptive=True, hint="do", - timeout=20) - - if virt_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 virt_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)) diff --git a/client/tests/kvm/tests/kdump.py b/client/tests/kvm/tests/kdump.py deleted file mode 100644 index 90c004b..0000000 --- a/client/tests/kvm/tests/kdump.py +++ /dev/null @@ -1,75 +0,0 @@ -import logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils - - -def run_kdump(test, params, env): - """ - KVM reboot test: - 1) Log into a guest - 2) Check and enable the kdump - 3) For each vcpu, trigger a crash and check the vmcore - - @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)) - crash_timeout = float(params.get("crash_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - def_kernel_param_cmd = ("grubby --update-kernel=`grubby --default-kernel`" - " --args=crashkernel=128M") - kernel_param_cmd = params.get("kernel_param_cmd", def_kernel_param_cmd) - def_kdump_enable_cmd = "chkconfig kdump on && service kdump start" - kdump_enable_cmd = params.get("kdump_enable_cmd", def_kdump_enable_cmd) - def_crash_kernel_prob_cmd = "grep -q 1 /sys/kernel/kexec_crash_loaded" - crash_kernel_prob_cmd = params.get("crash_kernel_prob_cmd", - def_crash_kernel_prob_cmd) - - def crash_test(vcpu): - """ - Trigger a crash dump through sysrq-trigger - - @param vcpu: vcpu which is used to trigger a crash - """ - session = vm.wait_for_login(timeout=timeout) - session.cmd_output("rm -rf /var/crash/*") - - logging.info("Triggering crash on vcpu %d ...", vcpu) - crash_cmd = "taskset -c %d echo c > /proc/sysrq-trigger" % vcpu - 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 on vcpu %d" % vcpu) - - logging.info("Waiting for kernel crash dump to complete") - session = vm.wait_for_login(timeout=crash_timeout) - - logging.info("Probing vmcore file...") - session.cmd("ls -R /var/crash | grep vmcore") - logging.info("Found vmcore.") - - session.cmd_output("rm -rf /var/crash/*") - - try: - logging.info("Checking the existence of crash kernel...") - try: - session.cmd(crash_kernel_prob_cmd) - except: - logging.info("Crash kernel is not loaded. Trying to load it") - session.cmd(kernel_param_cmd) - session = vm.reboot(session, timeout=timeout) - - logging.info("Enabling kdump service...") - # the initrd may be rebuilt here so we need to wait a little more - session.cmd(kdump_enable_cmd, timeout=120) - - nvcpu = int(params.get("smp", 1)) - for i in range (nvcpu): - crash_test(i) - - finally: - session.close() diff --git a/client/tests/kvm/tests/linux_s3.py b/client/tests/kvm/tests/linux_s3.py deleted file mode 100644 index 5a04fca..0000000 --- a/client/tests/kvm/tests/linux_s3.py +++ /dev/null @@ -1,41 +0,0 @@ -import logging, time -from autotest_lib.client.common_lib import error - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(timeout=timeout) - - logging.info("Checking that VM supports S3") - session.cmd("grep -q mem /sys/power/state") - - logging.info("Waiting for a while for X to start") - time.sleep(10) - - src_tty = session.cmd_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) - suspend_timeout = 120 + int(params.get("smp")) * 60 - session.cmd(command, timeout=suspend_timeout) - - logging.info("VM resumed after S3") - - session.close() diff --git a/client/tests/kvm/tests/mac_change.py b/client/tests/kvm/tests/mac_change.py deleted file mode 100644 index d2eaf01..0000000 --- a/client/tests/kvm/tests/mac_change.py +++ /dev/null @@ -1,60 +0,0 @@ -import logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils, virt_test_utils - - -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. - """ - 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) - # This session will be used to assess whether the IP change worked - session = vm.wait_for_login(timeout=timeout) - old_mac = vm.get_mac_address(0) - while True: - vm.free_mac_address(0) - new_mac = virt_utils.generate_mac_address(vm.instance, 0) - if old_mac != new_mac: - break - logging.info("The initial MAC address is %s", old_mac) - interface = virt_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 virt_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 = vm.wait_for_login(timeout=timeout) - if not session.is_responsive(): - raise error.TestFail("The new session is not responsive.") - - session.close() diff --git a/client/tests/kvm/tests/multicast.py b/client/tests/kvm/tests/multicast.py deleted file mode 100644 index 13e3f0d..0000000 --- a/client/tests/kvm/tests/multicast.py +++ /dev/null @@ -1,90 +0,0 @@ -import logging, os, re -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import virt_test_utils, aexpect - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - - def run_guest(cmd): - try: - session.cmd(cmd) - except aexpect.ShellError, e: - logging.warn(e) - - def run_host_guest(cmd): - run_guest(cmd) - utils.system(cmd, ignore_status=True) - - # flush the firewall rules - cmd_flush = "iptables -F" - cmd_selinux = ("if [ -e /selinux/enforce ]; then setenforce 0; " - "else echo 'no /selinux/enforce file present'; fi") - run_host_guest(cmd_flush) - run_host_guest(cmd_selinux) - # make sure guest replies to broadcasts - cmd_broadcast = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts" - cmd_broadcast_2 = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all" - run_guest(cmd_broadcast) - run_guest(cmd_broadcast_2) - - # base multicast address - mcast = params.get("mcast", "225.0.0.1") - # count of multicast addresses, less than 20 - mgroup_count = int(params.get("mgroup_count", 5)) - flood_minutes = float(params.get("flood_minutes", 10)) - ifname = vm.get_ifname() - prefix = re.findall("\d+.\d+.\d+", mcast)[0] - suffix = int(re.findall("\d+", mcast)[-1]) - # copy python script to guest for joining guest to multicast groups - mcast_path = os.path.join(test.bindir, "scripts/multicast_guest.py") - vm.copy_files_to(mcast_path, "/tmp") - output = session.cmd_output("python /tmp/multicast_guest.py %d %s %d" % - (mgroup_count, prefix, suffix)) - - # if success to join multicast, the process will be paused, and return PID. - try: - pid = re.findall("join_mcast_pid:(\d+)", output)[0] - except IndexError: - raise error.TestFail("Can't join multicast groups,output:%s" % output) - - try: - for i in range(mgroup_count): - new_suffix = suffix + i - mcast = "%s.%d" % (prefix, new_suffix) - - logging.info("Initial ping test, mcast: %s", mcast) - s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) - if s != 0: - raise error.TestFail(" Ping return non-zero value %s" % o) - - logging.info("Flood ping test, mcast: %s", mcast) - virt_test_utils.ping(mcast, None, interface=ifname, flood=True, - output_func=None, timeout=flood_minutes*60) - - logging.info("Final ping test, mcast: %s", mcast) - s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) - if s != 0: - raise error.TestFail("Ping failed, status: %s, output: %s" % - (s, o)) - - finally: - logging.debug(session.cmd_output("ipmaddr show")) - session.cmd_output("kill -s SIGCONT %s" % pid) - session.close() diff --git a/client/tests/kvm/tests/netperf.py b/client/tests/kvm/tests/netperf.py deleted file mode 100644 index 72d9cde..0000000 --- a/client/tests/kvm/tests/netperf.py +++ /dev/null @@ -1,90 +0,0 @@ -import logging, os, signal -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.virt import aexpect - -def run_netperf(test, params, env): - """ - Network stress test with netperf. - - 1) Boot up a VM. - 2) Launch netserver on guest. - 3) Execute netperf client on host 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_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") - guest_ip = vm.get_address() - result_file = os.path.join(test.resultsdir, "output_%s" % test.iteration) - - 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") - - tcpdump = env.get("tcpdump") - pid = None - if tcpdump: - # Stop the background tcpdump process - try: - pid = int(utils.system_output("pidof tcpdump")) - logging.debug("Stopping the background tcpdump") - os.kill(pid, signal.SIGSTOP) - except: - pass - - try: - logging.info("Setup and run netperf client on host") - utils.run(setup_cmd % netperf_dir) - list_fail = [] - result = open(result_file, "w") - result.write("Netperf test results\n") - - for i 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, i, - guest_ip, size) - logging.info("Netperf: protocol %s", i) - try: - netperf_output = utils.system_output(cmd, - retain_output=True) - result.write("%s\n" % netperf_output) - except: - logging.error("Test of protocol %s failed", i) - list_fail.append(i) - - result.close() - - if list_fail: - raise error.TestFail("Some netperf tests failed: %s" % - ", ".join(list_fail)) - - finally: - session_serial.cmd_output("killall netserver") - if tcpdump and pid: - logging.debug("Resuming the background tcpdump") - logging.info("pid is %s" % pid) - os.kill(pid, signal.SIGCONT) diff --git a/client/tests/kvm/tests/nic_promisc.py b/client/tests/kvm/tests/nic_promisc.py deleted file mode 100644 index 0ff07b8..0000000 --- a/client/tests/kvm/tests/nic_promisc.py +++ /dev/null @@ -1,39 +0,0 @@ -import logging, threading -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.tests.kvm.tests import file_transfer -from autotest_lib.client.virt import virt_test_utils, virt_utils - - -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: - transfer_thread.join(suppress_exception=True) - raise - else: - transfer_thread.join() diff --git a/client/tests/kvm/tests/nicdriver_unload.py b/client/tests/kvm/tests/nicdriver_unload.py deleted file mode 100644 index 6d3d4da..0000000 --- a/client/tests/kvm/tests/nicdriver_unload.py +++ /dev/null @@ -1,56 +0,0 @@ -import logging, threading, os, time -from autotest_lib.client.common_lib import error -from autotest_lib.client.bin import utils -from autotest_lib.client.tests.kvm.tests import file_transfer -from autotest_lib.client.virt import virt_test_utils, virt_utils - - -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)) - sys_path = "/sys/class/net/%s/device/driver" % (ethname) - driver = os.path.basename(session_serial.cmd("readlink -e %s" % - 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() - diff --git a/client/tests/kvm/tests/ping.py b/client/tests/kvm/tests/ping.py deleted file mode 100644 index 08791fb..0000000 --- a/client/tests/kvm/tests/ping.py +++ /dev/null @@ -1,73 +0,0 @@ -import logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_test_utils - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - - 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: %s", - i, nic) - continue - - for size in packet_size: - logging.info("Ping with packet size %s", size) - status, output = virt_test_utils.ping(ip, 10, - packetsize=size, - timeout=20) - if strict_check: - ratio = virt_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") - virt_test_utils.ping(ip, None, flood=True, output_func=None, - timeout=flood_minutes * 60) - - logging.info("Final ping test") - status, output = virt_test_utils.ping(ip, counts, - timeout=float(counts) * 1.5) - if strict_check: - ratio = virt_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() diff --git a/client/tests/kvm/tests/pxe.py b/client/tests/kvm/tests/pxe.py deleted file mode 100644 index 325e353..0000000 --- a/client/tests/kvm/tests/pxe.py +++ /dev/null @@ -1,29 +0,0 @@ -import logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import aexpect - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("pxe_timeout", 60)) - - logging.info("Try to boot from PXE") - output = aexpect.run_fg("tcpdump -nli %s" % vm.get_ifname(), - logging.debug, "(pxe capture) ", timeout)[1] - - 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") diff --git a/client/tests/kvm/tests/shutdown.py b/client/tests/kvm/tests/shutdown.py deleted file mode 100644 index ac41a4a..0000000 --- a/client/tests/kvm/tests/shutdown.py +++ /dev/null @@ -1,43 +0,0 @@ -import logging, time -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(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 virt_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() diff --git a/client/tests/kvm/tests/stress_boot.py b/client/tests/kvm/tests/stress_boot.py deleted file mode 100644 index e3ac14d..0000000 --- a/client/tests/kvm/tests/stress_boot.py +++ /dev/null @@ -1,53 +0,0 @@ -import logging -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_env_process - - -@error.context_aware -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)) diff --git a/client/tests/kvm/tests/vlan.py b/client/tests/kvm/tests/vlan.py deleted file mode 100644 index 9fc1f64..0000000 --- a/client/tests/kvm/tests/vlan.py +++ /dev/null @@ -1,175 +0,0 @@ -import logging, time, re -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils, virt_test_utils, aexpect - - -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(env.get_vm(params["main_vm"])) - vm.append(env.get_vm("vm2")) - for vm_ in vm: - vm_.verify_alive() - - def add_vlan(session, v_id, iface="eth0"): - session.cmd("vconfig add %s %s" % (iface, v_id)) - - def set_ip_vlan(session, v_id, ip, iface="eth0"): - iface = "%s.%s" % (iface, v_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, v_id, iface="eth0"): - rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi" - iface = "%s.%s" % (iface, v_id) - return session.cmd_status(rem_vlan_cmd % (iface, iface)) - - def nc_transfer(src, dst): - nc_port = virt_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 aexpect.ExpectError: - raise error.TestFail ("Fail to receive file" - " from vm%s to vm%s" % (src+1, dst+1)) - #check MD5 message digest of receive file in dst - output = session[dst].cmd_output("md5sum receive").strip() - digest_receive = re.findall(r'(\w+)', output)[0] - if digest_receive == digest_origin[src]: - logging.info("file succeed received in vm %s", vlan_ip[dst]) - else: - logging.info("digest_origin is %s", digest_origin[src]) - logging.info("digest_receive is %s", digest_receive) - raise error.TestFail("File transfered differ from origin") - session[dst].cmd_output("rm -f receive") - - for i in range(2): - session.append(vm[i].wait_for_login( - 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(virt_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 = virt_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 aexpect - # does not have the other method to interrupt the process in - # the guest rather than close the session. - session_flood = vm[src].wait_for_login(timeout=60) - virt_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 number 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() diff --git a/client/tests/kvm/tests/whql_client_install.py b/client/tests/kvm/tests/whql_client_install.py deleted file mode 100644 index 2d72a5e..0000000 --- a/client/tests/kvm/tests/whql_client_install.py +++ /dev/null @@ -1,136 +0,0 @@ -import logging, time, os -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils, virt_test_utils, rss_client - - -def run_whql_client_install(test, params, env): - """ - WHQL DTM client installation: - 1) Log into the guest (the client machine) and into a DTM server machine - 2) Stop the DTM client service (wttsvc) on the client machine - 3) Delete the client machine from the server's data store - 4) Rename the client machine (give it a randomly generated name) - 5) Move the client machine into the server's workgroup - 6) Reboot the client machine - 7) Install the DTM client software - 8) Setup auto logon for the user created by the installation - (normally DTMLLUAdminUser) - 9) Reboot again - - @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() - session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - - # Collect test params - server_address = params.get("server_address") - server_shell_port = int(params.get("server_shell_port")) - server_file_transfer_port = int(params.get("server_file_transfer_port")) - server_studio_path = params.get("server_studio_path", "%programfiles%\\ " - "Microsoft Driver Test Manager\\Studio") - server_username = params.get("server_username") - server_password = params.get("server_password") - client_username = params.get("client_username") - client_password = params.get("client_password") - dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", - "deps/whql_delete_machine_15.exe") - dsso_delete_machine_binary = virt_utils.get_path(test.bindir, - dsso_delete_machine_binary) - install_timeout = float(params.get("install_timeout", 600)) - install_cmd = params.get("install_cmd") - wtt_services = params.get("wtt_services") - - # Stop WTT service(s) on client - for svc in wtt_services.split(): - virt_test_utils.stop_windows_service(session, svc) - - # Copy dsso_delete_machine_binary to server - rss_client.upload(server_address, server_file_transfer_port, - dsso_delete_machine_binary, server_studio_path, - timeout=60) - - # Open a shell session with server - server_session = virt_utils.remote_login("nc", server_address, - server_shell_port, "", "", - session.prompt, session.linesep) - server_session.set_status_test_command(session.status_test_command) - - # Get server and client information - cmd = "echo %computername%" - server_name = server_session.cmd_output(cmd).strip() - client_name = session.cmd_output(cmd).strip() - cmd = "wmic computersystem get domain" - server_workgroup = server_session.cmd_output(cmd).strip() - server_workgroup = server_workgroup.splitlines()[-1] - regkey = r"HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" - cmd = "reg query %s /v Domain" % regkey - o = server_session.cmd_output(cmd).strip().splitlines()[-1] - try: - server_dns_suffix = o.split(None, 2)[2] - except IndexError: - server_dns_suffix = "" - - # Delete the client machine from the server's data store (if it's there) - server_session.cmd("cd %s" % server_studio_path) - cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), - server_name, client_name) - server_session.cmd(cmd, print_func=logging.info) - server_session.close() - - # Rename the client machine - client_name = "autotest_%s" % virt_utils.generate_random_string(4) - logging.info("Renaming client machine to '%s'", client_name) - cmd = ('wmic computersystem where name="%%computername%%" rename name="%s"' - % client_name) - session.cmd(cmd, timeout=600) - - # Join the server's workgroup - logging.info("Joining workgroup '%s'", server_workgroup) - cmd = ('wmic computersystem where name="%%computername%%" call ' - 'joindomainorworkgroup name="%s"' % server_workgroup) - session.cmd(cmd, timeout=600) - - # Set the client machine's DNS suffix - logging.info("Setting DNS suffix to '%s'", server_dns_suffix) - cmd = 'reg add %s /v Domain /d "%s" /f' % (regkey, server_dns_suffix) - session.cmd(cmd, timeout=300) - - # Reboot - session = vm.reboot(session) - - # Access shared resources on the server machine - logging.info("Attempting to access remote share on server") - cmd = r"net use \\%s /user:%s %s" % (server_name, server_username, - server_password) - end_time = time.time() + 120 - while time.time() < end_time: - try: - session.cmd(cmd) - break - except: - pass - time.sleep(5) - else: - raise error.TestError("Could not access server share from client " - "machine") - - # Install - logging.info("Installing DTM client (timeout=%ds)", install_timeout) - install_cmd = r"cmd /c \\%s\%s" % (server_name, install_cmd.lstrip("\\")) - session.cmd(install_cmd, timeout=install_timeout) - - # Setup auto logon - logging.info("Setting up auto logon for user '%s'", client_username) - cmd = ('reg add ' - '"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon" ' - '/v "%s" /d "%s" /t REG_SZ /f') - session.cmd(cmd % ("AutoAdminLogon", "1")) - session.cmd(cmd % ("DefaultUserName", client_username)) - session.cmd(cmd % ("DefaultPassword", client_password)) - - # Reboot one more time - session = vm.reboot(session) - session.close() diff --git a/client/tests/kvm/tests/whql_submission.py b/client/tests/kvm/tests/whql_submission.py deleted file mode 100644 index bbeb836..0000000 --- a/client/tests/kvm/tests/whql_submission.py +++ /dev/null @@ -1,275 +0,0 @@ -import logging, os, re -from autotest_lib.client.common_lib import error -from autotest_lib.client.virt import virt_utils, rss_client, aexpect - - -def run_whql_submission(test, params, env): - """ - WHQL submission test: - 1) Log into the client machines and into a DTM server machine - 2) Copy the automation program binary (dsso_test_binary) to the server machine - 3) Run the automation program - 4) Pass the program all relevant parameters (e.g. device_data) - 5) Wait for the program to terminate - 6) Parse and report job results - (logs and HTML reports are placed in test.debugdir) - - @param test: kvm test object - @param params: Dictionary with the test parameters - @param env: Dictionary with test environment. - """ - # Log into all client VMs - login_timeout = int(params.get("login_timeout", 360)) - vms = [] - sessions = [] - for vm_name in params.objects("vms"): - vms.append(env.get_vm(vm_name)) - vms[-1].verify_alive() - sessions.append(vms[-1].wait_for_login(timeout=login_timeout)) - - # Make sure all NICs of all client VMs are up - for vm in vms: - nics = vm.params.objects("nics") - for nic_index in range(len(nics)): - s = vm.wait_for_login(nic_index, 600) - s.close() - - # Collect parameters - server_address = params.get("server_address") - server_shell_port = int(params.get("server_shell_port")) - server_file_transfer_port = int(params.get("server_file_transfer_port")) - server_studio_path = params.get("server_studio_path", "%programfiles%\\ " - "Microsoft Driver Test Manager\\Studio") - dsso_test_binary = params.get("dsso_test_binary", - "deps/whql_submission_15.exe") - dsso_test_binary = virt_utils.get_path(test.bindir, dsso_test_binary) - dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", - "deps/whql_delete_machine_15.exe") - dsso_delete_machine_binary = virt_utils.get_path(test.bindir, - dsso_delete_machine_binary) - test_timeout = float(params.get("test_timeout", 600)) - - # Copy dsso binaries to the server - for filename in dsso_test_binary, dsso_delete_machine_binary: - rss_client.upload(server_address, server_file_transfer_port, - filename, server_studio_path, timeout=60) - - # Open a shell session with the server - server_session = virt_utils.remote_login("nc", server_address, - server_shell_port, "", "", - sessions[0].prompt, - sessions[0].linesep) - server_session.set_status_test_command(sessions[0].status_test_command) - - # Get the computer names of the server and clients - cmd = "echo %computername%" - server_name = server_session.cmd_output(cmd).strip() - client_names = [session.cmd_output(cmd).strip() for session in sessions] - - # Delete all client machines from the server's data store - server_session.cmd("cd %s" % server_studio_path) - for client_name in client_names: - cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), - server_name, client_name) - server_session.cmd(cmd, print_func=logging.debug) - - # Reboot the client machines - sessions = virt_utils.parallel((vm.reboot, (session,)) - for vm, session in zip(vms, sessions)) - - # Check the NICs again - for vm in vms: - nics = vm.params.objects("nics") - for nic_index in range(len(nics)): - s = vm.wait_for_login(nic_index, 600) - s.close() - - # Run whql_pre_command and close the sessions - if params.get("whql_pre_command"): - for session in sessions: - session.cmd(params.get("whql_pre_command"), - int(params.get("whql_pre_command_timeout", 600))) - session.close() - - # Run the automation program on the server - pool_name = "%s_pool" % client_names[0] - submission_name = "%s_%s" % (client_names[0], - params.get("submission_name")) - cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), - server_name, pool_name, submission_name, - test_timeout, " ".join(client_names)) - server_session.sendline(cmd) - - # Helper function: wait for a given prompt and raise an exception if an - # error occurs - def find_prompt(prompt): - m, o = server_session.read_until_last_line_matches( - [prompt, server_session.prompt], print_func=logging.info, - timeout=600) - if m != 0: - errors = re.findall("^Error:.*$", o, re.I | re.M) - if errors: - raise error.TestError(errors[0]) - else: - raise error.TestError("Error running automation program: " - "could not find '%s' prompt" % prompt) - - # Tell the automation program which device to test - find_prompt("Device to test:") - server_session.sendline(params.get("test_device")) - - # Tell the automation program which jobs to run - find_prompt("Jobs to run:") - server_session.sendline(params.get("job_filter", ".*")) - - # Set submission DeviceData - find_prompt("DeviceData name:") - for dd in params.objects("device_data"): - dd_params = params.object_params(dd) - if dd_params.get("dd_name") and dd_params.get("dd_data"): - server_session.sendline(dd_params.get("dd_name")) - server_session.sendline(dd_params.get("dd_data")) - server_session.sendline() - - # Set submission descriptors - find_prompt("Descriptor path:") - for desc in params.objects("descriptors"): - desc_params = params.object_params(desc) - if desc_params.get("desc_path"): - server_session.sendline(desc_params.get("desc_path")) - server_session.sendline() - - # Set machine dimensions for each client machine - for vm_name in params.objects("vms"): - vm_params = params.object_params(vm_name) - find_prompt(r"Dimension name\b.*:") - for dp in vm_params.objects("dimensions"): - dp_params = vm_params.object_params(dp) - if dp_params.get("dim_name") and dp_params.get("dim_value"): - server_session.sendline(dp_params.get("dim_name")) - server_session.sendline(dp_params.get("dim_value")) - server_session.sendline() - - # Set extra parameters for tests that require them (e.g. NDISTest) - for vm_name in params.objects("vms"): - vm_params = params.object_params(vm_name) - find_prompt(r"Parameter name\b.*:") - for dp in vm_params.objects("device_params"): - dp_params = vm_params.object_params(dp) - if dp_params.get("dp_name") and dp_params.get("dp_regex"): - server_session.sendline(dp_params.get("dp_name")) - server_session.sendline(dp_params.get("dp_regex")) - # Make sure the prompt appears again (if the device isn't found - # the automation program will terminate) - find_prompt(r"Parameter name\b.*:") - server_session.sendline() - - # Wait for the automation program to terminate - try: - o = server_session.read_up_to_prompt(print_func=logging.info, - timeout=test_timeout + 300) - # (test_timeout + 300 is used here because the automation program is - # supposed to terminate cleanly on its own when test_timeout expires) - done = True - except aexpect.ExpectError, e: - o = e.output - done = False - server_session.close() - - # Look for test results in the automation program's output - result_summaries = re.findall(r"---- \[.*?\] ----", o, re.DOTALL) - if not result_summaries: - raise error.TestError("The automation program did not return any " - "results") - results = result_summaries[-1].strip("-") - results = eval("".join(results.splitlines())) - - # Download logs and HTML reports from the server - for i, r in enumerate(results): - if "report" in r: - try: - rss_client.download(server_address, - server_file_transfer_port, - r["report"], test.debugdir) - except rss_client.FileTransferNotFoundError: - pass - if "logs" in r: - try: - rss_client.download(server_address, - server_file_transfer_port, - r["logs"], test.debugdir) - except rss_client.FileTransferNotFoundError: - pass - else: - try: - # Create symlinks to test log dirs to make it easier - # to access them (their original names are not human - # readable) - link_name = "logs_%s" % r["report"].split("\\")[-1] - link_name = link_name.replace(" ", "_") - link_name = link_name.replace("/", "_") - os.symlink(r["logs"].split("\\")[-1], - os.path.join(test.debugdir, link_name)) - except (KeyError, OSError): - pass - - # Print result summary (both to the regular logs and to a file named - # 'summary' in test.debugdir) - def print_summary_line(f, line): - logging.info(line) - f.write(line + "\n") - if results: - # Make sure all results have the required keys - for r in results: - r["id"] = str(r.get("id")) - r["job"] = str(r.get("job")) - r["status"] = str(r.get("status")) - r["pass"] = int(r.get("pass", 0)) - r["fail"] = int(r.get("fail", 0)) - r["notrun"] = int(r.get("notrun", 0)) - r["notapplicable"] = int(r.get("notapplicable", 0)) - # Sort the results by failures and total test count in descending order - results = [(r["fail"], - r["pass"] + r["fail"] + r["notrun"] + r["notapplicable"], - r) for r in results] - results.sort(reverse=True) - results = [r[-1] for r in results] - # Print results - logging.info("") - logging.info("Result summary:") - name_length = max(len(r["job"]) for r in results) - fmt = "%%-6s %%-%ds %%-15s %%-8s %%-8s %%-8s %%-15s" % name_length - f = open(os.path.join(test.debugdir, "summary"), "w") - print_summary_line(f, fmt % ("ID", "Job", "Status", "Pass", "Fail", - "NotRun", "NotApplicable")) - print_summary_line(f, fmt % ("--", "---", "------", "----", "----", - "------", "-------------")) - for r in results: - print_summary_line(f, fmt % (r["id"], r["job"], r["status"], - r["pass"], r["fail"], r["notrun"], - r["notapplicable"])) - f.close() - logging.info("(see logs and HTML reports in %s)", test.debugdir) - - # Kill the client VMs and fail if the automation program did not terminate - # on time - if not done: - virt_utils.parallel(vm.destroy for vm in vms) - raise error.TestFail("The automation program did not terminate " - "on time") - - # Fail if there are failed or incomplete jobs (kill the client VMs if there - # are incomplete jobs) - failed_jobs = [r["job"] for r in results - if r["status"].lower() == "investigate"] - running_jobs = [r["job"] for r in results - if r["status"].lower() == "inprogress"] - errors = [] - if failed_jobs: - errors += ["Jobs failed: %s." % failed_jobs] - if running_jobs: - for vm in vms: - vm.destroy() - errors += ["Jobs did not complete on time: %s." % running_jobs] - if errors: - raise error.TestFail(" ".join(errors)) diff --git a/client/tests/kvm/tests/yum_update.py b/client/tests/kvm/tests/yum_update.py deleted file mode 100644 index 7c9b96c..0000000 --- a/client/tests/kvm/tests/yum_update.py +++ /dev/null @@ -1,49 +0,0 @@ -import logging, time - - -def internal_yum_update(session, command, prompt, timeout): - """ - Helper function to perform the yum update test. - - @param session: shell session stablished to the host - @param command: Command to be sent to the shell session - @param prompt: Machine prompt - @param timeout: How long to wait until we get an appropriate output from - the shell session. - """ - session.sendline(command) - end_time = time.time() + timeout - while time.time() < end_time: - match = session.read_until_last_line_matches( - ["[Ii]s this [Oo][Kk]", prompt], - timeout=timeout)[0] - if match == 0: - logging.info("Got 'Is this ok'; sending 'y'") - session.sendline("y") - elif match == 1: - logging.info("Got shell prompt") - return True - else: - logging.info("Timeout or process exited") - return False - - -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 = env.get_vm(params["main_vm"]) - vm.verify_alive() - timeout = int(params.get("login_timeout", 360)) - session = vm.wait_for_login(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() diff --git a/client/virt/tests/autotest.py b/client/virt/tests/autotest.py new file mode 100644 index 0000000..cdea31a --- /dev/null +++ b/client/virt/tests/autotest.py @@ -0,0 +1,25 @@ +import os +from autotest_lib.client.virt import virt_test_utils + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(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 + + virt_test_utils.run_autotest(vm, session, control_path, timeout, outputdir, + params) diff --git a/client/virt/tests/boot.py b/client/virt/tests/boot.py new file mode 100644 index 0000000..4fabcd5 --- /dev/null +++ b/client/virt/tests/boot.py @@ -0,0 +1,26 @@ +import time + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = float(params.get("login_timeout", 240)) + session = vm.wait_for_login(timeout=timeout) + + if params.get("reboot_method"): + if params["reboot_method"] == "system_reset": + time.sleep(int(params.get("sleep_before_reset", 10))) + session = vm.reboot(session, params["reboot_method"], 0, timeout) + + session.close() diff --git a/client/virt/tests/clock_getres.py b/client/virt/tests/clock_getres.py new file mode 100644 index 0000000..d1baf88 --- /dev/null +++ b/client/virt/tests/clock_getres.py @@ -0,0 +1,37 @@ +import logging, os +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + vm.copy_files_to(test_clock, base_dir) + session.cmd(os.path.join(base_dir, t_name)) + logging.info("PASS: Guest reported appropriate clock resolution") + logging.info("Guest's dmesg:\n%s", session.cmd_output("dmesg").strip()) diff --git a/client/virt/tests/ethtool.py b/client/virt/tests/ethtool.py new file mode 100644 index 0000000..1152f00 --- /dev/null +++ b/client/virt/tests/ethtool.py @@ -0,0 +1,235 @@ +import logging, re +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import virt_test_utils, virt_utils, aexpect + + +def run_ethtool(test, params, env): + """ + Test offload functions of ethernet device by ethtool + + 1) Log into a guest. + 2) Initialize the callback of sub functions. + 3) Enable/disable sub function of NIC. + 4) Execute callback function. + 5) Check the return value. + 6) Restore original configuration. + + @param test: KVM test object. + @param params: Dictionary with the test parameters. + @param env: Dictionary with test environment. + + @todo: Not all guests have ethtool installed, so + find a way to get it installed using yum/apt-get/ + whatever + """ + def ethtool_get(f_type): + feature_pattern = { + 'tx': 'tx.*checksumming', + 'rx': 'rx.*checksumming', + 'sg': 'scatter.*gather', + 'tso': 'tcp.*segmentation.*offload', + 'gso': 'generic.*segmentation.*offload', + 'gro': 'generic.*receive.*offload', + 'lro': 'large.*receive.*offload', + } + o = session.cmd("ethtool -k %s" % ethname) + try: + return re.findall("%s: (.*)" % feature_pattern.get(f_type), o)[0] + except IndexError: + logging.debug("Could not get %s status", f_type) + + + def ethtool_set(f_type, status): + """ + Set ethernet device offload status + + @param f_type: Offload type name + @param status: New status will be changed to + """ + logging.info("Try to set %s %s", f_type, status) + if status not in ["off", "on"]: + return False + cmd = "ethtool -K %s %s %s" % (ethname, f_type, status) + if ethtool_get(f_type) != status: + try: + session.cmd(cmd) + return True + except: + return False + if ethtool_get(f_type) != status: + logging.error("Fail to set %s %s", f_type, status) + return False + return True + + + def ethtool_save_params(): + logging.info("Save ethtool configuration") + for i in supported_features: + feature_status[i] = ethtool_get(i) + + + def ethtool_restore_params(): + logging.info("Restore ethtool configuration") + for i in supported_features: + ethtool_set(i, feature_status[i]) + + + def compare_md5sum(name): + logging.info("Compare md5sum of the files on guest and host") + host_result = utils.hash_file(name, method="md5") + try: + o = session.cmd_output("md5sum %s" % name) + guest_result = re.findall("\w+", o)[0] + except IndexError: + logging.error("Could not get file md5sum in guest") + return False + logging.debug("md5sum: guest(%s), host(%s)", guest_result, host_result) + return guest_result == host_result + + + def transfer_file(src="guest"): + """ + Transfer file by scp, use tcpdump to capture packets, then check the + return string. + + @param src: Source host of transfer file + @return: Tuple (status, error msg/tcpdump result) + """ + session2.cmd_output("rm -rf %s" % filename) + dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" % + (filename, params.get("filesize"))) + failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd) + logging.info("Creating file in source host, cmd: %s", dd_cmd) + tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh" + if src == "guest": + tcpdump_cmd += " and src %s" % guest_ip + copy_files_from = vm.copy_files_from + try: + session.cmd_output(dd_cmd, timeout=360) + except aexpect.ShellCmdError, e: + return failure + else: + tcpdump_cmd += " and dst %s" % guest_ip + copy_files_from = vm.copy_files_to + try: + utils.system(dd_cmd) + except error.CmdError, e: + return failure + + # only capture the new tcp port after offload setup + original_tcp_ports = re.findall("tcp.*:(\d+).*%s" % guest_ip, + utils.system_output("/bin/netstat -nap")) + for i in original_tcp_ports: + tcpdump_cmd += " and not port %s" % i + logging.debug("Listen using command: %s", tcpdump_cmd) + session2.sendline(tcpdump_cmd) + if not virt_utils.wait_for( + lambda:session.cmd_status("pgrep tcpdump") == 0, 30): + return (False, "Tcpdump process wasn't launched") + + logging.info("Start to transfer file") + try: + copy_files_from(filename, filename) + except virt_utils.SCPError, e: + return (False, "File transfer failed (%s)" % e) + logging.info("Transfer file completed") + session.cmd("killall tcpdump") + try: + tcpdump_string = session2.read_up_to_prompt(timeout=60) + except aexpect.ExpectError: + return (False, "Fail to read tcpdump's output") + + if not compare_md5sum(filename): + return (False, "Files' md5sum mismatched") + return (True, tcpdump_string) + + + def tx_callback(status="on"): + s, o = transfer_file(src="guest") + if not s: + logging.error(o) + return False + return True + + + def rx_callback(status="on"): + s, o = transfer_file(src="host") + if not s: + logging.error(o) + return False + return True + + + def so_callback(status="on"): + s, o = transfer_file(src="guest") + if not s: + logging.error(o) + return False + logging.info("Check if contained large frame") + # MTU: default IPv4 MTU is 1500 Bytes, ethernet header is 14 Bytes + return (status == "on") ^ (len([i for i in re.findall( + "length (\d*):", o) if int(i) > mtu]) == 0) + + + def ro_callback(status="on"): + s, o = transfer_file(src="host") + if not s: + logging.error(o) + return False + return True + + + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + # Let's just error the test if we identify that there's no ethtool installed + session.cmd("ethtool -h") + session2 = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + mtu = 1514 + feature_status = {} + filename = "/tmp/ethtool.dd" + guest_ip = vm.get_address() + ethname = virt_test_utils.get_linux_ifname(session, vm.get_mac_address(0)) + supported_features = params.get("supported_features") + if supported_features: + supported_features = supported_features.split() + else: + supported_features = [] + test_matrix = { + # type:(callback, (dependence), (exclude) + "tx": (tx_callback, (), ()), + "rx": (rx_callback, (), ()), + "sg": (tx_callback, ("tx",), ()), + "tso": (so_callback, ("tx", "sg",), ("gso",)), + "gso": (so_callback, (), ("tso",)), + "gro": (ro_callback, ("rx",), ("lro",)), + "lro": (rx_callback, (), ("gro",)), + } + ethtool_save_params() + success = True + try: + for f_type in supported_features: + callback = test_matrix[f_type][0] + for i in test_matrix[f_type][2]: + if not ethtool_set(i, "off"): + logging.error("Fail to disable %s", i) + success = False + for i in [f for f in test_matrix[f_type][1]] + [f_type]: + if not ethtool_set(i, "on"): + logging.error("Fail to enable %s", i) + success = False + if not callback(): + raise error.TestFail("Test failed, %s: on", f_type) + + if not ethtool_set(f_type, "off"): + logging.error("Fail to disable %s", f_type) + success = False + if not callback(status="off"): + raise error.TestFail("Test failed, %s: off", f_type) + if not success: + raise error.TestError("Enable/disable offload function fail") + finally: + ethtool_restore_params() + session.close() + session2.close() diff --git a/client/virt/tests/file_transfer.py b/client/virt/tests/file_transfer.py new file mode 100644 index 0000000..5f6672d --- /dev/null +++ b/client/virt/tests/file_transfer.py @@ -0,0 +1,84 @@ +import logging, time, os +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import virt_utils + + +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 = 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) + + 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 + + host_path = os.path.join(dir_name, "tmp-%s" % + virt_utils.generate_random_string(8)) + host_path2 = host_path + ".2" + cmd = "dd if=/dev/zero of=%s bs=10M count=%d" % (host_path, count) + guest_path = (tmp_dir + "file_transfer-%s" % + virt_utils.generate_random_string(8)) + + 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() + vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout) + t_end = time.time() + throughput = filesize / (t_end - t_begin) + 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() + vm.copy_files_from(guest_path, host_path2, timeout=transfer_timeout) + t_end = time.time() + throughput = filesize / (t_end - t_begin) + logging.info("File transfer guest -> host succeed, " + "estimated throughput: %.2fMB/s", throughput) + else: + raise error.TestError("Unknown test file transfer mode %s" % + transfer_type) + + if (utils.hash_file(host_path, method="md5") != + utils.hash_file(host_path2, method="md5")): + raise error.TestFail("File changed after transfer host -> guest " + "and guest -> host") + + finally: + logging.info('Cleaning temp file on guest') + session.cmd("rm -rf %s" % guest_path) + logging.info('Cleaning temp files on host') + try: + os.remove(host_path) + os.remove(host_path2) + except OSError: + pass + session.close() diff --git a/client/virt/tests/guest_s4.py b/client/virt/tests/guest_s4.py new file mode 100644 index 0000000..5b5708d --- /dev/null +++ b/client/virt/tests/guest_s4.py @@ -0,0 +1,76 @@ +import logging, time +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils + + +@error.context_aware +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. + """ + error.base_context("before S4") + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + error.context("checking whether guest OS supports S4", logging.info) + session.cmd(params.get("check_s4_support_cmd")) + error.context() + + 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 = vm.wait_for_login(timeout=timeout) + + # Make sure the background program is running as expected + error.context("making sure background program is running") + check_s4_cmd = params.get("check_s4_cmd") + session2.cmd(check_s4_cmd) + logging.info("Launched background command in guest: %s", test_s4_cmd) + error.context() + error.base_context() + + # Suspend to disk + logging.info("Starting suspend to disk now...") + session2.sendline(params.get("set_s4_cmd")) + + # Make sure the VM goes down + error.base_context("after S4") + suspend_timeout = 240 + int(params.get("smp")) * 60 + if not virt_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...") + vm.create() + + # Log into the resumed VM + relogin_timeout = int(params.get("relogin_timeout", 240)) + logging.info("Logging into resumed VM, timeout %s", relogin_timeout) + session2 = vm.wait_for_login(timeout=relogin_timeout) + + # Check whether the test command is still alive + error.context("making sure background program is still running", + logging.info) + session2.cmd(check_s4_cmd) + error.context() + + logging.info("VM resumed successfuly after suspend to disk") + session2.cmd_output(params.get("kill_test_s4_cmd")) + session.close() + session2.close() diff --git a/client/virt/tests/guest_test.py b/client/virt/tests/guest_test.py new file mode 100644 index 0000000..3bc7da7 --- /dev/null +++ b/client/virt/tests/guest_test.py @@ -0,0 +1,80 @@ +import os, logging +from autotest_lib.client.virt import virt_utils + + +def run_guest_test(test, params, env): + """ + A wrapper for running customized tests in guests. + + 1) Log into a guest. + 2) Run 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. + """ + login_timeout = int(params.get("login_timeout", 360)) + reboot = params.get("reboot", "no") + + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + if params.get("serial_login") == "yes": + session = vm.wait_for_serial_login(timeout=login_timeout) + else: + session = vm.wait_for_login(timeout=login_timeout) + + if reboot == "yes": + logging.debug("Rebooting guest before test ...") + session = vm.reboot(session, timeout=login_timeout) + + try: + logging.info("Starting script...") + + # Collect test parameters + interpreter = params.get("interpreter") + script = params.get("guest_script") + dst_rsc_path = params.get("dst_rsc_path", "script.au3") + script_params = params.get("script_params", "") + test_timeout = float(params.get("test_timeout", 600)) + + logging.debug("Starting preparing resouce files...") + # Download the script resource from a remote server, or + # prepare the script using rss? + if params.get("download") == "yes": + download_cmd = params.get("download_cmd") + rsc_server = params.get("rsc_server") + rsc_dir = os.path.basename(rsc_server) + dst_rsc_dir = params.get("dst_rsc_dir") + + # Change dir to dst_rsc_dir, and remove the guest script dir there + rm_cmd = "cd %s && (rmdir /s /q %s || del /s /q %s)" % \ + (dst_rsc_dir, rsc_dir, rsc_dir) + session.cmd(rm_cmd, timeout=test_timeout) + logging.debug("Clean directory succeeded.") + + # then download the resource. + rsc_cmd = "cd %s && %s %s" % (dst_rsc_dir, download_cmd, rsc_server) + session.cmd(rsc_cmd, timeout=test_timeout) + logging.info("Download resource finished.") + else: + session.cmd_output("del %s" % dst_rsc_path, internal_timeout=0) + script_path = virt_utils.get_path(test.bindir, script) + vm.copy_files_to(script_path, dst_rsc_path, timeout=60) + + cmd = "%s %s %s" % (interpreter, dst_rsc_path, script_params) + + try: + logging.info("------------ Script output ------------") + session.cmd(cmd, print_func=logging.info, timeout=test_timeout) + finally: + logging.info("------------ End of script output ------------") + + if reboot == "yes": + logging.debug("Rebooting guest after test ...") + session = vm.reboot(session, timeout=login_timeout) + + logging.debug("guest test PASSED.") + finally: + session.close() diff --git a/client/virt/tests/image_copy.py b/client/virt/tests/image_copy.py new file mode 100644 index 0000000..cc921ab --- /dev/null +++ b/client/virt/tests/image_copy.py @@ -0,0 +1,45 @@ +import os, logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import virt_utils + + +def run_image_copy(test, params, env): + """ + Copy guest images from nfs server. + 1) Mount the NFS share directory + 2) Check the existence of source image + 3) If it exists, copy the image from NFS + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + mount_dest_dir = params.get('dst_dir', '/mnt/images') + if not os.path.exists(mount_dest_dir): + try: + os.makedirs(mount_dest_dir) + except OSError, err: + logging.warning('mkdir %s error:\n%s', mount_dest_dir, err) + + if not os.path.exists(mount_dest_dir): + raise error.TestError('Failed to create NFS share dir %s' % + mount_dest_dir) + + src = params.get('images_good') + image = '%s.%s' % (os.path.split(params['image_name'])[1], + params['image_format']) + src_path = os.path.join(mount_dest_dir, image) + dst_path = '%s.%s' % (params['image_name'], params['image_format']) + cmd = 'cp %s %s' % (src_path, dst_path) + + if not virt_utils.mount(src, mount_dest_dir, 'nfs', 'ro'): + raise error.TestError('Could not mount NFS share %s to %s' % + (src, mount_dest_dir)) + + # Check the existence of source image + if not os.path.exists(src_path): + raise error.TestError('Could not find %s in NFS share' % src_path) + + logging.debug('Copying image %s...', image) + utils.system(cmd) diff --git a/client/virt/tests/iofuzz.py b/client/virt/tests/iofuzz.py new file mode 100644 index 0000000..d244012 --- /dev/null +++ b/client/virt/tests/iofuzz.py @@ -0,0 +1,136 @@ +import logging, re, random +from autotest_lib.client.common_lib import error, aexpect +from autotest_lib.client.virt import aexpect + + +def run_iofuzz(test, params, env): + """ + KVM iofuzz test: + 1) Log into a guest + 2) Enumerate all IO port ranges through /proc/ioports + 3) On each port of the range: + * Read it + * Write 0 to it + * Write a random value to a random port on a random order + + If the guest SSH session hangs, the test detects the hang and the guest + is then rebooted. The test fails if we detect the qemu process to terminate + while executing the process. + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + def outb(session, port, data): + """ + Write data to a given port. + + @param session: SSH session stablished to a VM + @param port: Port where we'll write the data + @param data: Integer value that will be written on the port. This + value will be converted to octal before its written. + """ + logging.debug("outb(0x%x, 0x%x)", port, data) + outb_cmd = ("echo -e '\\%s' | dd of=/dev/port seek=%d bs=1 count=1" % + (oct(data), port)) + try: + session.cmd(outb_cmd) + except aexpect.ShellError, e: + logging.debug(e) + + + def inb(session, port): + """ + Read from a given port. + + @param session: SSH session stablished to a VM + @param port: Port where we'll read data + """ + logging.debug("inb(0x%x)", port) + inb_cmd = "dd if=/dev/port seek=%d of=/dev/null bs=1 count=1" % port + try: + session.cmd(inb_cmd) + except aexpect.ShellError, e: + logging.debug(e) + + + def fuzz(session, inst_list): + """ + Executes a series of read/write/randwrite instructions. + + If the guest SSH session hangs, an attempt to relogin will be made. + If it fails, the guest will be reset. If during the process the VM + process abnormally ends, the test fails. + + @param inst_list: List of instructions that will be executed. + @raise error.TestFail: If the VM process dies in the middle of the + fuzzing procedure. + """ + for (op, operand) in inst_list: + if op == "read": + inb(session, operand[0]) + elif op == "write": + outb(session, operand[0], operand[1]) + else: + raise error.TestError("Unknown command %s" % op) + + if not session.is_responsive(): + logging.debug("Session is not responsive") + if vm.process.is_alive(): + logging.debug("VM is alive, try to re-login") + try: + session = vm.wait_for_login(timeout=10) + except: + logging.debug("Could not re-login, reboot the guest") + session = vm.reboot(method="system_reset") + else: + raise error.TestFail("VM has quit abnormally during %s", + (op, operand)) + + + login_timeout = float(params.get("login_timeout", 240)) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login(timeout=login_timeout) + + 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: + ports[(int(beg, base=16), int(end, base=16))] = name.strip() + + for (beg, end) in ports.keys(): + name = ports[(beg, end)] + if name in skip_devices: + logging.info("Skipping device %s", name) + continue + + logging.info("Fuzzing %s, port range 0x%x-0x%x", name, beg, end) + inst = [] + + # Read all ports of the range + for port in range(beg, end + 1): + inst.append(("read", [port])) + + # Write 0 to all ports of the range + for port in range(beg, end + 1): + inst.append(("write", [port, 0])) + + # Write random values to random ports of the range + for seq in range(fuzz_count * (end - beg + 1)): + inst.append(("write", + [r.randint(beg, end), r.randint(0,255)])) + + fuzz(session, inst) + + finally: + session.close() diff --git a/client/virt/tests/ioquit.py b/client/virt/tests/ioquit.py new file mode 100644 index 0000000..34b4fb5 --- /dev/null +++ b/client/virt/tests/ioquit.py @@ -0,0 +1,31 @@ +import logging, time, random + + +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 = 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) + session2 = vm.wait_for_login(timeout=login_timeout) + 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() diff --git a/client/virt/tests/iozone_windows.py b/client/virt/tests/iozone_windows.py new file mode 100644 index 0000000..4046106 --- /dev/null +++ b/client/virt/tests/iozone_windows.py @@ -0,0 +1,40 @@ +import logging, os +from autotest_lib.client.bin import utils +from autotest_lib.client.tests.iozone import postprocessing + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(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(cmd=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() diff --git a/client/virt/tests/jumbo.py b/client/virt/tests/jumbo.py new file mode 100644 index 0000000..5108227 --- /dev/null +++ b/client/virt/tests/jumbo.py @@ -0,0 +1,127 @@ +import logging, commands, random +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import virt_utils, virt_test_utils + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + 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 = virt_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 = virt_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 = virt_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 virt_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") + virt_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 = virt_test_utils.ping(ip, count, interface=ifname, + packetsize=max_icmp_pkt_size, + timeout=float(count) * 2) + ratio = virt_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 = virt_test_utils.ping(ip, 1, interface=ifname, + packetsize=size, + hint="do", timeout=1) + if s != 0: + s, o = virt_test_utils.ping(ip, 10, interface=ifname, + packetsize=size, + adaptive=True, hint="do", + timeout=20) + + if virt_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 virt_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)) diff --git a/client/virt/tests/kdump.py b/client/virt/tests/kdump.py new file mode 100644 index 0000000..90c004b --- /dev/null +++ b/client/virt/tests/kdump.py @@ -0,0 +1,75 @@ +import logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils + + +def run_kdump(test, params, env): + """ + KVM reboot test: + 1) Log into a guest + 2) Check and enable the kdump + 3) For each vcpu, trigger a crash and check the vmcore + + @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)) + crash_timeout = float(params.get("crash_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + def_kernel_param_cmd = ("grubby --update-kernel=`grubby --default-kernel`" + " --args=crashkernel=128M") + kernel_param_cmd = params.get("kernel_param_cmd", def_kernel_param_cmd) + def_kdump_enable_cmd = "chkconfig kdump on && service kdump start" + kdump_enable_cmd = params.get("kdump_enable_cmd", def_kdump_enable_cmd) + def_crash_kernel_prob_cmd = "grep -q 1 /sys/kernel/kexec_crash_loaded" + crash_kernel_prob_cmd = params.get("crash_kernel_prob_cmd", + def_crash_kernel_prob_cmd) + + def crash_test(vcpu): + """ + Trigger a crash dump through sysrq-trigger + + @param vcpu: vcpu which is used to trigger a crash + """ + session = vm.wait_for_login(timeout=timeout) + session.cmd_output("rm -rf /var/crash/*") + + logging.info("Triggering crash on vcpu %d ...", vcpu) + crash_cmd = "taskset -c %d echo c > /proc/sysrq-trigger" % vcpu + 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 on vcpu %d" % vcpu) + + logging.info("Waiting for kernel crash dump to complete") + session = vm.wait_for_login(timeout=crash_timeout) + + logging.info("Probing vmcore file...") + session.cmd("ls -R /var/crash | grep vmcore") + logging.info("Found vmcore.") + + session.cmd_output("rm -rf /var/crash/*") + + try: + logging.info("Checking the existence of crash kernel...") + try: + session.cmd(crash_kernel_prob_cmd) + except: + logging.info("Crash kernel is not loaded. Trying to load it") + session.cmd(kernel_param_cmd) + session = vm.reboot(session, timeout=timeout) + + logging.info("Enabling kdump service...") + # the initrd may be rebuilt here so we need to wait a little more + session.cmd(kdump_enable_cmd, timeout=120) + + nvcpu = int(params.get("smp", 1)) + for i in range (nvcpu): + crash_test(i) + + finally: + session.close() diff --git a/client/virt/tests/linux_s3.py b/client/virt/tests/linux_s3.py new file mode 100644 index 0000000..5a04fca --- /dev/null +++ b/client/virt/tests/linux_s3.py @@ -0,0 +1,41 @@ +import logging, time +from autotest_lib.client.common_lib import error + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + logging.info("Checking that VM supports S3") + session.cmd("grep -q mem /sys/power/state") + + logging.info("Waiting for a while for X to start") + time.sleep(10) + + src_tty = session.cmd_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) + suspend_timeout = 120 + int(params.get("smp")) * 60 + session.cmd(command, timeout=suspend_timeout) + + logging.info("VM resumed after S3") + + session.close() diff --git a/client/virt/tests/mac_change.py b/client/virt/tests/mac_change.py new file mode 100644 index 0000000..d2eaf01 --- /dev/null +++ b/client/virt/tests/mac_change.py @@ -0,0 +1,60 @@ +import logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils, virt_test_utils + + +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. + """ + 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) + # This session will be used to assess whether the IP change worked + session = vm.wait_for_login(timeout=timeout) + old_mac = vm.get_mac_address(0) + while True: + vm.free_mac_address(0) + new_mac = virt_utils.generate_mac_address(vm.instance, 0) + if old_mac != new_mac: + break + logging.info("The initial MAC address is %s", old_mac) + interface = virt_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 virt_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 = vm.wait_for_login(timeout=timeout) + if not session.is_responsive(): + raise error.TestFail("The new session is not responsive.") + + session.close() diff --git a/client/virt/tests/multicast.py b/client/virt/tests/multicast.py new file mode 100644 index 0000000..13e3f0d --- /dev/null +++ b/client/virt/tests/multicast.py @@ -0,0 +1,90 @@ +import logging, os, re +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import virt_test_utils, aexpect + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + + def run_guest(cmd): + try: + session.cmd(cmd) + except aexpect.ShellError, e: + logging.warn(e) + + def run_host_guest(cmd): + run_guest(cmd) + utils.system(cmd, ignore_status=True) + + # flush the firewall rules + cmd_flush = "iptables -F" + cmd_selinux = ("if [ -e /selinux/enforce ]; then setenforce 0; " + "else echo 'no /selinux/enforce file present'; fi") + run_host_guest(cmd_flush) + run_host_guest(cmd_selinux) + # make sure guest replies to broadcasts + cmd_broadcast = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts" + cmd_broadcast_2 = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all" + run_guest(cmd_broadcast) + run_guest(cmd_broadcast_2) + + # base multicast address + mcast = params.get("mcast", "225.0.0.1") + # count of multicast addresses, less than 20 + mgroup_count = int(params.get("mgroup_count", 5)) + flood_minutes = float(params.get("flood_minutes", 10)) + ifname = vm.get_ifname() + prefix = re.findall("\d+.\d+.\d+", mcast)[0] + suffix = int(re.findall("\d+", mcast)[-1]) + # copy python script to guest for joining guest to multicast groups + mcast_path = os.path.join(test.bindir, "scripts/multicast_guest.py") + vm.copy_files_to(mcast_path, "/tmp") + output = session.cmd_output("python /tmp/multicast_guest.py %d %s %d" % + (mgroup_count, prefix, suffix)) + + # if success to join multicast, the process will be paused, and return PID. + try: + pid = re.findall("join_mcast_pid:(\d+)", output)[0] + except IndexError: + raise error.TestFail("Can't join multicast groups,output:%s" % output) + + try: + for i in range(mgroup_count): + new_suffix = suffix + i + mcast = "%s.%d" % (prefix, new_suffix) + + logging.info("Initial ping test, mcast: %s", mcast) + s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) + if s != 0: + raise error.TestFail(" Ping return non-zero value %s" % o) + + logging.info("Flood ping test, mcast: %s", mcast) + virt_test_utils.ping(mcast, None, interface=ifname, flood=True, + output_func=None, timeout=flood_minutes*60) + + logging.info("Final ping test, mcast: %s", mcast) + s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) + if s != 0: + raise error.TestFail("Ping failed, status: %s, output: %s" % + (s, o)) + + finally: + logging.debug(session.cmd_output("ipmaddr show")) + session.cmd_output("kill -s SIGCONT %s" % pid) + session.close() diff --git a/client/virt/tests/netperf.py b/client/virt/tests/netperf.py new file mode 100644 index 0000000..72d9cde --- /dev/null +++ b/client/virt/tests/netperf.py @@ -0,0 +1,90 @@ +import logging, os, signal +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.virt import aexpect + +def run_netperf(test, params, env): + """ + Network stress test with netperf. + + 1) Boot up a VM. + 2) Launch netserver on guest. + 3) Execute netperf client on host 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_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") + guest_ip = vm.get_address() + result_file = os.path.join(test.resultsdir, "output_%s" % test.iteration) + + 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") + + tcpdump = env.get("tcpdump") + pid = None + if tcpdump: + # Stop the background tcpdump process + try: + pid = int(utils.system_output("pidof tcpdump")) + logging.debug("Stopping the background tcpdump") + os.kill(pid, signal.SIGSTOP) + except: + pass + + try: + logging.info("Setup and run netperf client on host") + utils.run(setup_cmd % netperf_dir) + list_fail = [] + result = open(result_file, "w") + result.write("Netperf test results\n") + + for i 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, i, + guest_ip, size) + logging.info("Netperf: protocol %s", i) + try: + netperf_output = utils.system_output(cmd, + retain_output=True) + result.write("%s\n" % netperf_output) + except: + logging.error("Test of protocol %s failed", i) + list_fail.append(i) + + result.close() + + if list_fail: + raise error.TestFail("Some netperf tests failed: %s" % + ", ".join(list_fail)) + + finally: + session_serial.cmd_output("killall netserver") + if tcpdump and pid: + logging.debug("Resuming the background tcpdump") + logging.info("pid is %s" % pid) + os.kill(pid, signal.SIGCONT) diff --git a/client/virt/tests/nic_promisc.py b/client/virt/tests/nic_promisc.py new file mode 100644 index 0000000..0ff07b8 --- /dev/null +++ b/client/virt/tests/nic_promisc.py @@ -0,0 +1,39 @@ +import logging, threading +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.tests.kvm.tests import file_transfer +from autotest_lib.client.virt import virt_test_utils, virt_utils + + +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: + transfer_thread.join(suppress_exception=True) + raise + else: + transfer_thread.join() diff --git a/client/virt/tests/nicdriver_unload.py b/client/virt/tests/nicdriver_unload.py new file mode 100644 index 0000000..6d3d4da --- /dev/null +++ b/client/virt/tests/nicdriver_unload.py @@ -0,0 +1,56 @@ +import logging, threading, os, time +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils +from autotest_lib.client.tests.kvm.tests import file_transfer +from autotest_lib.client.virt import virt_test_utils, virt_utils + + +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)) + sys_path = "/sys/class/net/%s/device/driver" % (ethname) + driver = os.path.basename(session_serial.cmd("readlink -e %s" % + 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() + diff --git a/client/virt/tests/ping.py b/client/virt/tests/ping.py new file mode 100644 index 0000000..08791fb --- /dev/null +++ b/client/virt/tests/ping.py @@ -0,0 +1,73 @@ +import logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_test_utils + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + + 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: %s", + i, nic) + continue + + for size in packet_size: + logging.info("Ping with packet size %s", size) + status, output = virt_test_utils.ping(ip, 10, + packetsize=size, + timeout=20) + if strict_check: + ratio = virt_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") + virt_test_utils.ping(ip, None, flood=True, output_func=None, + timeout=flood_minutes * 60) + + logging.info("Final ping test") + status, output = virt_test_utils.ping(ip, counts, + timeout=float(counts) * 1.5) + if strict_check: + ratio = virt_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() diff --git a/client/virt/tests/pxe.py b/client/virt/tests/pxe.py new file mode 100644 index 0000000..325e353 --- /dev/null +++ b/client/virt/tests/pxe.py @@ -0,0 +1,29 @@ +import logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import aexpect + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("pxe_timeout", 60)) + + logging.info("Try to boot from PXE") + output = aexpect.run_fg("tcpdump -nli %s" % vm.get_ifname(), + logging.debug, "(pxe capture) ", timeout)[1] + + 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") diff --git a/client/virt/tests/shutdown.py b/client/virt/tests/shutdown.py new file mode 100644 index 0000000..ac41a4a --- /dev/null +++ b/client/virt/tests/shutdown.py @@ -0,0 +1,43 @@ +import logging, time +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(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 virt_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() diff --git a/client/virt/tests/stress_boot.py b/client/virt/tests/stress_boot.py new file mode 100644 index 0000000..e3ac14d --- /dev/null +++ b/client/virt/tests/stress_boot.py @@ -0,0 +1,53 @@ +import logging +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_env_process + + +@error.context_aware +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)) diff --git a/client/virt/tests/vlan.py b/client/virt/tests/vlan.py new file mode 100644 index 0000000..9fc1f64 --- /dev/null +++ b/client/virt/tests/vlan.py @@ -0,0 +1,175 @@ +import logging, time, re +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils, virt_test_utils, aexpect + + +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(env.get_vm(params["main_vm"])) + vm.append(env.get_vm("vm2")) + for vm_ in vm: + vm_.verify_alive() + + def add_vlan(session, v_id, iface="eth0"): + session.cmd("vconfig add %s %s" % (iface, v_id)) + + def set_ip_vlan(session, v_id, ip, iface="eth0"): + iface = "%s.%s" % (iface, v_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, v_id, iface="eth0"): + rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi" + iface = "%s.%s" % (iface, v_id) + return session.cmd_status(rem_vlan_cmd % (iface, iface)) + + def nc_transfer(src, dst): + nc_port = virt_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 aexpect.ExpectError: + raise error.TestFail ("Fail to receive file" + " from vm%s to vm%s" % (src+1, dst+1)) + #check MD5 message digest of receive file in dst + output = session[dst].cmd_output("md5sum receive").strip() + digest_receive = re.findall(r'(\w+)', output)[0] + if digest_receive == digest_origin[src]: + logging.info("file succeed received in vm %s", vlan_ip[dst]) + else: + logging.info("digest_origin is %s", digest_origin[src]) + logging.info("digest_receive is %s", digest_receive) + raise error.TestFail("File transfered differ from origin") + session[dst].cmd_output("rm -f receive") + + for i in range(2): + session.append(vm[i].wait_for_login( + 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(virt_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 = virt_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 aexpect + # does not have the other method to interrupt the process in + # the guest rather than close the session. + session_flood = vm[src].wait_for_login(timeout=60) + virt_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 number 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() diff --git a/client/virt/tests/whql_client_install.py b/client/virt/tests/whql_client_install.py new file mode 100644 index 0000000..2d72a5e --- /dev/null +++ b/client/virt/tests/whql_client_install.py @@ -0,0 +1,136 @@ +import logging, time, os +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils, virt_test_utils, rss_client + + +def run_whql_client_install(test, params, env): + """ + WHQL DTM client installation: + 1) Log into the guest (the client machine) and into a DTM server machine + 2) Stop the DTM client service (wttsvc) on the client machine + 3) Delete the client machine from the server's data store + 4) Rename the client machine (give it a randomly generated name) + 5) Move the client machine into the server's workgroup + 6) Reboot the client machine + 7) Install the DTM client software + 8) Setup auto logon for the user created by the installation + (normally DTMLLUAdminUser) + 9) Reboot again + + @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() + session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + + # Collect test params + server_address = params.get("server_address") + server_shell_port = int(params.get("server_shell_port")) + server_file_transfer_port = int(params.get("server_file_transfer_port")) + server_studio_path = params.get("server_studio_path", "%programfiles%\\ " + "Microsoft Driver Test Manager\\Studio") + server_username = params.get("server_username") + server_password = params.get("server_password") + client_username = params.get("client_username") + client_password = params.get("client_password") + dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", + "deps/whql_delete_machine_15.exe") + dsso_delete_machine_binary = virt_utils.get_path(test.bindir, + dsso_delete_machine_binary) + install_timeout = float(params.get("install_timeout", 600)) + install_cmd = params.get("install_cmd") + wtt_services = params.get("wtt_services") + + # Stop WTT service(s) on client + for svc in wtt_services.split(): + virt_test_utils.stop_windows_service(session, svc) + + # Copy dsso_delete_machine_binary to server + rss_client.upload(server_address, server_file_transfer_port, + dsso_delete_machine_binary, server_studio_path, + timeout=60) + + # Open a shell session with server + server_session = virt_utils.remote_login("nc", server_address, + server_shell_port, "", "", + session.prompt, session.linesep) + server_session.set_status_test_command(session.status_test_command) + + # Get server and client information + cmd = "echo %computername%" + server_name = server_session.cmd_output(cmd).strip() + client_name = session.cmd_output(cmd).strip() + cmd = "wmic computersystem get domain" + server_workgroup = server_session.cmd_output(cmd).strip() + server_workgroup = server_workgroup.splitlines()[-1] + regkey = r"HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" + cmd = "reg query %s /v Domain" % regkey + o = server_session.cmd_output(cmd).strip().splitlines()[-1] + try: + server_dns_suffix = o.split(None, 2)[2] + except IndexError: + server_dns_suffix = "" + + # Delete the client machine from the server's data store (if it's there) + server_session.cmd("cd %s" % server_studio_path) + cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), + server_name, client_name) + server_session.cmd(cmd, print_func=logging.info) + server_session.close() + + # Rename the client machine + client_name = "autotest_%s" % virt_utils.generate_random_string(4) + logging.info("Renaming client machine to '%s'", client_name) + cmd = ('wmic computersystem where name="%%computername%%" rename name="%s"' + % client_name) + session.cmd(cmd, timeout=600) + + # Join the server's workgroup + logging.info("Joining workgroup '%s'", server_workgroup) + cmd = ('wmic computersystem where name="%%computername%%" call ' + 'joindomainorworkgroup name="%s"' % server_workgroup) + session.cmd(cmd, timeout=600) + + # Set the client machine's DNS suffix + logging.info("Setting DNS suffix to '%s'", server_dns_suffix) + cmd = 'reg add %s /v Domain /d "%s" /f' % (regkey, server_dns_suffix) + session.cmd(cmd, timeout=300) + + # Reboot + session = vm.reboot(session) + + # Access shared resources on the server machine + logging.info("Attempting to access remote share on server") + cmd = r"net use \\%s /user:%s %s" % (server_name, server_username, + server_password) + end_time = time.time() + 120 + while time.time() < end_time: + try: + session.cmd(cmd) + break + except: + pass + time.sleep(5) + else: + raise error.TestError("Could not access server share from client " + "machine") + + # Install + logging.info("Installing DTM client (timeout=%ds)", install_timeout) + install_cmd = r"cmd /c \\%s\%s" % (server_name, install_cmd.lstrip("\\")) + session.cmd(install_cmd, timeout=install_timeout) + + # Setup auto logon + logging.info("Setting up auto logon for user '%s'", client_username) + cmd = ('reg add ' + '"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon" ' + '/v "%s" /d "%s" /t REG_SZ /f') + session.cmd(cmd % ("AutoAdminLogon", "1")) + session.cmd(cmd % ("DefaultUserName", client_username)) + session.cmd(cmd % ("DefaultPassword", client_password)) + + # Reboot one more time + session = vm.reboot(session) + session.close() diff --git a/client/virt/tests/whql_submission.py b/client/virt/tests/whql_submission.py new file mode 100644 index 0000000..bbeb836 --- /dev/null +++ b/client/virt/tests/whql_submission.py @@ -0,0 +1,275 @@ +import logging, os, re +from autotest_lib.client.common_lib import error +from autotest_lib.client.virt import virt_utils, rss_client, aexpect + + +def run_whql_submission(test, params, env): + """ + WHQL submission test: + 1) Log into the client machines and into a DTM server machine + 2) Copy the automation program binary (dsso_test_binary) to the server machine + 3) Run the automation program + 4) Pass the program all relevant parameters (e.g. device_data) + 5) Wait for the program to terminate + 6) Parse and report job results + (logs and HTML reports are placed in test.debugdir) + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + # Log into all client VMs + login_timeout = int(params.get("login_timeout", 360)) + vms = [] + sessions = [] + for vm_name in params.objects("vms"): + vms.append(env.get_vm(vm_name)) + vms[-1].verify_alive() + sessions.append(vms[-1].wait_for_login(timeout=login_timeout)) + + # Make sure all NICs of all client VMs are up + for vm in vms: + nics = vm.params.objects("nics") + for nic_index in range(len(nics)): + s = vm.wait_for_login(nic_index, 600) + s.close() + + # Collect parameters + server_address = params.get("server_address") + server_shell_port = int(params.get("server_shell_port")) + server_file_transfer_port = int(params.get("server_file_transfer_port")) + server_studio_path = params.get("server_studio_path", "%programfiles%\\ " + "Microsoft Driver Test Manager\\Studio") + dsso_test_binary = params.get("dsso_test_binary", + "deps/whql_submission_15.exe") + dsso_test_binary = virt_utils.get_path(test.bindir, dsso_test_binary) + dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", + "deps/whql_delete_machine_15.exe") + dsso_delete_machine_binary = virt_utils.get_path(test.bindir, + dsso_delete_machine_binary) + test_timeout = float(params.get("test_timeout", 600)) + + # Copy dsso binaries to the server + for filename in dsso_test_binary, dsso_delete_machine_binary: + rss_client.upload(server_address, server_file_transfer_port, + filename, server_studio_path, timeout=60) + + # Open a shell session with the server + server_session = virt_utils.remote_login("nc", server_address, + server_shell_port, "", "", + sessions[0].prompt, + sessions[0].linesep) + server_session.set_status_test_command(sessions[0].status_test_command) + + # Get the computer names of the server and clients + cmd = "echo %computername%" + server_name = server_session.cmd_output(cmd).strip() + client_names = [session.cmd_output(cmd).strip() for session in sessions] + + # Delete all client machines from the server's data store + server_session.cmd("cd %s" % server_studio_path) + for client_name in client_names: + cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), + server_name, client_name) + server_session.cmd(cmd, print_func=logging.debug) + + # Reboot the client machines + sessions = virt_utils.parallel((vm.reboot, (session,)) + for vm, session in zip(vms, sessions)) + + # Check the NICs again + for vm in vms: + nics = vm.params.objects("nics") + for nic_index in range(len(nics)): + s = vm.wait_for_login(nic_index, 600) + s.close() + + # Run whql_pre_command and close the sessions + if params.get("whql_pre_command"): + for session in sessions: + session.cmd(params.get("whql_pre_command"), + int(params.get("whql_pre_command_timeout", 600))) + session.close() + + # Run the automation program on the server + pool_name = "%s_pool" % client_names[0] + submission_name = "%s_%s" % (client_names[0], + params.get("submission_name")) + cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), + server_name, pool_name, submission_name, + test_timeout, " ".join(client_names)) + server_session.sendline(cmd) + + # Helper function: wait for a given prompt and raise an exception if an + # error occurs + def find_prompt(prompt): + m, o = server_session.read_until_last_line_matches( + [prompt, server_session.prompt], print_func=logging.info, + timeout=600) + if m != 0: + errors = re.findall("^Error:.*$", o, re.I | re.M) + if errors: + raise error.TestError(errors[0]) + else: + raise error.TestError("Error running automation program: " + "could not find '%s' prompt" % prompt) + + # Tell the automation program which device to test + find_prompt("Device to test:") + server_session.sendline(params.get("test_device")) + + # Tell the automation program which jobs to run + find_prompt("Jobs to run:") + server_session.sendline(params.get("job_filter", ".*")) + + # Set submission DeviceData + find_prompt("DeviceData name:") + for dd in params.objects("device_data"): + dd_params = params.object_params(dd) + if dd_params.get("dd_name") and dd_params.get("dd_data"): + server_session.sendline(dd_params.get("dd_name")) + server_session.sendline(dd_params.get("dd_data")) + server_session.sendline() + + # Set submission descriptors + find_prompt("Descriptor path:") + for desc in params.objects("descriptors"): + desc_params = params.object_params(desc) + if desc_params.get("desc_path"): + server_session.sendline(desc_params.get("desc_path")) + server_session.sendline() + + # Set machine dimensions for each client machine + for vm_name in params.objects("vms"): + vm_params = params.object_params(vm_name) + find_prompt(r"Dimension name\b.*:") + for dp in vm_params.objects("dimensions"): + dp_params = vm_params.object_params(dp) + if dp_params.get("dim_name") and dp_params.get("dim_value"): + server_session.sendline(dp_params.get("dim_name")) + server_session.sendline(dp_params.get("dim_value")) + server_session.sendline() + + # Set extra parameters for tests that require them (e.g. NDISTest) + for vm_name in params.objects("vms"): + vm_params = params.object_params(vm_name) + find_prompt(r"Parameter name\b.*:") + for dp in vm_params.objects("device_params"): + dp_params = vm_params.object_params(dp) + if dp_params.get("dp_name") and dp_params.get("dp_regex"): + server_session.sendline(dp_params.get("dp_name")) + server_session.sendline(dp_params.get("dp_regex")) + # Make sure the prompt appears again (if the device isn't found + # the automation program will terminate) + find_prompt(r"Parameter name\b.*:") + server_session.sendline() + + # Wait for the automation program to terminate + try: + o = server_session.read_up_to_prompt(print_func=logging.info, + timeout=test_timeout + 300) + # (test_timeout + 300 is used here because the automation program is + # supposed to terminate cleanly on its own when test_timeout expires) + done = True + except aexpect.ExpectError, e: + o = e.output + done = False + server_session.close() + + # Look for test results in the automation program's output + result_summaries = re.findall(r"---- \[.*?\] ----", o, re.DOTALL) + if not result_summaries: + raise error.TestError("The automation program did not return any " + "results") + results = result_summaries[-1].strip("-") + results = eval("".join(results.splitlines())) + + # Download logs and HTML reports from the server + for i, r in enumerate(results): + if "report" in r: + try: + rss_client.download(server_address, + server_file_transfer_port, + r["report"], test.debugdir) + except rss_client.FileTransferNotFoundError: + pass + if "logs" in r: + try: + rss_client.download(server_address, + server_file_transfer_port, + r["logs"], test.debugdir) + except rss_client.FileTransferNotFoundError: + pass + else: + try: + # Create symlinks to test log dirs to make it easier + # to access them (their original names are not human + # readable) + link_name = "logs_%s" % r["report"].split("\\")[-1] + link_name = link_name.replace(" ", "_") + link_name = link_name.replace("/", "_") + os.symlink(r["logs"].split("\\")[-1], + os.path.join(test.debugdir, link_name)) + except (KeyError, OSError): + pass + + # Print result summary (both to the regular logs and to a file named + # 'summary' in test.debugdir) + def print_summary_line(f, line): + logging.info(line) + f.write(line + "\n") + if results: + # Make sure all results have the required keys + for r in results: + r["id"] = str(r.get("id")) + r["job"] = str(r.get("job")) + r["status"] = str(r.get("status")) + r["pass"] = int(r.get("pass", 0)) + r["fail"] = int(r.get("fail", 0)) + r["notrun"] = int(r.get("notrun", 0)) + r["notapplicable"] = int(r.get("notapplicable", 0)) + # Sort the results by failures and total test count in descending order + results = [(r["fail"], + r["pass"] + r["fail"] + r["notrun"] + r["notapplicable"], + r) for r in results] + results.sort(reverse=True) + results = [r[-1] for r in results] + # Print results + logging.info("") + logging.info("Result summary:") + name_length = max(len(r["job"]) for r in results) + fmt = "%%-6s %%-%ds %%-15s %%-8s %%-8s %%-8s %%-15s" % name_length + f = open(os.path.join(test.debugdir, "summary"), "w") + print_summary_line(f, fmt % ("ID", "Job", "Status", "Pass", "Fail", + "NotRun", "NotApplicable")) + print_summary_line(f, fmt % ("--", "---", "------", "----", "----", + "------", "-------------")) + for r in results: + print_summary_line(f, fmt % (r["id"], r["job"], r["status"], + r["pass"], r["fail"], r["notrun"], + r["notapplicable"])) + f.close() + logging.info("(see logs and HTML reports in %s)", test.debugdir) + + # Kill the client VMs and fail if the automation program did not terminate + # on time + if not done: + virt_utils.parallel(vm.destroy for vm in vms) + raise error.TestFail("The automation program did not terminate " + "on time") + + # Fail if there are failed or incomplete jobs (kill the client VMs if there + # are incomplete jobs) + failed_jobs = [r["job"] for r in results + if r["status"].lower() == "investigate"] + running_jobs = [r["job"] for r in results + if r["status"].lower() == "inprogress"] + errors = [] + if failed_jobs: + errors += ["Jobs failed: %s." % failed_jobs] + if running_jobs: + for vm in vms: + vm.destroy() + errors += ["Jobs did not complete on time: %s." % running_jobs] + if errors: + raise error.TestFail(" ".join(errors)) diff --git a/client/virt/tests/yum_update.py b/client/virt/tests/yum_update.py new file mode 100644 index 0000000..7c9b96c --- /dev/null +++ b/client/virt/tests/yum_update.py @@ -0,0 +1,49 @@ +import logging, time + + +def internal_yum_update(session, command, prompt, timeout): + """ + Helper function to perform the yum update test. + + @param session: shell session stablished to the host + @param command: Command to be sent to the shell session + @param prompt: Machine prompt + @param timeout: How long to wait until we get an appropriate output from + the shell session. + """ + session.sendline(command) + end_time = time.time() + timeout + while time.time() < end_time: + match = session.read_until_last_line_matches( + ["[Ii]s this [Oo][Kk]", prompt], + timeout=timeout)[0] + if match == 0: + logging.info("Got 'Is this ok'; sending 'y'") + session.sendline("y") + elif match == 1: + logging.info("Got shell prompt") + return True + else: + logging.info("Timeout or process exited") + return False + + +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 = env.get_vm(params["main_vm"]) + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(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() -- 1.7.4