# MVP v2.5 端到端测试用例（正常/异常/边界）

本用例集目标：覆盖 v2.5 的关键能力与边界条件（User + jobs 隔离 + stateless node pool + API 队列调度）。

约束（v2.5 已确认）：
- TaskSpec 不扩展；不支持 reward_fn；不支持用户自定义 verl 代码。
- 输入统一 `/private/common/...`；用户隔离先只隔离 `/private/users/<uid>/jobs/...` 输出。

---

## 0. 环境前置

远端目录示例：
- `argus@h1:/home2/argus/infra/mvp/src/mvp/`

共享目录（宿主机）：
- `/home2/argus/infra/mvp/shared/`

容器内路径约定：
- `/private` 为共享存储挂载点

需要：
- GPU 0-7 可用
- 3 容器：head（无 GPU）+ 2 worker（各 4 GPU）

---

## 1. 正常用例（Happy Path）

### HP-1：v2.5 全链路（PPO → GRPO → SFT，串行）

步骤：
1) `cd /home2/argus/infra/mvp/src/mvp/scripts`
2) `MVP_INTERNAL_TOKEN=<admin_token> RESET_DB=1 ./run_all_v25_api.sh`

期望：
- Ray dashboard 显示 3 nodes（head+2 workers），GPU 总数 8。
- 3 个 task 最终为 `SUCCEEDED`。
- 输出目录存在且按用户隔离：
  - `/private/users/<uid>/jobs/<ray_submission_id>/{config,logs,checkpoints,debug}`

### HP-2：Driver 不在 head 跑

验证点（任选一种）：
- Ray job 的 driver node IP 不等于 head 容器 IP；
- 或日志/调度信息显示 entrypoint_resources 生效（driver 在 worker）。

---

## 2. 异常用例（Error Cases）

### E-Auth-1：缺 token

请求：
- `GET /api/v2/queue` 不带 `Authorization` 头

期望：
- 返回 401（missing bearer token）

### E-Auth-2：无效 token

请求：
- `Authorization: Bearer <random>`

期望：
- 返回 401（invalid token）

### E-Auth-3：用户禁用后拒绝访问

步骤：
1) admin 创建用户 `bob` 并签发 token
2) admin 禁用 `bob`
3) 用 bob token 请求 `/api/v2/queue`

期望：
- 返回 403（user disabled）

### E-Isolation-1：跨用户访问 task 资源（不泄露存在性）

步骤：
1) alice 提交 task 得到 `task_id`
2) bob 查询 `/api/v2/tasks/{task_id}`

期望：
- 返回 404（task not found）

### E-Input-1：输入路径不在 /private/common（v2.5 约束）

请求：
- 提交 taskspec 但 `train_file` 或 `code_path` 不以 `/private/common/` 开头

期望：
- 返回 400，并给出具体字段错误（例如 `train_file must start with /private/common/`）。

---

## 3. 边界用例（Boundary）

### B-Queue-1：资源不足时不提交 Ray（PENDING_RESOURCES）

步骤：
1) 构造任务需求 `nnodes=3` 且 `n_gpus_per_node=4`（total 12 GPU）
2) 提交后轮询状态

期望：
- task 进入 `PENDING_RESOURCES`（服务侧 pending，不向 Ray submit）
- 具备 `next_run_at`

### B-Cancel-1：任务取消（QUEUED/RUNNING）

步骤：
1) 提交一个较长 steps 的任务（确保有机会 RUNNING）
2) 调用 `POST /api/v2/tasks/{task_id}:cancel`

期望：
- task state 为 `CANCELED`
- attempt 中 `ray_status` 最终为 `STOPPED`（或 Ray 侧停止）

---

## 4. 可执行回归脚本

见：
- `src/mvp/scripts/run_e2e_v25_cases.sh`

脚本覆盖：
- HP-1
- E-Auth-1/E-Auth-2/E-Input-1
- E-Isolation-1
- B-Queue-1
- B-Cancel-1（best-effort）

