diff --git a/tests/ethtool.py b/tests/ethtool.py index c77ab2aa930f71d92ce108d64269dfc9a53604b5..96dd78d5ddafe878b5b687971bf74eb141831034 100644 --- a/tests/ethtool.py +++ b/tests/ethtool.py @@ -4,16 +4,24 @@ from autotest.client import utils from virttest import utils_net, utils_misc, remote, aexpect +@error.context_aware def run_ethtool(test, params, env): """ Test offload functions of ethernet device using ethtool 1) Log into a guest. - 2) Initialize the callback of sub functions. - 3) Enable/disable sub function of NIC. + 2) Saving ethtool configuration. + 3) Enable sub function of NIC. 4) Execute callback function. - 5) Check the return value. - 6) Restore original configuration. + 5) Disable sub function of NIC. + 6) Run callback function again. + 7) Run file transfer test. + 7.1) Creating file in source host. + 7.2) Listening network traffic with tcpdump command. + 7.3) Transfer file. + 7.4) Comparing md5sum of the files on guest and host. + 8) Repeat step 3 - 7. + 9) Restore original configuration. @param test: QEMU test object. @param params: Dictionary with the test parameters. @@ -41,7 +49,7 @@ def run_ethtool(test, params, env): return output - def ethtool_get(f_type): + def ethtool_get(session, f_type): feature_pattern = { 'tx': 'tx.*checksumming', 'rx': 'rx.*checksumming', @@ -60,14 +68,16 @@ def run_ethtool(test, params, env): logging.debug("(%s) %s: failed to get status", ethname, f_type) - def ethtool_set(f_type, status): + def ethtool_set(session, f_type, status): """ Set ethernet device offload status @param f_type: Offload type name @param status: New status will be changed to """ - logging.info("(%s) %s: set status %s", ethname, f_type, status) + txt = "Set ethernet device offload status." + txt += " (%s) %s: set status %s" % (ethname, f_type, status) + error.context(txt, logging.info) if status not in ["off", "on"]: return False @@ -80,6 +90,7 @@ def run_ethtool(test, params, env): send_cmd_safe(session, cmd) except aexpect.ShellCmdError, e: logging.error("%s, detail: %s", err_msg, e) + return False if ethtool_get(session, f_type) == status: return True @@ -88,20 +99,21 @@ def run_ethtool(test, params, env): return True - def ethtool_save_params(): - logging.info("Saving ethtool configuration") + def ethtool_save_params(session): + error.context("Saving ethtool configuration", logging.info) for i in supported_features: - feature_status[i] = ethtool_get(i) + feature_status[i] = ethtool_get(session, i) - def ethtool_restore_params(): - logging.info("Restoring ethtool configuration") + def ethtool_restore_params(session): + error.context("Restoring ethtool configuration", logging.info) for i in supported_features: - ethtool_set(i, feature_status[i]) + ethtool_set(session, i, feature_status[i]) def compare_md5sum(name): - logging.info("Comparing md5sum of the files on guest and host") + txt = "Comparing md5sum of the files on guest and host" + error.context(txt, logging.info) host_result = utils.hash_file(name, method="md5") try: o = session.cmd_output("md5sum %s" % name) @@ -122,15 +134,15 @@ def run_ethtool(test, params, env): @return: Tuple (status, error msg/tcpdump result) """ sess = vm.wait_for_login(timeout=login_timeout) - sess.cmd_output("rm -rf %s" % filename) - + session.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: %s" % dd_cmd) - - logging.info("Creating file in %s, cmd: %s", src, dd_cmd) - tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh" + failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd) + txt = "Creating file in source host, cmd: %s" % dd_cmd + error.context(txt, logging.info) + ethname = utils_net.get_linux_ifname(session, + vm.get_mac_address(0)) + tcpdump_cmd = "tcpdump -lep -i %s -s 0 tcp -vv port ssh" % ethname if src == "guest": tcpdump_cmd += " and src %s" % guest_ip copy_files_func = vm.copy_files_from @@ -148,18 +160,20 @@ def run_ethtool(test, params, env): # 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")) + utils.system_output("/bin/netstat -nap")) for i in original_tcp_ports: tcpdump_cmd += " and not port %s" % i - logging.debug("Listening traffic using command: %s", tcpdump_cmd) + txt = "Listening traffic using command: %s" % tcpdump_cmd + error.context(txt, logging.info) sess.sendline(tcpdump_cmd) if not utils_misc.wait_for( - lambda:session.cmd_status("pgrep tcpdump") == 0, 30): + lambda:session.cmd_status("pgrep tcpdump") == 0, 30): return (False, "Tcpdump process wasn't launched") - logging.info("Transfering file %s from %s", filename, src) + txt = "Transfering file %s from %s" % (filename, src) + error.context(txt, logging.info) try: copy_files_func(filename, filename) except remote.SCPError, e: @@ -197,7 +211,7 @@ def run_ethtool(test, params, env): if not s: logging.error(o) return False - logging.info("Check if contained large frame") + error.context("Check if contained large frame", logging.info) # 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) @@ -213,15 +227,18 @@ def run_ethtool(test, params, env): vm = env.get_vm(params["main_vm"]) vm.verify_alive() + error.context("Log into a guest.", logging.info) login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) # Let's just error the test if we identify that there's no ethtool installed + error.context("Check whether ethtool installed in guest.") session.cmd("ethtool -h") mtu = 1514 feature_status = {} filename = "/tmp/ethtool.dd" guest_ip = vm.get_address() + error.context("Try to get ethernet device name in guest.") ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) supported_features = params.get("supported_features") @@ -240,34 +257,36 @@ def run_ethtool(test, params, env): "gro": (ro_callback, ("rx",), ("lro",)), "lro": (rx_callback, (), ("gro",)), } - ethtool_save_params() + ethtool_save_params(session) failed_tests = [] 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"): + if not ethtool_set(session, i, "off"): e_msg = "Failed to disable %s" % i logging.error(e_msg) failed_tests.append(e_msg) for i in [f for f in test_matrix[f_type][1]] + [f_type]: - if not ethtool_set(i, "on"): + if not ethtool_set(session, i, "on"): e_msg = "Failed to enable %s" % i logging.error(e_msg) failed_tests.append(e_msg) - + txt = "Run callback function %s" % callback.func_name + error.context(txt, logging.info) if not callback(status="on"): e_msg = "Callback failed after enabling %s" % f_type logging.error(e_msg) failed_tests.append(e_msg) - if not ethtool_set(f_type, "off"): + if not ethtool_set(session, f_type, "off"): e_msg = "Failed to disable %s" % f_type logging.error(e_msg) failed_tests.append(e_msg) - + txt = "Run callback function %s" % callback.func_name + error.context(txt, logging.info) if not callback(status="off"): e_msg = "Callback failed after disabling %s" % f_type logging.error(e_msg)