130 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Exchanger.Hardware.Abstractions;
using Exchanger.Hardware.PeripheryController;
using NUnit.Framework;
namespace Exchanger.HardwareTests;
[TestFixture]
[NonParallelizable]
[Category("HardwareSafe")]
public sealed class BoardSafeTests
{
[Test]
public void TransportAndHandshake_ReachReadyAndCloseCleanly()
{
BoardTestConfiguration configuration = BoardTestConfiguration.RequireSafeTests();
using var session = new BoardTestSession(configuration);
session.ConnectAndAuthorize();
using (Assert.EnterMultipleScope())
{
Assert.That(session.Port.IsConnected, Is.True);
Assert.That(session.Controller.AuthenticationState, Is.EqualTo(ControllerAuthenticationState.Ready));
Assert.That(session.Controller.ConnectionState, Is.EqualTo(MachineConnectionState.Ready));
Assert.That(session.ConnectionStates, Does.Contain(MachineConnectionState.Authenticating));
Assert.That(session.ConnectionStates, Does.Contain(MachineConnectionState.Ready));
}
session.DisconnectAndWait();
Assert.That(session.Port.IsConnected, Is.False);
}
[Test]
public void DigitalInputs_QueryReturnsDocumentedTypedFrame()
{
BoardTestConfiguration configuration = BoardTestConfiguration.RequireSafeTests();
using var session = new BoardTestSession(configuration);
session.ConnectAndAuthorize();
ObservedBoardMessage response = session.SendAndWaitForMessage(
PeripheryProtocolCommands.QueryDigitalInputs,
message => message.Kind == PeripheryMessageKind.DigitalInputs,
"На команду 91 не получен документированный кадр INPUT<0..67108863>.");
Assert.That(response.NumericValue, Is.InRange(0, 67_108_863));
}
[Test]
public void Hopper1StockInput_UsesConfiguredBinaryPolarity()
{
BoardTestConfiguration configuration = BoardTestConfiguration.RequireSafeTests();
if (configuration.StockSensorInputIndex < 0)
{
Assert.Ignore("Проверка IN1 отключена параметром StockInput=-1.");
}
using var session = new BoardTestSession(configuration);
session.ConnectAndAuthorize();
ObservedBoardMessage response = session.SendAndWaitForMessage(
PeripheryProtocolCommands.QueryDigitalInputs,
message => message.Kind == PeripheryMessageKind.DigitalInputs,
"На команду 91 не получен снимок входов для проверки IN1.");
session.PumpOnce();
bool inputHigh = (response.NumericValue & (1 << configuration.StockSensorInputIndex)) != 0;
MachineStockLevel expected = inputHigh == configuration.StockLowWhenInputHigh
? MachineStockLevel.Low
: MachineStockLevel.Enough;
Assert.That(session.Controller.StockLevel, Is.EqualTo(expected));
TestContext.Progress.WriteLine($"IN{configuration.StockSensorInputIndex}: состояние запаса {expected}.");
}
[TestCase(PeripheryProtocolCommands.QueryCoinAcceptorStatus, TestName = "Status_CoinAcceptor_ReturnsFrame")]
[TestCase(PeripheryProtocolCommands.QueryBillAcceptorStatus, TestName = "Status_BillAcceptor_ReturnsFrame")]
[TestCase(PeripheryProtocolCommands.QueryCashlessStatus, TestName = "Status_Cashless_ReturnsFrame")]
[TestCase(PeripheryProtocolCommands.QueryHopper1Credit, TestName = "Status_Hopper1Credit_ReturnsFrame")]
[TestCase(PeripheryProtocolCommands.QueryControllerStatus, TestName = "Status_Controller_ReturnsFrame")]
public void StatusQuery_ReturnsNonHandshakeFrame(string command)
{
BoardTestConfiguration configuration = BoardTestConfiguration.RequireSafeTests();
using var session = new BoardTestSession(configuration);
session.ConnectAndAuthorize();
ObservedBoardMessage response = session.SendAndWaitForMessage(
command,
message => message.Kind is PeripheryMessageKind.Unknown
or PeripheryMessageKind.Hopper1Credit
or PeripheryMessageKind.ControllerError
or PeripheryMessageKind.TransportError,
$"Контроллер не вернул кадр на безопасный status-запрос {command}.");
using (Assert.EnterMultipleScope())
{
Assert.That(response.FrameLength, Is.GreaterThan(0));
Assert.That(response.Kind, Is.Not.EqualTo(PeripheryMessageKind.ControllerError));
Assert.That(response.Kind, Is.Not.EqualTo(PeripheryMessageKind.TransportError));
}
TestContext.Progress.WriteLine($"Status-запрос {command}: получен кадр категории {response.Kind}, длина скрыта из отчёта протокола.");
}
[Test]
public void ReconnectCycles_ReauthorizeExactlyOncePerCycle()
{
BoardTestConfiguration configuration = BoardTestConfiguration.RequireSafeTests();
using var session = new BoardTestSession(configuration);
for (int cycle = 1; cycle <= configuration.ReconnectCycles; cycle++)
{
TestContext.Progress.WriteLine($"Цикл переподключения {cycle}/{configuration.ReconnectCycles}.");
session.ConnectAndAuthorize();
session.DisconnectAndWait();
}
using (Assert.EnterMultipleScope())
{
Assert.That(
session.ConnectionStates.Count(state => state == MachineConnectionState.Authenticating),
Is.EqualTo(configuration.ReconnectCycles));
Assert.That(
session.ConnectionStates.Count(state => state == MachineConnectionState.Ready),
Is.EqualTo(configuration.ReconnectCycles));
Assert.That(
session.ConnectionStates.Count(state => state == MachineConnectionState.Disconnected),
Is.EqualTo(configuration.ReconnectCycles));
}
}
}