# YG_FT 模型微调平台测试脚本

## 环境准备

### 启动顺序

1. **数据库**：远程 PostgreSQL `www.caoxiaozhu.com:5432`（已就绪）
2. **后端**：
   ```cmd
   cd /d E:\yg_ft\backend
   set COMPUTE_STATUS_SYNC_MODE=off
   .\.venv\Scripts\python.exe -m uvicorn app.main:app --reload --port 17861
   ```
3. **算力服务**（Docker）：
   ```cmd
   cd /d E:\yg_ft
   docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest .
   cd docker/compute
   docker compose up -d
   ```
4. **前端**：
   ```cmd
   cd /d E:\yg_ft\frontend
   npm run dev
   ```

### 验证服务可用性

| 服务 | 验证命令 | 期望结果 |
|------|---------|---------|
| 后端 | `curl http://localhost:17861/modelTF/health` | `{"code":0,...,"data":{"cpu_percent":x,...}}` |
| 算力 | `curl http://localhost:19100/health` | `{"status":"ok","compute_host_id":"gpu-node-01"}` |
| 前端 | 浏览器打开 `http://localhost:16801` | 跳转登录页 |

---

## 一、登录与认证

### 1.1 登录

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 打开 `http://localhost:16801` | 显示登录页，不自动登录 |
| 2 | 输入账号 `admin`，密码 `admin123`，点击登录 | 提示"登录成功"，跳转看板页 |
| 3 | F12 控制台执行 `sessionStorage.getItem('sessionId')` | 有值（非 null） |
| 4 | 浏览器 Network 查看 `/modelTF/login` 响应 | 返回 `token`、`user`、`session_id` |

### 1.2 退出登录

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击侧边栏底部"退出登录"按钮 | 跳转登录页 |
| 2 | F12 控制台执行 `sessionStorage.getItem('hasAuthed')` | 返回 null |
| 3 | 浏览器 Network 查看 `/modelTF/logout` 请求 | 状态 200 |

### 1.3 刷新页面保持登录

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 登录后按 F5 刷新页面 | 仍在功能页，不跳登录页 |

### 1.4 关闭标签页再打开

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 登录后关闭浏览器标签页 | — |
| 2 | 重新打开 `http://localhost:16801` | 跳转登录页（sessionStorage 已清空） |

### 1.5 会话超时

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 登录后切到其他软件，等待 5 分钟以上 | — |
| 2 | 切回浏览器 | 提示"登录已过期"，跳转登录页 |

---

## 二、看板

### 2.1 服务状态

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 登录后进入看板页 | 显示 7 个服务：模型训练/模型评测/模型推理/模型管理/数据集管理/数据处理/数据类型转换 |
| 2 | 检查每个服务状态 | 全部显示"正常" |
| 3 | 检查实例数 | 模型管理有数量、数据集管理有数量等 |

### 2.2 运行中任务

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 查看顶部"运行中任务"数字 | 显示训练+评测+数据处理中 running 状态的任务总数 |
| 2 | 无运行任务时 | 显示 0 |

### 2.3 用户操作分布

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 查看饼图 | 4 个分类（数据处理/模型训练/模型评测/模型推理）各一色 |
| 2 | 无数据时 | 4 等分（各 25%） |
| 3 | 点击侧边栏"模型训练"菜单，回到看板 | 模型训练权重增加 |
| 4 | 点击"模型推理"菜单，回到看板 | 模型推理权重增加 |
| 5 | 浏览器控制台执行 `sessionStorage.clear()` 后重试 | 去重缓存清除，可再次记录 |

### 2.4 登录时长排行

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 查看柱状图 | 显示当前登录用户，时长 > 0 |
| 2 | 条形图上无文字标签 | 只在鼠标悬浮时显示 tooltip |
| 3 | Y 轴用户名清晰可读 | 字体颜色 `#1f2937`，非模糊 |

