用途
pdk-test 是一个用于为自定义 Omni Gateway 策略编写和运行基于 Docker 的功能集成测试的框架。它帮助开发者从「策略能编译为 WASM 但没有集成测试」推进到「测试能在 Docker 中启动真实 Omni Gateway、应用策略、发送 HTTP 流量并端到端断言行为」。
该技能适用于行为依赖真实 Omni 路由、TLS 终止、多策略链或监听器配置的场景。如果逻辑仅作用于请求/响应且依赖都可被 mock,应优先使用 pdk-unit;若两者都需要,先写 pdk-unit 获得快速反馈,再补充 pdk-test 冒烟测试。相关技能还包括 develop-pdk-policy(负责脚手架的构建、playground、发布与发布生命周期)。
前置条件
在编写任何测试前,需按顺序验证:
- Docker 正在运行:
docker info > /dev/null 2>&1 && echo "Docker OK" || echo "Docker NOT running" - 策略 WASM 已构建:
ls target/wasm32-wasip1/release/*.wasm 2>/dev/null && echo "WASM OK" || echo "Run 'make build' first" - 注册文件存在:
ls tests/config/registration.yaml 2>/dev/null && echo "Registration OK" || echo "MISSING - see Step 2"
任一检查失败需先修复再继续。若开发环境尚未搭建(缺少 Anypoint CLI、Rust、wasm target 或 Docker),应参考 pdk-prerequisites 技能。
主要能力
- 使用
#[pdk_test]宏将 async fn 转换为测试,创建 Tokio 多线程运行时并管理测试生命周期。框架通过 TestComposite 的 Drop 处理容器清理,并在每次测试运行开始时清理带有CreatedBy=pdk-test标签的遗留容器。 - TestComposite 编排多个 Docker 服务(Omni + 后端),采用 Builder 模式。
- 提供 FlexConfig(配置 Omni Gateway 容器,含版本、hostname、镜像覆盖、API 配置、配置挂载、就绪超时)、ApiConfig(配置 Omni 提供的虚拟 API,含名称、上游、destinationPath、监听端口、入站/出站策略)、PolicyConfig(配置应用到 API 的策略,含策略引用名与运行时配置)、HttpMockConfig(配置 httpmock 后端容器)等构建器。
- 支持 GrpcBin / GripMock(gRPC 测试)与 HttpBin(通用 HTTP echo 测试)。
- 支持通过环境变量
PDK_TEST_FLEX_IMAGE_NAME、PDK_TEST_FLEX_IMAGE_VERSION覆盖 Omni Docker 镜像名称与版本。
使用方式
1. 添加 dev-dependencies
在 Cargo.toml 的 [dev-dependencies] 下添加:pdk-test = "1.8.0"、httpmock = "0.6"、reqwest = "0.11"、serde_json = "1"、anyhow = "1"。pdk-test 版本应与 [dependencies] 中的 pdk 版本一致,它们从同一 workspace 一起发布。若项目使用 workspace,使用 { workspace = true } 语法。
2. 设置测试配置
tests/config/ 下需要配置文件:
- registration.yaml(必需,已 gitignore):告诉 Omni Gateway 如何在本地(断开)模式注册。前往 Anypoint Platform → Runtime Manager → Omni Gateway,点击 Add Gateway 选择 Docker,复制注册命令并将
--connected=true改为--connected=false,在 tests/config/ 下运行生成。也可从其他 PDK 项目或 playground 目录复制现成文件。重要:不要提交 registration.yaml,它包含私钥(base64 编码的 TLS 证书与密钥)。 - logging.yaml(可选但推荐):在测试中启用 debug 级 Omni 日志。示例配置含
apiVersion: gateway.mulesoft.com/v1alpha1、kind: Configuration、元数据名称 logging-config、spec.logging.runtimeLogs.logLevel: debug。
3. 创建 tests/common/mod.rs
定义共享常量,如 POLICY_DIR、COMMON_CONFIG_DIR 和 POLICY_NAME。POLICY_NAME 通过 make show-policy-ref-name 或读取 target/policy-ref-name.txt 获取,由 cargo anypoint get-policy-implementation-name 结合资产 ID 与主次版本号派生,不要手动推导。
4. 编写第一个集成测试
在 tests/requests.rs 中:引入 httpmock::MockServer、pdk_test::port::Port、pdk_test::services::flex 的 ApiConfig/Flex/FlexConfig/PolicyConfig、pdk_test::services::httpmock 的 HttpMock/HttpMockConfig、pdk_test 的 pdk_test 宏与 TestComposite。定义 FLEX_PORT 常量,使用 #[pdk_test] 异步函数,按顺序配置 mock 后端、被测策略、Omni 将提供的 API、Omni Gateway,启动 TestComposite,获取服务句柄,设置 mock 期望,发送请求并断言。
5. 运行测试
先 make build 构建 WASM,再运行 cargo test --test requests -- --nocapture 或 make test。因为要启动 Docker 容器,集成测试较慢(每个约 30-60 秒),用 --nocapture 查看 Omni Gateway 日志。测试顺序执行——框架获取全局互斥锁,一次只运行一个测试,避免 Docker 资源争用与清理竞争。
测试模式
- 策略阻止请求:不带头发送请求,断言状态码为 401。
- 策略修改头部:用 httpmock 断言验证到达后端的头部,通过
mock.assert()证明头部到达后端。 - 用配置辅助函数减少样板代码:将配置构建抽取为 helper,但需在测试作用域中保持 TestComposite 存活(丢弃它会销毁容器)。
- 测试链中的多个策略:在
.policies([first_policy, second_policy])中数组顺序决定求值顺序。 - 对具有异步初始化的策略重试:部分策略在 configure 函数中使用 Clock 做周期任务(如合同轮询、缓存刷新),可能需要在 Omni 就绪后短暂延迟。多数策略不需要,仅当策略在 configure 中有异步工作时才需要,推荐使用重试循环(非 503 时中断,最多 10 次,每次间隔 500ms)。
运行命令
# 运行所有集成测试
cargo test --test requests
# 运行特定测试
cargo test --test requests test_clean_request_passes
# 带输出(查看 Omni 日志)
cargo test --test requests -- --nocapture
# 通过 Makefile
make test
# 覆盖 Omni 版本
PDK_TEST_FLEX_IMAGE_VERSION=1.9.0 cargo test --test requests
限制与约束
- 每个测试只能定义一个 HttpMock 服务,添加第二个会导致
.build().await返回Err(TestError::NotSupportedConfig(...))。 - Hostname 唯一性:单个测试中,同类型服务必须使用唯一 hostname,用相同 hostname 两次调用
.with_service()会 panic。 - 集成测试较慢(约 30-60 秒/测试),且顺序执行。
- 路由机制:Omni 在
http://0.0.0.0:{port}上监听所有传入路径,转发到上游服务;.path()值会成为生成 Omni YAML 中的 destinationPath,控制后端接收请求的位置,而非匹配哪些传入路径。 - 就绪判定通过观察 Omni 输出的 "cds: added/updated" 日志消息,默认为 60 秒超时。
故障排查
- "Docker daemon not running" / "Cannot connect to Docker daemon":启动 Docker Desktop 或 Docker 守护进程,pdk-test 通过 bollard 使用 Docker API。
- 等待 Omni 就绪超时:框架等待 Omni 在 stdout 输出 "cds: added/updated"。若一直未出现,检查 Docker 资源(CPU/内存)、验证 Omni 镜像版本存在(
docker pull mulesoft/flex-gateway:1.10.0)、检查 registration.yaml 是否有效。 - 若 Docker 未运行、WASM 未构建或 registration.yaml 缺失,应指出根本原因并停止。
(资料中未提供的收费、价格等信息暂未提供。)