| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- using System;
- using System.Threading;
- using IvfTl.Hardware.HilTests.Infrastructure;
- using IvfTl.Hardware.Impl;
- using Xunit;
- using Xunit.Abstractions;
- namespace IvfTl.Hardware.HilTests
- {
- /// <summary>
- /// M-01/02/03 防回归:写命令(排气阀时间/灯光亮度)真下发到下位机,读回随写变化,写后立即恢复原值(非破坏)。
- /// 安全口径:默认 Skip(零写入);仅环境变量 HIL_ALLOW_WRITE=1 才执行。全程仅 EEPROM,无电机。
- /// </summary>
- [Collection("HIL")]
- public class EepromWriteHilTests
- {
- private readonly HardwareRigFixture _rig;
- private readonly ITestOutputHelper _out;
- public EepromWriteHilTests(HardwareRigFixture rig, ITestOutputHelper o) { _rig = rig; _out = o; }
- private static bool WriteAllowed =>
- Environment.GetEnvironmentVariable("HIL_ALLOW_WRITE") == "1";
- [SkippableFact]
- public void WriteVentTime_RoundTrips_AndRestoresOriginal()
- {
- Skip.IfNot(WriteAllowed, "写路径默认关闭;设 HIL_ALLOW_WRITE=1 才跑(写后立即恢复原值)");
- RoundTrip("排气阀时间(M-01写/M-02读)",
- ch => ch.ReadOpenVentTimeWait(), (ch, v) => ch.WriteOpenVentTimeWait(v));
- }
- [SkippableFact]
- public void WriteLightBrightness_RoundTrips_AndRestoresOriginal()
- {
- Skip.IfNot(WriteAllowed, "写路径默认关闭;设 HIL_ALLOW_WRITE=1 才跑(写后立即恢复原值)");
- RoundTrip("灯光亮度(M-03写)",
- ch => ch.ReadLightBrightnessWait(), (ch, v) => ch.WriteLightBrightnessWait(v));
- }
- private void RoundTrip(string label, Func<SerialChannelImpl, int> read, Action<SerialChannelImpl, int> write)
- {
- Skip.If(_rig.FirstChamberWithWells() == null, "无响应真舱:无硬件 / control 正占用串口 / 未连接");
- // 逐舱(排除舱11)找到第一个能读到该项的真舱再验:不同舱配置不同 E方,
- // 单一固定舱可能无此项(如灯光),逐舱试避免漏验该命令(对齐原 harness 取证逻辑)。
- foreach (var chamber in _rig.Chambers)
- {
- if (chamber.HouseSn == 11) continue; // 缓冲瓶/总控,无舱室排气阀/灯光
- SerialChannelImpl ch = null;
- try
- {
- ch = new SerialChannelImpl(0, chamber.Port);
- if (!ch.Open()) continue;
- // 读前丢弃一帧 + 间隔排空(隔离任何尾噪声),拿稳定原值。
- int ReadStable()
- {
- try { read(ch); } catch { }
- Thread.Sleep(700);
- int a = read(ch);
- Thread.Sleep(700);
- return a;
- }
- int v0 = ReadStable();
- if (v0 < 0) { _out.WriteLine($"[{label}] 舱{chamber.HouseSn} 无此项(读={v0}),试下一舱"); continue; }
- _out.WriteLine($"[{label}] 舱{chamber.HouseSn} 原值 V0={v0}");
- int target = v0 + 1;
- write(ch, target); Thread.Sleep(700);
- int v1 = ReadStable();
- _out.WriteLine($"[{label}] 写 {target} 后读回={v1}");
- write(ch, v0); Thread.Sleep(700); // 恢复原值
- int v2 = ReadStable();
- _out.WriteLine($"[{label}] 写回 {v0} 后读回={v2}");
- Assert.Equal(target, v1); // 写真下发:读回随写变化
- Assert.Equal(v0, v2); // 已恢复原值:非破坏
- return; // 已在该舱取得证据
- }
- finally { try { ch?.Close(); } catch { } }
- }
- Skip.If(true, $"[{label}] 所有真舱均无此项,无法取证(非失败)");
- }
- }
- }
|