- Introduced `CliTaskState` and `CliTaskInfo` classes for enhanced tracking of task states. - Added timeout handling logic to `CliRunner` with methods like `CancelUndoneTasksAsTimedOut` and state refresh. - Updated `TBF.csproj` to include new classes `CliTaskState` and `CliTaskInfo`. - Refactored test methods in `CliRunnerTest` and introduced new timeout-related tests in `CliRunnerTimeoutTest` and `CliRunnerTimeoutUnitTest`. - Standardized code formatting and added minor improvements to logging and task lifecycle management.
218 lines
9.4 KiB
C#
218 lines
9.4 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 RunMultipleTimesTestProgram_CheckParalelWork()
|
|
{
|
|
SerialPortData serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74);
|
|
|
|
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", 74);
|
|
|
|
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);
|
|
}
|
|
}
|
|
} |