MongoDB mongot 集成测试实战:从获取 mongot 二进制到编写 $search / $vectorSearch E2E 测试
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
要调试包含$search或$vectorSearch阶段的聚合管道,测试环境必须配备一个 mongot 二进制。本文基于 MongoDB 仓库自带的测试说明文档 jstests/with_mongot/e2e/mongot_testing_instructions.md,完整梳理三种获取 mongot 二进制的方式(下载 release/latest 预编译版本、从源码编译、从 Evergreen 构建产物中拉取指定版本),并讲解如何将新的 jstest 放入jstests/with_mongot/e2e、在单节点副本集与分片集群两种环境中运行,以及理解测试顺序限制背后的数据复制原理。读完后,你可以独立完成一次带 Atlas Search 的端到端调试。
一、测试环境的核心前提:需要一个 mongot 二进制
MongoDB 的 Atlas Search 能力由独立进程 mongot 承载:mongod 通过变更流(change stream)向 mongot 复制集合数据,查询时把$search、$vectorSearch阶段转发给 mongot 执行。因此,任何涉及这些阶段的集成测试,都必须先解决“mongot 从哪里来”的问题。
文档给出了三种选择,按验证目标的时效性递增:
| 来源 | 适用场景 | 获取方式 |
|---|---|---|
| release | 复现线上(Atlas 生产环境)行为 | db-contrib-tool setup-mongot-repro-env release |
| latest | 验证 10gen/mongot 仓库最近一次合入 master 的构建 | db-contrib-tool setup-mongot-repro-env latest(也是默认行为) |
| 本地编译 | mongot 侧带有未合入的本地改动 | 克隆 mongot 仓库后用其自身构建系统编译 |
下面逐一展开。
二、方式一:下载 release / latest 预编译 mongot 二进制
2.1 确认你的工作区架构
从~/mongo(即本仓库的检出目录)出发,先确认虚拟工作区(VM)的操作系统与 CPU 架构。假设 VM 是 Ubuntu(默认),在终端执行lscpu并查看输出的第一行即可确认架构。
2.2 最简命令(默认 latest + linux x86_64)
setup-mongot-repro的默认行为就是下载与linux x86_64兼容的latest版本 mongot。如果这正好满足你的 VM 与测试需求,直接运行:
bazel run db-contrib-tool -- setup-mongot-repro-env --installDir build/install/bin2.3 显式指定参数的等价形式
以下三种更啰嗦的写法与上面的默认命令完全等价,展示了各参数的默认取值:
# 显式指定架构 bazel run db-contrib-tool -- setup-mongot-repro-env --architecture x86_64 --installDir build/install/bin # 显式指定架构与平台 bazel run db-contrib-tool -- setup-mongot-repro-env --architecture x86_64 --platform linux --installDir build/install/bin # 连版本号(latest)也显式给出 bazel run db-contrib-tool -- setup-mongot-repro-env latest --architecture x86_64 --platform linux --installDir build/install/bin2.4 其他常见平台组合
安装生产版本(release)的 linux x86_64 二进制:
bazel run db-contrib-tool -- setup-mongot-repro-env release --architecture x86_64 --installDir build/install/bin架构为aarch64时安装 latest 二进制:
bazel run db-contrib-tool -- setup-mongot-repro-env --architecture aarch64 --installDir build/install/binVM 运行macOS时安装 latest 二进制:
bazel run db-contrib-tool -- setup-mongot-repro-env --platform macos --installDir build/install/bin需要查看setup-mongot-repro-env的完整命令行选项时,执行:
bazel run db-contrib-tool -- setup-mongot-repro-env --help2.5 源码侧的实现印证
本仓库在 Bazel 测试基建中也封装了同样的下载逻辑,位于 setup_mongot.sh。从源码结构看:
- 平台识别通过
OSTYPE完成,仅支持linux与macos两类,其余平台会直接报错退出; - 架构上,macOS 一律使用 x86_64 二进制(注释说明 mongot 不支持 macOS arm64,但 x86_64 二进制可通过 Rosetta 在 Apple Silicon 上运行);只有
uname -m为aarch64且平台为 linux 时才选择 aarch64; - 最终调用
db-contrib-tool setup-mongot-repro-env <version> --platform=... --architecture=... --installDir=.完成下载。
配套的 Bazel 规则 mongot.bzl 进一步说明了版本选择机制:通过--//bazel/resmoke/mongot:version=release之类的命令行开关切换latest/release,并额外支持localdev-url开关直接指定一个预构建 tarball 的 URL(供下游 mongot patch 使用)。该规则还刻意设置了no-cache/no-sandbox执行属性,因为latest始终跟踪 10gen/mongot 的 HEAD,构建产物会随时间变化,绝不能进入远程缓存。
三、方式二:从源码编译 mongot
当 mongot 二进制必须包含尚未合入的本地改动时,需要自行编译。步骤如下(注意:这些步骤操作的是 mongot 仓库自身,而非本仓库):
- 克隆 mongot 仓库到 VM:
git clone git@github.com:10gen/mongot.git进入 mongot 仓库,checkout 你关心的开发分支。
编译 mongot。linux x86_64 环境:
PLATFORM=linux_x86_64 make build.deploy.localdevlinux aarch64 环境:
PLATFORM=linux_aarch64 make build.deploy.localdev- 从产物 tarball 中提取 mongot-localdev 二进制:
tar -xvzf bazel-bin/deploy/mongot-localdev.tgz- 将生成的 mongot 二进制移动到服务端构建系统放置 mongod、mongos 与 shell 二进制的目录:
mv mongot-localdev ~/mongo/build/install/bin移动完成后,resmoke 的测试 fixture 就能在build/install/bin中找到 mongot 并与 mongod 配套启动。
四、新增测试:jstest 与 resmoke 套件
4.1 把测试放进 jstests/with_mongot/e2e
创建新的 search 集成测试时,将 jstest 文件添加到 jstests/with_mongot/e2e 目录。该目录下已按主题组织了大量现成用例,可参考其写法:
- search/:基础
$search功能、错误场景、unionWith、序列 token 等; - vector_search/:
$vectorSearch、explain、query stats 等; - hybridSearch/:ranked fusion / score fusion 混合搜索;
- metadata/:
$searchMeta相关校验; - views/:在 view 定义中使用 mongot 阶段的各种场景;
- sharding_no_passthrough/:分片环境下的 search 行为(如
search_shard_filtering.js、vector_search_explain_sharded.js)。
该目录下的任何测试都可以在单节点副本集或分片集群环境中运行:
# 作为单节点副本集运行 buildscripts/resmoke.py run --suites=mongot_e2e_single_node # 作为分片集群运行 buildscripts/resmoke.py run --suites=mongot_e2e_sharded_cluster4.2 套件定义在仓库中的真实形态
resmoke 套件配置位于 buildscripts/resmokeconfig/suites。以分片集群套件 mongot_e2e_sharded_cluster.yml 为例,其 fixture 配置说明了测试环境的实际拓扑:
fixture: class: ShardedClusterFixture auth_options: *authOptions launch_mongot: true num_shards: 2 num_rs_nodes_per_shard: 1 num_mongos: 3也就是说:3 个 mongos、2 个 shard(每个 shard 的副本集若干节点),且launch_mongot: true让每个 mongod 实例配套拉起一个 mongot。该套件选择器覆盖jstests/with_mongot/e2e/**/*.js、e2e_infrastructure_tests与e2e_lib,并排除带assumes_against_mongod_not_mongos标签的测试。
社区版单节点套件 mongot_community_e2e_single_node.yml 的说明则揭示了另一套细节:它与mongot_e2e_single_node完全相同,唯一区别是 mongod 通过 gRPC(而非 MongoRPC)与 mongot 通信,且 mongod 与 mongot 之间不做 SASL 认证——相应地,fixture 中设置了useGrpcForSearch: 1、featureFlagEgressGrpcForSearch: true与skipAuthenticationToMongot: true等服务端参数。两个套件都通过keyfile_for_testing完成__system用户的 SCRAM-SHA-256 认证,因为 mongot fixture 的初始化本身依赖认证通道。
4.3 关键约束:测试必须遵循“先数据、后索引、再查询”的顺序
文档特别强调,在 SERVER-86616 完成之前,你的测试必须遵循如下顺序:
- 插入测试所需的全部文档;
- 创建 search index;
- 执行查询。
这个顺序是保证测试正确性的必要条件,原因在于 mongot 与 mongod 之间的数据复制机制:mongot 通过$changeStream从 mongod 复制数据,因此与 mongod 的集合数据是最终一致的。测试基础设施通过两个手段保证正确性:
- 要求工程师在创建索引之后不再变更文档(即上面规定的顺序);
createSearchIndexshell 辅助函数会阻塞等待 mongot 确认索引可查询后才返回。具体而言,它通过$listSearchIndexes返回的索引状态(READY)来判断集合数据已完全复制并建立索引。
反之,如果在索引创建之后更新或新增文档,$listSearchIndexes的状态就不能再说明数据复制的进度,查询便可能读到过期的索引数据而返回错误结果。编写新测试时务必把“全部数据写入”放在建索引之前。
五、方式三:从 Evergreen 构建产物下载指定版本的 mongot
当你需要精确复现某次 Evergreen patch 或版本使用的 mongot 二进制(例如排查某个构建上出现的错误)时,可以使用setup-repro-env从构建产物中下载。
5.1 前提:选择编译了 mongot 的 build variant
只有包含build_mongot: true扩展变量的构建变体才有 mongot 产物可下载,典型包括:
- 被“运行 search e2e 测试的变体”所依赖的编译变体,例如
amazon-linux2023-arm64-static-compile(Amazon Linux 2023 arm64 Enterprise Shared Library Compile & Static Analysis),它被 “Amazon Linux 2023 arm64 Atlas Enterprise (all feature flags)” 变体依赖; - 既编译 mongot 又运行 search e2e 测试的变体,例如
amazon-linux2023-arm64-mongot-integration-patchable(AL2023 arm64 mongot integration tasks);任何名称中包含mongot的构建变体(如 “Enterprise RHEL 8.0 Mongot Integration”)都满足这一条件。
如果搞不清 Evergreen build variant 的关系,可以从仓库的 Evergreen 配置入手:etc/evergreen.yml 及其组件文件中定义了各变体与build_mongot扩展变量。
5.2 命令格式与示例
通用格式为:
bazel run db-contrib-tool -- setup-repro-env --variant <evergreen variant name> <evergreen patch id OR associated git commit hash>例如从AL2023 x86 mongot integration tasks cron only变体下载某个 git commit 对应的二进制:
bazel run db-contrib-tool -- setup-repro-env --variant amazon-linux-2023-x86-mongot-integration-cron-only 23b790a2a81767b8edbbc266043a205029867b74默认下载位置为build/multiversion_bin/<githash_patchid OR githash>/dist_test/,也可用--installDir指定:
bazel run db-contrib-tool -- setup-repro-env --variant amazon-linux2023-arm64-static-compile 23b790a2a81767b8edbbc266043a205029867b74 --installDir=build/multiversion_bin/my_variant此时 mongot 二进制会落在build/multiversion_bin/my_variant/23b790a2a81767b8edbbc266043a205029867b74/dist_test/bin/mongot-localdev。
5.3 一个常见陷阱
如果不显式传--variant,setup-repro-env会按本机架构自动挑选一个“合理”的变体——但自动选中的变体大概率没有编译 mongot,因此想下载 mongot 时必须显式传入含mongot的变体名。
六、小结:三种方式的选型速查
| 目标 | 命令/路径 | 关键点 |
|---|---|---|
| 快速跑本地 e2e 测试(latest,linux x86_64) | bazel run db-contrib-tool -- setup-mongot-repro-env --installDir build/install/bin | 默认即 latest + x86_64 |
| 对齐线上行为 | 同上,版本号改为release | 对应 Atlas 生产环境在跑的 mongot |
| 验证 mongot 未合入改动 | 克隆 mongot 仓库 →PLATFORM=linux_x86_64 make build.deploy.localdev→ 解压 tarball → 把二进制移入~/mongo/build/install/bin | 使用 mongot 仓库自身构建系统 |
| 复现某次 Evergreen 构建 | bazel run db-contrib-tool -- setup-repro-env --variant <mongot variant> <patch/commit> | 必须显式指定含 mongot 的变体 |
| 新增测试并运行 | jstest 放入jstests/with_mongot/e2e,用resmoke.py run --suites=mongot_e2e_single_node(或mongot_e2e_sharded_cluster) | 遵守“先插数据 → 建索引 → 查询”的顺序 |
掌握以上内容后,你可以独立搭建完整的 Atlas Search 集成调试环境:选择合适来源的 mongot 二进制,在单节点副本集或分片集群上运行自己编写的 jstest,并在遇到数据一致性问题时快速定位到测试顺序与索引 READY 状态等待机制这两个关键点。
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考