- restore the Morrisville release version metadata - add end-to-end logs for CLI execution, reader state, parsed results, and UI updates - prevent completed Poseidon reads from being started repeatedly in a cycle - use a fixed CLI directory and reliable working directory
462 lines
18 KiB
C#
462 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using JetBrains.Annotations;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
|
|
|
|
namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
|
|
{
|
|
[TestClass]
|
|
[TestSubject(typeof(CliRunner))]
|
|
public class CliRunnerTest
|
|
{
|
|
[TestMethod]
|
|
public void ExtractJson_Test()
|
|
{
|
|
string allOutput = " {\n \"DeviceId\": \"1000000267\"\n}\n";
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
Assert.IsFalse(string.IsNullOrEmpty(json));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ExtractJson_Test2()
|
|
{
|
|
string allOutput =
|
|
"{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
Assert.IsFalse(string.IsNullOrEmpty(json));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TryJsonStringDeserialize_Test()
|
|
{
|
|
string allOutput =
|
|
"{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
|
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
bool ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
|
|
|
Assert.IsTrue(ok, "Deserialization failed");
|
|
Assert.IsNotNull(dto);
|
|
Assert.AreEqual("1000000267", dto.DeviceId);
|
|
Assert.AreEqual("0003292.1", dto.Reading);
|
|
Assert.AreEqual("000329218", dto.Reading_Totalizer);
|
|
Assert.AreEqual(true, dto.NfcTagDetected);
|
|
Assert.AreEqual("74", dto.ProductType);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_NewDefaults_ShouldUsePoseidonMthTimeout10()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"HalCli.exe",
|
|
SerialPortData.MeterProduct.Poseidon);
|
|
|
|
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams);
|
|
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation readall",
|
|
args);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_HarryHat_ShouldUseHarry()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"HalCli.exe",
|
|
SerialPortData.MeterProduct.Poseidon,
|
|
SerialPortData.HatType.Harry,
|
|
30);
|
|
|
|
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.DeviceId);
|
|
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat harry --timeout 30 --operation read --parameter DeviceId",
|
|
args);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_OldConstructor_ShouldKeepOldMeterType()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData("COM3", "HalCli.exe", 74);
|
|
|
|
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams);
|
|
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation readall",
|
|
args);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_NewMeterTypes_ShouldGenerateCorrectMeterNames()
|
|
{
|
|
var testCases = new[]
|
|
{
|
|
new { Meter = SerialPortData.MeterProduct.Poseidon, Expected = "74" },
|
|
new { Meter = SerialPortData.MeterProduct.Ally, Expected = "ally" },
|
|
new { Meter = SerialPortData.MeterProduct.IperlPlus, Expected = "iperlplus" },
|
|
new { Meter = SerialPortData.MeterProduct.IperlLegacy, Expected = "iperllegacy" }
|
|
};
|
|
|
|
foreach (var testCase in testCases)
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"HalCli.exe",
|
|
testCase.Meter);
|
|
|
|
string args = serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams);
|
|
|
|
StringAssert.Contains(args, $"-m {testCase.Expected}");
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_ReadMacros_ShouldGenerateCorrectOperations()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"HalCliDemo.exe",
|
|
SerialPortData.MeterProduct.Poseidon);
|
|
|
|
serialPort.Macro = "readmacro1";
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro1",
|
|
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro1));
|
|
|
|
serialPort.Macro = "readmacro2";
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro2",
|
|
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro2));
|
|
|
|
serialPort.Macro = "readmacro3";
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation readmacro3",
|
|
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.ReadMacro3));
|
|
|
|
serialPort.Macro = "xxx";
|
|
Assert.AreEqual(
|
|
"-p COM3 -m 74 --hat mth --timeout 10 --operation xxx",
|
|
serialPort.DefaultArgSettings(SerialPortData.EMeterArg.AllParams));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SerialPortData_CliPath_ShouldAlwaysUseFixedCliDirectory()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
@"D:\obsolete\HatCliDemo.exe",
|
|
SerialPortData.MeterProduct.Poseidon);
|
|
|
|
Assert.AreEqual(
|
|
@"C:\TBF\Cli\HatCliDemo.exe",
|
|
serialPort.SerialPortCmdClientPath);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void RunMultipleTimesTestProgram_CheckParalelWork()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"cmdSleepTest.exe",
|
|
SerialPortData.MeterProduct.Poseidon,
|
|
SerialPortData.HatType.Mth,
|
|
10);
|
|
|
|
if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath))
|
|
{
|
|
Assert.Inconclusive(
|
|
$"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
|
return;
|
|
}
|
|
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
|
|
CliRunner cliRunnerOne = new CliRunner(false);
|
|
DateTime startTime = DateTime.Now;
|
|
|
|
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
|
serialPort,
|
|
SerialPortData.EMeterArg.AllParams);
|
|
|
|
cliRunnerOne.WaitAll();
|
|
|
|
TimeSpan oneEndTime = DateTime.Now - startTime;
|
|
|
|
startTime = DateTime.Now;
|
|
Console.WriteLine($"Start Time Loop: {startTime:yyyy-MM-dd HH:mm:ss}");
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
|
serialPort,
|
|
SerialPortData.EMeterArg.AllParams);
|
|
}
|
|
|
|
cliRunner.WaitAll();
|
|
|
|
DateTime endTime = DateTime.Now;
|
|
Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}");
|
|
|
|
TimeSpan delta = endTime - startTime;
|
|
|
|
Console.WriteLine(
|
|
$"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " +
|
|
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
|
|
|
Console.WriteLine($"Total tasks: {cliRunner.TaskPool.Count}");
|
|
|
|
foreach (CliTaskInfo taskInfo in cliRunner.TaskPool)
|
|
{
|
|
Assert.IsNotNull(taskInfo);
|
|
Assert.IsNotNull(taskInfo.Task);
|
|
|
|
if (taskInfo.UseResult)
|
|
{
|
|
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
|
Assert.IsNotNull(task, "Expected Task<JsonDataFromPoseidon>.");
|
|
|
|
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
|
|
|
Console.WriteLine($"Result: {jsonDataFromPoseidon?.DeviceId}");
|
|
|
|
Assert.IsNotNull(jsonDataFromPoseidon);
|
|
}
|
|
else
|
|
{
|
|
Assert.Fail(
|
|
$"Task did not complete successfully. State={taskInfo.State}, Status={taskInfo.Task.Status}");
|
|
}
|
|
}
|
|
|
|
Assert.IsTrue((cliRunner.TaskPool.Count * oneEndTime.Ticks) > delta.Ticks);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task RunMultipleTimesTestProgram_CheckParalelWorkCumulative()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData(
|
|
"COM3",
|
|
"cmdSleepTest.exe",
|
|
SerialPortData.MeterProduct.Poseidon,
|
|
SerialPortData.HatType.Mth,
|
|
10);
|
|
|
|
if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath))
|
|
{
|
|
Assert.Inconclusive(
|
|
$"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
|
return;
|
|
}
|
|
|
|
List<CliRunner> cliRunnerList = new List<CliRunner>();
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
cliRunnerList.Add(new CliRunner(false));
|
|
}
|
|
|
|
CliRunner cliRunnerOne = new CliRunner(false);
|
|
DateTime startTime = DateTime.Now;
|
|
|
|
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
|
serialPort,
|
|
SerialPortData.EMeterArg.AllParams);
|
|
|
|
cliRunnerOne.WaitAll();
|
|
|
|
TimeSpan oneEndTime = DateTime.Now - startTime;
|
|
|
|
startTime = DateTime.Now;
|
|
Console.WriteLine($"Start Time Loop: {startTime:yyyy-MM-dd HH:mm:ss}");
|
|
|
|
for (int iCliRunner = 0; iCliRunner < cliRunnerList.Count; iCliRunner++)
|
|
{
|
|
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
|
serialPort,
|
|
SerialPortData.EMeterArg.AllParams);
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
|
serialPort,
|
|
SerialPortData.EMeterArg.AllParams);
|
|
}
|
|
}
|
|
|
|
Task[] allTasks = cliRunnerList
|
|
.SelectMany(r => r.TaskPool)
|
|
.Where(ti => ti != null && ti.Task != null)
|
|
.Select(ti => ti.Task)
|
|
.ToArray();
|
|
|
|
await Task.WhenAll(allTasks);
|
|
|
|
DateTime endTime = DateTime.Now;
|
|
Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}");
|
|
|
|
TimeSpan delta = endTime - startTime;
|
|
|
|
Console.WriteLine(
|
|
$"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " +
|
|
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
|
|
|
Console.WriteLine($"Total tasks: {cliRunnerList.Sum(runner => runner.TaskPool.Count)}");
|
|
|
|
for (int iCliRunner = 0; iCliRunner < cliRunnerList.Count; iCliRunner++)
|
|
{
|
|
string results = $"iCliRunner: {iCliRunner}";
|
|
|
|
foreach (CliTaskInfo taskInfo in cliRunnerList[iCliRunner].TaskPool)
|
|
{
|
|
Assert.IsNotNull(taskInfo);
|
|
Assert.IsNotNull(taskInfo.Task);
|
|
|
|
if (taskInfo.UseResult)
|
|
{
|
|
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
|
Assert.IsNotNull(task, "Expected Task<JsonDataFromPoseidon>.");
|
|
|
|
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
|
|
|
results += $" ID: {jsonDataFromPoseidon?.DeviceId}";
|
|
|
|
Assert.IsNotNull(jsonDataFromPoseidon);
|
|
}
|
|
else
|
|
{
|
|
Assert.Fail(
|
|
$"Task did not complete successfully. Runner={iCliRunner}, State={taskInfo.State}, Status={taskInfo.Task.Status}");
|
|
}
|
|
}
|
|
|
|
Console.WriteLine(results);
|
|
}
|
|
|
|
Assert.IsTrue((cliRunnerList.Count * oneEndTime.Ticks) > delta.Ticks);
|
|
}
|
|
|
|
|
|
[TestMethod]
|
|
public void TryJsonStringDeserialize_ReadMacro1_Test()
|
|
{
|
|
string allOutput = @"{
|
|
""DeviceId"": ""1000000176"",
|
|
""MeterState"": ""MB012501A177"",
|
|
""CalibrationFactor"": ""3250"",
|
|
""Reading_Units"": ""0"",
|
|
""Reading_Totalizer"": 0,
|
|
""Reading_FlowRate"": 0,
|
|
""Reading_FlowDirection"": 0,
|
|
""Reading_Digits"": 0,
|
|
""Reading_Shift"": 0,
|
|
""Reading_Resolution"": 0,
|
|
""OpticalDataMode"": ""199"",
|
|
""MeterSize"": ""3"",
|
|
""ManufactureDate"": ""2026/04/20 00:56:00"",
|
|
""ProductType"": ""74"",
|
|
""ProductTypeVersion"": ""B1.0.29"",
|
|
""CliVersion"": ""2.0.0.0"",
|
|
""ReadingComplete"": true,
|
|
""NfcTagDetected"": true
|
|
}";
|
|
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
bool ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.IsNotNull(dto);
|
|
Assert.AreEqual("1000000176", dto.DeviceId);
|
|
Assert.AreEqual("MB012501A177", dto.MeterState);
|
|
Assert.AreEqual("3250", dto.CalibrationFactor);
|
|
Assert.AreEqual("199", dto.OpticalDataMode);
|
|
Assert.AreEqual("3", dto.MeterSize);
|
|
Assert.AreEqual("74", dto.ProductType);
|
|
Assert.AreEqual("2.0.0.0", dto.CliVersion);
|
|
Assert.IsTrue(dto.ReadingComplete);
|
|
Assert.IsTrue(dto.NfcTagDetected);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TryJsonStringDeserialize_ReadMacro2_Test()
|
|
{
|
|
string allOutput = @"{
|
|
""DeviceId"": ""1000000176"",
|
|
""Reading_Units"": ""0"",
|
|
""Reading_Totalizer"": 0,
|
|
""Reading_FlowRate"": 0,
|
|
""Reading_FlowDirection"": 0,
|
|
""Reading_Digits"": 0,
|
|
""Reading_Shift"": 0,
|
|
""Reading_Resolution"": 0,
|
|
""ProductType"": ""74"",
|
|
""ProductTypeVersion"": ""B1.0.29"",
|
|
""CliVersion"": ""2.0.0.0"",
|
|
""ReadingComplete"": true,
|
|
""NfcTagDetected"": true
|
|
}";
|
|
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
bool ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.IsNotNull(dto);
|
|
Assert.AreEqual("1000000176", dto.DeviceId);
|
|
Assert.AreEqual("0", dto.Reading_Units);
|
|
Assert.AreEqual("74", dto.ProductType);
|
|
Assert.AreEqual("B1.0.29", dto.ProductTypeVersion);
|
|
Assert.AreEqual("2.0.0.0", dto.CliVersion);
|
|
Assert.IsTrue(dto.ReadingComplete);
|
|
Assert.IsTrue(dto.NfcTagDetected);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TryJsonStringDeserialize_ReadMacro3_Test()
|
|
{
|
|
string allOutput = @"{
|
|
""DeviceId"": ""1000000176"",
|
|
""Reading_Units"": ""0"",
|
|
""Reading_Totalizer"": 0,
|
|
""Reading_FlowRate"": 0,
|
|
""Reading_FlowDirection"": 0,
|
|
""Reading_Digits"": 0,
|
|
""Reading_Shift"": 0,
|
|
""Reading_Resolution"": 0,
|
|
""CliVersion"": ""2.0.0.0"",
|
|
""ReadingComplete"": true,
|
|
""NfcTagDetected"": true
|
|
}";
|
|
|
|
CliRunner cliRunner = new CliRunner(false);
|
|
string json = cliRunner.ExtractJson(allOutput);
|
|
|
|
bool ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.IsNotNull(dto);
|
|
Assert.AreEqual("1000000176", dto.DeviceId);
|
|
Assert.AreEqual("0", dto.Reading_Units);
|
|
Assert.AreEqual("2.0.0.0", dto.CliVersion);
|
|
Assert.IsTrue(dto.ReadingComplete);
|
|
Assert.IsTrue(dto.NfcTagDetected);
|
|
}
|
|
|
|
}
|
|
}
|