cmvr-es/test/quic_gateway/README.md

9.3 KiB
Raw Permalink Blame History

CMVR QUIC test Gateway

cmvr_quic_test_gateway 是开发和验收工具,不是平台端生产 Gateway。它在本机 监听真实的 MsQuic/TLS/UDP 连接,用来验证 cmvr_es 的 QUIC edge v1 客户端。

测试链路:

output/bin/cmvr_es
  ├── reliable QUIC stream ──> cmvr_quic_test_gateway
  │    register / heartbeat / media metadata
  └── QUIC DATAGRAM ─────────> bounded media reassembler

Gateway 使用生产代码中的:

  • EdgeControlEnvelope protobuf
  • ControlFrameEncoder / ControlFrameDecoder
  • DatagramPacketizer::decodeHeader
  • CMQD v1 常量和类型。

它不会实现 WebTransport、WebRTC、HTTP API、节点数据库或浏览器播放。

构建

该目录的 CMakeLists.txt 由项目测试目录加入。MsQuic 通过根目录 request.txt 提供。依赖为:

  • msquic
  • cmvr_es::proto
  • cmvr_es::quic_edge_service
  • Threads::Threads

示例:

cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMVR_ARCH=x86 \
  -DBUILD_TESTING=ON

cmake --build build --target cmvr_quic_test_gateway -j2

默认只生成 build-tree 测试程序,不污染部署目录。如确实希望一同安装:

cmake -S . -B build \
  -DCMVR_INSTALL_QUIC_TEST_GATEWAY=ON
cmake --build build --target cmvr_quic_test_gateway -j2
cmake --install build

安装位置是 output/bin/cmvr_quic_test_gateway,可复用 output/lib/libmsquic.so 和现有相对 RUNPATH。

生成本地测试证书

QUIC 即使使用“不校验证书”的 client 模式Server 仍必须提供 TLS 证书。 不要提交真实私钥。下面命令只在 build 目录生成 loopback 测试证书:

mkdir -p build/test/quic_gateway/certs

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout build/test/quic_gateway/certs/server.key \
  -out build/test/quic_gateway/certs/server.crt \
  -days 7 \
  -subj "/CN=127.0.0.1" \
  -addext "subjectAltName=IP:127.0.0.1"

MsQuic/OpenSSL 当前要求这里的 PEM 私钥不带密码。

启动

固定端口适合人工联调。构建树中请使用 CMake 生成的启动包装器;它会补齐 仓库内 gRPC 等传递动态库的搜索路径:

build/test/quic_gateway/run_cmvr_quic_test_gateway \
  --bind 127.0.0.1 \
  --port 4433 \
  --cert build/test/quic_gateway/certs/server.crt \
  --key build/test/quic_gateway/certs/server.key \
  --scenario normal \
  --summary-file build/test/quic_gateway/summary.json

自动化测试应使用 --port 0 避免端口冲突。Gateway 会查询 Listener 实际端口, 在 stdout 和 --ready-file 写入一个 JSON 对象:

build/test/quic_gateway/run_cmvr_quic_test_gateway \
  --bind 127.0.0.1 \
  --port 0 \
  --cert build/test/quic_gateway/certs/server.crt \
  --key build/test/quic_gateway/certs/server.key \
  --ready-file build/test/quic_gateway/ready.json \
  --summary-file build/test/quic_gateway/summary.json \
  --exit-after-heartbeats 3

Ready 文件示例:

{"event":"ready","bind":"127.0.0.1:52319","port":52319,"alpn":"cmvr-quic-edge/1","scenario":"normal","datagram_enabled":true}

自动 runner 读取 port,将它写入临时 quic_edge_task.pb.txt 后再启动 cmvr_es。不要直接改唯一一份 output/bin/config/;普通安装默认会覆盖它。 只更新程序与运行库时,应在配置构建目录时设置 -DCMVR_INSTALL_DEFAULT_RUNTIME_ASSETS=OFF

cmvr_es 本机配置

第一轮只测试注册、IP 上报和心跳,保持设备和 tracks 关闭:

quic_edge {
  id: "quic_edge"
  server_host: "127.0.0.1"
  server_port: 4433
  alpn: "cmvr-quic-edge/1"
  node_id: "local-quic-test"
  software_version: "test"

  grpc_endpoint_host: "127.0.0.1"
  grpc_endpoint_port: 50052
  grpc_endpoint_tls: false
  include_loopback_interfaces: true

  heartbeat_interval_ms: 1000
  control_response_timeout_ms: 1000

  tls {
    allow_insecure: true
  }

  reconnect {
    initial_delay_ms: 100
    maximum_delay_ms: 1000
    multiplier: 2.0
    jitter_percent: 0
    connect_timeout_ms: 3000
  }

  maximum_datagram_bytes: 1200
  maximum_control_frame_bytes: 1048576
  maximum_frame_bytes: 524288
  datagram_send_queue_depth: 512
  media_poll_interval_ms: 2
}

在 TaskManager 中将 quic_edge entry 设为 enable: true。然后运行一份独立的 临时配置树:

output/bin/cmvr_es /tmp/cmvr-quic-e2e/config/cmvr_es.pb.txt

场景

