test/framework/business/data_management.py

266 lines
13 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from framework.config.settings import Config
from framework.core.logger import get_logger
from framework.business.login_page import LoginPage
from framework.business.file_manager_page import FileManagerPage
from framework.business.dev_machine_page import DevMachinePage
from framework.business.cloud_desktop_page import CloudDesktopPage
# 引入抽离出来的业务场景
from framework.scripts.file_system_scenario import run_full_file_lifecycle
from framework.scripts.compute_resource_scenario import run_dev_machine_lifecycle
from framework.scripts.desktop_lifecycle import run_cloud_desktop_lifecycle
from framework.scripts.mirror_assets import run_mirror_assets_lifecycle
from framework.scripts.three_d_generation_scenario import run_3d_generation_lifecycle
from framework.scripts.three_d_assets_scenario import run_3d_assets_lifecycle
from framework.scripts.quantization_scenario import run_quantization_lifecycle
from framework.scripts.monkey_scenario import run_monkey_testing
from framework.business.mirror_assets_page import MirrorAssetsPage
from framework.business.three_d_generation_page import ThreeDGenerationPage
from framework.business.three_d_assets_page import ThreeDAssetsPage
from framework.business.quantization_page import QuantizationPage
from framework.scripts.quantization_scenario import run_quantization_lifecycle
import time
import os
import json
logger = get_logger("DataManagementRunner")
class DataManagement:
"""符合 PO 模式的场景指挥官"""
def __init__(self, headless=False):
self.ui = LoginPage(headless=headless)
self.page = None
self.fm = None
self.dm = None
self.cd = None
self.ma = None
self.tg = None
self.ta = None
self.qp = None
self.results = [] # 记录结构化测试结果
def start(self):
"""启动浏览器并初始化组件"""
self.page = self.ui.start()
# 初始化页面原子对象
self.fm = FileManagerPage(self.page)
self.dm = DevMachinePage(self.page)
self.cd = CloudDesktopPage(self.page)
self.ma = MirrorAssetsPage(self.page)
self.tg = ThreeDGenerationPage(self.page)
self.ta = ThreeDAssetsPage(self.page)
self.qp = QuantizationPage(self.page)
def login(self, user, pwd):
"""执行登录流程"""
return self.ui.login(user, pwd)
def _safe_screenshot(self, name):
"""支持统一存放路径的截图"""
base_dir = os.environ.get("ROBOGO_SCREENSHOTS_DIR", ".")
task_id = os.environ.get("ROBOGO_TASK_ID", "local")
# 统一命名规范: {task_id}_{name}.png
filename = f"{task_id}_{name}" if ".png" in name else f"{task_id}_{name}.png"
target_path = os.path.join(base_dir, filename)
try:
# 增加对 page 状态的活跃检查 (包含 context 检查)
if not self.page or self.page.is_closed():
return
if not self.page.context or self.page.context.browser is None:
return
# 使用 self.page 截图(注意:这里使用的是 BasePage 注入的 playwirght 页面)
self.page.screenshot(path=target_path, full_page=True, timeout=5000)
logger.info(f"✨ 最终状态截图已保存: {target_path}")
except Exception as e:
# 忽略由于浏览器/上下文已关闭导致的截图失败
err_msg = str(e).lower()
if "closed" in err_msg or "not open" in err_msg:
logger.info(" 浏览器环境已销毁,跳过末尾截图存档")
else:
logger.warning(f"⚠️ 截图存档过程出错: {e}")
def record_result(self, name, desc, expected, status, duration):
"""记录一个测试用例的结果"""
self.results.append({
"name": name,
"desc": desc,
"expected": expected,
"status": status, # 'PASS', 'FAIL', 'SKIP'
"duration": f"{duration:.2f}s"
})
def save_results(self):
"""将结构化结果保存到文件"""
task_id = os.environ.get("ROBOGO_TASK_ID", "local")
reports_dir = os.environ.get("ROBOGO_REPORTS_DIR", "platform_reports")
os.makedirs(reports_dir, exist_ok=True)
target_path = os.path.join(reports_dir, f"{task_id}_results.json")
try:
with open(target_path, 'w', encoding='utf-8') as f:
json.dump(self.results, f, ensure_ascii=False, indent=2)
logger.info(f"📊 结构化数据已保存: {target_path}")
except Exception as e:
logger.warning(f"⚠️ 结构化数据保存失败: {e}")
def run_all_scenarios(self):
"""
场景指挥:依次执行所有的业务流
每个场景独立 try-except一个失败不阻塞后续场景
"""
env_name = os.environ.get("ROBOGO_ENV", "PROD")
scope = os.environ.get("ROBOGO_SCOPE", "all")
logger.info(f"🚦 启动场景编排 - 环境: {env_name} | 策略: {scope}")
# 动态定义本次要运行的模块
active_modules = []
if scope == "all":
active_modules = ["file", "dev", "cloud", "mirror", "quant" , "3d"]
elif scope == "smoke":
active_modules = ["file"] # 核心资源生命周期
elif scope == "core":
active_modules = ["cloud","dev", "mirror", "quant"] # 业务闭环
else:
active_modules = ["cloud"] # 默认兜底只跑云桌面
errors = []
# 1. 执行文件系统场景
if "file" in active_modules:
start_t = time.time()
try:
run_full_file_lifecycle(self.fm, Config.FOLDER_NAME)
self._safe_screenshot("file_system_final.png")
logger.info("✅ 文件系统场景通过")
self.record_result("file_system_lifecycle", "文件系统全生命周期测试", "文件夹创建、上传、重命名、删除全链路闭环", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 文件系统场景失败: {e}")
self._safe_screenshot("file_system_error.png")
errors.append(f"文件系统: {e}")
self.record_result("file_system_lifecycle", "文件系统全生命周期测试", "文件夹创建、上传、重命名、删除全链路闭环", "FAIL", time.time()-start_t)
# 2. 执行开发机场景
if "dev" in active_modules:
start_t = time.time()
try:
run_dev_machine_lifecycle(self.dm)
self._safe_screenshot("dev_machine_final.png")
logger.info("✅ 开发机场景通过")
self.record_result("dev_machine_lifecycle", "开发机全生命周期测试", "开发机申请、启动、关机、销毁全流程验证", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 开发机场景失败: {e}")
self._safe_screenshot("dev_machine_error.png")
errors.append(f"开发机: {e}")
self.record_result("dev_machine_lifecycle", "开发机全生命周期测试", "开发机申请、启动、关机、销毁全流程验证", "FAIL", time.time()-start_t)
# 3. 执行云桌面场景
if "cloud" in active_modules:
start_t = time.time()
try:
run_cloud_desktop_lifecycle(self.cd)
self._safe_screenshot("cloud_desktop_final.png")
logger.info("✅ 云桌面场景通过")
self.record_result("cloud_desktop_lifecycle", "云桌面全生命周期测试", "桌面创建、连接、保存镜像、关机、删除全流程验证", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 云桌面场景失败: {e}")
self._safe_screenshot("cloud_desktop_error.png")
errors.append(f"云桌面: {e}")
self.record_result("cloud_desktop_lifecycle", "云桌面全生命周期测试", "桌面创建、连接、保存镜像、关机、删除全流程验证", "FAIL", time.time()-start_t)
# 4. 执行镜像资产场景
if "mirror" in active_modules:
start_t = time.time()
try:
run_mirror_assets_lifecycle(self.ma, self.cd)
self._safe_screenshot("mirror_assets_final.png")
logger.info("✅ 镜像资产场景通过")
self.record_result("mirror_assets", "镜像资产巡检", "镜像列表加载及基本信息验证", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 镜像资产场景失败: {e}")
self._safe_screenshot("mirror_assets_error.png")
errors.append(f"镜像资产: {e}")
self.record_result("mirror_assets", "镜像资产巡检", "镜像列表加载及基本信息验证", "FAIL", time.time()-start_t)
# 5. 执行 3D 生成场景 -> 获取资产名 -> 执行归档场景
if "3d" in active_modules:
start_t = time.time()
try:
asset_name = run_3d_generation_lifecycle(self.tg)
self._safe_screenshot("3d_generation_final.png")
if asset_name:
# 联动:将生成的资产归档到数据中心
run_3d_assets_lifecycle(self.ta, asset_name)
self._safe_screenshot("3d_assets_archive_final.png")
logger.info("✅ 3D 生成与归档全链路已通过")
self.record_result("3d_lifecycle", "3D生成与资产归档", "通过 AIGC 生成 3D 模型并成功归档到资产中心", "PASS", time.time()-start_t)
else:
logger.warning("⚠️ 3D 生成未产生有效资产名,跳过归档场景")
self.record_result("3d_lifecycle", "3D生成与资产归档", "生成资产名为空", "SKIP", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 3D 链路失败: {e}")
self._safe_screenshot("3d_chain_error.png")
errors.append(f"3D链路: {e}")
self.record_result("3d_lifecycle", "3D生成与资产归档", "存在执行错误", "FAIL", time.time()-start_t)
# 6. 执行量化工具场景
if "quant" in active_modules:
start_t = time.time()
try:
run_quantization_lifecycle(self.qp)
self._safe_screenshot("quantization_final.png")
logger.info("✅ 量化工具场景通过")
self.record_result("quantization", "量化工具效能测试", "执行模型量化脚本并验证输出一致性", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 量化工具场景失败: {e}")
self._safe_screenshot("quantization_error.png")
errors.append(f"量化工具: {e}")
self.record_result("quantization", "量化工具效能测试", "执行模型量化脚本并验证输出一致性", "FAIL", time.time()-start_t)
# 7. 全局 Monkey 稳定性打底测试
if "monkey" in active_modules:
start_t = time.time()
try:
logger.info("🚀 开启全面压测: 注入大范围 Monkey 测试策略...")
run_monkey_testing(self.page, action_count=50)
self._safe_screenshot("monkey_pass.png")
logger.info("✅ 全链路存活Monkey 压路机测试无严重崩溃阻断")
self.record_result("monkey_testing", "Monkey 稳定性压测", "50 次随机点击/交互注入,验证系统抗崩溃能力", "PASS", time.time()-start_t)
except Exception as e:
logger.error(f"❌ 稳定性告警: Monkey 测试导致了非预期崩溃或抛错: {e}")
self._safe_screenshot("monkey_error.png")
errors.append(f"Monkey测试异常: {e}")
self.record_result("monkey_testing", "Monkey 稳定性压测", "50 次随机点击/交互注入,验证系统抗崩溃能力", "FAIL", time.time()-start_t)
# 汇总
if errors:
summary = " | ".join(errors)
logger.error(f"{len(errors)} 个场景失败: {summary}")
raise Exception(f"{len(errors)} 个场景失败: {summary}")
logger.info(f"🎉 Robogo {env_name} 环境 {scope} 巡检执行圆满完成!")
def run(self, user, pwd):
"""主入口"""
try:
self.start()
if not self.login(user, pwd):
return
# 开始执行指挥任务
self.run_all_scenarios()
finally:
self.save_results()
self.ui.stop()
if __name__ == "__main__":
account = input("账号: ")
password = input("密码: ")
dm = DataManagement(headless=False)
dm.run(account, password)