diff --git a/qemu/tests/cfg/win_guest_debugging_tool.cfg b/qemu/tests/cfg/win_guest_debugging_tool.cfg new file mode 100644 index 0000000000..a0ede6dcc2 --- /dev/null +++ b/qemu/tests/cfg/win_guest_debugging_tool.cfg @@ -0,0 +1,87 @@ +- win_guest_debugging_tool: install setup image_copy unattended_install.cdrom + only Windows + type = win_guest_debugging_tool + tmp_dir = %TEMP% + runtimeout = 360 + shutdown_command = "shutdown -s -t 0" + reboot_command = "shutdown -r -t 0" + cmd_unrestrict_policy = 'powershell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force' + test_tmp_dir = "%TEMP%\testtmpdir" + cmd_create_dir = "mkdir %s >nul 2>&1" + cmd_remove_dir = "rmdir /S /Q %s" + cdroms += " virtio" + cdrom_virtio = isos/windows/virtio-win.iso + cmd_findstr_in_file = type %s | findstr "%s" + include_sensitive_data = False + variants:``` + - check_script_execution: + windegtool_check_type = script_execution + - check_zip_package: + windegtool_check_type = zip_package + cmd_extract_zip = 'powershell.exe Expand-Archive -Path "%s" -DestinationPath %s -Force' + cmd_check_folder_size = powershell -c "$folderPath='%s'; $folderSize=(Get-ChildItem -Path $folderPath -Recurse | Measure-Object -Property Length -Sum).Sum; Write-Output $folderSize" + - check_run_tools_multi_times: + windegtool_check_type = run_tools_multi_times + - check_user_friendliness: + windegtool_check_type = user_friendliness + cmd_kill_powershell_process = taskkill /IM powershell.exe /F; powershell.exe -Command "Stop-Process -Name msinfo32 -Force" + invalid_params = "-invalidparam,IncludeSensitiveData,0000,hell,-H,-IncludeSensitiveData -h" + expect_output_prompt = "Usage: .\CollectSystemInfo.ps1 [-IncludeSensitiveData] [-Help]" + script_interrupt_signal_file = 'Collecting_Status.txt' + cmd_dir_del = powershell.exe -Command "Remove-Item -Path '%s' -Recurse -Force -ErrorAction SilentlyContinue" + cmd_query_path = powershell.exe "$lastDir = dir | Select-String 'System*' | Select-Object -Last 1; write-output $lastDir" + - check_disk_registry_collection: + windegtool_check_type = disk_registry_collection + virtio_disk_filepath = "%s\virtio_disk.txt" + new_reg_item = "HKLM:\SYSTEM\CurrentControlSet\Services\viostor\Parameters" + exist_reg_item = "HKLM:\SYSTEM\CurrentControlSet\Services\Disk" + cmd_reg_query = powershell.exe -Command "(Get-ItemProperty -Path %s).%s" + cmd_reg_add_item = powershell.exe "if (-not (Test-Path -Path '%s')) {New-Item -Path %s | Out-Null}" + cmd_reg_add_item_key = powershell.exe "if (-not (Test-Path -Path '%s')) {New-Item -Path %s -Name %s -ItemType Key | Out-Null}" + cmd_reg_set_value = powershell.exe -Command "Set-ItemProperty -Path '%s' -Name '%s' -Value %d" + cmd_reg_del = powershell.exe -Command "Remove-Item -Path '%s' -Recurse -Force -ErrorAction SilentlyContinue" + reg_subkey1 = IoTimeoutValue + reg_subkey2 = TimeoutValue + key_value1 = 100 + key_value2 = 150 + - check_includeSensitiveData_collection: + windegtool_check_type = includeSensitiveData_collection + include_sensitive_data = True + timeout = 360 + reboot_method = system_reset + memory_dmp_file = "%SystemRoot%\Memory.dmp" + mini_dmp_folder = "%SystemRoot%\Minidump" + crash_method = nmi + cmd_check_files = powershell.exe ls %s + - check_trigger_driver_msinfo_collection: + windegtool_check_type = trigger_driver_msinfo_collection + image_snapshot = yes + transfer_timeout = 720 + msinfo_file_path = "%s\msinfo32.txt" + drv_list_file_path = "%s\drv_list.csv" + target_driver = pvpanic + cmd_query_oem_inf = powershell.exe -Command "pnputil.exe /enum-drivers | Select-String -Pattern '%s.inf' -Context 1,1 | ForEach-Object { if ($_ -match 'Published Name:\s+(oem\d+\.inf)') { $matches[1] } }" + cmd_install_driver = pnputil.exe /add-driver "%s.inf" /install + cmd_uninstall_driver = pnputil.exe /delete-driver %s /uninstall /force + cmd_scan_device = pnputil.exe /scan-devices + cmd_backup_driver = Export-WindowsDriver -Online -Destination "C:\DriverBackup" + cmd_check_driver_ver = powershell.exe -Command "Get-WmiObject Win32_PnPSignedDriver | Where-Object DeviceName -eq '%s'" + new_system_name = "NewsystemName" + cmd_change_systemname = powershell.exe -Command "Rename-Computer -NewName %s" + cmd_query_from_file = powershell.exe -Command "Get-Content %s | Select-String '%s'" + cmd_check_systemname = echo %computername% + - check_networkadapter_collection: + windegtool_check_type = networkadapter_collection + check_adapter_name = powershell.exe -Command "Get-NetAdapter | Select-Object -ExpandProperty Name" + check_adapter_jp_info = powershell.exe -Command "Get-NetAdapterAdvancedProperty -Name '%s' | Where-Object { $_.DisplayName -eq 'Jumbo Packet' } | Select-Object -ExpandProperty DisplayValue" + cmd_set_adapter_jp_info = powershell.exe -Command "Set-NetAdapterAdvancedProperty -Name '%s' -DisplayName 'Jumbo Packet' -DisplayValue %d" + cmd_disable_adapter = powershell.exe -Command "Disable-NetAdapter -Name '%s' -Confirm:$false" + cmd_enable_adapter = powershell.exe -Command "Enable-NetAdapter -Name '%s' -Confirm:$false" + networkfile_path = "%s\NetworkInterfaces.txt" + ipconfigfile_path = "%s\IPConfiguration.txt" + static_dns = 8.8.8.8 + cmd_get_dns = powershell.exe -Command (Get-DnsClientServerAddress -AddressFamily IPv4).ServerAddresses + cmd_set_dns = netsh interface ipv4 set dns name="%s" static %s + cmd_set_dns_dhcp = netsh interface ipv4 set dns name="%s" dhcp + - check_documentation: + windegtool_check_type = documentation \ No newline at end of file diff --git a/qemu/tests/win_guest_debugging_tool.py b/qemu/tests/win_guest_debugging_tool.py new file mode 100644 index 0000000000..d5513ebf37 --- /dev/null +++ b/qemu/tests/win_guest_debugging_tool.py @@ -0,0 +1,641 @@ +import logging +import time +import os +import re +import base64 +import random +import string +import json +import threading + +import aexpect + +from distutils.util import strtobool +from avocado.utils import genio +from avocado.utils import path as avo_path +from avocado.utils import process +from avocado.core import exceptions +from aexpect.exceptions import ShellTimeoutError + +from virttest import error_context +from virttest import guest_agent +from virttest import utils_misc +from virttest import utils_disk +from virttest import env_process +from virttest import utils_net +from virttest import data_dir +from virttest import storage +from virttest import qemu_migration +from virttest.utils_version import VersionInterval + +from virttest.utils_windows import virtio_win +from provider.win_driver_installer_test import (uninstall_gagent, + run_installer_with_interaction) + +LOG_JOB = logging.getLogger('avocado.test') + + +class BaseVirtTest(object): + + def __init__(self, test, params, env): + self.test = test + self.params = params + self.env = env + + def initialize(self, test, params, env): + if test: + self.test = test + if params: + self.params = params + if env: + self.env = env + start_vm = self.params["start_vm"] + self.start_vm = start_vm + if self.start_vm == "yes": + vm = self.env.get_vm(params["main_vm"]) + vm.verify_alive() + self.vm = vm + + def setup(self, test, params, env): + if test: + self.test = test + if params: + self.params = params + if env: + self.env = env + + def run_once(self, test, params, env): + if test: + self.test = test + if params: + self.params = params + if env: + self.env = env + + def before_run_once(self, test, params, env): + pass + + def after_run_once(self, test, params, env): + pass + + def cleanup(self, test, params, env): + pass + + def execute(self, test, params, env): + self.initialize(test, params, env) + self.setup(test, params, env) + try: + self.before_run_once(test, params, env) + self.run_once(test, params, env) + self.after_run_once(test, params, env) + finally: + self.cleanup(test, params, env) + + +class WinDebugToolTest(BaseVirtTest): + def __init__(self, test, params, env): + super().__init__(test, params, env) + self._open_session_list = [] + self.vm = None + self.script_name = "CollectSystemInfo.ps1" # Assuming script is named CollectSystemInfo.ps1 + + def _get_session(self, params, vm): + if not vm: + vm = self.vm + vm.verify_alive() + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + return session + + def _cleanup_open_session(self): + try: + for s in self._open_session_list: + if s: + s.close() + except Exception: + pass + + def run_once(self, test, params, env): + BaseVirtTest.run_once(self, test, params, env) + if self.start_vm == "yes": + pass + + def cleanup(self, test, params, env): + self._cleanup_open_session() + + @error_context.context_aware + def setup(self, test, params, env): + BaseVirtTest.setup(self, test, params, env) + if self.start_vm == "yes": + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + + # 创建工作目录 + error_context.context("Create tmp work dir since testing " + "would create lots of " + "dir and files.", LOG_JOB.info) + self.tmp_dir = params['test_tmp_dir'] + session.cmd_output(params['cmd_create_dir'] % self.tmp_dir) + + + def _check_tool_exist(self, test, params, session): + # will includ into above fuc run_once + error_context.context("Check whether debug tool exists.", LOG_JOB.info) + cmd_check_dir = params['cmd_check_dir' % debug_tool_path] + file_check_list = params['file_check_list'] + s, o = session.cmd_status_output(cmd_check_dir) + if s == 0 and o: + for file in file_check_list: + if file in o: + test.error('File %s should exist under %s' % (file, debug_tool_path)) + else: + test.error('The debug tool path doesn not exist. Please contact with vendor.') + return s == 1 + self.script_path = script_path + return s == 0 + + def _cleanup_files(self, log_folder, dump_folder, log_zip, dump_zip): + # 清理文件, 目录, powershell 命令: + 'Remove-Item -Recurse -Force "C:\ExtractedFiles"' + # This function can be customized to clean up or archive files after test + cmd_clean_logfoler(self.params[cmd_clean_files] % log_folder) + cmd_clean_dumpfolder(self.params[cmd_clean_files] % dump_folder) + cmd_clean_logzip(self.params[cmd_clean_files] % log_zip) + cmd_clean_dumpzip(self.params[cmd_clean_files] % dump_zip) + session.cmd(cmd_clean_logfolder) + if dump_folder: + session.cmd(cmd_clean_dumpfolder) + session.cmd(cmd_clean_logzip) + if dump_zip: + session.cmd(cmd_clean_dumpzip) + + def _check_file_zip(self, test, params, env): + # Check the folder and zip package + pass + + def _get_path(self, output, sensitive_data=False): + log_folder_path_pattern = r"Log folder path: (.+)" + dump_folder_path_pattern = r"Dump folder path: (.+)" + + log_folder_match = re.search(log_folder_path_pattern, output) + dump_folder_match = re.search(dump_folder_path_pattern, output) if sensitive_data else None + + log_folder_path = log_folder_match.group(1) + print(f"Log folder path: {log_folder_path}") + log_zip_path = log_folder_path + ".zip" + print(f"Log zip path: {log_zip_path}") + + if dump_folder_match: + dump_folder_path = dump_folder_match.group(1) + print(f"Dump folder path: {dump_folder_path}") + if dump_folder_path: + dump_zip_path = dump_folder_path + ".zip" + print(f"Dump zip path: {dump_zip_path}") + return log_folder_path, log_zip_path, dump_folder_path, dump_zip_path + else: + return log_folder_path, log_zip_path + + + +class WinDebugToolTestBasicCheck(WinDebugToolTest): + def __init__(self, test, params, env): + super().__init__(test, params, env) + self._open_session_list = [] + self.vm = None + self.script_name = "CollectSystemInfo.ps1" # Assuming script is named CollectSystemInfo.ps1 + + @error_context.context_aware + def run_tool_scripts(self, session, return_zip_path=False): + error_context.context("Run Debug tool script to Query original info or value.", LOG_JOB.info) + # Running the PowerShell script on the VM + include_sensitive_data = bool(strtobool(self.params['include_sensitive_data'])) + print(include_sensitive_data) + sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else "" + + # Execute the command on the VM + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {sensitive_data_flag}" + s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=360) + + log_folder_path, log_zip_path = self._get_path(o, sensitive_data=False) + if not (log_zip_path and log_folder_path): + test.fail("debug tool run failed, please check it.") + elif return_zip_path: + return log_folder_path, log_zip_path + else: + return log_folder_path + + @error_context.context_aware + def windegtool_check_script_execution(self, test, params, env): + if not self.vm: + self.vm = env.get_vm(params["main_vm"]) + self.vm.verify_alive() + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + # Running the PowerShell script on the VM + include_sensitive_data = bool(strtobool(self.params['include_sensitive_data'])) + print(include_sensitive_data) + sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else "" + + # Ensure the script runs with an unrestricted execution policy + cmd_unrestrict_policy = self.params['cmd_unrestrict_policy'] + session.cmd(cmd_unrestrict_policy) + + # Execute the command on the VM + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {sensitive_data_flag}" + s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=360) + + log_folder_path, log_zip_path = self._get_path(o, sensitive_data=False) + if not (log_zip_path and log_folder_path): + test.fail("debug tool run failed, please check it.") + + @error_context.context_aware + def windegtool_check_zip_package(self, test, params, env): + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + # Running the PowerShell script on the VM + include_sensitive_data = bool(strtobool(self.params['include_sensitive_data'])) + sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else "" + + # Ensure the script runs with an unrestricted execution policy + cmd_unrestrict_policy = self.params['cmd_unrestrict_policy'] + session.cmd(cmd_unrestrict_policy) + + error_context.context("Execute powershell script.", LOG_JOB.info) + # Execute the command on the VM + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {sensitive_data_flag}" + s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=360) + log_folder_path, log_zip_path = self._get_path(o, sensitive_data=include_sensitive_data) + if not (log_zip_path and log_folder_path): + test.fail("debug tool run failed, please check it.") + + error_context.context("Extract ZIP and check the data files.", LOG_JOB.info) + # cmd解压缩命令 + session.cmd("cd %s" % self.tmp_dir) + extract_folder = log_zip_path+"_extract" + s, o = session.cmd_status_output(params['cmd_extract_zip'] % (log_zip_path, extract_folder)) + if s: + test.error("Extract ZIP failed, please take a look and check.") + + error_context.context("Compare the folders", LOG_JOB.info) + # Check the size of unzip folder and original folder. + extract_folder_size = session.cmd_output(params["cmd_check_folder_size"] % extract_folder) + log_folder_size = session.cmd_output(params["cmd_check_folder_size"] % log_folder_path) + if log_folder_size != extract_folder_size: + test.fail("ZIP package have problem, since the size of it is not same with the original log folder.") + + @error_context.context_aware + def windegtool_check_run_tools_multi_times(self, test, params, env): + if not self.vm: + self.vm = env.get_vm(params["main_vm"]) + self.vm.verify_alive() + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + error_context.context("Run scripts 100 times and check there is no problem", LOG_JOB.info) + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + include_sensitive_data = bool(strtobool(self.params['include_sensitive_data'])) + sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else "" + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {sensitive_data_flag}" + for i in range(1, 5): + s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=360) + log_folder_path, log_zip_path = self._get_path(o, sensitive_data=include_sensitive_data) + print('+++++++++++++++++++++++') + print(log_folder_path, log_zip_path) + if not (log_zip_path and log_folder_path): + test.fail("debug tool run failed, please check it.") + cmd_remove_zip = params['cmd_remove_dir'] % log_zip_path + cmd_remove_folder = params['cmd_remove_dir'] % log_folder_path + cmd_clean_dir = ('%s && %s' % (cmd_remove_folder, cmd_remove_zip)) + session.cmd(cmd_clean_dir) + + @error_context.context_aware + def windegtool_check_user_friendliness(self, test, params, env): + + def run_script(session): + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path}" + try: + session.cmd_output(cmd_run_deg_tool, timeout=5) + except ShellTimeoutError: + pass + + def kill_powershell_process(session1): + session1.cmd(params['cmd_kill_powershell_process']) + session1.cmd(params['cmd_kill_powershell_process1']) + + if not self.vm: + self.vm = env.get_vm(params["main_vm"]) + self.vm.verify_alive() + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session1 = self._get_session(params, self.vm) + self._open_session_list.append(session1) + session.cmd("cd %s" % self.tmp_dir) + + error_context.context("Run script with various of invalid parameters.", LOG_JOB.info) + session.cmd("rd /S /Q %s" % self.tmp_dir) + session.cmd_output(params['cmd_create_dir'] % self.tmp_dir) + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + invalid_params = list(params['invalid_params'].split(",")) + expect_output_prompt = params['expect_output_prompt'] + for invalid_param in invalid_params: + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {invalid_param}" + o = session.cmd_output(cmd_run_deg_tool, timeout=360) + if expect_output_prompt not in o: + test.fail("There should be friendly reminder output %s, telling " + "users how to run the script with reasonable parameters" + "please check it." % expect_output_prompt) + + error_context.context("Interrupt script when it's running to check the signal file.", LOG_JOB.info) + script_thread = threading.Thread(target=run_script(session)) + kill_thread = threading.Thread(target=kill_powershell_process(session1)) + script_thread.start() + time.sleep(5) + kill_thread.start() + script_thread.join() + kill_thread.join() + + script_interrupt_signal_file = params['script_interrupt_signal_file'] + log_path = session.cmd_output(params['cmd_query_path']).split()[0] + session.cmd("cd %s" % log_path) + output = session.cmd_output("dir") + if script_interrupt_signal_file not in output: + test.fail(f"There should be one {script_interrupt_signal_file} once the script is interrupted, " + f"but there isn't. Please check it.") + + error_context.context("Clean invalid files and re-run script again to check " + "whether it could be run well.", LOG_JOB.info) + session.cmd("cd ../") + session.cmd(params['cmd_dir_del'] % log_path) + self.run_tool_scripts(session) + + @error_context.context_aware + def windegtool_check_disk_registry_collection(self, test, params, env): + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + error_context.context("Run script first to collect 'virtio_disk.txt'.", LOG_JOB.info) + log_folder_path = self.run_tool_scripts(session) + virtio_disk_filepath = params['virtio_disk_filepath'] % log_folder_path + exist_reg_item = params['exist_reg_item'] + reg_subkey1, reg_subkey2 = params["reg_subkey1"], params['reg_subkey2'] + print("++++++++++++++++++") + print("exist_reg_item+'\\'+reg_subkey1: %s" % exist_reg_item+"\\"+reg_subkey1) + iotimeoutvalue_file = int(session.cmd_output(params['cmd_findstr_in_file'] % + (virtio_disk_filepath, (exist_reg_item+"\\"+reg_subkey1))).split(":")[-1].strip()) + timeoutvalue_file = int(session.cmd_output(params['cmd_findstr_in_file'] % + (virtio_disk_filepath, (exist_reg_item+"\\"+reg_subkey2))).split(":")[-1].strip()) + iotimeoutvalue_cmd = int(session.cmd_output(params['cmd_reg_query'] % (exist_reg_item, reg_subkey1))) + timeoutvalue_cmd = int(session.cmd_output(params['cmd_reg_query'] % (exist_reg_item, reg_subkey2))) + print("iotimeoutvalue_file: %d\n timeoutvalue_file: %d\n iotimeoutvalue_cmd: %d\n timeoutvalue_cmd: %d\n" % (iotimeoutvalue_file, timeoutvalue_file, iotimeoutvalue_cmd, timeoutvalue_cmd)) + if iotimeoutvalue_cmd != iotimeoutvalue_file or timeoutvalue_cmd != timeoutvalue_file: + test.error("The value of %s and %s is not same between %s and cmd, please have a check" % (reg_subkey1, reg_subkey2, virtio_disk_filepath)) + + try: + error_context.context("Edit exist value and create new sub-key for vioscsi/viostor for non-exist value", LOG_JOB.info) + new_reg_item = params['new_reg_item'] + cmd_reg_add_item = params['cmd_reg_add_item'] % (new_reg_item, new_reg_item) + cmd_reg_add_item_key = params['cmd_reg_add_item_key'] + cmd_reg_set_value = params['cmd_reg_set_value'] + key_value1, key_value2 = int(params['key_value1']), int(params['key_value2']) + s, o = session.cmd_status_output(cmd_reg_add_item) + if not s: + session.cmd_output(cmd_reg_add_item_key % (new_reg_item, new_reg_item, reg_subkey1)) + session.cmd_output(cmd_reg_add_item_key % (new_reg_item, new_reg_item, reg_subkey2)) + else: + test.error("Add register item for vioscsi/viostor failed, please help check.") + + session.cmd_output(cmd_reg_set_value % (exist_reg_item, reg_subkey1, key_value1)) + session.cmd_output(cmd_reg_set_value % (new_reg_item, reg_subkey1, key_value1)) + session.cmd_output(cmd_reg_set_value % (new_reg_item, reg_subkey2, key_value2)) + + error_context.context("Re-run guest debug tool script", LOG_JOB.info) + new_log_folder_path = self.run_tool_scripts(session) + new_virtio_disk_filepath = params['virtio_disk_filepath'] % new_log_folder_path + exist_iotimeoutvalue_file = int(session.cmd_output(params['cmd_findstr_in_file'] % + (new_virtio_disk_filepath, (exist_reg_item + "\\" + reg_subkey1))).split(":")[-1].strip()) + new_iotimeoutvalue_file = int(session.cmd_output(params['cmd_findstr_in_file'] % + (new_virtio_disk_filepath, (new_reg_item + "\\" + reg_subkey1))).split(":")[-1].strip()) + new_timeoutvalue_file = int(session.cmd_output(params['cmd_findstr_in_file'] % + (new_virtio_disk_filepath, (new_reg_item + "\\" + reg_subkey2))).split(":")[-1].strip()) + exist_iotimeoutvalue_cmd = int(session.cmd_output(params['cmd_reg_query'] % (exist_reg_item, reg_subkey1))) + new_iotimeoutvalue_cmd = int(session.cmd_output(params['cmd_reg_query'] % (new_reg_item, reg_subkey1))) + new_timeoutvalue_cmd = int(session.cmd_output(params['cmd_reg_query'] % (new_reg_item, reg_subkey2))) + print(exist_iotimeoutvalue_file, new_iotimeoutvalue_file, new_timeoutvalue_file, exist_iotimeoutvalue_cmd, new_iotimeoutvalue_cmd, new_timeoutvalue_cmd) + if exist_iotimeoutvalue_cmd != exist_iotimeoutvalue_file or new_iotimeoutvalue_cmd != new_iotimeoutvalue_file or new_timeoutvalue_cmd != new_timeoutvalue_file: + test.error("The value of %s and %s is not same between %s and cmd, please have a check" % (reg_subkey1, reg_subkey2, new_log_folder_path)) + finally: + session.cmd_output(params['cmd_reg_del'] % new_reg_item) + session.cmd_output(cmd_reg_set_value % (exist_reg_item, reg_subkey1, iotimeoutvalue_cmd)) + + @error_context.context_aware + def windegtool_check_includeSensitiveData_collection(self, test, params, env): + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + + error_context.context("Trigger BSOD situation.", LOG_JOB.info) + crash_method = params["crash_method"] + if crash_method == "nmi": + timeout = int(params.get("timeout", 360)) + self.vm.monitor.nmi() + time.sleep(timeout) + self.vm.reboot(session, method=params["reboot_method"], timeout=timeout) + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + error_context.context("Check the dmp files are existed.", LOG_JOB.info) + cmd_check_dmp_files = params["cmd_check_files"] % params["memory_dmp_file"] + cmd_check_minidmp_files = params["cmd_check_files"] % params["mini_dmp_folder"] + output = session.cmd_output('%s && %s' % (cmd_check_dmp_files, cmd_check_minidmp_files)) + if 'dmp' not in output: + test.error("Dump file should be existed, please have a check") + else: + error_context.context("Execute debug tool script with sensitivedata.", LOG_JOB.info) + include_sensitive_data = bool(strtobool(self.params['include_sensitive_data'])) + sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else "" + self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1" + cmd_run_deg_tool = f"powershell.exe -ExecutionPolicy Bypass -File {self.script_path} {sensitive_data_flag}" + s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=360) + + log_folder_path, log_zip_path, dump_folder_path, dump_zip_path = self._get_path(o, sensitive_data=include_sensitive_data) + print('+++++++++++++++++++++++') + print(log_folder_path, log_zip_path, dump_folder_path, dump_zip_path) + if not (log_zip_path and log_folder_path, dump_zip_path, dump_folder_path): + test.fail("debug tool run failed, please check it.") + + @error_context.context_aware + def windegtool_check_trigger_driver_msinfo_collection(self, test, params, env): + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + + error_context.context("Run script firstly to check system name and driver info.", LOG_JOB.info) + log_path = self.run_tool_scripts(session) + msinfo_file_path = params['msinfo_file_path'] % log_path + drv_list_file_path = params['drv_list_file_path'] % log_path + target_driver = params["target_driver"] + + old_systemname = str(session.cmd_output(params["cmd_query_from_file"] % + (msinfo_file_path, "System Name:")).split(":")[1]).strip() + systemname_guest = str(session.cmd_output(params["cmd_check_systemname"])).strip() + if old_systemname != systemname_guest: + test.error("The system name are different between cmd and file that collect " + "by tool, Please have a check") + drvinfo_output = session.cmd_output(params["cmd_query_from_file"] % (drv_list_file_path, target_driver)) + if target_driver not in drvinfo_output: + test.error("%s doesn't installed, there is no info about it, " + "Please have a check and change another target driver to test") + + error_context.context("Change the system name and uninstall certain driver.", LOG_JOB.info) + session.cmd(params["cmd_change_systemname"]) + driver_oem_file = session.cmd_output(params["cmd_query_oem_inf"] % target_driver).strip() + s, o = session.cmd_status_output(params["cmd_uninstall_driver"] % driver_oem_file) + if s or "Fail" in o: + test.error("Fail to uninstall %s driver, please take a look." % target_driver) + else: + session.cmd(params["cmd_scan_device"]) + + error_context.context("Re-Run script after rebooting to check whether system name and driver info changed.", + LOG_JOB.info) + session.cmd_output(params["reboot_command"]) + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + + new_log_path = self.run_tool_scripts(session) + new_msinfo_file_path = params['msinfo_file_path'] % new_log_path + new_drv_list_file_path = params['drv_list_file_path'] % new_log_path + new_systemname = session.cmd_output(params["cmd_query_from_file"] % + (new_msinfo_file_path, "System Name:")).split(":")[1].strip() + if params["new_system_name"].upper() not in str(new_systemname): + test.fail("New systemname wasn't captured by tool, Please have a check") + new_drvinfo_output = session.cmd_output(params["cmd_query_from_file"] % (new_drv_list_file_path, target_driver)) + if target_driver in new_drvinfo_output: + test.fail("Driver should be uninstalled, but tool wasn't captured this situation, Please have a check") + + @error_context.context_aware + def windegtool_check_networkadapter_collection(self, test, params, env): + + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + error_context.context("Run tool script firstly, and conducting " + "raw data comparison tests", LOG_JOB.info) + adapter_name = session.cmd_output(params['check_adapter_name']).strip() + print("adapter_name: %s" % adapter_name) + original_log_path = self.run_tool_scripts(session) + + original_networkfile_path = params['networkfile_path'] % original_log_path + raw_jp_value_from_file = session.cmd_output(params['cmd_findstr_in_file'] % + (original_networkfile_path, "Jumbo Packet")) + original_jp_value_from_file = int(raw_jp_value_from_file.split()[5]) + original_jp_value_from_cmd = int(session.cmd_output(params['check_adapter_jp_info'] % adapter_name)) + print("++++++++++++++++++++") + print(original_jp_value_from_file, original_jp_value_from_cmd) + if original_jp_value_from_cmd != original_jp_value_from_file: + test.error("Network info collection seems have problem, the value of" + "Jumbo Packet is not same between file and cmd.") + + ipconfigfile_path = params['ipconfigfile_path'] % original_log_path + original_ipconfig_output = session.cmd_output(params['cmd_findstr_in_file'] % + (ipconfigfile_path, adapter_name)) + dns_info = session.cmd_output(params['cmd_get_dns']).split() + print("++++++++++++++++") + print(dns_info) + for dns_info_item in dns_info: + print("Yes DNS existed") if dns_info_item in original_ipconfig_output else print("No, DNS doesn't existed") + # if adapter_name not in original_ipconfig_output: + # test.error("Network Adapter has problem at the testing beginning, Please check it.") + + error_context.context("Change the dhcp and check whether the file changed", LOG_JOB.info) + static_dns = params['static_dns'] + # session.cmd_output(params['cmd_disable_adapter'] % adapter_name, timeout=360) + session.cmd_output(params['cmd_set_dns'] % (adapter_name, static_dns), timeout=360) + + log_folder_path_new = self.run_tool_scripts(session) + ipconfigfile_path = params['ipconfigfile_path'] % log_folder_path_new + new_ipconfig_output = session.cmd_output(params['cmd_findstr_in_file'] % (ipconfigfile_path, static_dns)) + print("+++++++++++++++++") + print("new_ipconfig_output: %s" % new_ipconfig_output) + if static_dns not in new_ipconfig_output: + test.fail("DNS should be changed but it's not, please check it.") + else: + error_context.context("Checkpoint is pass, Re-enable adapter for next checkpoint.", LOG_JOB.info) + session.cmd(params['cmd_set_dns_dhcp'] % adapter_name) + + error_context.context("Changed the 'Jumbo Packet' value and compare.", LOG_JOB.info) + try: + session.cmd_output(params['cmd_set_adapter_jp_info'] % (adapter_name, 9014), timeout=360) + except ShellTimeoutError: + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + + log_folder_path_new = self.run_tool_scripts(session) + networkfile_path = params['networkfile_path'] % log_folder_path_new + raw_jp_value = session.cmd_output(params['cmd_findstr_in_file'] % (networkfile_path, "Jumbo Packet")) + new_jp_value = int(raw_jp_value.split()[5]) + print("new_jp_value: %s" % new_jp_value) + if original_jp_value_from_file == new_jp_value: + test.fail("Jumbo Packet should not be same with the original one, please check it.") + if new_jp_value != 9014: + test.error("Jumbo Packet should be the new value, but it's not somehow, Please check it.") + + error_context.context("Recover the env.", LOG_JOB.info) + try: + session.cmd(params['cmd_set_adapter_jp_info'] % (adapter_name, original_jp_value_from_file)) + except ShellTimeoutError: + session = self._get_session(params, self.vm) + self._open_session_list.append(session) + session.cmd("cd %s" % self.tmp_dir) + change_back_jp_value = int(session.cmd_output(params['check_adapter_jp_info'] % adapter_name)) + if change_back_jp_value != original_jp_value_from_file: + test.error("Please have a check, the value wasn't changed back to original.") + + + @error_context.context_aware + def windegtool_check_documentation(self, test, params, env): + # 1. Check all relevant documents to ensure they are complete. (README.md,LICENSE,CollectSystemInfo.ps1) + # 2. Follow the script according to the documentation to ensure all steps and instructions are correct. + pass + + def run_once(self, test, params, env): + WinDebugToolTest.run_once(self, test, params, env) + + windegtool_check_type = self.params["windegtool_check_type"] + chk_type = "windegtool_check_%s" % windegtool_check_type + if hasattr(self, chk_type): + func = getattr(self, chk_type) + func(test, params, env) + else: + test.error("Could not find matching test, check your config file") + + +def run(test, params, env): + """ + Test CollectSystemInfo.ps1 tool, this case will: + 1) Start VM with virtio-win rpm package. + 2) Execute CollectSystemInfo.ps1 with&without param + '-IncludeSensitiveData'. + 3) Run some basic test for CollectSystemInfo.ps1. + + :param test: kvm test object + :param params: Dictionary with the test parameters + :param env: Dictionary with test environmen. + """ + + collectinfotool_test = WinDebugToolTestBasicCheck(test, params, env) + collectinfotool_test.execute(test, params, env) \ No newline at end of file