chore: 同步本地更改
- 新增 aio-mcp 项目框架 - 新增 .trae/skills/ OCR/SKU 设计工具 - 更新 auto-check 配置和 stress 包 - 删除 fnhelp 文档目录 - 更新 Docker 压力测试脚本
This commit is contained in:
757
auto-check/docker/stress-test/vendor/fnscript/script/self_inspection.py
vendored
Normal file
757
auto-check/docker/stress-test/vendor/fnscript/script/self_inspection.py
vendored
Normal file
@@ -0,0 +1,757 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import subprocess
|
||||
import psutil
|
||||
import time
|
||||
import signal
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
# 尝试导入textual库,如果不存在则设置标志
|
||||
HAS_TEXTUAL = True
|
||||
try:
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.widgets import Header, Footer, Static, Button, Label, Input
|
||||
from textual.containers import Container, Horizontal, Vertical
|
||||
from textual.screen import Screen, ModalScreen
|
||||
import asyncio
|
||||
except ImportError:
|
||||
HAS_TEXTUAL = False
|
||||
# 如果没有textual但尝试无参数运行,我们需要提示用户
|
||||
if len(sys.argv) == 1:
|
||||
print("错误: 未安装textual库,无法启动图形界面。")
|
||||
print("您可以通过命令行参数使用此脚本的核心功能:")
|
||||
print(" 内存测试: python self_inspection.py --memory")
|
||||
print(" CPU测试: python self_inspection.py --cpu [测试时长(秒)]")
|
||||
print(" 查看帮助: python self_inspection.py -h")
|
||||
sys.exit(1)
|
||||
|
||||
# 定义颜色常量(保留以兼容原始代码)
|
||||
RESET = "\033[0m"
|
||||
BOLD = "\033[1m"
|
||||
RED = "\033[31m"
|
||||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
BLUE = "\033[34m"
|
||||
MAGENTA = "\033[35m"
|
||||
CYAN = "\033[36m"
|
||||
WHITE = "\033[37m"
|
||||
|
||||
# 全局变量存储当前运行的进程
|
||||
current_process = None
|
||||
|
||||
# 工具函数
|
||||
def clear_screen():
|
||||
"""清空终端屏幕"""
|
||||
os.system('clear' if os.name == 'posix' else 'cls')
|
||||
|
||||
def get_test_memory():
|
||||
"""计算可用于测试的内存 (剩余内存的 97%)"""
|
||||
available_memory = psutil.virtual_memory().available // (1024 * 1024) # 获取可用内存 (MB)
|
||||
return int(available_memory * 0.97) # 取 97% 进行测试
|
||||
|
||||
def check_memory_usage():
|
||||
"""检查当前内存使用情况"""
|
||||
return psutil.virtual_memory().percent
|
||||
|
||||
def run_command(command):
|
||||
"""执行命令并返回结果"""
|
||||
global current_process
|
||||
|
||||
result = {
|
||||
'status_code': 0,
|
||||
'stdout': '',
|
||||
'stderr': ''
|
||||
}
|
||||
|
||||
try:
|
||||
# 保存进程引用以便后续可以终止
|
||||
current_process = subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
bufsize=1
|
||||
)
|
||||
|
||||
# 等待进程完成
|
||||
stdout, stderr = current_process.communicate()
|
||||
|
||||
# 获取返回码
|
||||
result['status_code'] = current_process.returncode
|
||||
result['stdout'] = stdout
|
||||
result['stderr'] = stderr
|
||||
|
||||
# 清除当前进程引用
|
||||
current_process = None
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
if current_process:
|
||||
try:
|
||||
current_process.terminate()
|
||||
except:
|
||||
pass
|
||||
current_process = None
|
||||
|
||||
result['status_code'] = 1
|
||||
result['stderr'] = str(e)
|
||||
return result
|
||||
|
||||
def stop_current_process():
|
||||
"""停止当前正在运行的进程"""
|
||||
global current_process
|
||||
if current_process:
|
||||
try:
|
||||
current_process.terminate()
|
||||
# 给进程一点时间来终止
|
||||
time.sleep(0.5)
|
||||
# 如果进程还在运行,强制结束
|
||||
if current_process.poll() is None:
|
||||
current_process.kill()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
finally:
|
||||
current_process = None
|
||||
return False
|
||||
|
||||
# 命令行直接执行内存测试的函数
|
||||
def cli_memory_test():
|
||||
"""通过命令行直接执行内存测试"""
|
||||
memory_usage = check_memory_usage()
|
||||
|
||||
if memory_usage > 80:
|
||||
print(f"警告: 当前系统内存使用率已达 {memory_usage}%!")
|
||||
print("建议关闭一些软件后再运行,继续运行可能检测效果不够准确")
|
||||
print("是否继续? (y/n)")
|
||||
response = input().strip().lower()
|
||||
if response != 'y':
|
||||
print("操作已取消")
|
||||
return False
|
||||
|
||||
print("建议关闭所有docker容器以及停用所有应用程序以保证检测的准确性。")
|
||||
print("是否继续? (y/n)")
|
||||
response = input().strip().lower()
|
||||
if response != 'y':
|
||||
print("操作已取消")
|
||||
return False
|
||||
|
||||
mem_size = f"{get_test_memory()}M"
|
||||
print("正在运行内存测试,请勿进行其它操作,如果运行过程中出现死机重启则大概率为内存问题。")
|
||||
print("整个测试过程预计 30-120 分钟 具体根据内存大小,如果需要终止测试请按Ctrl+C。")
|
||||
|
||||
try:
|
||||
# 设置信号处理器以便可以通过Ctrl+C终止测试
|
||||
def signal_handler(sig, frame):
|
||||
print("\n测试已被用户终止")
|
||||
stop_current_process()
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
# 执行测试
|
||||
result = run_command(["sudo", "memtester", mem_size, "1"])
|
||||
|
||||
if result['status_code'] == 0:
|
||||
print("内存测试完成!未发现问题。")
|
||||
return True
|
||||
else:
|
||||
print(f"内存测试失败!错误信息:{result['stderr']}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
# 命令行直接执行CPU测试的函数
|
||||
def cli_cpu_test(duration=60):
|
||||
"""通过命令行直接执行CPU测试
|
||||
|
||||
Args:
|
||||
duration (int): 测试持续时间(秒),默认为60秒
|
||||
"""
|
||||
try:
|
||||
duration = int(duration)
|
||||
if duration <= 0:
|
||||
print("错误: 测试时长必须大于0")
|
||||
return False
|
||||
except ValueError:
|
||||
print("错误: 测试时长必须是一个有效的整数")
|
||||
return False
|
||||
|
||||
print(f"正在进行 CPU 压测,持续 {duration} 秒...如需提前结束测试,请按Ctrl+C。")
|
||||
|
||||
try:
|
||||
# 设置信号处理器以便可以通过Ctrl+C终止测试
|
||||
def signal_handler(sig, frame):
|
||||
print("\n测试已被用户终止")
|
||||
stop_current_process()
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
# 执行测试
|
||||
result = run_command(["stress", "--cpu", "4", "--timeout", str(duration)])
|
||||
|
||||
if result['status_code'] == 0:
|
||||
print("CPU 压测完成!未发现问题。")
|
||||
return True
|
||||
else:
|
||||
print(f"CPU 压测失败!错误信息:{result['stderr']}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生错误: {str(e)}")
|
||||
return False
|
||||
|
||||
def parse_arguments():
|
||||
"""解析命令行参数"""
|
||||
parser = argparse.ArgumentParser(description='系统健康检测工具')
|
||||
parser.add_argument('--memory', action='store_true',
|
||||
help='执行内存测试')
|
||||
parser.add_argument('--cpu', nargs='?', const=60, type=int,
|
||||
help='执行CPU压测,可选参数为测试时长(秒),默认为60秒')
|
||||
return parser.parse_args()
|
||||
|
||||
# 只有在导入了textual库的情况下才定义这些类
|
||||
if HAS_TEXTUAL:
|
||||
# 确认对话框
|
||||
class ConfirmDialog(ModalScreen):
|
||||
"""确认对话框"""
|
||||
|
||||
def __init__(self, message: str, action_callback=None):
|
||||
super().__init__()
|
||||
self.message = message
|
||||
self.action_callback = action_callback
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Container(id="dialog-container"):
|
||||
yield Label(f"[yellow]{self.message}[/yellow]", id="dialog-title")
|
||||
with Horizontal(id="dialog-buttons"):
|
||||
yield Button("确认", id="confirm", variant="primary")
|
||||
yield Button("取消", id="cancel", variant="error")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
if event.button.id == "confirm" and self.action_callback:
|
||||
self.dismiss(True)
|
||||
self.action_callback()
|
||||
else:
|
||||
self.dismiss(False)
|
||||
|
||||
# 成功提示对话框
|
||||
class SuccessDialog(ModalScreen):
|
||||
"""成功提示对话框"""
|
||||
|
||||
def __init__(self, message: str):
|
||||
super().__init__()
|
||||
self.message = message
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Container(id="dialog-container"):
|
||||
yield Label(f"[green]{self.message}[/green]", id="dialog-title")
|
||||
with Horizontal(id="dialog-buttons"):
|
||||
yield Button("确定", id="ok", variant="primary")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
self.dismiss(True)
|
||||
|
||||
# 错误提示对话框
|
||||
class ErrorDialog(ModalScreen):
|
||||
"""错误提示对话框"""
|
||||
|
||||
def __init__(self, message: str):
|
||||
super().__init__()
|
||||
self.message = message
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Container(id="dialog-container"):
|
||||
yield Label(f"[red]{self.message}[/red]", id="dialog-title")
|
||||
with Horizontal(id="dialog-buttons"):
|
||||
yield Button("确定", id="ok", variant="primary")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
self.dismiss(True)
|
||||
|
||||
# 输入对话框
|
||||
class InputDialog(ModalScreen):
|
||||
"""输入对话框"""
|
||||
|
||||
def __init__(self, message: str, default_value: str = "", action_callback=None):
|
||||
super().__init__()
|
||||
self.message = message
|
||||
self.default_value = default_value
|
||||
self.action_callback = action_callback
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Container(id="dialog-container"):
|
||||
yield Label(f"[blue]{self.message}[/blue]", id="dialog-title")
|
||||
yield Input(value=self.default_value, id="input-field")
|
||||
with Horizontal(id="dialog-buttons"):
|
||||
yield Button("确认", id="confirm", variant="primary")
|
||||
yield Button("取消", id="cancel", variant="error")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
if event.button.id == "confirm" and self.action_callback:
|
||||
input_value = self.query_one("#input-field", Input).value
|
||||
self.dismiss(input_value)
|
||||
self.action_callback(input_value)
|
||||
else:
|
||||
self.dismiss(None)
|
||||
|
||||
class SystemHealthApp(App):
|
||||
CSS = """
|
||||
Screen {
|
||||
background: $surface;
|
||||
}
|
||||
|
||||
#title {
|
||||
dock: top;
|
||||
text-align: center;
|
||||
text-style: bold;
|
||||
background: $accent;
|
||||
color: $text;
|
||||
padding: 1;
|
||||
margin-bottom: 1;
|
||||
}
|
||||
|
||||
#main-container {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 1;
|
||||
}
|
||||
|
||||
#menu-container {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 1;
|
||||
border: solid $primary;
|
||||
padding: 1;
|
||||
}
|
||||
|
||||
.menu-button {
|
||||
margin: 1;
|
||||
min-width: 30;
|
||||
min-height: 3;
|
||||
background: $primary;
|
||||
color: $text;
|
||||
border: tall $primary-lighten-2;
|
||||
}
|
||||
|
||||
#memory-test {
|
||||
background: $success-darken-1;
|
||||
color: $text;
|
||||
border: tall $success;
|
||||
}
|
||||
|
||||
#cpu-test {
|
||||
background: $warning-darken-1;
|
||||
color: $text;
|
||||
border: tall $warning;
|
||||
}
|
||||
|
||||
#stop-test {
|
||||
background: $error-darken-1;
|
||||
color: $text;
|
||||
border: tall $error;
|
||||
margin: 1;
|
||||
min-width: 30;
|
||||
min-height: 3;
|
||||
}
|
||||
|
||||
#status {
|
||||
height: auto;
|
||||
min-height: 3;
|
||||
margin: 1;
|
||||
padding: 1;
|
||||
border: solid $accent;
|
||||
background: $surface-darken-1;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
#dialog-container {
|
||||
width: 60%;
|
||||
height: auto;
|
||||
padding: 2;
|
||||
background: $surface;
|
||||
border: thick $accent;
|
||||
margin: 1 0;
|
||||
}
|
||||
|
||||
/* 成功对话框样式 */
|
||||
SuccessDialog #dialog-container {
|
||||
border: thick $success;
|
||||
}
|
||||
|
||||
/* 错误对话框样式 */
|
||||
ErrorDialog #dialog-container {
|
||||
border: thick $error;
|
||||
}
|
||||
|
||||
/* 确认对话框样式 */
|
||||
ConfirmDialog #dialog-container {
|
||||
border: thick $warning;
|
||||
}
|
||||
|
||||
/* 输入对话框样式 */
|
||||
InputDialog #dialog-container {
|
||||
border: thick $primary;
|
||||
}
|
||||
|
||||
#dialog-title {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-bottom: 2;
|
||||
}
|
||||
|
||||
#input-field {
|
||||
margin-bottom: 1;
|
||||
}
|
||||
|
||||
#dialog-buttons {
|
||||
align: center middle;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#dialog-buttons Button {
|
||||
margin: 0 2;
|
||||
min-width: 10;
|
||||
}
|
||||
|
||||
/* 按钮样式增强 */
|
||||
Button {
|
||||
background: $primary;
|
||||
border: tall $primary-lighten-2;
|
||||
padding: 1 2;
|
||||
}
|
||||
|
||||
Button:hover {
|
||||
background: $primary-lighten-1;
|
||||
}
|
||||
|
||||
Button#confirm {
|
||||
background: $success-darken-1;
|
||||
border: tall $success;
|
||||
}
|
||||
|
||||
Button#confirm:hover {
|
||||
background: $success;
|
||||
}
|
||||
|
||||
Button#cancel, Button#stop-test {
|
||||
background: $error-darken-1;
|
||||
border: tall $error;
|
||||
}
|
||||
|
||||
Button#cancel:hover, Button#stop-test:hover {
|
||||
background: $error;
|
||||
}
|
||||
|
||||
Button#ok {
|
||||
background: $primary-darken-1;
|
||||
border: tall $primary;
|
||||
}
|
||||
|
||||
Button#ok:hover {
|
||||
background: $primary;
|
||||
}
|
||||
"""
|
||||
|
||||
BINDINGS = [
|
||||
("q", "quit", "退出"),
|
||||
("escape", "quit", "退出"),
|
||||
("ctrl+c", "stop_test", "停止测试"),
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.is_testing = False
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Header(show_clock=True)
|
||||
yield Footer()
|
||||
|
||||
with Container(id="main-container"):
|
||||
yield Label("[b]系统健康检测工具[/b]", id="title")
|
||||
|
||||
with Container(id="menu-container"):
|
||||
yield Button("内存检测 (使用 memtester)", id="memory-test", classes="menu-button")
|
||||
yield Button("CPU 压测", id="cpu-test", classes="menu-button")
|
||||
yield Button("停止当前测试", id="stop-test", disabled=True)
|
||||
|
||||
# 状态输出
|
||||
yield Static("准备就绪,请选择检测项目。", id="status")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""按钮点击事件处理"""
|
||||
button_id = event.button.id
|
||||
|
||||
if button_id == "memory-test":
|
||||
self.start_memory_test()
|
||||
elif button_id == "cpu-test":
|
||||
self.start_cpu_test()
|
||||
elif button_id == "stop-test":
|
||||
self.stop_test()
|
||||
|
||||
def action_stop_test(self) -> None:
|
||||
"""键盘快捷键停止测试"""
|
||||
self.stop_test()
|
||||
|
||||
def stop_test(self) -> None:
|
||||
"""停止当前测试"""
|
||||
if not self.is_testing:
|
||||
return
|
||||
|
||||
status = self.query_one("#status")
|
||||
status.update("[yellow]正在停止测试...[/yellow]")
|
||||
|
||||
# 停止当前进程
|
||||
if stop_current_process():
|
||||
status.update("[green]测试已停止。[/green]")
|
||||
self.show_success_dialog("测试已成功停止。")
|
||||
else:
|
||||
status.update("[red]无法停止测试,可能测试已经完成。[/red]")
|
||||
|
||||
# 更新界面状态
|
||||
self.is_testing = False
|
||||
|
||||
# 使用try/except捕获可能的NoMatches异常
|
||||
try:
|
||||
stop_button = self.query_one("#stop-test", Button)
|
||||
if stop_button:
|
||||
stop_button.disabled = True
|
||||
|
||||
memory_button = self.query_one("#memory-test", Button)
|
||||
if memory_button:
|
||||
memory_button.disabled = False
|
||||
|
||||
cpu_button = self.query_one("#cpu-test", Button)
|
||||
if cpu_button:
|
||||
cpu_button.disabled = False
|
||||
except Exception as e:
|
||||
# 记录错误但不中断程序
|
||||
print(f"更新按钮状态时出错: {str(e)}")
|
||||
|
||||
def start_memory_test(self) -> None:
|
||||
"""开始内存测试"""
|
||||
status = self.query_one("#status")
|
||||
memory_usage = check_memory_usage()
|
||||
|
||||
if memory_usage > 80:
|
||||
warning_message = f"警告: 当前系统内存使用率已达 {memory_usage}%!\n建议关闭一些软件后再运行,继续运行可能检测效果不够准确"
|
||||
status.update(f"[yellow]{warning_message}[/yellow]")
|
||||
|
||||
# 显示确认对话框
|
||||
def confirm_callback():
|
||||
self.show_memory_test_warning()
|
||||
|
||||
self.push_screen(ConfirmDialog(warning_message, confirm_callback))
|
||||
else:
|
||||
self.show_memory_test_warning()
|
||||
|
||||
def show_memory_test_warning(self):
|
||||
"""显示内存测试警告"""
|
||||
warning = "建议关闭所有docker容器以及停用所有应用程序以保证检测的准确性。"
|
||||
status = self.query_one("#status")
|
||||
status.update(f"[red]{warning}[/red]")
|
||||
|
||||
def confirm_callback():
|
||||
self.run_memory_test()
|
||||
|
||||
self.push_screen(ConfirmDialog(warning, confirm_callback))
|
||||
|
||||
def run_memory_test(self) -> None:
|
||||
"""执行内存测试"""
|
||||
status = self.query_one("#status")
|
||||
mem_size = f"{get_test_memory()}M"
|
||||
|
||||
message = "正在运行内存测试,请勿进行其它操作,如果运行过程中出现死机重启则大概率为内存问题。整个测试过程预计 30-120 分钟 具体根据内存大小,如果需要终止测试请按Ctrl+C或点击停止按钮。"
|
||||
status.update(f"[blue]{message}[/blue]")
|
||||
|
||||
# 更新界面状态
|
||||
self.is_testing = True
|
||||
|
||||
# 使用try/except捕获可能的NoMatches异常
|
||||
try:
|
||||
stop_button = self.query_one("#stop-test", Button)
|
||||
if stop_button:
|
||||
stop_button.disabled = False
|
||||
|
||||
memory_button = self.query_one("#memory-test", Button)
|
||||
if memory_button:
|
||||
memory_button.disabled = True
|
||||
|
||||
cpu_button = self.query_one("#cpu-test", Button)
|
||||
if cpu_button:
|
||||
cpu_button.disabled = True
|
||||
except Exception as e:
|
||||
# 记录错误但不中断程序
|
||||
print(f"更新按钮状态时出错: {str(e)}")
|
||||
|
||||
# 创建异步任务
|
||||
asyncio.create_task(self.do_memory_test(mem_size))
|
||||
|
||||
async def do_memory_test(self, mem_size):
|
||||
"""异步执行内存测试"""
|
||||
status = self.query_one("#status")
|
||||
|
||||
try:
|
||||
# 在异步中执行测试
|
||||
result = await asyncio.to_thread(run_command, ["sudo", "memtester", mem_size, "1"])
|
||||
|
||||
if result['status_code'] == 0:
|
||||
success_message = "内存测试完成!未发现问题。"
|
||||
status.update(f"[green]{success_message}[/green]")
|
||||
self.show_success_dialog(success_message)
|
||||
else:
|
||||
# 检查是否是被用户手动终止的
|
||||
if current_process is None and not result['stderr']:
|
||||
status.update("[yellow]测试已被用户终止。[/yellow]")
|
||||
else:
|
||||
error_message = f"内存测试失败!错误信息:{result['stderr']}"
|
||||
status.update(f"[red]{error_message}[/red]")
|
||||
self.show_error_dialog(error_message)
|
||||
|
||||
except Exception as e:
|
||||
error_message = f"测试过程中发生错误: {str(e)}"
|
||||
status.update(f"[red]{error_message}[/red]")
|
||||
self.show_error_dialog(error_message)
|
||||
finally:
|
||||
# 恢复界面状态
|
||||
self.is_testing = False
|
||||
|
||||
# 使用try/except捕获可能的NoMatches异常
|
||||
try:
|
||||
stop_button = self.query_one("#stop-test", Button)
|
||||
if stop_button:
|
||||
stop_button.disabled = True
|
||||
|
||||
memory_button = self.query_one("#memory-test", Button)
|
||||
if memory_button:
|
||||
memory_button.disabled = False
|
||||
|
||||
cpu_button = self.query_one("#cpu-test", Button)
|
||||
if cpu_button:
|
||||
cpu_button.disabled = False
|
||||
except Exception as e:
|
||||
# 记录错误但不中断程序
|
||||
print(f"更新按钮状态时出错: {str(e)}")
|
||||
|
||||
def start_cpu_test(self) -> None:
|
||||
"""开始CPU测试"""
|
||||
def input_callback(duration):
|
||||
if duration and duration.isdigit() and int(duration) > 0:
|
||||
self.run_cpu_test(duration)
|
||||
else:
|
||||
self.show_error_dialog("请输入有效的时间(秒)!")
|
||||
|
||||
self.push_screen(InputDialog("请输入 CPU 压测时长 (秒):", "60", input_callback))
|
||||
|
||||
def run_cpu_test(self, duration):
|
||||
"""执行CPU测试"""
|
||||
status = self.query_one("#status")
|
||||
|
||||
message = f"正在进行 CPU 压测,持续 {duration} 秒...如需提前结束测试,请按Ctrl+C或点击停止按钮。"
|
||||
status.update(f"[blue]{message}[/blue]")
|
||||
|
||||
# 更新界面状态
|
||||
self.is_testing = True
|
||||
|
||||
# 使用try/except捕获可能的NoMatches异常
|
||||
try:
|
||||
stop_button = self.query_one("#stop-test", Button)
|
||||
if stop_button:
|
||||
stop_button.disabled = False
|
||||
|
||||
memory_button = self.query_one("#memory-test", Button)
|
||||
if memory_button:
|
||||
memory_button.disabled = True
|
||||
|
||||
cpu_button = self.query_one("#cpu-test", Button)
|
||||
if cpu_button:
|
||||
cpu_button.disabled = True
|
||||
except Exception as e:
|
||||
# 记录错误但不中断程序
|
||||
print(f"更新按钮状态时出错: {str(e)}")
|
||||
|
||||
# 创建异步任务
|
||||
asyncio.create_task(self.do_cpu_test(duration))
|
||||
|
||||
async def do_cpu_test(self, duration):
|
||||
"""异步执行CPU测试"""
|
||||
status = self.query_one("#status")
|
||||
|
||||
try:
|
||||
# 在异步中执行测试
|
||||
result = await asyncio.to_thread(run_command, ["stress", "--cpu", "4", "--timeout", duration])
|
||||
|
||||
if result['status_code'] == 0:
|
||||
success_message = "CPU 压测完成!未发现问题。"
|
||||
status.update(f"[green]{success_message}[/green]")
|
||||
self.show_success_dialog(success_message)
|
||||
else:
|
||||
# 检查是否是被用户手动终止的
|
||||
if current_process is None and not result['stderr']:
|
||||
status.update("[yellow]测试已被用户终止。[/yellow]")
|
||||
else:
|
||||
error_message = f"CPU 压测失败!错误信息:{result['stderr']}"
|
||||
status.update(f"[red]{error_message}[/red]")
|
||||
self.show_error_dialog(error_message)
|
||||
|
||||
except Exception as e:
|
||||
error_message = f"测试过程中发生错误: {str(e)}"
|
||||
status.update(f"[red]{error_message}[/red]")
|
||||
self.show_error_dialog(error_message)
|
||||
finally:
|
||||
# 恢复界面状态
|
||||
self.is_testing = False
|
||||
|
||||
# 使用try/except捕获可能的NoMatches异常
|
||||
try:
|
||||
stop_button = self.query_one("#stop-test", Button)
|
||||
if stop_button:
|
||||
stop_button.disabled = True
|
||||
|
||||
memory_button = self.query_one("#memory-test", Button)
|
||||
if memory_button:
|
||||
memory_button.disabled = False
|
||||
|
||||
cpu_button = self.query_one("#cpu-test", Button)
|
||||
if cpu_button:
|
||||
cpu_button.disabled = False
|
||||
except Exception as e:
|
||||
# 记录错误但不中断程序
|
||||
print(f"更新按钮状态时出错: {str(e)}")
|
||||
|
||||
def show_success_dialog(self, message: str) -> None:
|
||||
"""显示成功对话框"""
|
||||
self.push_screen(SuccessDialog(message))
|
||||
|
||||
def show_error_dialog(self, message: str) -> None:
|
||||
"""显示错误对话框"""
|
||||
self.push_screen(ErrorDialog(message))
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_arguments()
|
||||
|
||||
# 如果指定了命令行参数,则直接执行相应功能
|
||||
if args.memory:
|
||||
cli_memory_test()
|
||||
sys.exit(0)
|
||||
|
||||
if args.cpu is not None:
|
||||
cli_cpu_test(args.cpu)
|
||||
sys.exit(0)
|
||||
|
||||
# 如果没有指定命令行参数,则启动图形界面(如果textual可用)
|
||||
if HAS_TEXTUAL:
|
||||
app = SystemHealthApp()
|
||||
app.run()
|
||||
else:
|
||||
# 这种情况不应该发生,因为在导入时已经处理了,但为了代码完整性保留
|
||||
print("错误: 未安装textual库,无法启动图形界面。")
|
||||
print("您可以通过命令行参数使用此脚本的核心功能:")
|
||||
print(" 内存测试: python self_inspection.py --memory")
|
||||
print(" CPU测试: python self_inspection.py --cpu [测试时长(秒)]")
|
||||
print(" 查看帮助: python self_inspection.py -h")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user