diff --git a/qemu/tests/cfg/netkvm_buffer_shortage.cfg b/qemu/tests/cfg/netkvm_buffer_shortage.cfg new file mode 100644 index 0000000000..9a9d81e8f4 --- /dev/null +++ b/qemu/tests/cfg/netkvm_buffer_shortage.cfg @@ -0,0 +1,32 @@ +- netkvm_buffer_shortage: + virt_test_type = qemu + type = netkvm_buffer_shortage + only Windows + only virtio_net + vhost = on + timeout = 360 + cdroms += " virtio" + vms += " vm2" + image_snapshot = yes + start_vm = yes + start_vm_vm2 = no + smp = 2 + queues = ${smp} + vectors = 1024 + copy_dest = "C:" + nic_extra_params_nic1 = ",rx_queue_size=1024,tx_queue_size=256" + nic_extra_params_type = "{'rx_queue_size': int, 'tx_queue_size': int}" + i386: + psutil_whl = "psutil-6.1.1-cp37-abi3-win32.whl" + x86_64: + psutil_whl = "psutil-6.1.1-cp37-abi3-win_amd64.whl" + s_py = '.\server.py' + c_py = '.\client.py' + c_pip_copy_cmd = 'xcopy "WIN_UTILS:\packet_loss_scripts\${psutil_whl}" ${copy_dest}' + c_pip_cmd = "pushd ${copy_dest} & start py -m pip install ${psutil_whl}" + s_py_copy_cmd = 'xcopy "WIN_UTILS:\packet_loss_scripts\${s_py}" ${copy_dest}' + s_py_cmd = "pushd ${copy_dest} & start py ${s_py} 12345" + c_py_copy_cmd = 'xcopy "WIN_UTILS:\packet_loss_scripts\${c_py}" ${copy_dest}' + c_py_cmd = "pushd ${copy_dest} & start py ${c_py} 99999 %s 12345" + param_name = "MinRxBufferPercent" + param_values = "0 25 50 75 100" diff --git a/qemu/tests/netkvm_buffer_shortage.py b/qemu/tests/netkvm_buffer_shortage.py new file mode 100644 index 0000000000..db8989616e --- /dev/null +++ b/qemu/tests/netkvm_buffer_shortage.py @@ -0,0 +1,115 @@ +import re + +from virttest import env_process, error_context, utils_misc, utils_net +from virttest.utils_windows import virtio_win + + +@error_context.context_aware +def run(test, params, env): + """ + Simulate high packet rate between host and device by running Python scripts + on both server and client side. This test is executed on two VM guests: + + 1) Start a VM guest as the server. + 2) Start a VM guest as the client. + 3) Simulate buffer allocation issues on the server node. + 4) Use a Python script to connect the client to the server. + 5) Adjust the MinRxBufferPercent parameter to work around the issue. + 6) Ensure no BSOD occurs on the client node. + + :param test: QEMU test object. + :param params: Dictionary of test parameters. + :param env: Dictionary of test environment details. + """ + + def analyze_ping_results(session=None, dest=None, count=None, timeout=None): + """ + conduct a ping test to check the packet loss on slow memory buffer reallocation + + :param session: Local executon hint or session to execute the ping command. + :param dest: Destination address. + :param count: Count of icmp packet. + :param timeout: Timeout for the ping command. + """ + + status, output = utils_net.ping( + s_vm_ip, session=c_session, count=count, timeout=timeout + ) + if status != 0: + test.fail("Ping failed, status: %s," " output: %s" % (status, output)) + pattern = r"(\d+)% loss" + match = re.search(pattern, output) + if match: + return match.group(1) + + def modify_and_analyze_params_result(vm=None, netkvmco_name=None, value=None): + """ + First set netkvm driver parameter 'param_name' + to value 'param_value'. Then read the current and compare + to 'param_value' to check identity Raised exception when + checking netkvmco.exe setup was unsuccessful if something is wrong. + + param vm: the selected vm + param netkvmco_name: the netkvm driver parameter to modify + param value: the value to set to + """ + virtio_win.prepare_netkvmco(vm) + utils_net.set_netkvm_param_value(vm, netkvmco_name, value) + cur_value = utils_net.get_netkvm_param_value(vm, netkvmco_name) + if cur_value != value: + test.fail(f"Current value '{cur_value}' was not equires '{value}'") + + timeout = params.get_numeric("login_timeout", 360) + s_py_copy_cmd = params.get("s_py_copy_cmd") + s_py_cmd = params.get("s_py_cmd") + c_py_copy_cmd = params.get("c_py_copy_cmd") + c_py_cmd = params.get("c_py_cmd") + c_pip_copy_cmd = params.get("c_pip_copy_cmd") + c_pip_cmd = params.get("c_pip_cmd") + param_name = params.get("param_name") + param_values = params.get("param_values") + + s_vm_name = params["vms"].split()[0] + s_vm = env.get_vm(s_vm_name) + s_vm.verify_alive() + s_session = s_vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + s_vm_ip = s_vm.get_address() + + c_vm_name = params["vms"].split(s_vm_name)[1].strip() + c_vm_params = params.object_params(c_vm_name) + c_vm_params["nic_extra_params_nic1"] = "" + c_vm_params["start_vm"] = "yes" + env_process.preprocess_vm(test, c_vm_params, env, c_vm_name) + c_vm = env.get_vm(c_vm_name) + c_vm.verify_alive() + c_session = c_vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) + + c_pip_copy_cmd = utils_misc.set_winutils_letter(c_session, c_pip_copy_cmd) + c_session.cmd(c_pip_copy_cmd) + c_session.cmd(c_pip_cmd) + s_py_copy_cmd = utils_misc.set_winutils_letter(s_session, s_py_copy_cmd) + s_session.cmd(s_py_copy_cmd) + s_session.cmd(s_py_cmd) + c_py_copy_cmd = utils_misc.set_winutils_letter(c_session, c_py_copy_cmd) + c_session.cmd(c_py_copy_cmd) + c_session.cmd(c_py_cmd % s_vm_ip) + + ping_results = [] + for value in param_values.split(" "): + modify_and_analyze_params_result(vm=s_vm, netkvmco_name=param_name, value=value) + ping_results.append( + int(analyze_ping_results(session=c_session, count=100, timeout=timeout)) + ) + + if sum(ping_results) != 0: + if not all( + ping_results[i] > ping_results[i + 1] for i in range(len(ping_results) - 1) + ): + test.fail( + "With the MinRxBufferPercent parameter, " + "the number of lost packets should be less than without " + "the MinRxBufferPercent parameter." + ) + + for value in param_values: + modify_and_analyze_params_result(vm=c_vm, netkvmco_name=param_name, value=value)