Skip to content

Commit

Permalink
win_guest_debugging_tool: Support new feature for first case
Browse files Browse the repository at this point in the history
win_guest_debugging_tool is a new feature for windows guest to
gather a wide range of information. including system configuration
 event logs, drivers, registry settings, update logs, services,
uptime, processes, installed applications,network configuration
 installed KBs (knowledge base articleand optionally, memory dumps
It's a powershell script is designed for comprehensive system
diagnostics.
So the first case is just run the script and checkout the output
files whether are exact same with official doc.

Signed-off-by: Dehan Meng <[email protected]>
  • Loading branch information
6-dehan committed Dec 30, 2024
1 parent b2108ff commit 3e2b3a3
Show file tree
Hide file tree
Showing 2 changed files with 274 additions and 0 deletions.
22 changes: 22 additions & 0 deletions qemu/tests/cfg/win_guest_debugging_tool.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- 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
target_files = "msinfo32.txt,system.evtx,security.evtx,application.evtx,drv_list.csv,virtio_disk.txt,WindowsUpdate.log,Services.csv,WindowsUptime.txt,RunningProcesses.csv,InstalledApplications.csv,InstalledKBs.csv,NetworkInterfaces.txt,IPConfiguration.txt,setupapi.dev.log,setupapi.setup.log,setupapi.offline.log,ErrorWindowsUpdate.log,OutputWindowsUpdate.log,LocaleMetaData"
target_dump_files = "MEMORY.DMP,Minidump"
script_name = "CollectSystemInfo.ps1"
cmd_search_file_global = powershell.exe -Command "Get-PSDrive -PSProvider FileSystem | ForEach-Object { Get-ChildItem -Path $_.Root -Recurse -Filter '%s' -ErrorAction SilentlyContinue } | ForEach-Object { Join-Path -Path $_.Directory.FullName -ChildPath $_.Name }"
variants:
- check_script_execution:
windegtool_check_type = script_execution
252 changes: 252 additions & 0 deletions qemu/tests/win_guest_debugging_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
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_dir = None
self.script_name = params.get("script_name", "") # Assuming script is named CollectSystemInfo.ps1
self.script_path = params.get("script_path", "")
self.tmp_dir = params.get("test_tmp_dir", "")

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("Check whether debug tool exists.", LOG_JOB.info)
cmd_get_debug_tool_script = params['cmd_search_file_global'] % self.script_name
script_path = str(session.cmd_output(cmd_get_debug_tool_script, timeout=360)).strip()
print("script_path: %s\n" % script_path)
if script_path:
self.script_path = script_path
self.script_dir = self.script_path.replace(self.script_name, "").rstrip("\\")
self.script_path = "%TEMP%\CollectSystemInfo.ps1"
else:
test.error("The tool script file CollectSystemInfo.ps1 was not found. Please check.")

error_context.context("Create tmp work dir since testing "
"would create lots of dir and files.", LOG_JOB.info)
session.cmd_output(params['cmd_create_dir'] % self.tmp_dir)

def _check_generated_files(self, session, path, sensitive_data=False):
output = str(session.cmd_output(f"dir /b {path}")).strip()
print(output)

target_files = (
self.params["target_dump_files"] if sensitive_data
else self.params["target_files"]
).split(',')

for target_file in target_files:
if target_file not in output:
self.test.error(f"{target_file} is not included, please check it.")

def _get_path(self, output, session, sensitive_data=False):
log_folder_path = re.search(r"Log folder path: (.+)", output).group(1)
self._check_generated_files(session, log_folder_path)
print(f"Log folder path: {log_folder_path}")
log_zip_path = f"{log_folder_path}.zip"
print(f"Log zip path: {log_zip_path}")

if sensitive_data:
dump_folder_match = re.search(r"Dump folder path: (.+)", output)
if dump_folder_match:
dump_folder_path = dump_folder_match.group(1)
self._check_generated_files(session, dump_folder_path, sensitive_data=True)
print(f"Dump folder path: {dump_folder_path}")
dump_zip_path = f"{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

return log_folder_path, log_zip_path


class WinDebugToolTestBasicCheck(WinDebugToolTest):
def __init__(self, test, params, env):
super().__init__(test, params, env)

@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
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)

paths = self._get_path(o, session, sensitive_data=include_sensitive_data)
if include_sensitive_data:
log_folder_path, log_zip_path, dump_folder_path, dump_zip_path = paths
if not all(paths):
test.fail("Debug tool run failed, please check it.")
return paths if return_zip_path else (log_folder_path, dump_folder_path)
else:
log_folder_path, log_zip_path = paths
if not all(paths):
test.fail("Debug tool run failed, please check it.")
return paths if return_zip_path else 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)

log_folder_path, log_zip_path = self.run_tool_scripts(session, return_zip_path=True)
if not (log_zip_path and log_folder_path):
test.fail("debug tool run failed, please check it.")

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)

0 comments on commit 3e2b3a3

Please sign in to comment.