sched-ext discussion
[PATCH] selftests/sched_ext: Fail interrupted test runs
LLM 分析
selftests/sched_ext:让被打断的测试运行正确返回失败
系列概况
- 标题: [PATCH] selftests/sched_ext: Fail interrupted test runs
- 作者: Tianyi Chen
<hi@tychen.cc> - 版本: v1(单封 patch,没有 vN 标记)
- 规模: 1 个文件,1 insertion(+),1 deletion(-)
- 修改文件:
tools/testing/selftests/sched_ext/runner.c - 代码统计:
1 file changed, 1 insertion(+), 1 deletion(-) - Message-ID:
20260906135507.749280-1-hi@tychen.cc - 完整性: 完整。包含 diff hunk、Fixes tag、Assisted-by LLM、Signed-off-by,并附带 GDB 手工验证四种信号投递 case 的结果。
补丁目的
让 selftests/sched_ext 的 runner 在收到 SIGINT/SIGTERM 中断时返回非零退出码,避免把"被打断的运行"误报成"全部通过",从而让 CI 和脚本能可靠区分两种语义完全不同的结束状态。
旧流程的问题
runner.c 在收到信号时会让信号处理函数置 exit_req = 1,主循环据此跳出。但 main() 末尾的退出码判定只看 failed:
return failed > 0 ? 1 : 0;
只要被打断前没有任何测试失败,进程就以 0 退出。这是经典的"沉默退出"——CI 流水线看到 0 会认为测试全部通过,掩盖了"中途被 Ctrl+C / build system 超时杀掉"的事实。先前的修复 commit 9d851afa4826 只解决了"中止循环",却没解决"中止后正确报错"。
新流程
将退出码判定改为同时考虑 failed 与 exit_req:
return failed > 0 || exit_req ? 1 : 0;
短路求值先看显式失败,再看中断标志。failed 计数器仍只统计真正跑过的测试,所以"被中断时跑过的若干测试都过"不会被记为失败,但整体 run 仍以非零退出,调用方可以可靠地感知异常。
关键实现
patch 的 hunk 只有一行,作用于 main() 末尾的返回值表达式;不改动信号处理、不改动测试循环、不改动输出。
- return failed > 0 ? 1 : 0;
+ return failed > 0 || exit_req ? 1 : 0;
关键观察:
exit_req由先前的 commit9d851afa4826 ("selftests/sched_ext: Abort test loop on signal")引入,信号处理函数里置位,主循环里读取,无需在main中再次注册信号。failed计数语义保持不变:如果中断前已有测试失败,会先因failed > 0返回 1;只有"零失败 + 被中断"才走exit_req这条新分支。- 作者在 GDB 下用四种 case 验证:信号在"第一个测试前"送达 vs "example 通过后"送达;原 runner 返回 0,修复后返回 1;正常
-h/-l/-t example调用仍返回 0。
状态机
runner 主循环的状态转移:
[INIT]
|
v
parse_args (-h / -l / -t)
|
v
setup tests
|
v
+------------------------------+
| while (next && !exit_req) |-- SIGINT/SIGTERM --+
| run test | |
| failed += result |<------------------+
+------------------------------+
|
v
print summary
|
v
return failed > 0 ? 1 : 0 (OLD: ignore exit_req)
return failed > 0 || exit_req ? 1 : 0 (NEW: interrupt -> 1)
类比
把 runner 想象成一场马拉松的终点裁判:完赛证书只应该发给"跑完全程且没有退赛"的选手。
- 旧逻辑:只要到终点时还没人摔倒,就盖章"完赛"——哪怕选手是被强制拦下来的,也算"通过"。
- 新逻辑:必须真的跑完全程才能盖章;被拦下的即使没摔倒,也得标记 DNF。
CI 看到盖章(退出码 0)就放心,看到不盖章(退出码非 0)就知道这次跑得有问题。
Highlight:风险与注意点
- 行为变更:依赖"Ctrl+C runner 后 exit 0"的本地脚本或流水线需要注意——但这是与 POSIX/惯例一致的方向(被信号终止应返回非零),多数 CI 反而会更喜欢。
failed的语义保持不变:只有"零失败 + 被中断"才走exit_req新分支;已有失败仍先由failed > 0触发返回 1。- stdout 输出不区分:runner 在被中断路径下不会打印完整 summary,调用方若要进一步区分"全过被中断"和"中断后清理",得结合 stdout 最后一行而不是只靠退出码。
Assisted-by: LLM标签:部分 maintainer 对 AI-assisted patch 持保留态度,可能会要求作者对修改做更详细的解释,或对变更做更彻底的人工 review。
一句话总结
selftests/sched_ext runner 现在把"被打断"也算作失败,让 CI 能从退出码可靠地察觉异常中断。