南向采集通道回归验证测试方案
文档性质:南向采集通道联机/压测回归方案(步骤与判定标准)。
最后更新:2026-07-04(回归复测执行 + 排期更新)
相关文档:ScanEngine 重构方案 · ScanEngine 测试报告 · 南向驱动测试报告 · B1 采集间隔核验 · Q3 Phase A–D 复测 · 影子设备设计测试
- BACnet
- OPC UA
- Modbus(TCP / RTU)
- 通道级隔离
- 设备级隔离
- 轮询压力测试
- 10ms 采集节点间隔验证
- 数据正确性验证
- 异常场景注入
目标是验证:
① 采集通道独立运行 ② 单设备离线不影响同通道其他设备 ③ 不同通道互不影响 ④ 在线设备数据点位持续正确更新 ⑤ 轮询间隔控制为 10ms(避免串流) ⑥ 在全量压力测试下系统稳定
现行架构已引入 ShadowCore 与快照层;采集调度内核为 ScanEngine(
deviceLoop/CollectionScheduler已下线)。以下测试项在不改动北向实现的前提下,验证调度隔离、快照一致性与 Commit 发布路径。
一、总体测试架构
┌──────────────────────────────────────────┐
│ Edge Gateway │
│ ScanEngine(10ms Tick 全局调度) │
│ ├ ExecutionLayer │
│ │ ├ SerialQueue(Modbus/DLT645 等) │
│ │ └ ParallelExecutor(OPC UA/BACnet) │
│ └ ConnectionController(设备连接态) │
└────────────────────┬─────────────────────┘
│ dispatch → Driver.ReadPoints
┌───────────────────────────┼───────────────────────────┐
│ │ │
BACnet Channel OPC UA Channel Modbus Channel
(Parallel 执行) (Parallel 执行) (Serial 硬隔离)
▼(采集完成)
ShadowCore(原子快照) → Snapshot Bus(合并/优先级) → Points Commit(差量) → MQTT/OPC UA(复用)
架构详图见 ScanEngine 重构方案 §1;影子设备写入闭环见 影子设备设计测试。
强制架构要求(必须验证)
| 项目 | 必须满足 |
|---|---|
| 调度内核 | ScanEngine 10ms Tick,任务经 ExecutionLayer 分发 |
| 通道/协议 | SerialQueue 串行硬隔离;Parallel/Limited 背压受控 |
| 设备连接 | ConnectionController 独立超时/退避/半开探测 |
| 设备失败 | 不得 panic / 不得阻塞 ScanEngine Tick |
| 采集间隔 | 同通道串行设备之间间隔 ≥10ms(Hard Jitter) |
| 超时控制 | 单设备超时 ≤3s |
| 数据隔离 | 不得出现设备数据串流 |
| 快照一致 | ShadowCore Snapshot Version 单调递增,组完成后递增 |
| 发布源唯一 | 北向发布仅由 Points Commit 触发 |
验证状态对照(2026-07-04 回归复测)
| 测试组 / 项 | 自动化 / 代码层 | 联机 / 长跑 | 证据 |
|---|---|---|---|
| ScanEngine / ExecutionLayer / ShadowCore | ✅ PASS | — | go test ./internal/core/... -short;ScanEngine 测试报告 §2.7 |
| 13 协议注册 + 100 设备混合压测 | ✅ PASS(含于 core -short) |
— | 同上 §2.3–2.5 |
| G007 调度吞吐(≥950 设备/秒) | ⚠️ WARN(947/s,零失败) | — | make bench-g007;_run_logs/2026-07-04_regression_bench_g007.txt |
| Q3 10k tag / deadline | ✅ PASS | — | make bench-q3(9505 pts/s,miss=0);_run_logs/2026-07-04_regression_bench_q3.txt |
南向驱动 -short 全包 |
✅ PASS | — | TestConnectionManager_RecordFailureBackoffAndDead 退避断言已修复(2026-07-05);_run_logs/2026-07-04_regression_driver_short.txt |
integration -short |
✅ PASS | — | _run_logs/2026-07-04_regression_integration_short.txt |
| SLA short soak / diagnostics | ✅ PASS(五 gate) | — | make test-soak-short;_run_logs/2026-07-04_regression_soak_short.txt |
| D 组 10ms 间隔 | — | ✅ 已核验(Modbus TCP 样本) | B1 采集间隔核验 |
| A–C / E–G 全量联机回归 | 部分单测覆盖 | ⚠️ 待执行 | 见 §八 回归执行计划;72h / 12h soak 未跑 |
二、测试环境准备
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 / Degraded |
| Modbus | 正常 |
| OPCUA | 正常 |
| ScanEngine | Tick 无阻塞、无 backlog 失控 |
| 快照与 Commit | 非 BACnet 通道的快照与 Commit 正常 |
测试组 D:10ms 间隔验证(防串流)
目标
验证:
任意两个设备采集时间间隔 ≥10ms(串行协议经 SerialQueue 硬隔离;并行协议受 Hard Jitter 约束)
已核验样本:B1 采集间隔核验报告(Modbus TCP 三从站,2026-02-14 现场 PollStart Δt 均 ≥10ms)。本组全协议复测仍按下列步骤执行。
验证方法
方法一(推荐,联机):在 Driver ReadPoints 入口或 ExecutionLayer 派发处打时间戳日志:
[PollStart] device=xxx channel=xxx ts=...
导出日志后验证:
设备A 10:00:00.000
设备B 10:00:00.012
设备C 10:00:00.023
方法二(辅助):GET /diagnostics/scan-engine 查看 scan_lag_p95_ms、scan_miss_deadline_total(稳态应为 0);串行队列可通过 [ScanEngineAdapter] 设备注册/执行日志对照同一 Tick 内设备顺序。
要求:
Δt >= 10ms
并且:ShadowCore 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) |
五、自动化验证建议
下列命令覆盖代码层与 benchmark gate;不等价于本方案 A–G 全量联机回归,但可作为执行前冒烟与 CI 门禁。详见 ScanEngine 测试报告 §2.7 与 Q3 Phase 复测。
1️⃣ CI / benchmark 入口
# ScanEngine / ShadowCore / ConnectionController(2026-07-04 回归:PASS,~50s)
CGO_ENABLED=0 go test ./internal/core/... -short -count=1
# 南向驱动单元测试(2026-07-04 回归:根包 1 FAIL,子包全 PASS)
CGO_ENABLED=0 go test ./internal/driver/... -short -count=1
# 集成层短测(2026-07-04 回归:PASS)
CGO_ENABLED=0 go test ./internal/integration/... -short -count=1
# G007 调度吞吐(1000 设备 · 1s · mock;2026-07-04:947/s WARN,0 failed)
make bench-g007
# Q3 10k tag deadline gate(2026-07-04:PASS,9505 pts/s,miss=0)
make bench-q3
# SLA short soak(30s,五 gate;2026-07-04:PASS)
make test-soak-short
2026-07-04 回归日志:docs/testing/_run_logs/ 下 2026-07-04_regression_*.txt。
2️⃣ 联机自动化轮询(待补)
模拟:
- 启停设备
- 修改数据
- 验证 ShadowCore / Points 存储
- 验证 Snapshot Version 与 Commit 计数器
3️⃣ 日志自动分析
统计:
- 设备间隔(PollStart / ReadPoints 时间戳)
- ConnectionController 状态分布与退避
- 错误 / 超时分布
- SnapshotBus 延迟与去抖动效果
GET /diagnostics/scan-engine中sla_warnings[]
4️⃣ goroutine泄漏检测
runtime.NumGoroutine()
每分钟记录一次。
六、最终验收标准
系统必须满足:
✔ 单设备离线不影响同通道 ✔ 单通道离线不影响其他通道 ✔ 设备间采集间隔 ≥10ms ✔ 数据无串流 ✔ 连续运行12小时无崩溃 ✔ 数据100%刷新 ✔ Snapshot Version 单调递增,组完成后递增 ✔ 北向发布仅由 Points Commit 触发(零侵入)
七、现行调度模型(ScanEngine,2026-07)
说明:旧版
deviceLoop/CollectionScheduler与「Channel goroutine + device loop sleep 10ms」并发模型已废弃(阶段 4 完全切换)。现行唯一采集调度内核如下;本方案验收应对照此模型,而非重新引入并发for all devices。
ScanEngine(10ms Tick)
↓ dispatch(PriorityQueue + Hard Jitter)
ExecutionLayer
├ SerialQueueManager → Modbus / DLT645 / Omron FINS 等(同通道串行,Δt≥10ms)
├ ParallelExecutor → OPC UA / BACnet IP 等(背压 512 并发 / 1000 req/s)
└ LimitedExecutor → S7 / EtherNet/IP / Profinet / IEC104 等
↓ Driver.ReadPoints + ConnectionController(超时/退避/CB)
ShadowCore.applyCollectToShadow
↓
Snapshot Bus → Points Commit → 北向复用
禁止在同通道串行协议上采用无队列的全设备并发 ReadPoints,否则易出现串流、阻塞与雪崩。并行协议亦须受 ExecutionLayer 背压与 DriverCircuitBreaker 约束。
八、回归执行计划(2026-07-04)
排期以 Week1 自动化 gate → Week2 Modbus/BACnet 联机 → Week3 12h soak 为基准;负责人待项目指派,下表「负责人」列暂用职能角色。
发布门禁分级
| 级别 | 含义 | 项 |
|---|---|---|
| BLOCK | 未通过不得发布 | B/C/E 隔离与串流;F 12h 稳态;驱动 -short 全绿;A 全量 30min 轮询 |
| WARN | 可发布但须跟踪 | G007 吞吐边界(≥950/s);G 随机异常;D 全协议复测;72h soak |
| PASS | 已闭合 | core/integration -short;Q3 benchmark;short soak 五 gate;D Modbus TCP 样本 |
建议排期
| 周期 | 目标 | 命令 / 步骤 |
|---|---|---|
| Week1(7/4–7/10) | 自动化 gate 全绿 | §五 全部命令;TestConnectionManager_RecordFailureBackoffAndDead 抖动 |
| Week2(7/11–7/17) | Modbus + BACnet 联机 | A1/B1/B2/C(Modbus+BACnet);D 全协议 PollStart;E 串流;资产见 test/manual/ |
| Week3(7/18–7/24) | OPC UA + 长跑 | A–C OPC UA 补测;F 12h(SOAK_DURATION=12h 或现场 35 台);G 异常注入;启动 72h nightly |
测试组 A–G 执行清单
| 组 | 项 | 负责人 | 前置条件 | 命令 / 步骤 | 判定 | 门禁 |
|---|---|---|---|---|---|---|
| A | 基础轮询 | QA / 现场 | 35 台模拟器在线,1s 周期 + 10ms 间隔 | 运行 30min;统计 GroupComplete / Snapshot Version++ / Commit 次数 | 全设备轮询、CPU<70%、无 panic | BLOCK |
| B | 单设备离线隔离 | QA | Modbus/BACnet/OPC UA 模拟器可断线 | B1 关 1 台 Modbus 5min;B2 关 3 Modbus + 2 BACnet + 1 OPC UA | 同通道其余正常、无阻塞、无串流 | BLOCK |
| C | 通道级隔离 | QA | 独立 BACnet 网段 | 关闭整个 BACnet 网络 10min | Modbus/OPC UA 正常;ScanEngine Tick 无 backlog | BLOCK |
| D | 10ms 间隔 | QA | 串行 + 并行协议各 ≥3 设备 | PollStart 日志 Δt≥10ms;GET /diagnostics/scan-engine lag/miss |
无 0ms 连续触发、无 CRC/粘包异常 | Modbus 样本 ✅;全协议 WARN |
| E | 数据串流 | QA | 设备 A=111、B=222 固定值 | 运行 10min,查 Points 存储 | 无交叉写入 | BLOCK |
| F | 12h 压力 | Ops | 35 台全在线 | 连续 12h;每分钟 runtime.NumGoroutine() |
内存/goroutine 不泄漏、SnapshotBus P95≤350ms | BLOCK(生产) |
| G | 随机异常 | QA | 脚本每 5min 断/恢/延迟 | 运行 2h | 无死锁/panic;恢复后采集正常 | WARN |
联机资产与参考
| 资产 | 路径 | 用途 |
|---|---|---|
| 联调脚本与样本 | test/README.md |
Modbus 从站 JSON、BACnet 抓包、IEC104 模拟器 |
| BACnet 矩阵 | test/manual/bacnet-who-is-iam-matrix.md |
Who-Is / I-Am 联机 |
| EtherNet/IP 清单 | test/manual/ethernet-ip-checklist.md |
ENIP 模拟器联调 |
| B1 10ms 样本 | B1 采集间隔核验 | D 组 Modbus TCP 已核验基准 |
| 集成压测(非 short) | go test ./internal/integration/... -run ModbusPLC -count=1 |
Modbus PLC 压力(需模拟器) |
| 长跑 soak | make test-soak(1h)/ SOAK_DURATION=72h go test -tags=soak ... |
F 组 / 阶段退出条件 |
结论
这套方案可以验证:
- ScanEngine / ExecutionLayer 架构隔离能力
- ConnectionController 调度稳定性
- 工业级可靠性
- 协议层隔离性(Serial / Parallel / Limited)
- ShadowCore 数据正确性与 Commit 发布路径
2026-07 进度摘要:2026-07-04 自动化回归已执行(见 §一、§五、§八);core/integration/short soak/Q3 PASS;驱动根包 1 用例 FAIL、G007 WARN(947/s);D 组 10ms 已有 Modbus TCP 现场样本;A–C / E–G 全量联机与 12h/72h 长跑按 §八 排期执行。