拓冰建站拓冰建站
首页 / 资讯中心 / 正文

MongoDB 仓库 Resmoke 套件的 Bazel 执行架构:RBE 远程执行与本地执行双轨调度

MongoDB 仓库 Resmoke 套件的 Bazel 执行架构RBE 远程执行与本地执行双轨调度【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo导读本文讲解 MongoDB 开源仓库中resmoke测试套件如何通过 Bazel 在 CIEvergreen EngFlow中执行每个编译变体variant的每套测试套件依据incompatible_with_bazel_remote_test标签被划分为远程 RBE 执行与本地执行两个互不相交的集合由resmoke_tests调度器统一编排。读完本文你将掌握该双轨调度模型的任务生成逻辑、执行时序、结果收集链路以及仓库中对应的源码与脚本实现便于在本地复现或调试这套 CI 流程。双轨执行模型每个套件二选一在 docs/evergreen-testing/resmoke_bazel_execution.md 描述的模型中每个变体都通过两种方式运行它的套件按套件per suite选择选择依据是套件 Bazel target 上的incompatible_with_bazel_remote_test标签套件类别执行位置触发方式RBE 兼容未打该标签远程EngFlow 集群bazel test --configremote_test不兼容打了该标签本地Evergreen 主机bazel test --installed_dist_test两个集合互不相交它们的并集恰好是该变体选中的全部套件。这意味着CI 既不会遗漏套件也不会重复执行套件——标签是唯一的路由键。该标签在仓库中的定义与使用可见于 buildscripts/generate_result_tasks.py本地过滤串LOCAL_INCOMPATIBLE_FILTER ,incompatible_with_bazel_remote_test、本地任务标签LOCAL_TASK_TAG resmoke_local_test并有 buildscripts/tests/test_generate_result_tasks.py 的单元测试佐证RBE 集合过滤为--test_tag_filtersci-default,-incompatible_with_bazel_remote_test本地集合过滤为--test_tag_filtersci-default,incompatible_with_bazel_remote_test。套件在哪里运行总体架构图整体链路涉及三类基础设施Evergreen 主机负责编译产物归档、调度、结果收集与本地执行、EngFlow 集群负责远程执行 RBE 兼容套件以及 S3中转 build events 快照与测试产物。边线语义实线depends_on依赖点线 由 runner 触发的激活粗线bazel test与测试结果传输。从图中可读出三条关键依赖关系本地任务依赖编译产物每个本地执行的套件任务通过depends_on依赖编译变体compile variant上的archive_dist_test任务后者负责把预编译好的 dist-test 二进制归档供本地任务下载。runner 是唯一的调度者无论远程还是本地任务初始状态都是activate: False未激活由resmoke_testsrunner 在不同时机激活它们。结果任务只做取数RBE result tasks 不重新跑测试只从 runner 发布的build_events.json中拉取结果。任务生成bazel_result_tasks_gen 一分为二每个bazel_result_tasks_gen任务运行 buildscripts/generate_result_tasks.py入口见 main 函数按变体产出上述两套结果任务的 Evergreen 配置JSON通过 Evergreen 的generate.tasks机制在任务内动态生成。集合的推导两阶段 Bazel 查询query_targetsbuildscripts/generate_result_tasks.py按变体推导两套 target 集合分两个阶段阶段一bazel query非配置态。基于变体的resmoke_tests_tag_filter扩展如ci-default构造标签查询借助_build_tag_query同文件 L520-L545对kind(_resmoke_test, ...)目标做包含/排除运算RBE 集合ci-tags − incompatible_with_bazel_remote_test正标签并集再排除不兼容标签与负标签本地集合ci-tags ∩ incompatible_with_bazel_remote_test在正标签并集上用^求交。阶段二bazel cquery配置态。仅针对阶段一候选目标做配置分析通过target_compatible_with/IncompatiblePlatformProvider剔除与变体平台不兼容的目标避免把无法运行的套件纳入集合。查询时还会附加--//bazel/resmoke:skip_deps_for_cquery、--repo_envno_c_toolchain1、--keep_going、--//bazel/resmoke:support_extended_shard_countFalse等 flag 以加速配置分析buildscripts/generate_result_tasks.py。两个集合在 main 函数 中被并行查询随后各自独立产出任务。产物任务组与独立任务RBE 集合 → 任务组Task Group命名为resmoke_tests_results_variant组内每个 result task 对应一个套件 targetactivate: Falsemax_hosts等于套件数组内任务共享主机资源。见make_task_groupbuildscripts/generate_result_tasks.py。本地集合 → 独立任务STANDALONE task每个不兼容套件生成一个独立任务打上resmoke_local_test标签runner 借此识别并提前激活并depends_on编译变体的archive_dist_test。见make_local_results_taskbuildscripts/generate_result_tasks.py。变体级分配所有任务引用以activate: False加入变体且都依赖生成任务bazel_result_tasks_gen作为空depends_on的 workaround见 L820-L826。此外本地任务的调度还考虑了主机规格套件若打了requires_large_host/requires_xlarge_host标签任务引用会被安排到该变体的large_distro_name/xlarge_distro_name扩展指定的更大发行版上resolve_large_host_distrobuildscripts/generate_result_tasks.py。执行时序早激活本地、晚激活远程runner 的执行逻辑实现在 evergreen/resmoke_tests_execute_bazel.shmain函数见 L339-L397。核心策略是先尽早激活本地任务让它们与远程批处理并行再在远程批处理结束后激活 RBE 结果任务去取数。Local tasks self-run, so they start early. RBE result tasks only fetch from the runnersbuild_events.json, so they must wait for it.要点本地任务自运行因此可以提前启动RBE 结果任务只从 runner 的build_events.json取数因此必须等它产生。早激活--local-onlyrunner 在启动远程bazel test之前先调用activate_local_tasks_earlyevergreen/resmoke_tests_execute_bazel.shpython buildscripts/evergreen_activate_result_tasks.py \ --expansion-file ../expansions.yml --local-only || echo WARNING: failed to activate local-exec tasks early; continuing with remote execution.对应地buildscripts/evergreen_activate_result_tasks.py 在local_onlyTrue时只选取带resmoke_local_test标签的任务get_local_tasksL62-L66进行激活。激活采用尽力而为策略——即使失败也不中断远程执行脚本末尾的|| echo WARNING。本地执行下载 dist-test --installed_dist_test本地任务激活后自行执行。其 setup 阶段_make_setup_groupbuildscripts/generate_result_tasks.py会从 S3 下载${mongo_binaries}归档并解压到src/tar -xf mongo-binaries.tgz -C src使//bazel/resmoke:installed_dist_test_enabled能 glob 到工作区根目录下的 dist-test 二进制执行bazel test并附加--//bazel/resmoke:installed_dist_test与--//bazel/resmoke:in_evergreen等 flag见 build_ci_flags。由于本地任务在同一主机上串行运行整套套件脚本会把 bazel 级超时扩展到 14400 秒4 小时远超远程执行的默认值evergreen/resmoke_tests_execute_bazel.sh并使用bazel_local_memory_ram_ratio1.0让 bazel 按宿主物理内存调度测试动作buildscripts/generate_result_tasks.py。远程执行--configremote_test与 build_events.json远程路径下runner 执行bazel test --configremote_test --build_event_json_filebuild_events.json ${targets}对应 evergreen/resmoke_tests_execute_bazel.sh。Bazel 会把测试过程以 Build Event ProtocolNDJSON实时写入build_events.json这份文件是后续一切结果收集的数据源。--configremote_test会把测试动作调度到 EngFlow 集群的 worker 上执行。构建阶段使用--build_tests_only --remote_download_outputsminimal并带 3 次重试build_attempts3见run_build_and_testevergreen/resmoke_tests_execute_bazel.sh远程构建只需确认目标能编译产物留在 CAS 中测试阶段再按需拉取从而节省主机下载带宽而测试阶段本身不重试RETRY_ON_FAIL0以便忠实上报失败。流式激活不等整批结束为了不让结果收集等到整批远程测试全部结束runner 还启动了流式激活守护进程start_streaming_activationevergreen/resmoke_tests_execute_bazel.shpython buildscripts/stream_result_task_activation.py \ --expansion-file ../expansions.yml \ --build-events-file build_events.json \ --bazel-pid $bazel_pid buildscripts/stream_result_task_activation.py 的实现要点以轮询方式增量读取正在增长的build_events.jsonBEPTail.read_new_linesL51-L71每收到某个 target 的testSummary事件该 target 所有 run/shard 完成的最终信号L35-L43就把过滤后的 BEP 快照仅保留started/testResult/testSummary三类下游关心的行上传到 S3 的{project}/{version_id}/{build_variant}/{resmoke_tasks}/build_events.json通过 Evergreen API 立即激活该 target 对应的 result task。流程上先上传快照、后激活任务避免结果任务被激活时还拉不到自己的 testResult 事件失败则留待下一轮轮询重试并由 runner 收尾时的激活兜底。已处理的标签会记录到streamed_result_tasks.txtSTREAMED_TASKS_FILE供 runner 收尾激活时跳过防止重复重启L202-L246。晚激活--build-events-file远程批处理结束后runner 调用activate_result_tasksevergreen/resmoke_tests_execute_bazel.sh做收尾激活python buildscripts/evergreen_activate_result_tasks.py \ --expansion-file ../expansions.yml --build-events-file build_events.jsonbuildscripts/evergreen_activate_result_tasks.py 在此路径下会先执行assert_all_tests_have_tasksL95-L110——把build_events.json中实际执行过的测试标签与已生成的 Evergreen 任务逐一比对若有执行过的测试没有对应任务直接抛错把这当作任务生成阶段的 bug 暴露出来。随后剔除流式激活已处理的任务激活其余未激活者若 runner 是重跑execution 0则对已激活任务执行restart_task以复用本次执行的结果L81-L92。结果收集与退出码语义RBE result tasks 的取数每个结果任务在 setup 阶段s3.get拉取 runner 上传的build_events.json快照_make_build_events_fetchbuildscripts/generate_result_tasks.py再由fetch remote test results函数按test_label解析出本套件的 testResult 事件并生成report.json由于快照随目标完成而增长每个任务取到自己 target 的事件是有保证的。产物上传结果任务与任务组在 teardown 阶段把**/*outputs.zip、**/*_MANIFEST、**/*test.log上传至 S3_result_artifact_uploadsbuildscripts/generate_result_tasks.py并调用attach engflow links、save failed tests、map resmoke test debug symbols、generate result task hang analyzer等收尾函数。退出码语义runner 对bazel test返回码做了专门解释exit_for_runner_taskevergreen/resmoke_tests_execute_bazel.sh返回码3表示构建成功但部分测试失败——失败详情已由各结果任务单独上报因此 runner 任务本身不判失败exit 0返回码4表示无测试运行套件迁移期预期行为exit 0其余非零码视为构建失败并原样退出。结果任务侧exit_for_result_taskL51-L64则是在拉取结果后再判失败。结合源码验证任务生成的两处细节本地结果任务的重复执行守卫exit_early_if_result_taskevergreen/resmoke_tests_execute_bazel.sh规定——RBE 结果任务若发现本地已存在src/build_events.json且任务由mongodb-mongo-ci-user激活说明测试已由 runner 远程执行过直接跳过重跑而本地执行的结果任务resmoke_disable_rbetrue必须自行运行bazel test因为远程路径不覆盖这些套件。--local-only与晚激活的互斥evergreen_activate_result_tasks.py通过LOCAL_TASK_TAG在get_result_tasks中跳过本地任务L53-L58确保晚激活只针对 RBE 结果任务早激活只针对本地任务两条路径互不干扰。总结MongoDB 的 ResmokeBazel CI 执行模型可以概括为一个标签、两套集合、三个时机一个标签incompatible_with_bazel_remote_test决定套件走 EngFlow 远程执行还是 Evergreen 主机本地执行两套集合bazel_result_tasks_gen用两阶段 Bazel 查询把变体的套件拆成互不相交的 RBE 集与本地集并分别生成任务组与独立任务三个时机runner 先流式激活测试完成即激活、早激活本地任务--local-only、最后晚激活 RBE 结果任务--build-events-file三者配合实现远程执行与结果收集的高度并行。这套机制的全部实现与测试均可在本仓库追溯任务生成见 buildscripts/generate_result_tasks.py、执行编排见 evergreen/resmoke_tests_execute_bazel.sh、激活逻辑见 buildscripts/evergreen_activate_result_tasks.py 与 buildscripts/stream_result_task_activation.py行为契约由 buildscripts/tests/test_generate_result_tasks.py 与 buildscripts/tests/burn_in/test_bazel_burn_in.py 锁定。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门