@@ -21,13 +21,6 @@ gVisor 是 Google 开发的容器运行时沙箱,包含了大量的系统调
2121
2222执行`make test-syscall`命令。该命令将启动DragonOS并自动执行gvisor syscall测试套件,测试完成后会退出qemu。同时根据测试用例成功率选择是成功返回还是失败返回,成功率不等于100%则失败返回。该命令的执行流程如下:
2323
24- 1. 执行 `toggle_compile_gvisor.sh enable ` 注释 `app-blocklist.toml ` 中与 gvisor 测试套件相关的屏蔽配置
25- 2. 编译DragonOS
26- 3. 写入镜像
27- 4. 后台qemu无图形模式启动DragonOS,同时设置环境变量`AUTO_TEST`(自动测试选项,目前仅支持syscall测试)和`SYSCALL_TEST_DIR`(测试套所在目录),这两个环境变量会通过命令行参数传递到DragonOS。然后当busybox init进程执行rcS脚本时,该脚本会通过`AUTO_TEST`选项执行对应的测试
28- 5. 执行`monitor_test_results.sh`定时查看qemu串口输出内容,并根据测试结果选择成功返回还是失败返回
29- 6. 执行 `toggle_compile_gvisor.sh disable ` 取消 `app-blocklist.toml ` 中相关配置的注释,恢复默认屏蔽状态
30-
3124对应的workflow配置文件为`test-x86.yml`
3225
3326手动测试
@@ -83,6 +76,320 @@ gVisor 是 Google 开发的容器运行时沙箱,包含了大量的系统调
8376
8477对于每个测试程序,可以通过 ``blocklists/ `` 目录下的文件屏蔽特定的测试用例。这对于跳过暂不支持或不稳定的测试非常有用。
8578
79+ 测例修复指引
80+ ============
81+
82+ 本部分介绍如何修复gvisor测例,帮助开发者快速参与系统调用修复工作。
83+
84+ 准备工作
85+ --------
86+
87+ 1. **首次安装测例 **
88+
89+ 在开始修复工作前,需要先执行一次 `make test-syscall ` 确保测例已安装到DragonOS系统中:
90+
91+ .. code-block :: bash
92+
93+ make test-syscall
94+
95+ 该命令会下载测试套件、编译DragonOS、写入镜像并自动运行测试。首次执行后,测例会安装到DragonOS的 ``/opt/tests/gvisor `` 目录。
96+
97+ 2. **克隆测例源代码仓库 **
98+
99+ 测例的源代码位于gvisor仓库中,需要克隆到本地以便查看和修复:
100+
101+ .. code-block :: bash
102+
103+ git clone https://cnb.cool/DragonOS-Community/gvisor.git
104+ cd gvisor
105+ git checkout dragonos/release-20250616.0
106+
107+ 测例代码位于 ``test/syscalls/linux `` 目录下,使用gtest框架编写,每个系统调用对应一个或多个 ``.cc `` 文件。
108+
109+ 测试执行流程
110+ ------------
111+
112+ 1. **进入DragonOS系统 **
113+
114+ 使用以下命令以无图形模式启动DragonOS:
115+
116+ .. code-block :: bash
117+
118+ make run-nographic
119+
120+ 2. **执行测试查看报错 **
121+
122+ 在DragonOS系统内,切换到测例目录并执行具体的测试程序:
123+
124+ .. code-block :: bash
125+
126+ cd /opt/tests/gvisor
127+ ./< test_name>
128+
129+ 例如,要测试socket相关的系统调用:
130+
131+ .. code-block :: bash
132+
133+ ./socket_test
134+
135+ 执行测试后,会看到测试结果。失败的测试用例会显示详细的错误信息,包括:
136+
137+ - 失败的测试用例名称
138+ - 错误原因(如系统调用返回错误码、行为不符合预期等)
139+
140+ 如果测例卡住(无响应或长时间不返回),需要查看堆栈跟踪信息来定位问题:
141+
142+ .. code-block :: bash
143+
144+ # 在DragonOS运行的情况下,新开一个终端窗口
145+ # 在DragonOS项目根目录执行
146+ make gdb
147+
148+ 在gdb中,首先需要选择对应的vcpu线程,然后查看堆栈跟踪:
149+
150+ .. code-block :: gdb
151+
152+ # 查看所有线程
153+ info threads
154+
155+ # 选择对应的vcpu线程(例如thread 2)
156+ thread 2
157+
158+ # 查看堆栈跟踪
159+ bt
160+
161+ # 或者查看完整的堆栈跟踪(包含局部变量)
162+ bt full
163+
164+ **注意 **:DragonOS是多核系统,可能有多个vcpu线程。需要根据实际情况选择正确的线程来查看堆栈跟踪。
165+
166+ 3. **记录失败的测试用例 **
167+
168+ 将失败的测试用例名称、错误信息和堆栈跟踪信息记录下来,这些信息将用于后续的修复工作。
169+
170+ 代码修复流程
171+ ------------
172+
173+ 1. **复制测例源代码 **
174+
175+ 从克隆的gvisor仓库中,找到对应的测例源代码文件(通常是 ``<test_name>.cc ``),复制到DragonOS项目根目录:
176+
177+ .. code-block :: bash
178+
179+ cp /path/to/gvisor/test/syscalls/linux/< test_name> .cc /path/to/DragonOS/
180+
181+ 例如,修复socket_test:
182+
183+ .. code-block :: bash
184+
185+ cp gvisor/test/syscalls/linux/socket_test.cc /home/jinlong/code/DragonOS/
186+
187+ 2. **使用AI助手进行修复 **
188+
189+ 将复制的 ``.cc `` 文件提供给AI助手(如Cursor的AI功能),并说明:
190+
191+ - 测试失败的具体错误信息
192+ - 要求AI遵循Linux语义来修复测例
193+ - DragonOS的系统调用实现特点(参考Linux 6.6语义)
194+
195+ AI助手会分析代码,识别问题所在,并提供修复建议或直接修复代码。
196+
197+ 一些小建议:
198+
199+ - 如果问题较为复杂,我们建议先使用Plan模式制定修复计划,然后再修复。
200+ - 如果AI助手难以定位问题,可以让他在内核的适当位置添加少量日志辅助定位
201+ - 如果终端日志被截断,可以到serial_opt.txt去查看完整日志,复制给AI助手
202+ - 如果AI助手难以定位问题,那么可以让他在`user/apps/c_unitest`下面写简单的测试程序来修复问题。这些测试程序会被编译安装到DragonOS的bin目录下。
203+ - 时刻注意提醒AI助手寻找是否有可以复用的代码、建立合理且适当的抽象。不然代码会很冗余!
204+
205+ 3. **验证修复效果 **
206+
207+ 修复完成后,需要重新编译DragonOS并测试:
208+
209+ .. code-block :: bash
210+
211+ # 在DragonOS项目根目录
212+ make run-nographic
213+
214+ 然后在DragonOS内再次执行测试,确认修复是否成功。
215+
216+ 白名单管理
217+ ----------
218+
219+ 修复完成的测例需要添加到白名单中,才能被测试框架执行。
220+
221+ 1. **编辑白名单文件 **
222+
223+ 打开 ``user/apps/tests/syscall/gvisor/whitelist.txt `` 文件,添加测试程序名称:
224+
225+ .. code-block :: text
226+
227+ # 文件系统相关测试
228+ open_test
229+ stat_test
230+ socket_test # 新添加的测试
231+
232+ 2. **白名单格式说明 **
233+
234+ - 每行一个测试程序名称(不带路径和扩展名)
235+ - 以 ``# `` 开头的行是注释,会被忽略
236+ - 空行会被忽略
237+ - 可以按功能分类组织,使用注释分组
238+
239+ 3. **注意事项 **
240+
241+ - 测试程序名称必须与可执行文件名完全一致
242+ - 添加后需要重新`make test-syscall`才能生效
243+ - 建议在添加前先验证测试能够正常运行
244+
245+ 黑名单管理
246+ ----------
247+
248+ 如果某个测试程序中的部分测试用例暂时无法修复或不需要支持,可以创建blocklist文件来屏蔽这些测试用例。
249+
250+ 1. **何时需要创建blocklist **
251+
252+ - 测试用例依赖DragonOS暂不支持的功能(如IPv6、某些文件系统特性等)
253+ - 测试用例存在已知的不稳定性或竞争条件
254+ - 测试用例需要特殊权限或环境配置,当前环境无法满足
255+
256+ 2. **创建blocklist文件 **
257+
258+ 在 ``user/apps/tests/syscall/gvisor/blocklists/ `` 目录下创建与测试程序同名的文件:
259+
260+ .. code-block :: bash
261+
262+ # 例如,为socket_test创建blocklist
263+ touch user/apps/tests/syscall/gvisor/blocklists/socket_test
264+
265+ 3. **blocklist文件格式 **
266+
267+ 在文件中添加要屏蔽的测试用例名称,每行一个:
268+
269+ .. code-block :: text
270+
271+ # 这是注释行,会被忽略
272+
273+ # 屏蔽IPv6相关测试
274+ SocketTest.IPv6*
275+ SocketTest.IPv6Socket*
276+
277+ # 屏蔽需要特殊权限的测试
278+ SocketTest.PrivilegedSocket
279+
280+ # 屏蔽已知不稳定的测试
281+ SocketTest.UnimplementedFeature
282+
283+ 4. **格式说明 **
284+
285+ - 支持通配符 ``* `` 匹配任意字符
286+ - 测试用例名称格式通常为 ``TestSuite.TestCase ``
287+ - 以 ``# `` 开头的行是注释
288+ - 空行会被忽略
289+ - **重要 **:必须在文件中注明屏蔽原因,方便后续维护
290+
291+ 5. **示例 **
292+
293+ 查看现有的blocklist文件作为参考:
294+
295+ - ``user/apps/tests/syscall/gvisor/blocklists/socket_test `` - socket测试的黑名单
296+ - ``user/apps/tests/syscall/gvisor/blocklists/epoll_test `` - epoll测试的黑名单
297+
298+ 完整工作流示例
299+ --------------
300+
301+ 以下是一个完整的修复流程示例,以修复 ``open_test `` 为例:
302+
303+ 1. **准备工作 **
304+
305+ .. code-block :: bash
306+
307+ # 首次安装测例(如果还没安装)
308+ make test-syscall
309+
310+ # 克隆测例源代码
311+ git clone https://cnb.cool/DragonOS-Community/gvisor.git
312+ cd gvisor
313+ git checkout dragonos/release-20250616.0
314+
315+ 2. **发现问题 **
316+
317+ .. code-block :: bash
318+
319+ # 进入DragonOS
320+ make run-nographic
321+
322+ # 在DragonOS内执行测试
323+ cd /opt/tests/gvisor
324+ ./open_test
325+
326+ # 发现部分测试用例失败,记录错误信息
327+
328+ 3. **修复代码 **
329+
330+ .. code-block :: bash
331+
332+ # 复制源代码到DragonOS根目录
333+ cp gvisor/test/syscalls/linux/open_test.cc /home/jinlong/code/DragonOS/
334+
335+ # 使用AI助手修复(在Cursor中打开文件并提供错误信息)
336+ # AI会分析代码并提供修复方案
337+
338+ 4. **验证修复 **
339+
340+ .. code-block :: bash
341+
342+ # 重新编译
343+ make kernel
344+ make run-nographic
345+
346+ # 再次测试
347+ cd /opt/tests/gvisor
348+ ./open_test
349+
350+ # 确认所有测试用例通过
351+
352+ 5. **添加到白名单 **
353+
354+ .. code-block :: bash
355+
356+ # 编辑白名单文件
357+ vim user/apps/tests/syscall/gvisor/whitelist.txt
358+
359+ # 添加:open_test
360+
361+ 6. **处理无法修复的测试用例 **
362+
363+ 如果某些测试用例暂时无法修复(如依赖未实现的功能),创建blocklist:
364+
365+ .. code-block :: bash
366+
367+ # 创建blocklist文件
368+ vim user/apps/tests/syscall/gvisor/blocklists/open_test
369+
370+ # 添加内容:
371+ # 屏蔽依赖O_TMPFILE的测试(DragonOS暂不支持)
372+ OpenTest.Tmpfile*
373+ # 原因:O_TMPFILE需要特定的文件系统支持,当前未实现
374+
375+ 7. **最终验证 **
376+
377+ .. code-block :: bash
378+
379+ # 重新编译并运行完整测试套件
380+ make test-syscall
381+
382+ # 确认open_test能够正常运行,失败的用例已被blocklist屏蔽
383+
384+ 注意事项
385+ --------
386+
387+ - **符合Linux语义 **:修复时要确保系统调用行为符合Linux 6.6的语义,不要使用workaround绕过问题
388+ - **深入分析 **:修复前要深入分析问题根源,结合测例代码、DragonOS实现和Linux行为进行对比
389+ - **测试验证 **:每次修复后都要重新测试,确保修复有效且没有引入新的问题
390+ - **文档记录 **:在blocklist中详细记录屏蔽原因,方便后续维护和重新启用
391+ - **代码质量 **:修复后的代码要符合DragonOS的代码规范,运行 ``make fmt `` 进行格式化
392+
86393更多详细信息
87394==============
88395
0 commit comments