南向采集通道回归验证测试方案
- BACnet
- OPC UA
- Modbus(TCP / RTU)
- 通道级隔离
- 设备级隔离
- 轮询压力测试
- 10ms 采集节点间隔验证
- 数据正确性验证
- 异常场景注入
目标是验证:
① 采集通道独立运行 ② 单设备离线不影响同通道其他设备 ③ 不同通道互不影响 ④ 在线设备数据点位持续正确更新 ⑤ 轮询间隔控制为 10ms(避免串流) ⑥ 在全量压力测试下系统稳定
(已引入影子设备与快照层,以下测试项在不改动北向实现的前提下进行增强验证)
一、总体测试架构
┌──────────────────────────┐
│ Edge Gateway │
│ Poller + ChannelMgr │
└────────────┬─────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
BACnet Channel OPCUA Channel Modbus Channel
(独立协程池) (独立协程池) (独立协程池)
▼(采集完成)
Shadow Device(原子快照) → Snapshot Bus(合并/优先级) → Points Commit(差量) → MQTT/OPC UA(复用)
强制架构要求(必须验证)
| 项目 | 必须满足 |
|---|---|
| 通道 | 独立 goroutine / context |
| 设备 | 独立超时控制 |
| 设备失败 | 不得 panic / 不得阻塞调度 |
| 采集间隔 | 设备之间间隔 ≥10ms |
| 超时控制 | 单设备超时 ≤3s |
| 数据隔离 | 不得出现设备数据串流 |
| 快照一致 | Snapshot Version 单调递增,组完成后递增 |
| 发布源唯一 | 北向发布仅由 Points Commit 触发 |
二、测试环境准备
1️⃣ 模拟器准备
Modbus
- 20台模拟设备(TCP + RTU混合)
- 每台 50 个点位
- 可随机延迟
- 可强制断线
推荐:
- modbus-pal
- mbserver
- 自定义TCP mock
BACnet
- 10台 BACnet/IP 模拟设备
- 每台 30 个 object
- 支持 Who-Is / I-Am
- 支持 ReadProperty
推荐:
- YABE + 模拟器
- BACnet Stack Demo
OPC UA
- 5个 OPC UA Server
- 每个 100+ 节点
- 支持读写
- 支持强制断开
推荐:
- Prosys Simulation Server
- Unified Automation Demo Server
2️⃣ 压测规模建议
| 协议 | 设备数 | 总点位 |
|---|---|---|
| Modbus | 20 | 1000 |
| BACnet | 10 | 300 |
| OPC UA | 5 | 500 |
| 总计 | 35 | 1800 |
三、核心验证项设计
测试组 A:基础轮询验证
A1 正常轮询验证
步骤:
- 所有设备在线
- 设置轮询周期 1s
- 设置设备间隔 10ms
- 运行 30 分钟
- 记录每个采集组完成事件(GroupComplete)与对应 Snapshot Version++;统计 Commit 次数与点位变更次数。
验证项:
| 验证点 | 判定标准 |
|---|---|
| 轮询不丢设备 | 所有设备都被轮询 |
| 数据刷新 | 所有点位持续更新 |
| CPU稳定 | < 70% |
| 无panic | 日志无异常 |
| 快照生成 | 每组完成均有 Version++ |
| Commit去抖 | Commit 次数 < 原始点位变更数 |
测试组 B:单设备离线隔离验证(关键)
B1 单设备离线
步骤:
- 正常运行
- 手动关闭 1台 Modbus
- 观察 5分钟
验证:
| 验证点 | 标准 |
|---|---|
| 该设备状态 | Offline |
| 同通道其他设备 | 正常轮询 |
| 不出现阻塞 | 轮询日志连续 |
| 数据无串流 | 不出现数据错写 |
| 快照一致性 | 离线设备不生成新快照,在线设备快照正常 |
| 北向源唯一 | 无点位直推,仅 Commit 触发发布 |
B2 同时离线多个设备
关闭:
- 3台 Modbus
- 2台 BACnet
- 1台 OPCUA
验证:
- 其他在线设备正常
- 通道状态为 degraded
- 不影响其他协议通道
测试组 C:通道级隔离验证
关闭整个 BACnet 网络。
验证:
| 验证点 | 预期 |
|---|---|
| BACnet通道 | Offline |
| Modbus | 正常 |
| OPCUA | 正常 |
| 主调度器 | 无阻塞 |
| 快照与 Commit | 非 BACnet 通道的快照与 Commit 正常 |
测试组 D:10ms 间隔验证(防串流)
目标
验证:
任意两个设备采集时间间隔 ≥10ms
验证方法
在采集层增加时间戳日志:
[PollStart] device=xxx ts=...
导出日志后验证:
设备A 10:00:00.000
设备B 10:00:00.012
设备C 10:00:00.023
要求:
Δt >= 10ms
并且:Snapshot Version 仅在组完成后递增,不因单点位更新而递增。
判定标准
| 项目 | 标准 |
|---|---|
| 平均间隔 | ≥10ms |
| 无 0ms 连续触发 | |
| 不出现RTU CRC错误 | |
| 不出现TCP粘包异常 |
测试组 E:数据串流验证(关键)
目标
验证:
设备A的数据不会写入设备B 且仅在 Mapping Commit 回写 Points 后才触发北向发布。
方法
人为制造:
- 设备A返回固定值 111
- 设备B返回固定值 222
运行 10分钟
验证数据库:
deviceA = 111
deviceB = 222
若出现:
deviceA = 222
说明数据串流(严重BUG)
测试组 F:压力极限测试
条件:
- 35台设备全部在线
- 1s 轮询周期
- 10ms间隔
- 连续运行 12小时
验证:
| 项目 | 标准 |
|---|---|
| 内存增长 | 不持续上涨 |
| goroutine | 不泄漏 |
| CPU | 稳定 |
| 数据丢失 | 0 |
| 崩溃 | 0 |
| SnapshotBus 延迟 | P95 ≤ 350ms |
| Commit 差量率 | ≥ 60% |
测试组 G:随机异常注入
每5分钟:
- 随机断1台设备
- 随机恢复
- 随机增加延迟 2秒
验证:
- 调度系统稳定
- 不出现死锁
- 不出现panic
- 恢复后自动恢复采集
- 快照生成与分发恢复正常;Commit 不堆积
四、验证指标体系
1️⃣ 通道级指标
| 指标 | 目标 |
|---|---|
| ChannelState | Running / Degraded / Offline |
| 失败率 | <5% |
| 平均轮询耗时 | < 500ms |
| SnapshotBus延迟 | P95 ≤ 350ms |
2️⃣ 设备级指标
| 指标 | 目标 |
|---|---|
| 设备成功率 | >95% |
| Timeout | 正常触发 |
| 错误不传播 | |
| SnapshotVersion | 单调递增 |
| ShadowAtomicWrite | 无并发破坏 |
3️⃣ 数据级指标
| 指标 | 目标 |
|---|---|
| 点位刷新率 | 100% |
| 错写 | 0 |
| 串流 | 0 |
| Commit差量率 | ≥ 60% |
| 发布源唯一性 | 100%(仅 Commit) |
五、自动化验证建议
1️⃣ 写自动化轮询测试程序
模拟:
- 启停设备
- 修改数据
- 验证数据库
- 验证 Snapshot Version 与 Commit 计数器
2️⃣ 日志自动分析
统计:
- 设备间隔
- 错误分布
- 超时分布
- SnapshotBus 延迟与去抖动效果
3️⃣ goroutine泄漏检测
runtime.NumGoroutine()
每分钟记录一次。
六、最终验收标准
系统必须满足:
✔ 单设备离线不影响同通道 ✔ 单通道离线不影响其他通道 ✔ 设备间采集间隔 ≥10ms ✔ 数据无串流 ✔ 连续运行12小时无崩溃 ✔ 数据100%刷新 ✔ Snapshot Version 单调递增,组完成后递增 ✔ 北向发布仅由 Points Commit 触发(零侵入)
七、推荐调度实现模型(建议)
强烈建议采用:
Channel goroutine
↓
Device worker pool
↓
device loop
sleep 10ms
(组完成→写入 Shadow → OnSnapshot → 合并→差量 Commit→北向复用)
而不是:
for all devices concurrently
否则:
- 极易串流
- 极易阻塞
- 极易雪崩
结论
这套方案可以验证:
- 架构隔离能力
- 调度稳定性
- 工业级可靠性
- 协议层隔离性
- 数据正确性