十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

workerd 中 WPT 依赖更新与测试分类(Triage)实践指南

workerd 中 WPT 依赖更新与测试分类(Triage)实践指南 workerd 中 WPT 依赖更新与测试分类Triage实践指南【免费下载链接】workerdThe JavaScript / Wasm runtime that powers Cloudflare Workers项目地址: https://gitcode.com/GitHub_Trending/wo/workerd本文基于仓库.opencode/skills/wpt-update/SKILL.md撰写。WPTWeb Platform Tests是评估运行时对 Web 标准符合性的开源测试套件workerd 在 src/wpt 下维护自己的运行配置因为部分测试不适用、或覆盖了 workerd 尚未实现的行为。读完本文你将掌握 workerd 中更新 WPT 依赖bump与分类处理测试结果triage的完整工作流从一条命令完成依赖升级到按 suite/subtest 粒度逐层分类、运行 Bazel 测试、输出最终报告并做 Git 交接。WPT 与 workerd为什么需要更新 分类双流程WPT 是衡量运行时是否符合 Web 标准的权威测试集。workerd 并不直接逐条通过所有 WPT 用例而是采用依赖 本地配置的组合策略依赖层面通过 build/deps/shared_deps.jsonc 将上游 WPT 以wpt-sha形式冻结为一个发布当前为wpt-5af6acac2SHA 后缀对应上游 WPT 提交配置层面在 src/wpt 下为每个套件编写suite-test.ts配置文件声明哪些子测试预期失败expectedFailures、无法运行disabledTests或不适用omittedTests。因此一次更新 WPT的请求天然包含两部分依赖更新bump和结果分类triage。除非用户明确要求仅 bump否则两者都要完成——SKILL.md 开篇即声明了这一默认约定。更新范围哪些文件可以动哪些不能动WPT 更新允许修改的只有两类文件更新器updater生成的依赖元数据src/wpt下的 WPT 配置文件。不要在 WPT 更新过程中顺手修复运行时符合性 bug。如果正确的分类需要改动运行时、harness、构建规则、补丁或上游内容应把这些作为后续工作follow-up写入报告而非当场修改——除非用户明确扩大范围。动手前的 Preflight 检查确定 checkout 形态判断 workerd 是独立仓库standalone还是作为子模块submodule被检出这直接决定后续 Bazel 命令的 label 前缀//src/wpt/...还是workerd//src/wpt/...读取所有适用的AGENTS.md仓库根目录与 src/wpt 等子目录均有对应的 AGENTS.md需先了解仓库协作约定检查工作树保留与本次更新无关的改动避免混入提交在编辑 TypeScript 配置文件前加载ts-style技能遵循仓库的 TS 代码风格。Bump WPT 依赖一条命令与两个产物文件在 workerd 根目录执行./build/deps/update_wpt.py更新器会从cloudflare/workerd-tools仓库挑选标题形如wpt-*的最新发布。一次正常的更新只会改动两个文件build/deps/shared_deps.jsoncbuild/deps/gen/shared_deps.MODULE.bazel更新器的选择逻辑源码视角build/deps/update_wpt.py 的实现值得注意TITLE re.compile(rwpt-.*)用于过滤标题匹配的发布all_releases()会分页拉取全部 release 列表每页 100 条因为 GitHub 的 releases 接口按created_at排序、且无法排序而created_at是发布所基于提交的日期而非发布日期——数十个 release 可能共享同一时间戳最新发布不一定在第一页matching_releases()排除 draft草稿按published_at降序排列取第一个即为目标版本若最新 tag 与当前freeze_version相同则打印wpt is up to date at tag并直接返回否则更新freeze_version并设置TARGET_FILTER wpt调用 build/deps/update-deps.py只重新生成 wpt 这一个依赖下载发布以记录其哈希与 strip_prefix其余依赖保持不变。产物验证点更新后需确认新 tag 在以下位置一致出现且生成了新的 SHA-256freeze_versionstrip_prefix归档下载 URL以 build/deps/shared_deps.jsonc 中的 wpt 条目为例其关键字段包括type: github_release、file_regex: wpt-.*.tar.gz、build_file: workerd//:build/BUILD.wpt以及应用在发布上的 patches/wpt/0001-disable-virtualenv-for-serve-command.patch。生成产物严禁手工编辑——生成文件头部即带有 AUTOGENERATED ... DO NOT EDIT 警告。失败处理与无关发布的干扰更新器会先写 manifest更新freeze_version再下载并重新生成元数据。如果中途失败绝不能带着不一致的文件继续而应解决失败 → 重新运行更新器 → 同时校验两个产物文件。另外由于workerd-tools仓库同时承载多种工具clang-format、wpt 等通用依赖更新器可能提示有更新的 release 可用——这不一定是 WPT 的发布。判定成功与否的唯一依据是选中的 WPT tag 与最终 diff。若更新器报告 WPT 已是最新bump-only 请求到此为止。依赖改动与 triage 改动必须保持分离若用户明确要求提交则先提交依赖更新再继续 triage否则不提交、继续。Triage 流程总览以固定 SHA 为准绳triage-only 请求只做分类、不 bump的第一步是确认相对约定基线存在 pin 变化从依赖 diff 中读取新旧wpt-sha值后缀即上游 WPT 的对应提交。所有上游调研必须基于pinned SHA而不是上游main分支——main 上的内容可能与 pin 的提交不同会导致误判。由于 GitHub 的 compare 接口对大型 WPT 更新会截断需要完整 diff 时应使用 compare 接口并追加.diff后缀即形如old-sha...new-sha.diff的完整差异文本。拿到完整 diff 后先过滤出 src/wpt/BUILD.bazel 中wpt_directory所映射的 WPT 目录范围内的改动。对单个失败用例则要逐一检查变更文件 → 相关提交 → 关联 PR → 链接的规范spec变更。运行 WPT 测试套件Bazel 命令以下命令展示了正确的仓库 label。请按当前 checkout 形态选用并加上 test-hygiene 规范要求的全部 flag。独立仓库standalone在 workerd 根目录执行bazel test //src/wpt/... --test_size_filters子模块形态submodule在父仓库根目录执行bazel test workerd//src/wpt/... --test_size_filters清空test_size_filters--test_size_filters后接空值是为了确保体积巨大的 WPT target 被包含进测试。完整模式会运行默认与 all-autogates 两种变体外加 ESLint 与 TypeScript 检查。迭代单个套件时使用受影响的 suite target注意必须带后缀# standalone bazel test //src/wpt:suite \ --test_size_filters \ --test_outputerrors # submodule bazel test workerd//src/wpt:suite \ --test_size_filters \ --test_outputerrors不要使用 test-case 过滤参数。日志根目录用bazel info bazel-testlogs解析或直接采用 Bazel 打印的路径子模块形态下日志嵌套在外部 workerd 仓库之下。日志定位技巧不要通读整份日志而是优先搜索以下关键消息Missing test configuration unexpectedly failed unexpectedly succeeded Please update the test config Test file ... not found这些消息直接对应 harness 源码中的错误路径缺少配置会抛Missing test configuration for file见 src/wpt/harness/harness.tsunexpectedly failed/unexpectedly succeeded与Please update the test config则来自RunnerState.validate()同文件 L168-L195而Test file ... not found说明被引用的资源未声明到.wd-test绑定中需要更新wpt_test.bzl见 L327-L333。处理 suite 级变化suite是发现出的单个 WPT JavaScript 文件。它的配置 key 是相对 src/wpt/BUILD.bazel 中声明的wpt_directory的精确、大小写敏感的路径。发现Discovery规则从源码 build/wpt_test.bzl 的is_test_file()可以确认 suite 发现的排除规则非.js文件不是测试路径位于resources/子目录的文件被视为资源由测试 include而非独立运行路径含.tentative.或/tentative/的文件被排除——tentative 测试针对尚未标准化的提案特性跳过可避免不稳定规范的噪声。配置 key 的排序约束配置 key必须保持升序这是 ESLint 的sort-keys规则强制要求的见 src/wpt/eslint.config.mjs该规则仅对src/wpt/**/*-test.ts生效。比较时必须依据完整原始 key标点会影响排序例如-排在.之前——不要仅凭视觉分组就安放新 key。新增 / 删除 / 改名先检查 rename 或 move不要一上来就把改名当作新增 删除处理对真正的 rename要把现有配置整体迁移过去删除已消失 suite 的配置 key为每个新 suite 添加一个排好序的空条目以便观察其行为path/to/example.any.js: {},值得注意的是JavaScript helper 文件也会被纳入发现除非其直接父目录是resources。位于resources之外的 helper哪怕不注册任何测试可能需要显式配置omittedTests以避免缺少配置错误——例如 src/wpt/WebCryptoAPI-test.ts 中就有derived_bits_length_testcases.js这种不在 resources/ 目录的资源文件被标记omittedTests: true的真实案例。套件 key 对齐后必须重跑全量调和套件 key 之后重新运行完整的 WPT 测试集反复直到不再出现 missing / stale 配置错误。并且每次编辑配置后都要运行聚合 target//src/wpt:wpt-alltsprojecteslintsubmodule 形态加workerd前缀不能只依赖单个 suite 的 ESLint target。处理 subtest 级变化subtest是 suite 内单个具名的test()或promise_test()源码中的Test类见 src/wpt/harness/test.ts。处理流程先检查移除的名称 新增的名称是否对应一次subtest 改名当一条 expected failure 现在通过了要先判断是 workerd 实现了改进还是上游改名、删除或弱化了该测试再决定是否移除预期失败配置每条新增或新失败的 subtest 在分类前都必须调查清楚。迭代时重跑受影响的 suite最后重跑完整 WPT 集直到不存在 unexpected failures 或 unexpected successes。分析失败测试的七步法对每个 unexpected 结果按如下顺序调查读取确切的 subtest 失败信息与堆栈检查新 pinned SHA处的上游文件定位引入该测试的提交与规范变更检查 workerd 相关实现或依赖判断该测试是相关、无法安全运行还是不适用记录当前原因以及超出范围的修复方向对比 default 与 all-autogates 两种行为再决定是否合并为一条共享配置。严禁为了让 target 通过而把不确定的结果强行分类。运行时修复超出范围——应在报告中说明可能的修复方式而不是当场修。META 脚本与加载失败的特殊性META 脚本与顶层代码在 subtest 注册之前执行。这意味着expectedFailures条目无法分类此阶段出现的资源缺失或求值错误——因为此时还没有 subtest 可供匹配局部的disabledTests/omittedTests数组同样无法规避这个问题。只有整文件的disabledTests: true与omittedTests: true会在 META import 之前跳过求值源码见 src/wpt/harness/harness.ts。使用它们的前提是该分类本身独立成立。不能仅仅因为 harness 支持缺失就省略一个本应相关的 suite。三种分类的语义与配置写法workerd 的 WPT 配置基于TestRunnerConfig类型定义于 src/wpt/harness/harness.ts三种分类语义如下配置项语义适用场景expectedFailures相关 subtest确实执行但当前因 workerd 不符合规范而断言失败已知的符合性差距disabledTests相关测试无法可靠或安全运行挂起hang、崩溃、状态破坏、harness 限制omittedTests测试对 workerd 不适用排除在覆盖率之外浏览器专属行为、不支持的算法每个属性既可接受true整 suite也可接受精确字符串与正则表达式的数组。优先使用精确的 subtest 名称只有必要时才用正则且正则必须窄、尽量锚定并逐一核对所有目标名称。禁止用宽泛正则或整 suitetrue来强行让 target 通过。每条分类都必须带comment描述当前技术原因。源码注释只描述当前行为不写调查过程或历史额外的证据与历史可放进提交信息与报告中。harness 会报告未匹配的expectedFailuresexpected to fail but instead succeeded但正则仍可能隐藏部分过期的条目而 stale 的 disabled/omitted 数组条目不会被报告——必须针对上游改名、删除的 subtest 手动审计。真实配置示例src/wpt/url-test.ts 展示了完整写法satisfies TestRunnerConfig提供类型检查import { type TestRunnerConfig } from harness/harness; export default { idlharness.any.js: { comment: IDL tests fail because Workers exposes globals differently than browsers (not as own properties of self), expectedFailures: [ URLSearchParams interface: iterableUSVString, USVString, ], }, percent-encoding.window.js: { comment: Implement test code modification feature to allow running this test without document, disabledTests: true, }, url-setters-a-area.window.js: { comment: Excluded because it uses the same test data as url-setters.any.js, omittedTests: true, }, urlencoded-parser.any.js: { comment: Requests fail due to HTTP method LADIDA, responses fail due to shift_jis encoding, expectedFailures: [ /request\.formData\(\) with input:/, /response\.formData\(\) with input:/, ], }, toascii.window.js: { replace: (code): string code.replace(/\[url, a, area\]/, [ url ]), }, } satisfies TestRunnerConfig;src/wpt/WebCryptoAPI-test.ts 则展示了更丰富的分类组合derive_bits_keys/hkdf.https.any.js用正则/with 100000 iterations/排除超时用例encap_decap/ml_kem_vectors.js后量子 ML-KEM 未支持与encrypt_decrypt/aes_ocb_vectors.jsAES-OCB 未支持均以omittedTests: true排除。除配置项外CommonOptions还支持before/after钩子、replace运行前改写测试代码、only仅执行该测试收尾前必须移除与runInGlobalScope等能力。收尾验证清单完成前逐项确认移除临时的only设置确认无 missing 或 stale 的 suite key确认无 unexpected failures 或 successes手动审计所有变更的 disabled / omitted 选择器用当前 checkout 对应的命令运行完整 WPT target 集要求 Bazel 报告Build completed successfully确认最终Executed N out of N tests: N tests pass汇总覆盖每一个选中的 target不要把被打断或仅部分分析的调用当作成功在 workerd 根目录运行格式与空白检查python3 tools/cross/format.py --check git git diff --check最终报告与 Git 交接报告必须包含新旧 WPT tag 与 pinned 上游对比 URLold-sha...new-sha新增、删除、改名的 suites新增或移除的 expectations每条分类及其持久的技术原因相关的上游与 workerd 源码位置建议的超范围修复与未解决问题精确的验证命令与最终执行计数最终 Git 状态。Git 交接要求依赖 bump 与 WPT triage 分成两个独立提交保持历史可追溯、可单独回滚。持续改进回读 SKILL.md每次更新完成后回读 .opencode/skills/wpt-update/SKILL.md 本身若其中有表述不清或需要额外查询才能理解的细节就补充进文档与WPT 测试框架在 workerd 中如何工作相关的信息是有价值的沉淀但不要记录本次更新遇到的个例——那属于瞬时信息对未来的更新无益。【免费下载链接】workerdThe JavaScript / Wasm runtime that powers Cloudflare Workers项目地址: https://gitcode.com/GitHub_Trending/wo/workerd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表