- Add Workspace domain (entity, repository, service, handler, DTO) - Add multi-tenant K8s client with tenant binding and quota management - Add K8s diagnostics client (instance diagnostics) - Add authorization middleware (authz package) - Restructure frontend to feature-based architecture (features/) - Add User Management page in configuration - Add AccessDenied page and route guards - Refactor shared components (form inputs, layout, UI) - Update Tailwind config for new design system - Add comprehensive documentation (docs/, tasks/, plans) - Improve cluster service with better kubeconfig handling - Add tests for crypto, config, helm client, tenant binding
142 lines
5.6 KiB
Markdown
142 lines
5.6 KiB
Markdown
# OCDP 第二次测试报告
|
||
|
||
**测试日期:** 2026-05-11
|
||
**测试环境:** http://10.6.80.114:18080
|
||
|
||
---
|
||
|
||
## 测试1: 资源配额限额
|
||
|
||
### 测试方法
|
||
使用 test-user-b(quota: cpu=2, mem=4Gi, gpu=0, gpumem=0)在 k3s 集群部署 nginx chart
|
||
|
||
### 测试结果
|
||
|
||
| 测试 | 操作 | 预期 | 实际 | 结论 |
|
||
|------|------|------|------|------|
|
||
| Test A | 部署 nginx(默认值,在配额内) | 成功 | 部署完成,状态 deployed | ✅ |
|
||
| Test B | 部署 nginx(requests.cpu=2, mem=4Gi, replica=5,超配额) | 被配额阻止 | Helm release 创建成功,所有 Pod 被 ResourceQuota 阻塞,状态永远 stuck 在 pending-install | ⚠️ 部分通过 |
|
||
| Test C | 部署 vllm-serve(gpuLimit=1,gpu配额=0) | 被配额阻止 | Helm release 创建成功,Pod 被 ResourceQuota 阻塞,状态 pending-install | ⚠️ 部分通过 |
|
||
|
||
### 关键发现
|
||
|
||
**1. 没有 API 层的预检查配额验证**
|
||
- 后端 API 无条件接受所有部署请求,不检查是否超配额
|
||
- 所有超配额请求返回 HTTP 200 + status: pending-install
|
||
- 后端日志中**没有任何配额相关的条目**
|
||
|
||
**2. K8s ResourceQuota 在 Pod 级别执行**
|
||
- `tenant-quota` ResourceQuota 对象确实存在并执行限制
|
||
- 当 Pod 超配额时,K8s 明确拒绝创建并给出错误消息
|
||
- 但 Helm release、Service、Deployment、ReplicaSet **仍然被创建**
|
||
|
||
**3. 实例永远 stuck 在 "pending-install"**
|
||
- 超配额的实例永远不会转换到 deployed/failed/error
|
||
- OCDP 平台不检测 ResourceQuota 拒绝事件
|
||
- 唯一知道失败的方式是直接查 K8s events
|
||
|
||
**4. GPU 配额绕过**
|
||
- gpu=0 的用户可以提交需要 GPU 的 chart 部署
|
||
- K8s ResourceQuota 最终会阻止,但 Helm release 等资源已被创建
|
||
|
||
**5. 有效的 ResourceQuota 配置**
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: ResourceQuota
|
||
metadata:
|
||
name: tenant-quota
|
||
namespace: ocdp-u-test-b
|
||
spec:
|
||
hard:
|
||
requests.cpu: "2"
|
||
requests.memory: 4Gi
|
||
requests.nvidia.com/gpu: "0"
|
||
requests.nvidia.com/gpumem: "0"
|
||
```
|
||
|
||
### 建议
|
||
1. **添加 API 层预检查配额验证** — 在接受部署前检查请求资源是否超过用户配额
|
||
2. **处理 pending-install 超时** — 监控 Helm release 创建后 Pod 是否 stuck,更新状态为 failed
|
||
3. **GPU 配额预检查** — 如果 chart 需要 GPU 而用户 gpu=0,在 API 层拒绝
|
||
4. **UI 配额指示器** — 在部署表单上显示剩余配额
|
||
|
||
---
|
||
|
||
## 测试2: values.yaml 覆盖优先级
|
||
|
||
### 测试方法
|
||
使用 test-user-c(quota: cpu=4, mem=8Gi, gpu=1, gpumem=5000)部署 vllm-serve:0.6.0 chart
|
||
|
||
### 测试结果
|
||
|
||
| 方法 | 提交方式 | 是否部署成功 | 存储的值 | 结论 |
|
||
|------|----------|-------------|---------|------|
|
||
| 方法1 | `values` JSON 字段 | ✅ | cpuRequest=2, gpuMem=10000 | JSON 值被准确接受和存储 |
|
||
| 方法2 | `valuesYaml` 字符串 | ✅ | cpuRequest=4, gpuMem=10000 | YAML 被正确解析为结构化 values |
|
||
| 方法3 | 同时提供 `values` + `valuesYaml`(冲突) | ✅ 无任何错误/警告 | **values JSON 全胜** | `values` JSON 静默覆盖 `valuesYaml` |
|
||
| 方法4 | 不提供任何 values(使用 chart 默认) | ✅ | 仅 namespace | chart 默认值不存储在 API 响应中 |
|
||
|
||
### 优先级最终结论
|
||
|
||
| 优先级 | 来源 | 说明 |
|
||
|--------|------|------|
|
||
| **最高** | `values` JSON 字段 | 请求体中的结构化 JSON |
|
||
| **中** | `valuesYaml` 字符串 | 请求体中的 YAML 字符串 |
|
||
| **最低** | Chart 内置 values.yaml | Helm chart 打包的默认值 |
|
||
|
||
### 冲突测试详细结果
|
||
|
||
当同时提供 `values` 和 `valuesYaml` 且值冲突时:
|
||
- `values` JSON 字段**完全覆盖** `valuesYaml`
|
||
- **没有任何错误或警告**返回给用户
|
||
- 两者被合并到统一的 DB `values` 字段
|
||
|
||
### gpuMem=10000 行为
|
||
- 整数值 `10000` 在 `values` JSON 和 `valuesYaml` 中都被**正确接受**
|
||
- 无单位转换(作为整数 MB 标量存储)
|
||
- 符合项目规范
|
||
|
||
### 建议
|
||
1. **记录优先级顺序** — 用户需知道同时提供两者时 values JSON 优先
|
||
2. **添加冲突警告** — 当两个字段存在冲突值时应返回警告
|
||
3. **考虑废弃一个字段** — values 和 valuesYaml 语义重复易混淆
|
||
|
||
---
|
||
|
||
## 测试3: 前端 UI 溢出/滚动/刷新
|
||
|
||
### 测试方法
|
||
Playwright + 源码分析,测试 1920/768/375 三个视口
|
||
|
||
### 测试结果
|
||
**总体结论: PASS** — 没有导致功能问题的关键溢出问题
|
||
|
||
| 测试项 | 结果 | 详情 |
|
||
|--------|------|------|
|
||
| 水平溢出 | ✅ 无问题 | 所有视口均无水平溢出 |
|
||
| 文本截断 | ⚠️ 1 个低风险 | InstanceCard h3 标题 truncate 无 title tooltip |
|
||
| 响应式设计 | ✅ 正确 | sm/md/lg/xl 断点覆盖完整 |
|
||
| 滚动行为 | ✅ 流畅 | Sidebar 和内容区独立滚动,overscroll-contain 防滚动穿透 |
|
||
| 模态框布局 | ✅ 正确 | body scroll lock + 内容独立滚动 |
|
||
| 页面刷新 | ✅ 正常 | 受保护路由正确重定向到登录页 |
|
||
| 颜色对比度 | ⚠️ 1 个中风险 | 登录页错误文本 red-400 在白色背景上仅 2.5:1 (WCAG AA 要求 4.5:1) |
|
||
|
||
### 通过的细分项
|
||
- Chart Browser 全高 + overflow-y-auto 布局 ✅
|
||
- InstanceCard 操作按钮网格 grid-cols-2/3/5 响应正确 ✅
|
||
- Tabs 支持 overflow-x-auto 水平滚动 ✅
|
||
- 用户管理表格 overflow-x-auto ✅
|
||
- iOS 触摸滚动 (`-webkit-overflow-scrolling: touch`) 已配置 ✅
|
||
|
||
### 建议
|
||
1. 将登录页错误文本从 text-red-400 改为 text-red-600/700
|
||
2. InstanceCard h3 标题添加 title 属性
|
||
|
||
---
|
||
|
||
## 综合建议
|
||
1. 添加 API 层配额预检查
|
||
2. 处理 pending-install 超时 + 状态更新
|
||
3. 记录 values 覆盖优先级并添加冲突警告
|
||
4. 统一 values JSON/YAML 的 API 设计
|