### 2.5 顶部状态栏

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 查看顶部 CPU/内存/磁盘 | 显示真实数值（非 0） |
| 2 | 等待 30 秒 | 数值自动刷新 |

---

## 三、租户管理

### 3.1 列表

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 平台治理 → 租户管理 | 显示列表（名称/用户ID/状态/创建时间） |
| 2 | 检查列名 | "编码"已改为"用户ID" |
| 3 | 检查操作列 | 有"详情"和"删除"按钮，无"配额"按钮 |

### 3.2 新建租户

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"新建租户" | 弹窗显示：名称、用户ID、GPU数量、存储配额、最大项目数 |
| 2 | 填写名称"测试租户"，GPU=2，存储=100，项目=5，点击创建 | 提示"租户创建成功"，列表新增一行 |

### 3.3 租户详情与配额

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"详情" | 跳转详情页，显示基本信息 + 配额 |
| 2 | 配额显示格式 | `GPU 2 | 存储 100GB | 项目 5` |
| 3 | 修改配额数字，点击"保存配额" | 提示"配额已保存" |
| 4 | 检查详情页无"项目空间"卡片 | 已移除 |

### 3.4 删除租户

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 在列表页点击"删除" | 弹出确认框 |
| 2 | 点击"确定删除" | 提示"租户已删除"，列表刷新 |

---

## 四、项目空间

### 4.1 列表

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 项目空间 | 显示列表（项目名/编码ID/状态/描述/创建时间） |
| 2 | 检查列名 | "编码"已改为"编码ID" |
| 3 | 顶部有租户筛选下拉框 | 可按租户过滤 |

### 4.2 新建项目

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"新建项目" | 弹窗显示：名称、编码ID（下拉）、描述 |
| 2 | 编码ID下拉选项 | 显示已有租户的编码 |
| 3 | 选择编码ID后提交 | 提示"项目创建成功" |

### 4.3 项目详情

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"详情" | 显示基本信息 |
| 2 | 查看成员管理区域 | 显示成员列表 + 添加成员按钮 |
| 3 | 点击"资源授权(ACL)" | 弹窗显示 ACL 编辑器 |

### 4.4 ACL 授权

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"添加授权项" | 新增一行 |
| 2 | 主体类型选"用户" | 显示用户下拉框（非文本输入） |
| 3 | 主体类型选"项目角色" | 显示角色下拉框（member/admin/viewer） |
| 4 | 勾选权限后保存 | 提示"ACL 已保存" |

### 4.5 删除项目

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"删除" | 确认弹窗 |
| 2 | 确认删除 | 提示"项目已删除" |

---

## 五、算力节点

### 5.1 节点列表

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 算力节点 | 显示节点列表 |
| 2 | 检查 gpu-node-01 | 状态为启用 |

### 5.2 测试连接

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击 gpu-node-01 的"测试"按钮 | 提示"连接成功，发现 X 张 GPU，延迟 Xms" |
| 2 | 检查 GPU Tab | 显示 GPU 资源列表 |

### 5.3 节点启停

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"停用" | 节点状态变为停用 |
| 2 | 点击"启用" | 节点状态变为启用 |

---

## 六、用户设置

### 6.1 用户列表

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 系统设置 → 用户设置 | 显示用户列表 |
| 2 | admin 用户 | 不可停用、不可删除 |

### 6.2 创建用户

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"创建用户" | 跳转创建页 |
| 2 | 填写账号/显示名/密码/角色/权限 | 表单正常 |
| 3 | 提交 | 提示创建成功，列表新增 |

### 6.3 权限分配

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击某用户"页面权限" | 弹窗显示 12 个权限 checkbox |
| 2 | 取消某权限，保存 | 该用户侧边栏不再显示对应菜单 |

### 6.4 重置密码

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 点击"重置密码" | 弹窗显示默认密码 `Platform@123` |
| 2 | 确认 | 提示重置成功 |

---

## 七、审批管理

