资讯动态

MongoDB 仓库 burn_in_tests 深入指南:用重复执行验证新增与修改 jstests 的稳定性

发布时间:2026/9/12 16:12:05 来源:尧图企业网站定制
MongoDB 仓库 burn_in_tests 深入指南用重复执行验证新增与修改 jstests 的稳定性【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo导读burn_in_tests是 MongoDB 服务器仓库mongo中用于验证 JavaScript 测试稳定性的专用工具它基于 git 差异自动识别自上次提交以来新增或修改的 jstests并在 resmoke 中以重复执行模式运行这些测试以尽早暴露偶发flaky失败。本文以 burn_in_tests.md 为主线结合 buildscripts/burn_in_tests.py 的完整实现、etc/burn_in_tests.yml 的排除规则配置以及对应的单元测试系统讲解该工具的 Evergreen 云端用法、本地命令行用法、重复执行策略的底层参数映射与校验规则帮助你理解并直接上手这套变更驱动的回归验证方案。burn_in_tests 是什么burn_in_tests的核心定位在 docs/evergreen-testing/burn_in_tests.md 中被明确为检测自上次 git 命令以来新增或变更的 JavaScript 测试位于仓库的 jstests 目录然后以重复模式运行这些测试以验证其稳定性。与全量回归测试不同burn_in 刻意将范围收窄到本次改动涉及的测试文件从而聚焦风险面只有与本次代码改动相关的测试会被反复执行节省 CI 资源暴露偶发问题通过重复执行默认 2 次起步最多 1000 次或 10 分钟放大不稳定测试的失败概率辅助回滚决策一旦 burn_in 任务失败说明新增/修改的测试本身不可靠可及时修复或回退避免脏测试污染主干。从源码看这一理念贯穿整个实现burn_in_tests.py顶部 docstring 即写着Command line utility for determining what jstests have been added or modifiedCLI 的run命令帮助文本也重申Run new or changed tests in repeated mode to validate their stability。整体工作流程从 git diff 到重复执行整个 burn_in 流程由BurnInOrchestrator.burn_in()串起buildscripts/burn_in_tests.py可分解为四个阶段变更检测FileChangeDetector本地场景为LocalFileChangeDetector通过 git 计算当前工作区与基准版本默认 HEAD或用--origin-rev指定的 revision之间的差异得到变更文件集合。其中is_file_a_test_file()只保留满足以下条件的文件扩展名为.js文件在磁盘上真实存在可能在 patch 中被移动或删除路径中包含jstests目录。返回的文件路径统一经过os.path.normpath()规范化。套件映射create_tests_by_task()读取排除规则后用get_suites(suite_names_or_paths[with_server], test_fileschanged_tests)找出哪些 resmoke 套件包含这些测试再通过create_executor_list()借助测试→执行器executor成员关系映射反查出每个变更测试会被哪些套件/任务运行。这正是原文档强调的一个 JavaScript 测试可能被包含在多个测试套件中的实现基础——create_test_membership_map()会为每个测试建立到多个 suite 的关联。任务分发create_task_list()从指定的 Evergreen build variant 中挑选所有is_run_tests_task或is_generate_resmoke_task的任务为每个任务生成TaskToBurnInInfo含 display task 名与待运行的套件、测试列表。重复执行BurnInExecutor负责真正执行。本地场景使用LocalBurnInExecutor将重复配置翻译为 resmoke 参数如--repeatTestsSecs600 --repeatTestsMin2 --repeatTestsMax1000并调用python buildscripts/resmoke.py run args tests逐套件执行任何一个 suite 返回非零退出码run_tests()都会以该退出码终止整个 burn_inbuildscripts/burn_in_tests.py 中subprocess.check_call后捕获CalledProcessError并sys.exit。在 Evergreen 上使用burn_in_tests_gen 生成任务原文档明确指出在 Evergreen 上使用burn_in_tests的方式是创建 patch 时勾选burn_in_tests_gen任务。之所以名字带_gen后缀是因为它属于**生成任务generated task**机制——详见仓库的 task_generation.md。其工作方式分两步version_gen任务通过 mongo-task-generator 为整个版本一次性生成所有子任务的配置并提交给 Evergreen任务先以inactive状态创建同时把占位任务隐藏进名为generator_tasks的 display task 中占位任务随后运行找到自己对应的生成任务并将其激活。这样用户在初始任务选择页即可勾选burn_in_tests_gen即使具体子任务此时尚未生成。burn_in_tests任务的特性如下来自原文档并可在源码中印证会在每个适用的 build variant上各生成一个burn_in_tests任务每个任务可能包含多个子任务分别运行不同测试套件且只运行本次新增或修改的 JavaScript 测试重复策略每个测试最少运行 2 次最多运行 1000 次或 10 分钟以先到者为准。这一2 次/1000 次/10 分钟的默认策略与源码中的RepeatConfig设计完全吻合默认REPEAT_SUITES 2提供下限保障同时--repeatTestsMin/--repeatTestsMax/--repeatTestsSecs组合提供了时间与次数的双边界约束详见下文重复执行策略一节。在本地使用命令行详解除了 Evergreen你可以在 mongo 仓库内直接运行python buildscripts/burn_in_tests.py更详细的帮助信息可通过python buildscripts/burn_in_tests.py --help查看。基于 buildscripts/burn_in_tests.py 中的 click 定义完整参数如下参数默认值作用--build-variant BUILD_VARIANTenterprise-amazon-linux2023-arm64-all-feature-flags从这个 build variant 中选取要运行的任务--repeat-tests N无每个测试精确重复 N 次对应 resmoke 的--repeatSuites--repeat-tests-min N无指定时间模式时每个测试最少重复 N 次--repeat-tests-max N无指定时间模式时最多重复 N 次达到后停止--repeat-tests-secs SECONDS无按秒数持续重复执行测试--no-execFalseflag只做测试发现不真正执行打印任务/套件/测试清单--yamlFalseflag将发现的测试任务以 YAML 形式输出不执行测试--verboseFalseflag输出 DEBUG 级别的详细日志--origin-rev REV无指定与本地改动做对比的基准 revision必须存在于 mongodb 仓库中--evg-project-file FILEetc/evergreen.ymlEvergreen 项目配置文件路径resmoke_args位置参数空追加传给 resmoke.py 的任意参数几个关键行为需要特别说明--origin-rev的语义不传时默认将你的最新改动与HEAD对比传了则以该 revision 为基准计算变更文件。这让你可以在任意历史提交上做 burn_in 验证。参数透传命令行末尾任何未识别的参数都会原样转交给 resmoke。原文档源码 docstring 给出的示例是python buildscripts/burn_in_tests.py --dbpathPrefix /some/other/directory其中--dbpathPrefix /some/other/directory会被透传给 resmoke。--no-exec / --yaml 是演练模式前者将发现的测试以层级清单打印对应NopBurnInExecutor后者输出结构化的DiscoveredTaskListYAML对应YamlBurnInExecutor便于先确认 burn_in 会跑哪些内容再实际执行。测试专用隐藏参数--test-changed-files 逗号分隔列表用于直接指定变更文件绕过 git 检测源码注释标明for testing purposes only会驱动MockFileChangeDetector普通用户无需使用。实际运行示例# 默认策略每个变更测试至少重复 2 次无时间限制 python buildscripts/burn_in_tests.py # 固定重复 5 次 python buildscripts/burn_in_tests.py --repeat-tests 5 # 在 10 分钟内持续重复最少 2 次、最多 1000 次 python buildscripts/burn_in_tests.py --repeat-tests-secs 600 --repeat-tests-min 2 --repeat-tests-max 1000 # 指定对比基准 只输出将运行的测试清单 python buildscripts/burn_in_tests.py --origin-rev HEAD~3 --no-exec # 换个 build variant 选择任务来源 python buildscripts/burn_in_tests.py --build-variant enterprise-rhel-8-64-bit重复执行策略RepeatConfig 与 resmoke 参数映射重复策略是 burn_in 的灵魂其核心实现在RepeatConfig类buildscripts/burn_in_tests.py它把 CLI 参数翻译成 resmoke 的重复选项若指定了--repeat-tests-secs时间模式生成--repeatTestsSecssecs并可叠加--repeatTestsMinmin与--repeatTestsMaxmax否则次数模式生成--repeatSuitesNN 取--repeat-tests的值未指定时使用默认REPEAT_SUITES 2。也就是说原文档中最少 2 次、最多 1000 次或 10 分钟在命令行上的等价写法即上例中的--repeat-tests-secs 600 --repeat-tests-min 2 --repeat-tests-max 1000。RepeatConfig.validate()内置了严格的参数合法性校验违反即抛ValueError--repeat-tests与--repeat-tests-secs不能同时指定指定--repeat-tests-max时必须同时指定--repeat-tests-secs指定--repeat-tests-min时必须同时指定--repeat-tests-secs--repeat-tests-min不能大于--repeat-tests-max。这些规则与 resmoke 侧 buildscripts/resmokelib/configure_resmoke.py 中--repeatTestsSecs/--repeatTestsMin/--repeatTestsMax/--repeatTests的解析约束保持了一致如 Cannot specify --repeatTests and --repeatTestsSecs、Must specify --repeatTestsSecs with --repeatTestsMax并在 buildscripts/tests/burn_in/test_burn_in.py 中被逐条覆盖例如test_validate_with_both_repeat_options_specified验证次数模式与时间模式互斥test_validate_with_repeat_max_with_no_secs验证 max 依赖 secstest_get_resmoke_repeat_options_secs_min_max验证三者可同时映射为--repeatTestsSecs5 --repeatTestsMin2 --repeatTestsMax2。在 resmoke 执行端repeat_tests_secs会进入套件选项time_repeat_tests_secs驱动 buildscripts/resmokelib/testing/job.py 与 buildscripts/resmokelib/testing/queue_element.py 中的按时间重复调度逻辑buildscripts/resmokelib/run/init.py 还针对--repeatTestsSecs场景给出了套件定义约束的提示信息。排除规则配置etc/burn_in_tests.yml不是所有套件、任务和测试都适合做 burn_in 重复执行因此仓库提供了集中排除配置文件 etc/burn_in_tests.yml由find_excludes()解析要求文件必须包含selector.js_test键返回三组排除列表随后在create_tests_by_task()与filter_tests()中生效exclude_suites排除套件按 resmoke 套件名排除。当前仓库的排除清单包括queryable_wt需要后台 HTTP 服务器支持streams_kafka拆分为多个套件时每个套件都需要独立的 brokerstreams_aspio_0/1、streams_aspio_iceberg_*、streams_aspio_large、streams_aspio_utilities、streams_aspio_pubsub等这些套件需要 sidecar 容器with_mongot_extension_*系列hybridSearch/search/vectorSearch 的 disabled/enabled 组合、concurrency_with_mongot_extension_*等属于临时的实验性套件只能运行于 extensions secure-mode 构建mongot_e2e_*套件已提供相同测试的 burn_in 覆盖disagg_pali_chaos_keyTODO SERVER-131289待测试稳定后移除、disagg_pali_chaos资源消耗过大。exclude_tasks排除 Evergreen 任务当前为空列表用于按 etc/evergreen.yml 中的任务名排除。exclude_tests排除测试文件当前排除了依赖外部脚本预置环境的 enterprise 模块测试例如src/mongo/db/modules/enterprise/jstests/external_auth_oidc/oidc_e2e_okta.js需先运行external_auth_oidc.shoidc_e2e_azure.js、oidc_e2e_azure_machine.js需先运行external_auth_azure_setup.sh、之后再运行external_auth_azure_teardown.shoidc_e2e_gcp_machine.js需先运行external_auth_gcp_setup.sh。exclude_tests支持使用*与**通配符做目录/文件级模式匹配由filter_tests()通过globstar.iglob()展开后再从变更测试集合中剔除。另外还有一个企业版相关的隐式规则当所选 build variant不是 enterprise 构建时代码会自动把src/mongo/db/modules/enterprise/**/*追加到排除列表对应ENTERPRISE_MODULE_PATH src/mongo/db/modules/enterprise确保社区版 variant 不会尝试运行企业模块的测试。变更测试的种类与特征标记并非所有变更的.js文件都会被同等对待。create_test_membership_map()支持以下测试种类SUPPORTED_TEST_KINDSfsm_workload_test、parallel_fsm_workload_test并发/FSM 工作负载测试js_test普通 jstestjson_schema_testmulti_stmt_txn_passthroughall_versions_js_test多版本兼容测试magic_restore_js_test。此外burn_in 在分析测试时统一追加--runAllFeatureFlagsTests运行选项源码常量RUN_ALL_FEATURE_FLAG_TESTS确保 feature flag 开关不同组合下的测试路径都被纳入成员关系计算。CI 提速测试成员映射缓存create_executor_list()在首次运行时需要通过create_test_membership_map()构建测试→套件全量映射这一步非常耗时。由于 task generator 会为大量 build variant 反复运行脚本仓库专门提供了 CI 专用子命令python buildscripts/burn_in_tests.py generate-test-membership-map-file-for-ci该命令源码中为generate_test_membership_map_file_for_ci预先计算成员映射并写入burn_in_test_membership_map_file_for_ci.json。后续执行时create_executor_list()会优先读取该缓存文件命中时打印 Using cached test membership file ...显著加速 CI 中的任务生成过程。此命令应仅在 CI 中、于运行 burn_in task generator 之前执行。测试与验证仓库如何自证burn_in_tests 自身的正确性由 buildscripts/tests/burn_in/BUILD.bazel 下的三个测试目标保障test_burn_intest_burn_in.py单元测试覆盖RepeatConfig的全部校验分支与 resmoke 参数生成逻辑、变更文件过滤is_file_a_test_file、排除规则解析等并通过 mock git diff 验证变更检测test_burn_in_end2endtest_burn_in_end2end.py端到端测试验证真实场景下任务与测试的发现流程test_bazel_burn_intest_bazel_burn_in.py针对 Bazel 版 burn_in 的单元测试。另外注意仓库同时存在 Bazel 变体bazel_burn_in.py它通过create_burn_in_target()在jstests/BUILD.bazel中动态创建*_burn_in_*目标如//jstests:core_burn_in_find_js将原测试目标的srcs替换为变更测试并设置shard_count1同时注入--repeatTestsSecs600.010 分钟与 Evergreen 任务默认的 10 分钟上限保持一致见 test_bazel_burn_in.py 中--repeatTestsSecs600.0的断言。相关工具burn_in_tags 与 ! Run All Affected JStestsburn_in 家族还有一个姊妹工具burn_in_tags其行为在 burn_in_tags.md 中有专门说明它与burn_in_tests的差异在于运行位置——burn_in_tests在测试原有的 build variant 上运行而burn_in_tags会在单独生成的 burn_in build variant如enterprise-rhel-8-64-bit-inmem、enterprise-rhel-8-64-bit-multiversion上运行以隔离资源占用。在 patch 中选择burn_in_tags_gen即可触发。此外还有一个特殊 variant! Run All Affected JStests其上的单个burn_in_tags_gen任务会为所有 required 与 suggested variant 创建并激活burn_in_tests任务使 patch 中修改的 jstests 在所有关键 variant 上获得完整覆盖为是否会导致回滚或后续修复提交提供明确信号。小结burn_in_tests是 MongoDB 开发流程中连接代码变更与测试稳定性的关键一环Evergreen 侧通过burn_in_tests_gen生成任务实现云端自动化本地侧通过python buildscripts/burn_in_tests.py提供灵活的命令行控制RepeatConfig将最少 2 次、最多 1000 次或 10 分钟的重复策略翻译为 resmoke 参数并施加严格校验etc/burn_in_tests.yml则以集中声明的方式屏蔽不适宜重复执行的套件、任务与测试。理解它的数据流git 变更 → 测试成员映射 → 任务清单 → 重复执行与参数语义能帮助你在提交 jstests 改动时快速获得高质量的稳定性反馈。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价