|
| 1 | +import re |
| 2 | + |
| 3 | +from virttest import env_process, error_context, utils_misc, utils_net |
| 4 | +from virttest.utils_windows import virtio_win |
| 5 | + |
| 6 | + |
| 7 | +@error_context.context_aware |
| 8 | +def run(test, params, env): |
| 9 | + """ |
| 10 | + Simulate high packet rate between host and device by running Python scripts |
| 11 | + on both server and client side. This test is executed on two VM guests: |
| 12 | +
|
| 13 | + 1) Start a VM guest as the server. |
| 14 | + 2) Start a VM guest as the client. |
| 15 | + 3) Simulate buffer allocation issues on the server node. |
| 16 | + 4) Use a Python script to connect the client to the server. |
| 17 | + 5) Adjust the MinRxBufferPercent parameter to work around the issue. |
| 18 | + 6) Ensure no BSOD occurs on the client node. |
| 19 | +
|
| 20 | + :param test: QEMU test object. |
| 21 | + :param params: Dictionary of test parameters. |
| 22 | + :param env: Dictionary of test environment details. |
| 23 | + """ |
| 24 | + |
| 25 | + def analyze_ping_results(session=None, dest=None, count=None, timeout=None): |
| 26 | + """ |
| 27 | + conduct a ping test to check the packet loss on slow memory buffer reallocation |
| 28 | +
|
| 29 | + :param session: Local executon hint or session to execute the ping command. |
| 30 | + :param dest: Destination address. |
| 31 | + :param count: Count of icmp packet. |
| 32 | + :param timeout: Timeout for the ping command. |
| 33 | + """ |
| 34 | + |
| 35 | + status, output = utils_net.ping( |
| 36 | + s_vm_ip, session=c_session, count=count, timeout=timeout |
| 37 | + ) |
| 38 | + if status != 0: |
| 39 | + test.fail("Ping failed, status: %s," " output: %s" % (status, output)) |
| 40 | + pattern = r"(\d+)% loss" |
| 41 | + match = re.search(pattern, output) |
| 42 | + if match: |
| 43 | + return match.group(1) |
| 44 | + |
| 45 | + def modify_and_analyze_params_result(vm=None, netkvmco_name=None, value=None): |
| 46 | + """ |
| 47 | + First set netkvm driver parameter 'param_name' |
| 48 | + to value 'param_value'. Then read the current and compare |
| 49 | + to 'param_value' to check identity Raised exception when |
| 50 | + checking netkvmco.exe setup was unsuccessful if something is wrong. |
| 51 | +
|
| 52 | + param vm: the selected vm |
| 53 | + param netkvmco_name: the netkvm driver parameter to modify |
| 54 | + param value: the value to set to |
| 55 | + """ |
| 56 | + virtio_win.prepare_netkvmco(vm) |
| 57 | + utils_net.set_netkvm_param_value(vm, netkvmco_name, value) |
| 58 | + cur_value = utils_net.get_netkvm_param_value(vm, netkvmco_name) |
| 59 | + if cur_value != value: |
| 60 | + test.fail(f"Current value '{cur_value}' was not equires '{value}'") |
| 61 | + |
| 62 | + timeout = params.get_numeric("login_timeout", 360) |
| 63 | + s_py_copy_cmd = params.get("s_py_copy_cmd") |
| 64 | + s_py_cmd = params.get("s_py_cmd") |
| 65 | + c_py_copy_cmd = params.get("c_py_copy_cmd") |
| 66 | + c_py_cmd = params.get("c_py_cmd") |
| 67 | + c_pip_copy_cmd = params.get("c_pip_copy_cmd") |
| 68 | + c_pip_cmd = params.get("c_pip_cmd") |
| 69 | + param_name = params.get("param_name") |
| 70 | + param_values = params.get("param_values") |
| 71 | + |
| 72 | + s_vm_name = params["vms"].split()[0] |
| 73 | + s_vm = env.get_vm(s_vm_name) |
| 74 | + s_vm.verify_alive() |
| 75 | + s_session = s_vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) |
| 76 | + s_vm_ip = s_vm.get_address() |
| 77 | + |
| 78 | + c_vm_name = params["vms"].split(s_vm_name)[1].strip() |
| 79 | + c_vm_params = params.object_params(c_vm_name) |
| 80 | + c_vm_params["nic_extra_params_nic1"] = "" |
| 81 | + c_vm_params["start_vm"] = "yes" |
| 82 | + env_process.preprocess_vm(test, c_vm_params, env, c_vm_name) |
| 83 | + c_vm = env.get_vm(c_vm_name) |
| 84 | + c_vm.verify_alive() |
| 85 | + c_session = c_vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) |
| 86 | + |
| 87 | + c_pip_copy_cmd = utils_misc.set_winutils_letter(c_session, c_pip_copy_cmd) |
| 88 | + c_session.cmd(c_pip_copy_cmd) |
| 89 | + c_session.cmd(c_pip_cmd) |
| 90 | + s_py_copy_cmd = utils_misc.set_winutils_letter(s_session, s_py_copy_cmd) |
| 91 | + s_session.cmd(s_py_copy_cmd) |
| 92 | + s_session.cmd(s_py_cmd) |
| 93 | + c_py_copy_cmd = utils_misc.set_winutils_letter(c_session, c_py_copy_cmd) |
| 94 | + c_session.cmd(c_py_copy_cmd) |
| 95 | + c_session.cmd(c_py_cmd % s_vm_ip) |
| 96 | + |
| 97 | + ping_results = [] |
| 98 | + for value in param_values.split(" "): |
| 99 | + modify_and_analyze_params_result(vm=s_vm, netkvmco_name=param_name, value=value) |
| 100 | + ping_results.append( |
| 101 | + int(analyze_ping_results(session=c_session, count=100, timeout=timeout)) |
| 102 | + ) |
| 103 | + |
| 104 | + if sum(ping_results) != 0: |
| 105 | + if not all( |
| 106 | + ping_results[i] > ping_results[i + 1] for i in range(len(ping_results) - 1) |
| 107 | + ): |
| 108 | + test.fail( |
| 109 | + "With the MinRxBufferPercent parameter, " |
| 110 | + "the number of lost packets should be less than without " |
| 111 | + "the MinRxBufferPercent parameter." |
| 112 | + ) |
| 113 | + |
| 114 | + for value in param_values.split(" "): |
| 115 | + modify_and_analyze_params_result(vm=c_vm, netkvmco_name=param_name, value=value) |
0 commit comments