--scenario 支持:

当前 CTest 自动回归仅运行 normal 场景;其余场景保留为手工故障注入和验收入口, 尚未纳入自动回归。

名称 行为 预期 Edge 行为
normal 接受注册并精确 ACK 心跳 保持同一连接
reject-registration 返回 accepted=false 退避后重新注册
drop-heartbeat-ack 接收但不回复心跳 response timeout 后重连
wrong-ack-session ACK 使用错误 session ID 判定协议错误并重连
fatal-protocol-error 注册成功后发送 fatal ProtocolError 重连
nonfatal-protocol-error 注册成功后发送 nonfatal ProtocolError 保持连接并继续心跳
datagram-disabled 不协商 QUIC DATAGRAM 注册和心跳正常,媒体不发送

可以用以下条件让程序自动成功退出:

  • --exit-after-registrations N
  • --exit-after-heartbeats N
  • --run-for-ms N

收到 SIGINTSIGTERMGateway 会停止 Listener、关闭活动连接、排空工作 队列并写 summary。

协议验证

每个连接独立维护:

  • control framing buffer
  • Edge 和 Gateway 各自的严格递增 message_sequence
  • node、boot、registration session
  • media session epoch
  • track descriptor generation token
  • DATAGRAM 重组缓存。

Gateway 要求:

  1. NodeRegisterRequest 是第一条应用消息;
  2. protocol version 为 1
  3. 后续 envelope sequence 严格增加;
  4. heartbeat 的 node、boot 和 session 与注册一致;
  5. media session 先于 descriptor
  6. DATAGRAM 的 epoch、track、kind 和 generation token 与可靠元数据一致。

observed_source_ip 从 MsQuic peer address 获取,不从 Edge 上报字段复制。 Heartbeat 中存在 device_managerGateway 会记录 Manager 元数据以及设备 总数、启用数、禁用数、确认异常数和未知健康数;该字段是 v1 的兼容性追加项, 并在最终 summary 的 heartbeat_devices 数组中保留最近一次完整设备行。测试 Gateway 仍接受没有该字段的旧 Edge。当前 Edge 只发送已启用设备,因此正常情况 下禁用数为 0该统计仍用于兼容旧发送端和发现协议违规。 summary 还会保留每类媒体最近一次 descriptor以及已完成帧中的最大 frame_sequence、长度、flags、采集时间戳和 FNV-1a 64 位载荷哈希。这里的哈希 只用于测试中精确比对字节,不用于安全认证。真实 E2E 会先发送 discovery 帧并等 descriptor 到达,再发送 priming/validation 帧,从而避免 reliable stream 与 DATAGRAM 跨通道乱序造成偶发误判。

DATAGRAM 安全边界

MsQuic callback 只复制收到的数据并进入有界队列;控制消息使用高优先级队列, 不会被媒体洪峰长期阻塞。后台线程完成 protobuf 处理和媒体重组。

重组 key 是:

(session_epoch, track_id, frame_sequence)

接收器限制:

  • 总缓存字节;
  • 在途帧数;
  • 单帧大小;
  • 单帧最多 8192 个分片;
  • 不完整帧超时;
  • fragment index 冲突;
  • byte range 重叠;
  • 新 session epoch 清理旧分片。

相关 CLI

--max-reassembly-bytes
--max-reassembly-frames
--max-frame-bytes
--max-work-queue-bytes
--reassembly-timeout-ms

输出与判定

stdout 每行都是一个 JSON 对象或 JSON-compatible 单行事件。最终 summary 包含:

  • connection/register/heartbeat 计数;
  • 注册和最近一次心跳上报的网卡数量、gRPC endpoint 与对端源 IP
  • 最近一次 DeviceManager 名称/版本/描述,以及已上报设备总数、启用数、兼容性 禁用数、确认异常数、未知健康数和 heartbeat_devices 完整设备行;
  • ACK、故障场景和协议错误计数
  • media session/descriptor/DATAGRAM 计数;
  • 完整帧(含视频/音频分项)、无效包、队列丢包;
  • 超时、容量淘汰和 session 清理的不完整帧。

自动化脚本至少应检查:

runtime_failed == false
registrations_accepted >= 1        # normal 场景
heartbeats_received >= 1
heartbeat_acks_sent >= 1
protocol_violations == 0

媒体场景还应检查:

media_sessions_opened >= 1
track_descriptors_received >= 1
datagrams_received >= 1
frames_completed >= 1

无设备主机的限制

关闭全部设备时,实际 output/bin/cmvr_es 可以完整验证 TLS、ALPN、控制 stream、 注册、IP 上报、心跳和重连,但不会产生音视频。

要在无硬件环境验证媒体 DATAGRAM测试侧还需要 synthetic MediaSourceHub producer 或测试专用 fake camera/microphone。该 Gateway 已具备媒体接收和重组能力,但不会 伪造 Edge 发出的媒体。

安全说明

  • 仅监听 loopback 是默认值;
  • allow_insecure 仅限本机开发;
  • 不要将测试 Gateway 暴露到不受信任网络;
  • 不要复用或提交生产证书、生产私钥;
  • 该工具没有生产级认证、授权、持久化和多租户隔离。