tbf/TBFTests/Rig/TestMethods/iPerlCommunication/common/OptoTelegramRawTest.cs

350 lines
11 KiB
C#

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TBF.Rig.TestMethods.iPerlCommunication.common;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.parserer;
namespace TBFTests.Rig.TestMethods.iPerlCommunication.common
{
[TestClass]
public class OptoTelegramRawTest
{
private static DiagnosticLedState7Data CreateDiagnosticLedState7Data(
double volumeLiters,
double timeSeconds,
short rawFlow = 0)
{
uint rawVolumeTicks = (uint)Math.Round(volumeLiters / 0.00025);
uint timestampTicks = (uint)Math.Round(timeSeconds * 8192.0);
string[] fields =
{
"000000",
"0000",
((ushort)rawFlow).ToString("X4"),
rawVolumeTicks.ToString("X6"),
"0000",
"0000",
timestampTicks.ToString("X8"),
"00",
"00000000",
"0000",
"0000",
"0000",
"0000",
"00",
"0000",
"0000",
"00",
"00",
"00000000",
"00",
"000000",
"000000",
"0000",
"0000",
"00",
"00"
};
string rawLine = string.Join("\t", fields) + "\r\n";
return new DiagnosticLedState7Data(rawLine, fields);
}
[TestMethod]
public void UpdateFromSmart_FirstSample_ShouldInitializeFields()
{
var telegram = new OptoTelegramRaw();
var data = CreateDiagnosticLedState7Data(
volumeLiters: 2.5,
timeSeconds: 100.0);
double lastVolume = double.NaN;
double lastTimestamp = double.NaN;
telegram.UpdateFromSmart(data, counter: 7, refFlow: 1.5f, ref lastVolume, ref lastTimestamp);
Assert.AreEqual(7, telegram.Counter);
Assert.AreEqual(1.5f, telegram.RefFlow);
Assert.AreEqual(OptoTelegramFlags.OK, telegram.Flags);
Assert.AreEqual(2.5, telegram.VolumeRaw, 1e-9);
Assert.AreEqual(2.5, telegram.VolumeRawExt, 1e-9);
Assert.AreEqual(2.5, lastVolume, 1e-9);
Assert.AreEqual(100.0, telegram.Timestamp, 1e-9);
Assert.AreEqual(100.0, telegram.TimestampExt, 1e-9);
Assert.AreEqual(100.0, lastTimestamp, 1e-9);
Assert.AreNotEqual(default(DateTime), telegram.DateTime);
Assert.AreEqual(0, telegram.FlowRaw);
Assert.AreEqual(0, telegram.CheckSum);
Assert.AreEqual(0, telegram.Impedance);
Assert.AreEqual(0, telegram.EmfRaw);
Assert.AreEqual(0, telegram.MagneticFieldRaw);
}
[TestMethod]
public void UpdateFromSmart_RealDecodedSample_ShouldMapExpectedValues()
{
var telegram = new OptoTelegramRaw();
var data = CreateDiagnosticLedState7Data(
volumeLiters: 0.48025,
timeSeconds: 62727.0);
double lastVolume = double.NaN;
double lastTimestamp = double.NaN;
telegram.UpdateFromSmart(data, counter: 1, refFlow: 0.0f, ref lastVolume, ref lastTimestamp);
Assert.AreEqual(1, telegram.Counter);
Assert.AreEqual(0.0f, telegram.RefFlow);
Assert.AreEqual(OptoTelegramFlags.OK, telegram.Flags);
Assert.AreEqual(0.48025, telegram.VolumeRaw, 1e-9);
Assert.AreEqual(0.48025, telegram.VolumeRawExt, 1e-9);
Assert.AreEqual(0.48025, lastVolume, 1e-9);
Assert.AreEqual(62727.0, telegram.Timestamp, 1e-9);
Assert.AreEqual(62727.0, telegram.TimestampExt, 1e-9);
Assert.AreEqual(62727.0, lastTimestamp, 1e-9);
}
[TestMethod]
public void UpdateFromSmart_TimestampOverflow_ShouldKeepIncreasingExtendedTimestamp()
{
double lastVolumeExt = double.NaN;
double lastTimestampExt = double.NaN;
double[] times =
{
524280.0,
524287.0,
1.0,
2.0,
10.0
};
double previousExt = double.NaN;
for (int i = 0; i < times.Length; i++)
{
var telegram = new OptoTelegramRaw();
var data = CreateDiagnosticLedState7Data(1.0, times[i]);
telegram.UpdateFromSmart(data, i, 0, ref lastVolumeExt, ref lastTimestampExt);
if (!double.IsNaN(previousExt))
{
Assert.IsTrue(
telegram.TimestampExt >= previousExt,
$"Timestamp decreased at index {i}. Prev={previousExt}, Current={telegram.TimestampExt}");
}
previousExt = telegram.TimestampExt;
}
}
[TestMethod]
public void UpdateFromSmart_TimeDelta_ShouldNeverBeNegativeAcrossOverflow()
{
double lastVolumeExt = double.NaN;
double lastTimestampExt = double.NaN;
OptoTelegramRaw.TestStartTimestampDec = 524280m;
double[] times =
{
524280.0,
524287.0,
1.0,
2.0,
10.0
};
decimal previousDelta = decimal.MinValue;
for (int i = 0; i < times.Length; i++)
{
var telegram = new OptoTelegramRaw();
var data = CreateDiagnosticLedState7Data(1.0, times[i]);
telegram.UpdateFromSmart(data, i, 0, ref lastVolumeExt, ref lastTimestampExt);
decimal delta = telegram.TimeDelta();
Assert.IsTrue(delta >= 0, $"Negative TimeDelta at index {i}: {delta}");
Assert.IsTrue(delta >= previousDelta,
$"TimeDelta decreased at index {i}. Previous={previousDelta}, Current={delta}");
previousDelta = delta;
}
}
[TestMethod]
public void UpdateFromSmart_VolumeOverflow_ShouldKeepIncreasingExtendedVolume()
{
double lastVolumeExt = double.NaN;
double lastTimestampExt = double.NaN;
double volumeRange = 16777216.0 * 0.00025; // 4194.304 L
double[] volumes =
{
4194.0,
4194.25,
volumeRange + 0.25,
volumeRange + 1.0,
volumeRange + 2.0
};
double previousExt = double.NaN;
for (int i = 0; i < volumes.Length; i++)
{
var telegram = new OptoTelegramRaw();
var data = CreateDiagnosticLedState7Data(volumes[i], i);
telegram.UpdateFromSmart(data, i, 0, ref lastVolumeExt, ref lastTimestampExt);
if (!double.IsNaN(previousExt))
{
Assert.IsTrue(
telegram.VolumeRawExt >= previousExt,
$"Volume decreased at index {i}. Prev={previousExt}, Current={telegram.VolumeRawExt}");
}
previousExt = telegram.VolumeRawExt;
}
}
[TestMethod]
public void SetFlags_ShouldChangeFlags()
{
var telegram = new OptoTelegramRaw();
telegram.SetFlags(OptoTelegramFlags.SyncError);
Assert.AreEqual(OptoTelegramFlags.SyncError, telegram.Flags);
}
[TestMethod]
public void Label_ShouldReturnExpectedText()
{
var telegram = new OptoTelegramRaw();
telegram.Flags = OptoTelegramFlags.OK_TestStart;
Assert.AreEqual("#### start test ####", telegram.Label());
telegram.Flags = OptoTelegramFlags.OK_TestEnd;
Assert.AreEqual("#### end of test ####", telegram.Label());
telegram.Flags = OptoTelegramFlags.OK;
Assert.AreEqual(string.Empty, telegram.Label());
}
[TestMethod]
public void TimestampDec_ShouldConvertCorrectly()
{
var telegram = new OptoTelegramRaw
{
TimestampExt = 8192.0
};
Assert.AreEqual(8192.0m, telegram.TimestampDec());
}
[TestMethod]
public void VolumeDelta_ShouldReturnDifferenceAgainstPrevious()
{
var previous = new OptoTelegramRaw { VolumeRawExt = 1000.0 };
var current = new OptoTelegramRaw { VolumeRawExt = 2000.0 };
double scalingFactor = 2.0;
double expectedPrevious = 0.0000625 * scalingFactor * 1000.0;
double expectedCurrent = 0.0000625 * scalingFactor * 2000.0;
double expectedDelta = expectedCurrent - expectedPrevious;
Assert.AreEqual(expectedDelta, current.VolumeDelta(scalingFactor, previous), 1e-12);
}
[TestMethod]
public void UpdateFromStringDummy_InvalidLength_ShouldReturnFalse_AndSetInvalidFlag()
{
var telegram = new OptoTelegramRaw();
bool result = telegram.UpdateFromStringDummy("short");
Assert.IsFalse(result);
Assert.AreEqual(OptoTelegramFlags.InvalidTelegram, telegram.Flags);
}
[TestMethod]
public void UpdateFromStringDummy_ValidFormatButWrongChecksum_ShouldReturnFalse_AndSetInvalidFlag()
{
var telegram = new OptoTelegramRaw();
string dummy = "FFFFFE\t51EA\t0000\t65324E\t0087\tF6319DFF\t00\r\n";
bool result = telegram.UpdateFromStringDummy(dummy);
Assert.IsFalse(result);
Assert.AreEqual(OptoTelegramFlags.InvalidTelegram, telegram.Flags);
}
[TestMethod]
public void ToString_WhenSyncError_ShouldReturnSynchronizationErrorText()
{
var telegram = new OptoTelegramRaw
{
Flags = OptoTelegramFlags.SyncError
};
string text = telegram.ToString(1.0, null);
Assert.AreEqual("Sychronization error", text);
}
[TestMethod]
public void ToString_WhenInvalidTelegram_ShouldReturnInvalidTelegramText()
{
var telegram = new OptoTelegramRaw
{
Flags = OptoTelegramFlags.InvalidTelegram
};
string text = telegram.ToString(1.0, null);
Assert.AreEqual("Invalid telegram", text);
}
[TestMethod]
public void ToString_WhenOk_ShouldContainCounterAndLabel()
{
var telegram = new OptoTelegramRaw
{
Flags = OptoTelegramFlags.OK_TestStart,
DateTime = new DateTime(2024, 1, 1, 10, 11, 12, 123),
Counter = 5,
EmfRaw = 1,
MagneticFieldRaw = 2,
FlowRaw = 3,
VolumeRaw = 4,
Impedance = 5,
Timestamp = 6,
CheckSum = 7,
VolumeRawExt = 1000,
TimestampExt = 8192,
RefFlow = 1.25f
};
OptoTelegramRaw.TestStartTimestampDec = 0m;
string text = telegram.ToString(2.0, null);
Assert.IsTrue(text.Contains("5 :"), "Counter should be present in output.");
Assert.IsTrue(text.Contains("#### start test ####"), "Label should be present in output.");
}
}
}