ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Skia Job Analysis 指南:用 jq + Miller 审计 jobs.json,找出 CI 测试覆盖缺口

Skia Job Analysis 指南:用 jq + Miller 审计 jobs.json,找出 CI 测试覆盖缺口 图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载本文围绕 Skia 仓库中 infra/bots/analysis/README.md 所描述的Job Analysis工具链展开介绍如何通过一组 Shell 脚本与 Makefile 目标对 infra/bots/jobs.json 中的 716 个 CI 任务进行结构化解析从而快速找出当前完全没有跑 Perf 基准、没有跑 Test、或者没有覆盖 Vulkan 后端的 CPU / GPU 设备组合。读完本文你将掌握该分析套件的运行环境要求、数据流水线原理jobs.json → /tmp/alljobs.csv → 缺口报告并能自定义 Miller 布尔过滤器扩展出自己的覆盖度审计查询。一、Job Analysis 是做什么的infra/bots/analysis目录下存放着一套面向 Skia 基础设施团队的分析脚本其目标非常明确分析jobs.json发现测试配置中的空洞holes。这里的空洞指的是某些 CPU 或 GPU 设备即cpu_or_gpu_value维度上的取值虽然出现在总设备清单中却没有任何对应类型的 CI 任务在运行它们——例如某个 GPU 从未被跑过 Perf 基准测试或从未以 Vulkan 后端跑过 Test。这套分析的价值在于Skia 的 CI 矩阵非常庞大jobs.json中仅本仓库当前就包含约 716 条任务定义可通过grep -c name infra/bots/jobs.json验证覆盖 Android、iOS、Linux、Windows、Mac 等多个平台与数十种 CPU/GPU 型号。人工核对极易遗漏覆盖空白而将任务名解析为结构化 CSV 后用 Miller 做集合差差集运算即可自动列出所有缺口。该目录包含 4 个文件分工如下文件职责README.md使用说明与快速上手Makefile封装常见查询的 make 目标create-alljobs.sh把jobs.json解析为/tmp/alljobs.csvaxis.sh生成指定列的唯一值轴CSVmissing.sh核心缺口查询脚本对 CSV 做过滤 差集二、环境要求与安装根据 README.md 的要求运行这套脚本需要两个命令行工具jq用于解析jobs.json这个 JSON 文件mlrMiller用于对 CSV 做过滤filter、切列cut、排序sort、去重uniq与连接join等操作。在 Debian / Ubuntu 系系统上一条命令即可安装$ sudo apt install jq miller安装后可用jq --version与mlr --version验证。Miller 的完整查询语法可参考其官方参考文档README 中给出的 https://miller.readthedocs.io/en/latest/reference-dsl.html 本文后续也会结合脚本实际用到的 DSL 子集进行说明。需要注意mlr --csv子命令对 CSV 的列名大小写敏感分析脚本中统一使用Type、os、model、cpu_or_gpu_value等精确列名。三、快速上手运行第一个缺口查询进入分析目录后直接使用 Makefile 封装好的目标即可$ cd infra/bots/analysis $ make missing_perf_jobs该命令会输出一份清单列出所有当前没有运行 Perf 基准测试的cpu_or_gpu_value以及对应的设备型号 model。例如输出形如cpu_or_gpu_value,model Adreno540,Pixel2XL Adreno615,Pixel3a MaliG72,GalaxyS9 ...以 infra/bots/jobs.json 中的真实任务名验证Perf-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Release-All-Android与Test-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Debug-All-Android这类任务名会同时贡献 MaliT880 这一cpu_or_gpu_value而如果某个 GPU 只出现在 Test 任务中、从未出现在 Perf 任务中missing_perf_jobs就会把它报告出来。Makefile 中总共封装了三个现成目标Makefilemissing_perf_jobs: ./missing.sh $$Type Perf missing_test_jobs: ./missing.sh $$Type Test missing_vulkan_jobs: ./missing.sh $$vulkan true三个目标本质都是调用missing.sh只是传入的 Miller 布尔过滤器不同make 目标过滤器查询语义missing_perf_jobs$Type Perf找出没有 Perf 任务覆盖的设备missing_test_jobs$Type Test找出没有 Test 任务覆盖的设备missing_vulkan_jobs$vulkan true找出没有 Vulkan 后端任务覆盖的设备注意 Makefile 中$$Type的写法这是 make 的变量转义规则$$在传给 Shell 时会展开成单个$最终交给 Miller 的是$Type Perf这样的 DSL 表达式。四、数据流水线原理从 jobs.json 到缺口报告整个分析过程是一条清晰的数据流水线共分三步解析create-alljobs.sh 读取jobs.json把每个任务名拆解为结构化 CSV 行产出/tmp/alljobs.csv取轴axis.sh 从全量任务中抽取所有cpu_or_gpu_value的唯一值及其型号产出基准清单/tmp/cpu_or_gpu_value,model.csv求差missing.sh 先按过滤器筛出符合条件的任务再与该基准清单做差集最终输出符合条件任务未覆盖的设备。下面逐层拆解每一步的源码实现。4.1 create-alljobs.sh任务名 → 结构化 CSVcreate-alljobs.sh 是整个流水线的入口核心逻辑如下# 写入起始表头 echo Type,os,compiler,model,cpu_or_gpu,cpu_or_gpu_value,arch,configuration,test_filter,extra /tmp/alljobs.csv # 用 jq 提取每个 job 的 name只保留 Perf / Test 开头者并把 - 替换为 , # 同时把末尾的 All 补成 All,none保证每列都有值 cat ../jobs.json | jq .[] -r | grep ^[Perf|Test] | sed s#-#,#g | sed s#All\$#All,none#g /tmp/alljobs.csv # 追加 vulkan / metal 布尔列 mlr --csv -I put $vulkan$extra ~ Vulkan /tmp/alljobs.csv mlr --csv -I put $metal$extra ~ Metal /tmp/alljobs.csv # 校验输出是合法 CSV mlr --icsv check /tmp/alljobs.csv结合 jobs.json 的实际结构每条记录形如{name: Perf-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Release-All-Android, ...}可以还原其解析逻辑jq .[] -r逐条输出每个 job 的原始 JSON-r保证输出为裸字符串rawgrep ^[Perf|Test]只保留任务名以 Perf 或 Test 开头的条目跳过 BazelBuild、BazelTest 等其它类型第一个sed s#-#,#g把任务名中的所有-替换为,从而把Perf-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Release-All-Android这样的名字拆成 10 个字段恰好对应表头的 10 列TypePerf、osAndroid、compilerClang、modelGalaxyS7_G930FD、cpu_or_gpuGPU、cpu_or_gpu_valueMaliT880、archarm64、configurationRelease、test_filterAll、extraAndroid第二个sed s#All\$#All,none#g处理test_filter为All的情况因为任务名到All处已经结束后面没有-可拆所以补一个none占位保证extra列不为空$vulkan$extra ~ Vulkan与$metal$extra ~ Metal是 Miller 的 put 语句利用正则匹配extra列新增vulkan、metal两个布尔列。这也是missing_vulkan_jobs能够用$vulkan true查询的原因——任务名如Perf-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Release-All-Android_Vulkan的extra段含有Vulkan该行vulkan列即为 true最后mlr --icsv check做完整性校验若 CSV 格式不合法脚本会直接失败set -e。4.2 axis.sh生成设备轴清单axis.sh 负责从全量任务中提取某个或某几个列的唯一取值组合mlr --csv uniq -f $1 /tmp/alljobs.csv | mlr --csv sort -f $1 /tmp/$1.csv其唯一参数是逗号分隔的列名列表同时这个列表也用作输出文件名。例如./axis.sh cpu_or_gpu_value,model会用mlr --csv uniq -f cpu_or_gpu_value,model对两列组合去重用mlr --csv sort -f cpu_or_gpu_value,model排序输出到/tmp/cpu_or_gpu_value,model.csv。这份文件就是Skia 测试矩阵中已知的全部设备清单——凡是没有出现在某类任务里的设备都会被后续的差集运算揪出来。4.3 missing.sh过滤 差集定位覆盖空洞missing.sh 是查询核心接收一个 Miller 布尔过滤器作为唯一参数完整流程如下if [ $# -ne 1 ]; then echo $0 filter echo Example: $0 \$vulkan \true\ exit 1 fi FILTER$1 # 确保 /tmp/alljobs.csv 已生成 ./create-alljobs.sh # 提取全部 cpu_or_gpu_value 与对应 model ./axis.sh cpu_or_gpu_value,model # 过滤出符合条件的任务 → 提取设备列 → 排序去重 → 与基准清单做差集 mlr --csv filter ${FILTER} /tmp/alljobs.csv | \ mlr --csv cut -f cpu_or_gpu_value,model | \ mlr --csv sort -f cpu_or_gpu_value | \ mlr --csv uniq -f cpu_or_gpu_value | \ mlr --csv join -f /tmp/cpu_or_gpu_value,model.csv -j cpu_or_gpu_value --ul --np这条五段式 Miller 管道是整套分析的精髓逐段说明阶段作用mlr --csv filter ${FILTER}按传入的布尔表达式如$Type Perf筛选行得到符合条件的那类任务mlr --csv cut -f cpu_or_gpu_value,model只保留设备列丢弃其它无关字段mlr --csv sort -f cpu_or_gpu_value按键排序保证后续 join 的效率与确定性mlr --csv uniq -f cpu_or_gpu_value去重得到这类任务实际覆盖过的设备集合mlr --csv join -f /tmp/cpu_or_gpu_value,model.csv -j cpu_or_gpu_value --ul --np与设备全集做左连接--np表示不打印匹配行--ul表示打印左表即设备全集中未被匹配的行--ul --np这两个参数值得单独说明脚本注释中也有解释--npno print matches让 join 不输出两边都命中的行--ulunmatched left只输出左表——即/tmp/cpu_or_gpu_value,model.csv设备全集——中在右表找不到对应项的行。两者结合的效果正是设备全集 − 已覆盖设备 覆盖缺口的集合差运算。五、自定义查询把分析扩展到任意维度missing.sh的过滤器参数完全开放任何能作用于alljobs.csv列的 Miller 布尔表达式都可以使用。结合 create-alljobs.sh 中定义的表头可用列包括Type, os, compiler, model, cpu_or_gpu, cpu_or_gpu_value, arch, configuration, test_filter, extra, vulkan, metal据此可以扩展出很多实用查询例如# 找出没有跑 Metal 后端任务的设备注意列名是 metal布尔匹配 $ ./missing.sh $metal true # 找出没有在 Release 配置下跑 Perf 的设备组合条件 $ ./missing.sh $Type Perf $configuration Release # 找出没有在 64 位 arm 架构下跑 Test 的设备 $ ./missing.sh $Type Test $arch arm64 # 找出连 Debug 配置的 Test 都没有的设备 $ ./missing.sh $Type Test $configuration Debug由于vulkan/metal列由extra列的子串匹配生成凡是任务名中带有_Vulkan、_Metal后缀的条目都会自动归入对应布尔列这一设计让按图形后端审计覆盖变得非常直接。若想固定下来复用参照 Makefile 的写法新增一个目标即可注意 DSL 中的$需要写成$$以通过 make 的转义。六、与任务生成体系的衔接jobs.json 从哪来这套分析所依赖的 infra/bots/jobs.json 并不是手写的静态文件而是与 Skia 的任务生成体系深度绑定的。在 infra/bots/gen_tasks_logic/gen_tasks_logic.go 中可以找到其定义与加载逻辑JobInfo类型第 312 行附近描述了 jobs.json 中每条记录的结构即任务名 可选的 cq_configGenTasks函数第 365 行附近负责重新生成tasks.json其第一步就是通过LoadJson(filepath.Join(relpathBaseDir, jobs.json), jobsWithInfo)加载任务清单在任务展开过程中第 961 行附近生成逻辑会按cpu_or_gpu_value查找设备映射表若遇到未知设备会直接log.Fatalf报错——这说明cpu_or_gpu_value是任务展开的关键键值与本文分析脚本以它作为缺口判定维度完全一致。因此分析脚本与任务生成器共享同一份事实来源当开发者在jobs.json中新增或删除任务后重新运行make missing_*即可立刻看到新引入的覆盖缺口形成配置 → 生成 → 审计的闭环。七、常见问题与注意事项输出文件路径固定脚本约定所有中间产物都写在/tmp下/tmp/alljobs.csv、/tmp/cpu_or_gpu_value,model.csv多次运行会覆盖若要保留历史结果需自行拷贝。任务名前缀过滤create-alljobs.sh 中的grep ^[Perf|Test]只纳入 Perf / Test 开头的任务Bazel 系列任务如BazelTest-...、BazelBuild-...不会进入 CSV因此jobs.json中约 716 条任务并非全部参与分析。缺列的兜底任务名末尾的All通过sed s#All\$#All,none#g补成All,none保证extra列不为空否则第 10 列会缺失导致列数错位。大小写与引号Miller 的filter表达式对列名大小写敏感且 Bash 传参时要注意$的转义——命令行直接调用用单引号包住$Type Perf写进 Makefile 则需写成$$Type。依赖工具版本脚本基于 jq 与 Miller 的--csv子命令与join含--ul、--np选项特性编写建议使用较新的 Miller 版本以获得完整的 DSL 支持。综上infra/bots/analysis提供了一套轻量、可组合的 CI 覆盖审计工具理解 README.md 中jq mlr的定位后通过 Makefile 的现成目标即可秒级定位测试空洞而借助missing.sh的开放式过滤器还能把审计扩展到任意架构、配置与图形后端的组合是维护 Skia 庞大测试矩阵时值得常备的实用工具链。赞分享图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载相关推荐用 Miller 与 jq 挖掘 Skia CI 测试盲区jobs.json 任务矩阵分析实战用 Miller 与 jq 挖掘 Skia CI 测试盲区jobs.json 任务矩阵分析实战 本篇文章围绕 Skia 仓库 infra/bots/analy图形学IronClaw 变异审计实战用 Mutation Testing 找出覆盖率看不见的测试空洞IronClaw 变异审计实战用 Mutation Testing 找出覆盖率看不见的测试空洞 在 IronClaw一个聚焦隐私、安全与可扩展性的 Agen人工智能AI 应用交互助手AI AgentRust 代码覆盖率实战用 cargo-llvm-cov 找出测试盲区并搭建 CI 覆盖率门禁Rust 代码覆盖率实战用 cargo llvm cov 找出测试盲区并搭建 CI 覆盖率门禁 导读 本文以工程实践手册 ch04 code coverag文档教程上一篇5大滤波算法实战指南从噪声处理到状态估计下一篇ctxsync 完全指南本地文件自动同步 Claude.ai Projects 的开源神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表