### 7.1 审批模板

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 审批模板 | 显示模板列表 |
| 2 | 点击新建 | 弹窗显示名称 + 步骤 JSON |
| 3 | 填写并提交 | 列表新增 |

### 7.2 审批中心

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 审批中心 | 显示实例列表 |
| 2 | 按状态筛选 | 列表过滤正常 |
| 3 | 对 pending 实例点"通过/拒绝" | 弹窗填写意见，提交后状态变更 |

---

## 八、审计日志

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 审计日志 | 显示日志列表 |
| 2 | 填写筛选条件查询 | 列表过滤 |
| 3 | 点击"导出" | 下载 CSV 文件 |

---

## 九、平台性能

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 平台性能 | 显示 CPU/内存/磁盘/GPU 卡片 |
| 2 | 数据非 0 | 与本机实际使用率一致 |
| 3 | 开启自动刷新（3秒） | 趋势图实时更新 |
| 4 | 点击 GPU 卡片 | 弹出详情抽屉 |

---

## 十、查看日志

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 查看日志 | 显示系统日志 Tab |
| 2 | 选择日期和文件 | 显示日志内容 |
| 3 | 输入关键词搜索 | 高亮匹配 |
| 4 | 切换到训练日志 Tab | 显示训练日志列表 |

---

## 十一、数据流主链路

### 11.1 数据集管理

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 进入数据集管理 | 显示列表 |
| 2 | 新建数据集 | 创建成功 |
| 3 | 上传文件 | 文件上传成功 |
| 4 | 预览文件 | 显示内容 |

### 11.2 数据类型转换

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 侧边栏 → 数据类型转换 | 显示任务列表 |
| 2 | 点击"新建转换任务"，填写名称，点击创建 | 列表新增一行，状态为"待上传" |
| 3 | 点击"上传文件"，选择 `.json` 文件 | 上传成功后自动转换为 JSONL 并导入数据集 |
| 4 | 检查任务状态 | 变为"已完成"，显示输入/输出数 |
| 5 | 进入数据集管理 → 上传任务 Tab | 可看到自动导入的数据集 |
| 6 | 上传非 `.json` 文件 | 提示"仅支持 .json 文件" |
| 7 | 点击"删除" | 确认后任务删除 |

### 11.3 数据处理

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 进入数据处理 | 显示任务列表 |
| 2 | 创建数据处理任务 | 创建成功 |
| 3 | 启动任务 | 状态变为 running |
| 4 | 回到看板 | "运行中任务"数字 +1 |

### 11.4 模型训练

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 进入模型训练 | 显示训练任务列表 |
| 2 | 创建训练任务 | 选择数据集 + 模型 + GPU |
| 3 | 启动训练 | 状态变为 running |
| 4 | 查看训练日志 | 显示实时日志 |
| 5 | 训练完成 | 产出模型 |

### 11.5 模型评测

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 进入模型评测 | 显示评测任务列表 |
| 2 | 创建评测任务 | 选择模型 + 数据集 |
| 3 | 启动评测 | 状态变为 running |
| 4 | 评测完成 | 显示指标结果 |

### 11.6 模型推理

| 步骤 | 操作 | 预期结果 |
|------|------|---------|
| 1 | 进入模型推理 | 显示推理会话列表 |
| 2 | 创建推理任务 | 选择模型 + 加载 |
| 3 | 开始对话 | 返回模型回复 |

---

## 十二、异常场景

| 场景 | 操作 | 预期结果 |
|------|------|---------|
| 数据库断开 | 停止远程数据库连接 | 所有接口返回 500 |
| 算力服务停掉 | `docker compose down` | 算力测试返回失败 |
| 未登录访问 | 直接访问 `/dashboard` | 跳转登录页 |
| 权限不足 | 普通用户访问用户设置 | 跳转 403 页面 |
| Token 过期 | 关闭标签页再打开 | 跳转登录页（sessionStorage 清空） |
