Skip to content

Commit 59abb7b

Browse files
committed
win_guest_debugging_tool: Support new feature
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. Signed-off-by: Dehan Meng <[email protected]>
1 parent d516da1 commit 59abb7b

File tree

2 files changed

+332
-0
lines changed

2 files changed

+332
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
- win_guest_debugging_tool: install setup image_copy unattended_install.cdrom
2+
only Windows
3+
type = win_guest_debugging_tool
4+
tmp_dir = %TEMP%
5+
runtimeout = 360
6+
shutdown_command = "shutdown -s -t 0"
7+
reboot_command = "shutdown -r -t 0"
8+
cmd_unrestrict_policy = 'powershell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force'
9+
test_tmp_dir = "%TEMP%\testtmpdir"
10+
cmd_create_dir = "mkdir %s >nul 2>&1"
11+
cmd_remove_dir = "rmdir /S /Q %s" # 静默、递归删除
12+
cdroms += " virtio"
13+
cdrom_virtio = isos/windows/virtio-win.iso
14+
variants:
15+
- check_script_execution:
16+
windegtool_check_type = script_execution
17+
include_sensitive_data = False
18+
- check_zip_package:
19+
windegtool_check_type = zip_package
20+
cmd_extract_zip = 'powershell.exe Expand-Archive -Path "%s" -DestinationPath %s -Force'
21+
cmd_check_folder_size = powershell -c "$folderPath='%s'; $folderSize=(Get-ChildItem -Path $folderPath -Recurse | Measure-Object -Property Length -Sum).Sum; Write-Output $folderSize"
22+
- check_run_tools_multi_times:
23+
windegtool_check_type = run_tools_multi_times
24+
- check_user_friendliness:
25+
windegtool_check_type = user_friendliness
26+
- check_disk_registry_collection:
27+
windegtool_check_type = disk_registry_collection
28+
- check_includeSensitiveData_collection:
29+
windegtool_check_type = includeSensitiveData_collection
30+
include_sensitive_data = True
31+
- check_trigger_driver_collection:
32+
windegtool_check_type = trigger_driver_collection
33+
- check_networkadapter_collection:
34+
windegtool_check_type = networkadapter_collection
35+
- check_documentation:
36+
windegtool_check_type = documentation
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
import logging
2+
import time
3+
import os
4+
import re
5+
import base64
6+
import random
7+
import string
8+
import json
9+
10+
import aexpect
11+
12+
from avocado.utils import genio
13+
from avocado.utils import path as avo_path
14+
from avocado.utils import process
15+
from avocado.core import exceptions
16+
from aexpect.exceptions import ShellTimeoutError
17+
18+
from virttest import error_context
19+
from virttest import guest_agent
20+
from virttest import utils_misc
21+
from virttest import utils_disk
22+
from virttest import env_process
23+
from virttest import utils_net
24+
from virttest import data_dir
25+
from virttest import storage
26+
from virttest import qemu_migration
27+
from virttest.utils_version import VersionInterval
28+
29+
from virttest.utils_windows import virtio_win
30+
from provider.win_driver_installer_test import (uninstall_gagent,
31+
run_installer_with_interaction)
32+
33+
LOG_JOB = logging.getLogger('avocado.test')
34+
35+
36+
class BaseVirtTest(object):
37+
38+
def __init__(self, test, params, env):
39+
self.test = test
40+
self.params = params
41+
self.env = env
42+
43+
def initialize(self, test, params, env):
44+
if test:
45+
self.test = test
46+
if params:
47+
self.params = params
48+
if env:
49+
self.env = env
50+
start_vm = self.params["start_vm"]
51+
self.start_vm = start_vm
52+
if self.start_vm == "yes":
53+
vm = self.env.get_vm(params["main_vm"])
54+
vm.verify_alive()
55+
self.vm = vm
56+
57+
def setup(self, test, params, env):
58+
if test:
59+
self.test = test
60+
if params:
61+
self.params = params
62+
if env:
63+
self.env = env
64+
65+
def run_once(self, test, params, env):
66+
if test:
67+
self.test = test
68+
if params:
69+
self.params = params
70+
if env:
71+
self.env = env
72+
73+
def before_run_once(self, test, params, env):
74+
pass
75+
76+
def after_run_once(self, test, params, env):
77+
pass
78+
79+
def cleanup(self, test, params, env):
80+
pass
81+
82+
def execute(self, test, params, env):
83+
self.initialize(test, params, env)
84+
self.setup(test, params, env)
85+
try:
86+
self.before_run_once(test, params, env)
87+
self.run_once(test, params, env)
88+
self.after_run_once(test, params, env)
89+
finally:
90+
self.cleanup(test, params, env)
91+
92+
93+
class WinDebugToolTest(BaseVirtTest):
94+
def __init__(self, test, params, env):
95+
super().__init__(test, params, env)
96+
self._open_session_list = []
97+
self.vm = None
98+
self.script_name = "CollectSystemInfo.ps1" # Assuming script is named CollectSystemInfo.ps1
99+
100+
def _get_session(self, params, vm):
101+
if not vm:
102+
vm = self.vm
103+
vm.verify_alive()
104+
timeout = int(params.get("login_timeout", 360))
105+
session = vm.wait_for_login(timeout=timeout)
106+
return session
107+
108+
def _cleanup_open_session(self):
109+
try:
110+
for s in self._open_session_list:
111+
if s:
112+
s.close()
113+
except Exception:
114+
pass
115+
116+
def run_once(self, test, params, env):
117+
BaseVirtTest.run_once(self, test, params, env)
118+
if self.start_vm == "yes":
119+
pass
120+
121+
def cleanup(self, test, params, env):
122+
self._cleanup_open_session()
123+
124+
@error_context.context_aware
125+
def setup(self, test, params, env):
126+
BaseVirtTest.setup(self, test, params, env)
127+
if self.start_vm == "yes":
128+
session = self._get_session(params, self.vm)
129+
self._open_session_list.append(session)
130+
131+
# 创建工作目录
132+
error_context.context("Create tmp work dir since testing "
133+
"would create lots of "
134+
"dir and files.", LOG_JOB.info)
135+
self.tmp_dir = params['test_tmp_dir']
136+
session.cmd(params['cmd_create_dir'] % self.tmp_dir)
137+
138+
error_context.context("Change to the temporary "
139+
"work directory.", LOG_JOB.info)
140+
# 在工作临时目录中执行脚本
141+
session.cmd("cd %s" % self.tmp_dir)
142+
143+
144+
145+
def _check_tool_exist(self, test, params, session):
146+
# will includ into above fuc run_once
147+
error_context.context("Check whether debug tool exists.", LOG_JOB.info)
148+
cmd_check_dir = params['cmd_check_dir' % debug_tool_path]
149+
file_check_list = params['file_check_list']
150+
s, o = session.cmd_status_output(cmd_check_dir)
151+
if s == 0 and o:
152+
for file in file_check_list:
153+
if file in o:
154+
test.error('File %s should exist under %s' % (file, debug_tool_path))
155+
else:
156+
test.error('The debug tool path doesn not exist. Please contact with vendor.')
157+
return s == 1
158+
self.script_path = script_path
159+
return s == 0
160+
161+
def _cleanup_files(self, log_folder, dump_folder, log_zip, dump_zip):
162+
# 清理文件, 目录, powershell 命令:
163+
'Remove-Item -Recurse -Force "C:\ExtractedFiles"'
164+
# This function can be customized to clean up or archive files after test
165+
cmd_clean_logfoler(self.params[cmd_clean_files] % log_folder)
166+
cmd_clean_dumpfolder(self.params[cmd_clean_files] % dump_folder)
167+
cmd_clean_logzip(self.params[cmd_clean_files] % log_zip)
168+
cmd_clean_dumpzip(self.params[cmd_clean_files] % dump_zip)
169+
session.cmd(cmd_clean_logfolder)
170+
if dump_folder:
171+
session.cmd(cmd_clean_dumpfolder)
172+
session.cmd(cmd_clean_logzip)
173+
if dump_zip:
174+
session.cmd(cmd_clean_dumpzip)
175+
176+
def _check_file_zip(self, test, params, env):
177+
# Check the folder and zip package
178+
pass
179+
180+
181+
182+
class WinDebugToolTestBasicCheck(WinDebugToolTest):
183+
184+
@error_context.context_aware
185+
def windegtool_check_script_execution(self, test, params, env):
186+
if not self.vm:
187+
self.vm = env.get_vm(params["main_vm"])
188+
self.vm.verify_alive()
189+
190+
session = self._get_session(params, self.vm)
191+
self._open_session_list.append(session)
192+
# Running the PowerShell script on the VM
193+
include_sensitive_data = self.params.get("include_sensitive_data", False)
194+
sensitive_data_flag = "-IncludeSensitiveData" if include_sensitive_data else ""
195+
196+
# Ensure the script runs with an unrestricted execution policy
197+
cmd_unrestrict_policy = self.params['cmd_unrestrict_policy']
198+
session.cmd(cmd_unrestrict_policy)
199+
200+
# Execute the command on the VM
201+
self.script_path = "E:\\tools\\debug\\CollectSystemInfo.ps1"
202+
cmd_run_deg_tool = f"powershell {self.script_path} {sensitive_data_flag}"
203+
s, o = session.cmd_status_output(cmd_run_deg_tool, timeout=300)
204+
205+
log_folder_path_pattern = r"Log folder path: (.+)"
206+
log_folder_match = re.search(log_folder_path_pattern, o)
207+
if log_folder_match:
208+
log_folder_path = log_folder_match.group(1)
209+
print(f"Log folder path: {log_folder_path}")
210+
if log_folder_path:
211+
# 拼接 ZIP 文件路径
212+
log_zip_path = log_folder_path + ".zip"
213+
# 确保路径合法性
214+
log_zip_path = os.path.normpath(log_zip_path)
215+
print(f"Log zip path: {log_zip_path}")
216+
return log_folder_path, log_zip_path
217+
else:
218+
test.fail("debug tool run failed, please check it.")
219+
220+
@error_context.context_aware
221+
def windegtool_check_zip_package(self, test, params, env):
222+
error_context.context("Extract ZIP and check the data files.", LOG_JOB.info)
223+
# cmd解压缩命令
224+
session.cmd("cd %s" % self.tmp_dir)
225+
extract_folder = "zip_package"+"_extract"
226+
s, o = session.cmd_status_output(params['cmd_extract_zip'] % (zip_package, extract_folder))
227+
if s:
228+
test.error("Extract ZIP failed, please take a look and check.")
229+
230+
error_context.context("Compare the folders", LOG_JOB.info)
231+
# Check the size of unzip folder and original folder.
232+
extract_folder_size = session.cmd_output(params["cmd_check_folder_size"] % extract_folder)
233+
log_folder_size = session.cmd_output(params["cmd_check_folder_size"] % log_folder_path)
234+
if log_folder_size != extract_folder_size:
235+
test.fail("ZIP package have problem, since the size of it is not same with the original log folder.")
236+
237+
def windegtool_check_run_tools_multi_times(self, test, params, env):
238+
error_context.context("Run scripts 100 times and check there is no problem", LOG_JOB.info)
239+
# 1. cmd 运行脚本100次
240+
# 2. 检查所有文件是否都在
241+
242+
243+
def windegtool_check_user_friendliness(self, test, params, env):
244+
# 1. 运行无效参数, 看脚本是否可以运行
245+
#2. 运行脚本, 但是5秒钟后中断脚本运行, 查看:
246+
# 2.1 是否有'Collecting_Status.txt'来记录脚本运行进程, 以告知用户
247+
# 3. Clean the folder that was interrupted.
248+
# 3.1 `Remove - Item - Path.\SystemInfo_2024 - xx_xx - xx\ -ErrorActionSilentlyContinue - Force - Recurse`
249+
# 4. Re-running a script after an abnormal interruption
250+
pass
251+
252+
def windegtool_check_disk_registry_collection(self, test, param, env):
253+
254+
pass
255+
256+
def windegtool_check_includeSensitiveData_collection(self, test, param, env):
257+
pass
258+
259+
def windegtool_check_trigger_driver_collection(self, test, param, env):
260+
pass
261+
262+
def windegtool_check_networkadapter_collection(self, test, param, env):
263+
pass
264+
265+
def windegtool_check_documentation(self, test, param, env):
266+
# 1. Check all relevant documents to ensure they are complete. (README.md,LICENSE,CollectSystemInfo.ps1)
267+
# 2. Follow the script according to the documentation to ensure all steps and instructions are correct.
268+
pass
269+
270+
def run_once(self, test, params, env):
271+
WinDebugToolTest.run_once(self, test, params, env)
272+
273+
windegtool_check_type = self.params["windegtool_check_type"]
274+
chk_type = "windegtool_check_%s" % windegtool_check_type
275+
if hasattr(self, chk_type):
276+
func = getattr(self, chk_type)
277+
func(test, params, env)
278+
else:
279+
test.error("Could not find matching test, check your config file")
280+
281+
282+
def run(test, params, env):
283+
"""
284+
Test CollectSystemInfo.ps1 tool, this case will:
285+
1) Start VM with virtio-win rpm package.
286+
2) Execute CollectSystemInfo.ps1 with&without param
287+
'-IncludeSensitiveData'.
288+
3) Run some basic test for CollectSystemInfo.ps1.
289+
290+
:param test: kvm test object
291+
:param params: Dictionary with the test parameters
292+
:param env: Dictionary with test environmen.
293+
"""
294+
295+
collectinfotool_test = WinDebugToolTestBasicCheck(test, params, env)
296+
collectinfotool_test.execute(test, params, env)

0 commit comments

Comments
 (0)