
ente-test-support 集成测试基础设施在 Rust 测试中一键拉起 Museum、临时 Postgres 与本地对象存储【免费下载链接】ente End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/ente导读ente 仓库的 Rust 侧提供了一批针对后端 Museum 的集成测试而ente-test-support源码位于 rust/crates/test-support正是承载这些测试的轻量级测试基础设施它能在测试进程内自动启动一个由临时 Postgres 与本地内存对象存储支撑的 Museum 实例并通过 Cargo feature 门控让普通cargo test默认跳过、按需开启。读完本文你将掌握这套测试装置的工作原理、环境依赖、运行命令以及如何在其上编写自己的端到端测试。它解决什么问题Museum 是 ente 的后端服务见 server其正常运行需要依赖数据库与对象存储。要让 Rust 集成测试真正覆盖账号注册、同步、导出、分享等全链路行为测试环境就必须具备一个真实可用的 Museum HTTP 服务一个可读写的关系型数据库Postgres一个兼容 S3/B2 语义的对象存储。ente-test-support的价值在于把这些外部依赖全部内嵌进测试进程Postgres 由 postgresql_embedded 按需下载并管理对象存储则是一个运行在线程内的极简 HTTP 服务器Museum 二进制由go build现场编译。整个环境是临时的、进程内的、随测试销毁的无需开发者预先安装 Postgres、配置 S3 或准备任何密钥。环境准备与依赖按照 rust/crates/test-support/README.md 的说明运行这类测试只需满足两点PATH 中必须有go命令——用于编译并启动 Museum。server.rs中的require_go()会先执行go version校验失败时直接返回 Museum live tests requiregoon PATHrust/crates/test-support/src/server.rsPostgres 二进制无需手动安装postgresql_embedded会在首次使用时自动下载并缓存。关于缓存位置值得展开说明postgresql_embedded默认把二进制放在$HOME/.theseus而 postgres.rs 中的install_dir()将其重定向到系统约定的缓存目录下的.theseus/postgresql例如 Linux 上为$XDG_CACHE_HOME或~/.cache/.theseus/postgresql避免污染家目录根级。依赖配置见 Cargo.tomlpostgresql_embedded 0.20.4启用了blocking、rustls、theseus三个 feature同时使用tokiort-multi-thread、uuidv4与dirs。该 crate 标记为publish false属于仓库内部的专用测试库不对外发布。架构组成四个协同模块src/lib.rs 对外只暴露Museum类型与少量常量内部按职责拆分为四个模块模块职责postgres.rs管理临时 Postgres 实例创建测试数据库ente_testobject_store.rs线程内运行的极简 HTTP 对象存储内存版 S3server.rs编译并启动 Museum注入全部环境变量等待就绪process.rs子进程封装日志落盘、状态检查、Drop 时回收临时 Postgrespostgres.rs 的start()构造Settings时使用temporary: true、随机空闲端口free_port()启动后调用create_database(ente_test)创建专用数据库并通过host()/port()/username()/password()/database()向外部暴露连接参数。内存对象存储object_store.rs 用TcpListener绑定随机端口在后台线程里循环 accept 连接实现了一个最小可用的对象存储协议PUT记录对象路径与长度返回200 OKHEAD按路径返回200带 Content-Length或404 Not Found其他方法一律返回405 Method Not Allowed。对象数据存放在线程内的HashMapString, usize中只记大小、不落盘足以支撑 Museum 上传/探测对象的逻辑。Museum 的编译与启动server.rs 的start()做了三件事定位 server 目录由CARGO_MANIFEST_DIR即本 crate 目录向上回溯三层得到仓库根目录再拼接server对应仓库根下的 server 目录编译 Museum执行go build -o 临时目录/museum ./cmd/museum注入环境变量并启动通过Command为 Museum 进程设置全套ENTE_*环境变量。就绪探测与日志启动后wait_for_museum()会在90 秒内以500ms间隔轮询GET /ping直到返回 HTTP 200 才认为就绪超时或进程提前退出时会把保存在临时目录logs/museum.log中的日志摘要一并抛出便于排查见 server.rs。子进程在 Drop 时会被 kill 并回收process.rs。环境变量注入清单Museum 通过环境变量读取配置。server.rs的start()注入的变量是理解整套测试装配的关键归纳如下数据库连接指向临时 Postgres变量值ENTE_DB_HOST/ENTE_DB_PORT临时 Postgres 地址ENTE_DB_NAMEente_testENTE_DB_USER/ENTE_DB_PASSWORD临时实例的账号密码ENTE_DB_SSLMODEdisable对象存储指向内存 S3变量值ENTE_S3_ARE_LOCAL_BUCKETStrue声明桶为本地的不校验真实云凭证ENTE_S3_B2_EU_CEN_KEY/ENTE_S3_B2_EU_CEN_SECRETchangeme/changeme1234测试占位凭证ENTE_S3_B2_EU_CEN_ENDPOINT内存对象存储地址ENTE_S3_B2_EU_CEN_REGIONeu-central-2ENTE_S3_B2_EU_CEN_BUCKET/ENTE_SPACE_ASSETS_PRIMARYBUCKETb2-eu-cenHTTP 与测试辅助变量值ENTE_HTTP_PORT随机空闲端口测试据此得到 endpointENTE_CREDENTIALS_FILE指向一个空文件见下文空配置文件的用意ENTE_INTERNAL_HARDCODED_OTT_LOCAL_DOMAIN_SUFFIXexample.orgENTE_INTERNAL_HARDCODED_OTT_LOCAL_DOMAIN_VALUE123456ENTE_JOBS_CRON_SKIPtrue跳过定时任务保证测试确定性其中HARDCODED_OTT 123456与HARDCODED_OTT_EMAIL_SUFFIX example.org定义在 src/lib.rs任何以example.org结尾的测试邮箱都可以直接用固定 OTP123456完成登录从而绕开真实邮件发送链路。空配置文件的用意write_config()特意写一个空文件作为ENTE_CREDENTIALS_FILE源码注释说明了原因不能在这里写任何配置否则会覆盖开发者本地的museum.yaml而空文件本身又能屏蔽掉任何真实的本地凭据文件防止测试意外连到生产/开发环境。如何使用Cargo feature 门控与运行命令按 README 约定使用该装置的测试统一通过名为museum的 Cargo feature 门控。例如 CLI crate 的 Cargo.toml 中声明了museum []对应集成测试文件如 rust/apps/cli/tests/sync.rs首行就是#![cfg(feature museum)]——意味着不启用该 feature 时普通cargo test会直接跳过这些测试不影响日常开发。启用 feature 后运行cargo test -p ente-rs --features museum以上命令即 rust/crates/test-support/README.md 中给出的标准调用方式。从源码结构看当前仓库中使用ente-test-support的集成测试还包括rust/apps/cli/tests/paste.rs、rust/apps/cli/tests/sync.rsCLI 的粘贴与同步全链路rust/crates/accounts/tests/accounts.rs、rust/crates/contacts/tests/contacts.rs、rust/crates/space/tests/space.rs账号、联系人、Space 等模块的集成测试。Museum::run 与 run_asyncsrc/museum.rs 提供两个入口Museum::run(|museum| ...)同步版本闭包接收Museum内部用catch_unwind包裹测试体任何错误或 panic 都会触发temp_dir.retain()——保留临时目录并打印路径方便事后检查日志与数据Museum::run_async(|endpoint| ...)异步版本内部新建 tokio runtime 并block_on闭包直接拿到endpoint字符串。Museum对外暴露两个方法endpoint()返回http://127.0.0.1:port形式的服务地址temp_dir()返回临时工作目录。临时目录以ente-test-uuid命名正常结束时随 Drop 自动删除src/museum.rs 中的TempDir。一个真实的测试示例以 rust/apps/cli/tests/sync.rs 为例可以看到完整的用法模式#[test] fn sync() - TestResult { Museum::run(|museum| { let cli support::cli_session(museum, sync)?; let export_dir museum.temp_dir().join(export); std::fs::create_dir_all(export_dir)?; cli.run_ok([ account, create, --email, sync-testexample.org, --password, sync-test-password, --endpoint, museum.endpoint(), --export-dir, export_dir.to_str().unwrap(), --otp, HARDCODED_OTT, // 123456 ])?; let output cli.run_ok([export])?; assert!(output.contains(Sync completed), export did not sync: {output}); Ok(()) }) }这个测试在 5 行内完成了启动全套后端 → 注册账号用固定 OTP 验证→ 执行导出同步 → 断言输出的完整闭环充分体现了这套基础设施对集成测试的简化能力。测试账号夹具与常量src/lib.rs 还内置了一个account_fixture模块供需要预置账号密钥的测试复用PASSWORD museum-account-fixture-passwordKEK密钥加密密钥与其KEK_SALT为预计算的固定值注释说明其派生参数为 Argon2id(密码, 16 × 0x4d 盐, 256 MiB 内存, 16 次迭代)MEM_LIMIT 268_435_456256 MiB、OPS_LIMIT 16与 Argon2id 参数一一对应。使用预计算 KEK 可以让涉及加密导出的测试跳过昂贵的密钥派生过程同时保证加解密结果可预期。运行前提与注意事项必须启用museumfeature否则相关测试被#![cfg(feature museum)]直接裁剪表现为测试不存在而非测试失败首次运行会下载 Postgres 二进制缓存在缓存目录的.theseus/postgresql下需要网络与磁盘空间之后运行不再重复下载需要go工具链编译 Museum对应 server 目录下的cmd/museum编译产物写入测试临时目录不做全局安装端口全部动态分配Postgres 端口、对象存储端口、Museum HTTP 端口均通过bind(0)获取随机空闲端口net.rs多测试并行时不会冲突环境隔离测试通过环境变量注入配置且使用空ENTE_CREDENTIALS_FILE不会读取开发者本地的museum.yaml或真实云凭证失败可诊断一旦 Museum 未就绪、进程提前退出或测试失败临时目录会被保留终端会打印retaining integration test temp dir: 路径其中logs/museum.log是首选的排障入口。小结ente-test-support是一个小而美的测试基础设施它以极少的对外 APIMuseum::run/run_async、endpoint()、temp_dir()、HARDCODED_OTT、account_fixture封装了编译 Go 后端 下载托管 Postgres 内存对象存储 子进程生命周期管理的全部复杂度。理解它的环境变量注入清单与临时目录保留策略是你在 rust/apps/cli/tests 与 rust/crates 各模块测试目录下阅读、扩展或新写集成测试时最重要的前置知识。【免费下载链接】ente End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/ente创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考