diff --git a/qemu/tests/cfg/queues_number_test.cfg b/qemu/tests/cfg/queues_number_test.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c736211ac3a353c3a9b8e9e8e9688f806e8563e9 --- /dev/null +++ b/qemu/tests/cfg/queues_number_test.cfg @@ -0,0 +1,22 @@ +- queues_number_test: + only Linux + only virtio_net + queues = 4 + virt_test_type = qemu + type = queues_number_test + # netperf server is host, the netperf client is the main vm + wait_bg_time = 45 + run_bgstress = netperf_stress + repeat_counts = 90 + background_ping_time = 180 + netperf_test_duration = 180 + # netperf_para_sessions should bigger than queues parameter. + netperf_para_sessions = 6 + test_protocol = TCP_STREAM + netperf_output_unit = m + netperf_sizes = 1024 + netperf_server_link = netperf-2.7.1.tar.bz2 + netperf_client_link = ${netperf_server_link} + server_path = /var/tmp/ + client_path = ${server_path} + change_list = 1,2,1,3,1,4,1,4 diff --git a/qemu/tests/queues_number_test.py b/qemu/tests/queues_number_test.py new file mode 100644 index 0000000000000000000000000000000000000000..3c4464f477114970fefb60aa7abef8301829e988 --- /dev/null +++ b/qemu/tests/queues_number_test.py @@ -0,0 +1,213 @@ +import logging +import re +import os + +from virttest import error_context +from virttest import data_dir +from virttest import utils_net +from virttest import utils_test +from virttest import utils_misc +from virttest import utils_netperf + + +@error_context.context_aware +def run(test, params, env): + """ + MULTI_QUEUE chang queues number test + 1) Boot up VM, and login guest + 2) Enable the queues in guest + 3) Run netperf_and_ping test + 4) Change queues number repeatedly during netperf_and_ping stress testing + 5) Reboot VM + 6) Repeat above 1-4 steps + :param test: QEMU test object. + :param params: Dictionary with the test parameters. + :param env: Dictionary with test environment. + """ + def change_queues_number(ifname, q_number, queues_status=None): + """ + change queues number + """ + if not queues_status: + queues_status = get_queues_status(ifname) + mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number) + output = session_serial.cmd_output_safe(mq_set_cmd) + cur_queues_status = get_queues_status(ifname) + + err_msg = "" + expect_q_number = q_number + if q_number != queues_status[1] and q_number <= queues_status[0]: + if (cur_queues_status[1] != q_number + or cur_queues_status[0] != queues_status[0]): + err_msg = "Param is valid, but change queues failed, " + elif cur_queues_status != queues_status: + if q_number != queues_status[1]: + err_msg = "Param is invalid, " + err_msg += "Current queues value is not expected, " + expect_q_number = queues_status[1] + + if len(err_msg) > 0: + err_msg += "current queues set is %s, " % cur_queues_status[1] + err_msg += "max allow queues set is %s, " % cur_queues_status[0] + err_msg += "when run cmd: '%s', " % mq_set_cmd + err_msg += "expect queues are %s," % expect_q_number + err_msg += "expect max allow queues are %s, " % queues_status[0] + err_msg += "output: '%s'" % output + test.fail(err_msg) + + return cur_queues_status + + def get_queues_status(ifname): + """ + Get queues status + """ + mq_get_cmd = "ethtool -l %s" % ifname + nic_mq_info = session_serial.cmd_output_safe(mq_get_cmd) + queues_reg = re.compile(r"Combined:\s+(\d)", re.I) + queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines())) + if len(queues_info) != 2: + err_msg = "Oops, get guest queues info failed, " + err_msg += "make sure your guest support MQ.\n" + err_msg += "Check cmd is: '%s', " % mq_get_cmd + err_msg += "Command output is: '%s'." % nic_mq_info + test.cancel(err_msg) + return [int(x) for x in queues_info] + + def ping_test(dest_ip, ping_time, ping_lost_ratio): + """ + ping guest from host,until change queues finished. + """ + _, output = utils_net.ping(dest=dest_ip, timeout=ping_time) + packets_lost = utils_test.get_loss_ratio(output) + if packets_lost > ping_lost_ratio: + err = " %s%% packages lost during ping. " % packets_lost + err += "Ping command log:\n %s" % "\n".join( + output.splitlines()[-3:]) + test.fail(err) + + def netperf_test(): + """ + Netperf stress test for nic option. + """ + try: + n_server.start() + # Run netperf with message size defined in range. + netperf_test_duration = params.get_numeric("netperf_test_duration") + test_protocols = params.get("test_protocols", "TCP_STREAM") + netperf_output_unit = params.get("netperf_output_unit") + test_option = params.get("test_option", "") + test_option += " -l %s" % netperf_test_duration + if netperf_output_unit in "GMKgmk": + test_option += " -f %s" % netperf_output_unit + t_option = "%s -t %s" % (test_option, test_protocols) + n_client.bg_start(utils_net.get_host_ip_address(params), + t_option, + params.get_numeric("netperf_para_sessions"), + params.get("netperf_cmd_prefix", ""), + package_sizes=params.get("netperf_sizes")) + if utils_misc.wait_for(n_client.is_netperf_running, 10, 0, 1, + "Wait netperf test start"): + logging.info("Netperf test start successfully.") + else: + test.error("Can not start netperf client.") + utils_misc.wait_for( + lambda: not n_client.is_netperf_running(), + netperf_test_duration, 0, 5, + "Wait netperf test finish %ss" % netperf_test_duration) + finally: + n_server.stop() + + login_timeout = params.get_numeric("login_timeout", 360) + netperf_stress = params.get("run_bgstress") + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + vm.wait_for_serial_login(timeout=login_timeout) + guest_ip = vm.get_address() + n_client = utils_netperf.NetperfClient( + guest_ip, params.get("client_path"), + netperf_source=os.path.join(data_dir.get_deps_dir("netperf"), + params.get("netperf_client_link")), + client=params.get("shell_client"), + username=params.get("username"), + password=params.get("password"), + compile_option=params.get("compile_option", "")) + n_server = utils_netperf.NetperfServer( + utils_net.get_host_ip_address(params), + params.get("server_path", "/var/tmp"), + netperf_source=os.path.join(data_dir.get_deps_dir("netperf"), + params.get("netperf_server_link")), + password=params.get("hostpassword"), + compile_option=params.get("compile_option", "")) + wait_time = params.get_numeric("wait_bg_time") + ping_lost_ratio = params.get_numeric("background_ping_package_lost_ratio", 5) + ping_time = params.get_numeric("background_ping_time") + required_reboot = True + bg_test = True + try: + while bg_test: + session_serial = vm.wait_for_serial_login(timeout=login_timeout) + n_client.session = session_serial + error_context.context("Enable multi queues in guest.", logging.info) + for nic in vm.virtnet: + ifname = utils_net.get_linux_ifname(session_serial, nic.mac) + queues = int(nic.queues) + change_queues_number(ifname, queues) + error_context.context("Run test %s background" % netperf_stress, + logging.info) + stress_thread = utils_misc.InterruptedThread(netperf_test) + stress_thread.start() + utils_misc.wait_for(lambda: wait_time, 0, 5, + "Wait %s start background" % netperf_stress) + + # ping test + error_context.context("Ping guest from host", logging.info) + args = (guest_ip, ping_time, ping_lost_ratio) + bg_ping = utils_misc.InterruptedThread(ping_test, args) + bg_ping.start() + + error_context.context("Change queues number repeatedly", + logging.info) + repeat_counts = params.get_numeric("repeat_counts") + for nic in vm.virtnet: + queues = int(nic.queues) + if queues == 1: + logging.info("Nic with single queue, skip and continue") + continue + ifname = utils_net.get_linux_ifname(session_serial, nic.mac) + change_list = params.get("change_list").split(",") + for repeat_num in range(repeat_counts): + error_context.context("Change queues number -- %sth" + % repeat_num, logging.info) + queues_status = get_queues_status(ifname) + for q_number in change_list: + queues_status = change_queues_number(ifname, + int(q_number), + queues_status) + + logging.info("wait for background test finish") + try: + stress_thread.join() + except Exception as err: + err_msg = "Run %s test background error!\n " + err_msg += "Error Info: '%s'" + test.error(err_msg % (netperf_stress, err)) + + logging.info("Wait for background ping test finish.") + try: + bg_ping.join() + except Exception as err: + txt = "Fail to wait background ping test finish. " + txt += "Got error message %s" % err + test.fail(txt) + + if required_reboot: + logging.info("Rebooting guest ...") + vm.reboot() + required_reboot = False + else: + bg_test = False + finally: + n_server.cleanup(True) + n_client.cleanup(True) + if session_serial: + session_serial.close()