Alpha 阶段测试报告
测试计划
- 前端功能测试(结果见 bug 列表)
- 前端资源压测
- API 压测
- API 单元测试
- 评测压测
Bug 列表
后端
- 权限不足时 HTTP 状态码应为 403 而非 401(caesium-backend#35)
- 没有用户有权限向任务中添加学生(caesium-backend#36)
- 当学生没有对应的开发分支时,应当返回合适的值,而不是粗暴地返回 502(caesium-backend#37)
- 布置任务 API 中接受的应该是学工号,其类型是 string(caesium-backend#38)
- 评测记录应从新到旧按顺序显示(caesium-backend#39)
- /student/problem/all 应返回 display_index(caesium-backend#40)
- Global Filter 中报错信息有误(caesium-backend#41)
- 无需返回 raw_output(caesium-backend#42)
- 查询评测记录时,传入的学工号没有以字符串匹配方式做过滤(caesium-backend#43)
- display index 类型定义错误(caesium-backend#44)
学生前端
- 时间显示格式可读性(pendulum-frontend#42)
- 提交界面缺少加载动画(pendulum-frontend#43)
- 提交信息 POST 参数类型错误(pendulum-frontend#45)
- 代码提交部分逻辑有误(pendulum-frontend#47)
- 评测状态渲染不正确(pendulum-frontend#48)
- 题目/提交切换时存在冗余非透明层(pendulum-frontend#49)
- Problem Select 适配(pendulum-frontend#50)
- 课程公告移动端适配问题(pendulum-frontend#51)
- 通过 /xx/announcement/all 接口获得公告后应按时间排序再显示(pendulum-frontend#53)
- 学生前端退出重定向后无端口号(pendulum-frontend#54)
- Firefox 中无法退出登录(pendulum-frontend#55)
- 前端显示应按 display_index 排序(pendulum-frontend#56)
- 进度查看无需拼接 lab 名称(pendulum-frontend#57)
- 进度视图中 7 个题目的 Lab 适配问题(pendulum-frontend#63)
- 公式渲染的 CDN 问题(pendulum-frontend#65)
- 校外网访问 Network Error(pendulum-frontend#66)
教师前端
- 在最后一页切换显示数量后出现无法显示数据的问题(sundial-board#31)
- 批量导入用户信息显示“解析失败:表格格式错误”,考虑编码问题(sundial-board#32)
- 任务管理 -> 配置:课下,提示信息显示需用“空格”分割学生 id,但实测中发现只有用逗号分隔才能正常解析。(sundial-board#34)
- 编辑权限 -> 添加用户权限 输入框中输入回车会导致 url 变化(sundial-board#35)
- 题目管理--前端描述有误(sundial-board#36)
- 布置任务、取消任务时传给后端的应是 string 类型的学工号(sundial-board#37)
- 前端公告显示未排序(sundial-board#38)
- 前端显示应按 display_index 排序(sundial-board#39)
- firefox 中无法退出登录(sundial-board#40)
- 评测记录里应该显示评测节点,没有必要显示任课教师(sundial-board#41)
- 学生完成情况页面不必分栏(sundial-board#43)
- 评测记录详情中 commit hash 显示不全(sundial-board#44)
- 公式渲染的 CDN 问题 (sundial-board#46)
- 校外网访问 Network Error (sundial-board#47)
评测端
- 并发控制机制有误(quartz-judger#8)
- 部署映像过大(quartz-judger#10)
- 应使用官方文件覆盖学生文件(quartz-judger#11)
- raw_output 未限制(quartz-judger#12)
- 存在并发争夺测试目录可能性(quartz-judger#13)
- docker 禁网(quartz-judger#14)
压测结果
前端资源压测
使用 apache bench 模拟 100 路并发获取前端资源,结果如下:
Document Path: /css/chunk-vendors.22aaa98d.css
Document Length: 1027049 bytes
Concurrency Level: 100
Time taken for tests: 8.450 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 10272870000 bytes
HTML transferred: 10270490000 bytes
Requests per second: 1183.40 [#/sec] (mean)
Time per request: 84.503 [ms] (mean)
Time per request: 0.845 [ms] (mean, across all concurrent requests)
Transfer rate: 1187194.33 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 1.2 3 9
Processing: 43 82 10.3 81 141
Waiting: 0 2 1.1 2 16
Total: 46 84 10.4 84 145
Percentage of the requests served within a certain time (ms)
50% 84
66% 86
75% 88
80% 89
90% 97
95% 106
98% 112
99% 122
100% 145 (longest request)
使用 python 通过 asyncio 和 aiohttp 进行 100 路并发获取前端多个资源,多次测试结果如下:
Number: 100 Cost time: 12.052839517593384
Number: 100 Cost time: 11.757410287857056
Number: 100 Cost time: 12.067590951919556
Number: 100 Cost time: 12.219527006149292
Number: 100 Cost time: 14.292008876800537
Number: 100 Cost time: 12.145517826080322
Number: 100 Cost time: 12.295380353927612
Number: 100 Cost time: 11.780519723892212
获取的前端资源为:
http://osome.act.buaa.edu.cn
http://osome.act.buaa.edu.cn/css/chunk-vendors.98b4b6f6.css
http://osome.act.buaa.edu.cn/css/app.6eacfbb4.css
http://osome.act.buaa.edu.cn/js/app.3b5dd086.js
http://osome.act.buaa.edu.cn/js/chunk-vendors.eae90d45.js
http://osome.act.buaa.edu.cn/fonts/materialdesignicons-webfont.ad0f7b3f.woff2
http://osome.act.buaa.edu.cn/favicon.ico
可以发现我们的前端资源访问速度瓶颈在于带宽而不在于服务端,其在高并发下仍然能够保持高速响应。
API 压测
我们使用涉及信息量最多的评测记录 API 进行测试,请求全部数据的结果如下:
Document Path: /board/judge/query-all?limit=233333&offset=0
Document Length: 524808 bytes
Concurrency Level: 100
Requests per second: 159.53 [#/sec] (mean)
Time per request: 626.860 [ms] (mean)
Time per request: 6.269 [ms] (mean, across all concurrent requests)
Transfer rate: 81778.96 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.1 0 5
Processing: 38 609 267.1 569 1772
Waiting: 29 570 260.1 525 1769
Total: 39 610 267.4 569 1774
只请求单页数据时,数据如下:
Document Path: /board/judge/query-all?limit=50&offset=233
Document Length: 11799 bytes
Concurrency Level: 100
Requests per second: 463.75 [#/sec] (mean)
Time per request: 215.632 [ms] (mean)
Time per request: 2.156 [ms] (mean, across all concurrent requests)
Transfer rate: 5404.72 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 2.0 0 7
Processing: 10 204 191.1 97 866
Waiting: 10 204 191.1 97 865
Total: 10 205 191.9 97 873
对于一共 2000 余条数据,后端处理其的平均用时是 6.269ms,对于单页数据,这一响应时间缩短至 2.156ms,足以供教师、助教使用。
对于学生,我们同样请求评测数据,结果如下:
Document Path: /student/judge/self?judge_id=2232
Document Length: 203 bytes
Concurrency Level: 600
Requests per second: 692.32 [#/sec] (mean)
Time per request: 144.443 [ms] (mean)
Time per request: 1.444 [ms] (mean, across all concurrent requests)
Transfer rate: 242.72 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.7 0 4
Processing: 2 140 125.2 167 619
Waiting: 2 140 125.2 166 619
Total: 2 140 125.3 167 619
后端处理请求的平均用时是 1.444ms,能满足所有同学每秒刷新查看评测记录一次,足够供同学使用。
我们使用 python 通过 asyncio 和 aiohttp 进行 2000 路并发访问登录 API,多次测试结果如下:
Number: 2000 Cost time: 30.67525625228882
Number: 2000 Cost time: 28.96584916114807
Number: 2000 Cost time: 30.91935896873474
Number: 2000 Cost time: 35.23388433456421
Number: 2000 Cost time: 30.99039053916931
Number: 2000 Cost time: 30.856276273727417
Number: 2000 Cost time: 31.30082893371582
在此期间用户可以正常登录。
评测压测
- 评测选用一道 20 个评测点的简单 BFS 题。
- 在同一个仓库内提交 2194 个 commit,并全部提交至系统内。
- 评测自 5 月 6 日 18:11:34 开始,至 19:56:58 结束,共评测 2175 个提交,19 个提交由于部分虚拟机评测节点内存不足未能顺利完成评测,进行了重测。
- 在主服务器上一共开启了 8 个评测结点,5 位测试人员各自在笔记本电脑上开启虚拟机,运行 2 个结点,一共 18 个评测节点。
- 在临时扩容机制下,平均每分钟可评测 400 余个测试点。
后端 API 单元测试情况
由于 API 过多,无法对所有 API 都进行单元测试,因此只挑选了部分重要的 API 进行测试。对于每一个 API,设计了功能测试、授权测试、非法行为测试,最终覆盖率为 62.6%(完整测试报告可见 caesium-backend test-CI 报告)
覆盖率不高,一方面是因为没有完全测试所有的 API,一方面是因为 Golang 的异常处理机制导致某些分支在数据库正常运行的情况下不可能触发。
涉及的 API 系列如下:
- 鉴权与登录
- 用户管理
- 课程管理
- 评测管理
- 实验管理
- 公告管理
单元测试采用并行与串行结合的方式,既提高了运行效率,又降低了各个测试之间的并发依赖关系。
var stages = [][]func(*testing.T){
{rootLogin, staff1Login, staff2Login, studentLogin, illegalLogin},
{tokenExpirationAfterLogout, tokenExpirationAfterResetPassword},
{rootCreateAccount, staffCreateAccount, illegalCreateAccount},
{rootUpdateAccount, staffUpdateAccount, illegalUpdateAccount},
{rootResetAccountPassword, staffResetAccountPassword, illegalResetAccountPassword, illegalSetPermission},
{rootQueryAllAccounts, staffQueryAllAccounts, illegalQueryAllAccounts},
{getAllTeachers},
{rootGetAccountPermissions, staffGetAccountPermissions, illegalGetAccountPermissions},
{rootGetAccountCourses, staffGetAccountCourses, illegalGetAccountCourses},
{getAllAnnouncements},
{rootCreateAnnouncement, staffCreateAnnouncement, illegalCreateAnnouncement},
{rootUpdateAnnouncement, staffUpdateAnnouncement, illegalUpdateAnnouncement},
{rootDeleteAnnouncement, staffDeleteAnnouncement, illegalDeleteAnnouncement},
{rootGetAllCourses, staffGetAllCourses, illegalGetAllCourses},
{rootCreateCourse, staffCreateCourse, illegalCreateCourse},
{rootUpdateCourse, staffUpdateCourse, illegalUpdateCourse},
{rootQueryAllJudgeResults, staffQueryAllJudgeResults, illegalQueryAllJudgeResults},
{selfJudgeResult},
{rootGetJudgeResultDetail, staffGetJudgeResultDetail, illegalGetJudgeResultDetail},
{rootGetAllLabs, staffGetAllLabs, illegalGetAllLabs},
{rootCreateLab, staffCreateLab, illegalCreateLab},
{rootUpdateLab, staffUpdateLab, illegalUpdateLab},
{rootDeleteLab, staffDeleteLab, illegalDeleteLab},
{rootChangeLabsOrder, staffChangeLabsOrder, illegalChangeLabsOrder},
}
func goTestWithWait(wg *sync.WaitGroup, t *testing.T, f func(t *testing.T)) {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("--> run " + runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name())
f(t)
}()
}
func Test(t *testing.T) {
wg := sync.WaitGroup{}
for _, group := range stages {
InitDatabase()
for _, f := range group {
goTestWithWait(&wg, t, f)
}
wg.Wait()
}
}
场景测试
教师工作
典型场景 | 教师工作日常 |
---|---|
用户 | 黄锐 |
知识层次与能力 | 教授 |
生活情况 | 给同学们上课、答疑,做科研 |
动机、目的、困难 | 管理教学班级、关注同学们的学习情况,无奈学生太多 |
用户偏好 | 班级管理简便,教学与考试情况一目了然;又可深度分析具体学生的学习状况 |
场景描述 | 添加、管理班级学生、助教,查看学生课下测试情况,查看学生具体提交情况 |
典型场景 | 教师工作日常 |
---|---|
用户 | 吴天域 |
知识层次与能力 | 副教授 |
生活情况 | 研究分布式系统,兼顾 OS 课程教学 |
动机、目的、困难 | 查看本班同学们的课下完成情况、导入学生名单 |
用户偏好 | 更喜欢 GUI 界面,不喜欢操作数据库 |
场景描述 | 在前端可以查看学生完成情况,在课程开始前使用 CSV 导入学生信息 |
助教工作
典型场景 | 助教工作日常 |
---|---|
用户 | 葡萄味 |
知识层次与能力 | 计算机专业本科 |
生活情况 | 睡大觉 |
动机、目的、困难 | 睡大觉、睡大觉、干活影响睡大觉 |
用户偏好 | 喜欢好的排版,喜欢快的访问速度,喜欢弄清楚所有 bug 的产生原因 |
场景描述 | 查看并编辑公告、题目,在后端可以查看学生的原始输出 |
典型场景 | 助教工作日常 |
---|---|
用户 | 夜捉人 |
知识层次与能力 | 计算机专业本科 |
生活情况 | 关在学校里,每天吃吃喝喝睡大觉,给同学答疑 |
动机、目的、困难 | 查看题目、配置题目、查看评测记录 |
用户偏好 | 懒得用 SQL 查数据库、喜欢好看的界面、喜欢观察学生输出找 bug |
场景描述 | 查看题目、验题、查验评测信息 |
学生工作
典型场景 | 学生情况 |
---|---|
用户 | 青文王 |
知识层次和能力 | 计算机专业本科 |
生活情况 | 被困学校,每天被 OO 和 OS 夹击 |
动机、目的、困难 | 阅读题目、查看评测记录、提交代码 |
用户偏好 | 喜欢直观的 UI 界面,喜欢看以前的提交记录来帮助 debug |
场景描述 | 阅读题目、查看评测记录、提交代码 |
恶意攻击
典型场景 | 恶意攻击系统 |
---|---|
用户 | 辰囸添 |
知识层次和能力 | 计算机专业本科 |
生活情况 | 关在学校里,每天软工 25 小时 |
动机、目的、困难 | 看看能不能黑进管理员账户 / 把管理员密码改掉,或者把系统 D 瘫痪,或者拿个 Web Shell 玩玩 |
用户偏好 | 喜欢弱密码、喜欢私钥泄露、喜欢 SQL 直接拼接、喜欢 HTML 代码不过滤、喜欢用世界上最好的语言写的项目 |
场景描述 | nmap 服务器、sqlmap 各个 API、使用弱口令字典破密码、在可控输入的位置 XSS 等 |
测试矩阵
平台信息 | 浏览器版本 | 登录 | 公告查看 | 进度查看 | 个人中心 | 用户管理 | 教学管理 | 公告通知 | 实验管理 | 考试管理 | 统计分析 | 评测管理 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Windows NT 10.0; Win64; x64 | Chrome/80.0.3987.163 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Windows NT 10.0; Win64; x64 | Chrome/100.0.4896.127 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Windows NT 10.0; Win64; x64 | Chrome/101.0.4951.54 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Windows NT 10.0; Win64; x64 | Edg/101.0.1210.39 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Windows NT 10.0; Win64; x64; rv:100.0 | Firefox/100.0 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Windows NT 10.0; Win64; x64; rv:100.0 | Safari/537.36 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Macintosh; Intel Mac OS X 10_15_6 | Safari/605.1.15 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
Macintosh; Intel Mac OS X 10_15_6 | Chrome/101.0.4951.44 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
X11; Linux x86_64 | Chrome/101.0.4951.54 | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
出口条件
功能条件
在完成原定的 Alpha 阶段基本课程管理、学生使用、代码评测功能的基础上,按照操作系统课程老师的要求,新增基本的统计任务信息的功能。
测试条件
编写并通过全部单元测试,尽可能提高测试覆盖率。
进行简单的后端压力测试、评测机压力测试。压测情况下系统稳定不崩溃。
数据条件
创建 2022 春季学期计算机学院操作系统课程,并将该课程全部学生、助教、老师信息导入系统。
创建课程所需的题目、评测用例、评测脚本。