Add parallel execution tests and improve cancellation handling in `CliRunner` - Introduced new tests (`RunMultipleTimesTestProgram_CheckParalelWork` and `RunMultipleTimesTestProgram_CheckParalelWorkCumulative`) to verify parallel execution behavior. - Enhanced `SendAsync` and `RunAndCaptureJsonAsync` methods in `CliRunner` with `CancellationToken` support for better task cancellation. - Refactored process output handling for improved clarity and robustness. - Added error handling during CLI logger initialization.
172 lines
8.7 KiB
C#
172 lines
8.7 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.IsTrue(!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.IsTrue(!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);
|
|
|
|
var 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 RunMultipleTimesTestProgram_CheckParalelWork()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData("COM3","cmdSleepTest.exe",74);
|
|
|
|
// Check if the executable exists in current directory
|
|
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.ToString("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.ToString("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 (Task<JsonDataFromPoseidon> task in cliRunner.TaskPool)
|
|
{
|
|
if (task != null)
|
|
{
|
|
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
|
Console.WriteLine($"Result: {jsonDataFromPoseidon.DeviceId}");
|
|
Assert.IsNotNull(jsonDataFromPoseidon);
|
|
}
|
|
}
|
|
|
|
// Check that the total time is greater than the sum of the individual times
|
|
Assert.IsTrue((cliRunner.TaskPool.Count*OneEndTime.Ticks) > delta.Ticks);
|
|
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task RunMultipleTimesTestProgram_CheckParalelWorkCumulative()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData("COM3","cmdSleepTest.exe",74);
|
|
|
|
// Check if the executable exists in current directory
|
|
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.ToString("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);
|
|
}
|
|
}
|
|
|
|
// Wait for ALL tasks from ALL runners
|
|
var allTasks = cliRunnerList.SelectMany(r => r.TaskPool).ToArray();
|
|
await Task.WhenAll(allTasks);
|
|
|
|
DateTime EndTime = DateTime.Now;
|
|
Console.WriteLine($"End Time Loop: {EndTime.ToString("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 (Task<JsonDataFromPoseidon> task in cliRunnerList[iCliRunner].TaskPool)
|
|
{
|
|
if (task != null)
|
|
{
|
|
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
|
results += ($" ID: {jsonDataFromPoseidon.DeviceId}");
|
|
Assert.IsNotNull(jsonDataFromPoseidon);
|
|
}
|
|
}
|
|
Console.WriteLine(results);
|
|
}
|
|
|
|
// Check that the total time is greater than the sum of the individual times
|
|
Assert.IsTrue((cliRunnerList.Count*OneEndTime.Ticks) > delta.Ticks);
|
|
}
|
|
}
|
|
} |