#mqtt #单元测试 #测试服务器 #服务器 #测试

bin+lib mqttest

为单元测试 MQTT 客户端而设计的 MQTT 服务器

1 个不稳定版本

0.2.0 2020 年 4 月 6 日

#6 in #测试服务器

Apache-2.0 协议

68KB
1K SLoC

MQTT 测试服务器

Mqttest 是一个为客户端单元测试而设计的 MQTT 服务器。

与 Mosquitto 等标准服务器相比,Mqttest 提供了 CI 友好的二进制文件、快速的无 RC 测试、详细的机器可读数据包转储、网络问题模拟、可选的实现怪癖、作为库运行服务器等。

初期开发由 Munic 赞助。

当前和计划中的功能

  • 简化 CI 镜像
    • 自动端口发现(简化并行测试执行)
    • 静态构建的单文件 CLI 二进制文件(无运行时依赖或复杂的安装)
    • 作为 Rust 库使用
      • 将文件转储解码为 Rust 结构体
      • 配置和启动服务器
      • 使用 Rust 通道进行运行时服务器控制和客户端交互
      • 每次运行后返回转储和统计信息
    • 从其他语言中作为库使用
  • 详细日志文件和网络转储
    • 不需要连接观察者客户端的 RC 风险
    • MQTT 数据包数据和元数据(时间、连接 ID 等)的 JSON 转储
    • 全局或按连接的转储文件名
    • 灵活的负载解码
  • 可控制的连接行为
    • 确认延迟
    • 在发送一定数量的数据包或超时后关闭连接
    • 离线
    • 不良数据包流(意外的/缺失的确认/发布)
    • 覆盖会话寿命
    • 按 ID 或密码拒绝客户端
    • 不同的进程 ID 分配策略
    • 后续连接的不同行为
    • 在连接数达到一定数量后停止服务器
    • 在最大运行时间后停止服务器
    • 在此处添加您有用的行为
  • 协议支持
    • MQTT 3.1.1
    • MQTT 5
    • IPv6
    • 警告或拒绝扩展客户端标识符
    • 警告 MQTT3 习语已被 MQTT5 弃用
    • 文档突出显示 MQTT 实现的难点

非功能特性

  • 编解码器级别的错误(最好在编解码器库级别进行单元测试)。
  • 通配符主题(至少目前如此——可能不是很有用)。
  • 数据库或集群支持(离题)。
  • 高性能/可扩展性(尽管目标是小型且快速)。

使用方法

如果需要,安装 Rust >= 1.39.0。

独立二进制文件

# Build and install the executable
cargo install --path .

# See help
mqttest -h

Mqttest 启动只需几毫秒。您可以为每个客户端单元测试启动具有不同行为的服务器。或者,您可以启动单个实例并在进行一些临时测试时让它运行。

Rust 库

在您的 Cargo.toml

[dev-dependencies]
# MQTT test server.
mqttest = { version = "0.2.0", default-features = false }
# mqttest needs to be started from a tokio async context.
tokio = "0.2"
# At your discretion, if you want to see server logs.
env_logger = "0.7"

在您的单元测试中(有关更详细的示例,请参阅 test.rs

/// Boiler-plate to run and log async code from a unittest.
fn block_on<T>(f: impl Future<Output = T>) -> T {
    let _ = env_logger::builder().is_test(true).parse_filters("debug").try_init();
    tokio::runtime::Builder::new().basic_scheduler().enable_all().build().unwrap().block_on(f)
}

/// Example unittest. Bring your own client.
#[test]
fn connect() {
    let conns: Vec<ConnInfo> = block_on(async {
        // Create a server config
        let conf = Conf::new().max_connect(1);
        // Start the server
        let srv = Mqttest::start(conf).await.expect("Failed listen").await;
        // Start your client on the port that the server selected
        client::start(srv.port).await.expect("Client failure");
        // Wait for the server to finish
        srv.fut.await.unwrap()
    });
    // Check run results
    assert_eq!(1, conns.len());
}

可选功能

命令行界面

构建二进制文件所需(与库相反)。默认启用。

依赖项

约7–17MB
约207K SLoC