MongoDB jstests/suites:用 Bazel 运行与配置 resmoke 测试套件(size、tags 与平台排除策略)
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
在 MongoDB 仓库中,集成测试通过 resmoke 框架执行,并由 Bazel 以resmoke_suite_test规则封装为可调度、可分片、可远程执行的测试目标,这些目标集中定义在jstests/suites/目录下。本文以 jstests/suites/README.md 为主体,完整讲解该目录下测试目标的三类核心配置——size(资源分配)、tags(批量执行与 CI 语义)和target_compatible_with(平台排除),并结合 bazel/resmoke/resmoke.bzl 与 bazel/test_exec_properties.bzl 的源码实现,说明每项配置背后的调度机制,帮助你既能正确编写新套件目标,也能理解 CI 中测试为何被选中或跳过。
jstests/suites 是什么:resmoke 套件的 Bazel 测试目标
jstests/suites/README.md 开篇即定义了该目录的定位:Bazel test targets for resmoke suites——即把一个个 resmoke 测试套件(suite)包装成 Bazel 测试目标。套件的具体 YAML 配置(含selector.roots测试选择器)存放在buildscripts/resmokeconfig/suites/下,例如 Bazel 标签//buildscripts/resmokeconfig:suites/core.yml;而每个套件目标通过resmoke_suite_test规则声明config、deps(如//src/mongo/db:mongod、//src/mongo/shell:mongo)等属性,完整规则文档见 bazel/resmoke/README.md。
从目录结构看,jstests/suites/按功能域划分为二十多个子目录(query/、replication/、transactions/、sharding相关、security/、timeseries/、backup-restore/、cluster-scalability/、index-builds/等),每个子目录包含自己的BUILD.bazel;根目录的 jstests/suites/BUILD.bazel 是空文件,说明套件目标全部分散定义在各功能域子包中。
resmoke_suite_test本身是一个宏(macro),它在 bazel/resmoke/resmoke.bzl 中定义,除创建测试目标外还自动生成多个伴生目标:由 YAML 的selector.roots派生srcs并生成解析后的配置(*_config目标)、历史运行时长文件、供 Evergreen Test Selection Services 使用的测试清单(*_tss_test_list)等。因此理解宏的参数,就等于理解这些自动化行为的输入。
配置size:决定测试跑在哪个执行池
README 的第一个配置项是size。测试的资源由其 Bazelsize属性驱动,该属性选择测试所运行的远程执行池(remote execution pool);同样的资源分配通过.bazelrc中的--default_test_resources作用于本地执行。映射关系为:
size | Memory | CPUs |
|---|---|---|
small | 3.5 GB | 1 |
medium(默认) | 3.5 GB | 1 |
large | 7 GB | 2 |
enormous | 14 GB | 4 |
resmoke_suite_test( name = "my_suite", size = "large", # Uses the 7 GB, 2-core pool. ... )“medium是默认值”这一点在源码中得到印证:宏内部以kwargs.get("size", "medium")取 size(bazel/resmoke/resmoke.bzl),并传入test_exec_properties()。而 bazel/test_exec_properties.bzl 揭示了 size 到池的完整映射机制:
SIZE_TO_MEMORY_MB字典定义了各 size 的内存请求:small3584 MB、medium3584 MB、large7168 MB、enormous14336 MB,与 README 表格逐一对应,并明确要求与.bazelrc的--default_test_resources保持同步;- 每个架构(x86_64 与 arm64)有一组内存档位相同的池,如 x86 的
x86_64(3.5 GB / 1 核)、large_mem_2core_x86_64(7 GB / 2 核)、high_mem_2core_x86_64(14 GB),arm64 为test_runner_arm64_1core、test_runner_arm64_2core、test_runner_arm64_4core; _choose_pool()按字典顺序选出内存容量不小于请求量的最小池,若没有足够大的池则回退到最大的池。核心数随内存档位缩放,因此测试的size单独就能决定池选择,cpus仅作文档记录。
也就是说,把size从默认medium改为large,意味着该套件会被调度到 7 GB / 2 核的池上,本地执行时同样获得等量资源。仓库中的真实用例可见 jstests/suites/query-execution/BUILD.bazel:concurrency套件声明size = "large",而core套件未声明(即使用默认 medium)。
配置tags:批量执行与 CI 任务语义
README 的第二个配置项是tags。你可以为测试目标添加任意标签以便分组、批量执行,例如用自定义标签一次性运行所有匹配的套件:
bazel test //jstests/suites/... --test_tag_filters=my_tag以下标签具有特殊语义:
| 标签 | 用途 | 示例 |
|---|---|---|
ci-系列标签 | 配置任务在 CI 中的优先级;设置其中任一标签即代表该测试允许在 CI 中运行。可取值为ci-default、ci-release-critical、ci-development-critical、ci-development-critical-single-variant。各标签的具体语义见 README 引用的 Evergreen 任务选择标签文档(docs/evergreen-testing/yaml_configuration/task_selection_tags.md) | tags = ["ci-default"] |
incompatible_with_bazel_remote_test | 将测试排除在 Bazel 远程执行环境(如远程 CI 执行器)之外。当测试依赖远程执行器上不存在的资源或环境特性时使用 | tags = ["incompatible_with_bazel_remote_test"], # Requires openssl, which is missing on remote executors. |
仓库中的真实用法与文档描述一致:jstests/suites/query-execution/BUILD.bazel 中core套件带有ci-development-critical和ci-development-critical-single-variant,concurrency带有ci-release-critical,其余多数套件带有ci-default,再附加change_streams、aggregation、sharded、sharding等用于功能分组的普通标签;而 jstests/suites/backup-restore/BUILD.bazel、jstests/suites/cluster-scalability/BUILD.bazel 和 jstests/suites/index-builds/BUILD.bazel 中的部分套件声明了incompatible_with_bazel_remote_test,避免其被调度到缺少相应环境的远程执行器上。
另外从源码结构看,宏还会在用户标签之外自动追加固定标签no-cache、resources:port_block:1和resmoke_suite_test(bazel/resmoke/resmoke.bzl),其中resources:port_block:1用于保证端口资源隔离,resmoke_suite_test标签则可反过来用于筛选所有由该宏生成的目标。
配置target_compatible_with:按平台与构建选项排除套件
README 的第三个配置项是target_compatible_with:用于声明测试兼容的平台/构建选项组合,从而把套件从特定 CI 平台上排除。README 给出的示例——排除 PPC64LE / S390x / macOS / TSAN 构建——如下:
target_compatible_with = select({ "@platforms//cpu:ppc64le": ["@platforms//:incompatible"], "@platforms//cpu:s390x": ["@platforms//:incompatible"], "@platforms//os:macos": ["@platforms//:incompatible"], "//bazel/config:tsan_enabled": ["@platforms//:incompatible"], "//conditions:default": [], # Otherwise, the test is compatible and can be run. })select()中命中任一incompatible分支时,该目标在对应配置下被视为不兼容,bazel test会直接跳过而不是失败。仓库中有多种实际写法:
- 平台排除:jstests/suites/query-execution/BUILD.bazel 中的
concurrency套件排除了ppc64le、s390x和macos; - 构建选项排除:
change_streams_mongos_sessions_passthrough等套件通过//bazel/config:tsan_enabled在 TSAN 构建下不兼容(源码注释说明 TSAN 下运行极慢,留待重新启用);aggregation_mongos_pqs_hints、aggregation_pqs_hints等 PQS 提示类套件则同时排除了asan_enabled、ubsan_enabled、tsan_enabled三种 sanitizer 构建; - 版本维度排除:从源码看,若某套件的
multiversion_deps只含单个last-continuous或last-patch依赖,宏会依据//bazel/resmoke/multiversion:last_continuous_redundant/last_patch_unavailable设置自动为其追加一条select(),在不值得(或不可能)测试对端版本时直接标记@platforms//:incompatible(bazel/resmoke/resmoke.bzl)。这属于规则自动行为,无需在BUILD.bazel中手写。
快速上手:运行与单测一个套件
结合 README 与 jstests/suites/query-execution/BUILD.bazel 顶部注释,最常用的操作为:
# 运行整个套件 bazel test //jstests/suites/query-execution:core # 在套件中只运行单个测试(禁用分片,用 --test_arg 指定测试文件) bazel test //jstests/suites/query-execution:core --test_sharding_strategy=disabled --test_arg=jstests/some_test.js # 不使用 Bazel 沙箱时,仍可直接调用 resmoke python buildscripts/resmoke.py run --suites=core补充两点实战细节:其一,resmoke_suite_test的shard_count用于把大套件拆到多个并行测试执行中以缩短总时长(详见 bazel/resmoke/README.md 的 Test Sharding 一节),core套件使用了shard_count = 24;从源码看,Bazel 原生shard_count上限为 50,超过时宏通过配置迁移(configuration transition)以forced=N分片策略强制真实分片数,禁用该迁移时会退化为 50 分片而非单分片。其二,测试的timeout默认为"eternal"(bazel/resmoke/resmoke.bzl),实际单测超时由--testTimeout=$(RESMOKE_TEST_TIMEOUT)在 resmoke 内部控制。
小结
jstests/suites/下的每个resmoke_suite_test目标由三项配置决定其调度行为:size通过 bazel/test_exec_properties.bzl 的“最小满足内存池”算法映射到远程/本地执行池;tags中的ci-*标签决定测试是否以及如何参与 CI,incompatible_with_bazel_remote_test将其排除出远程执行器;target_compatible_with以select()精确控制套件在特定 CPU 架构、操作系统或 sanitizer 构建下的兼容性。理解这三者与 bazel/resmoke/resmoke.bzl 中宏的自动伴生行为,即可完整掌握 MongoDB 集成测试套件在 Bazel 下的配置与运行方式。
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考