using System.Threading; using IvfTl.Hardware.HilTests.Infrastructure; using IvfTl.Hardware.Impl; using Xunit; using Xunit.Abstractions; namespace IvfTl.Hardware.HilTests { /// /// M-05 防回归:0x12 写 E方回包帧长修复为 12 后,读路径不被残留字节污染。 /// 帧长若回退为 6,写后残留字节会错位污染紧接的读 → 出现 -1/垃圾值。 /// 纯读变体:连续多轮读排气阀时间,断言全部 sane 非负。纯 0x11 读,无电机,非破坏。 /// (帧长表本身另由 ivf_tl_SerialHelper.Tests/CustomProtocolLengthTests 单测逐项锁死。) /// [Collection("HIL")] public class FrameLengthHilTests { private readonly HardwareRigFixture _rig; private readonly ITestOutputHelper _out; public FrameLengthHilTests(HardwareRigFixture rig, ITestOutputHelper o) { _rig = rig; _out = o; } [SkippableFact] public void RepeatedReads_AreClean_NoFrameCorruption() { var chamber = _rig.FirstChamberWithWells(); Skip.If(chamber == null, "无响应真舱:无硬件 / control 正占用串口 / 未连接"); const int rounds = 12; int clean = 0; SerialChannelImpl ch = null; try { ch = new SerialChannelImpl(0, chamber.Port); Assert.True(ch.Open(), $"{chamber.Port} 打开失败"); for (int r = 0; r < rounds; r++) { int v = ch.ReadOpenVentTimeWait(); if (v >= 0) clean++; else _out.WriteLine($"轮{r} 读={v}(脏/无响应)"); Thread.Sleep(80); } } finally { try { ch?.Close(); } catch { } } _out.WriteLine($"舱{chamber.HouseSn} 连续读 {rounds} 轮,干净 {clean}/{rounds}"); Assert.Equal(rounds, clean); // 帧长正确则每轮都 sane;有错位则出现 -1 } } }