Skip to content

Commit

Permalink
Merge pull request #17 from eulynx-live/Baseline4R2
Browse files Browse the repository at this point in the history
Add Support for EULYNX Baseline 4 Release 2 in Point Simulator
  • Loading branch information
Scretch9 authored Dec 13, 2023
2 parents 369f53d + ed571b5 commit c1d72cc
Show file tree
Hide file tree
Showing 44 changed files with 7,884 additions and 2,899 deletions.
364 changes: 364 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

138 changes: 138 additions & 0 deletions src/FieldElementSubsystems.Test/Connection/Baseline4R1Test.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2;
using EulynxLive.FieldElementSubsystems.Interfaces;
using EulynxLive.Messages.Baseline4R2;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Moq;
using PointMovePointCommand = EulynxLive.Messages.Baseline4R2.PointMovePointCommand;

public class Baseline4R2Test{

private static readonly IDictionary<string, string?> TestSettings = new Dictionary<string, string?> {
{"PointSettings:LocalId", "99W1" },
{"PointSettings:LocalRastaId", "100" },
{"PointSettings:RemoteId", "INTERLOCKING" },
{"PointSettings:RemoteEndpoint", "http://localhost:50051" },
{"PointSettings:AllPointMachinesCrucial", "false" },
{"PointSettings:SimulateRandomTimeouts", "false" },
};

private readonly IConfiguration _configuration = new ConfigurationBuilder()
.AddInMemoryCollection(TestSettings)
.Build();

[Fact]
public void Test_Connect(){
// Arrange
var mockConnection = new Mock<IConnection>();
var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), _configuration, CancellationToken.None);

// Act
connection.Connect(mockConnection.Object);

// Assert
Assert.Equal(connection.CurrentConnection, mockConnection.Object);
}

[Fact]
public async Task Test_Initialization(){
// Arrange
var mockConnection = new Mock<IConnection>();
mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray())
.ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray());
var args = new List<byte[]>();
mockConnection.Setup(x => x.SendAsync(Capture.In(args)))
.Returns(Task.FromResult(0));

var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), _configuration, CancellationToken.None);

// Act
connection.Connect(mockConnection.Object);
await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None);

// Assert
mockConnection.Verify(v => v.ReceiveAsync(It.IsAny<CancellationToken>()), Times.Exactly(2));
mockConnection.Verify(v => v.SendAsync(It.IsAny<byte[]>()), Times.Exactly(4));
Assert.Equal(new PointPdiVersionCheckMessage("99W1________________", "INTERLOCKING________", PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }).ToByteArray(), args[0]);
Assert.Equal(new PointStartInitialisationMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[1]);
Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[2]);
Assert.Equal(new PointInitialisationCompletedMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[3]);
}

[Fact]
public async Task Test_Send_Position(){
// Arrange
var mockConnection = new Mock<IConnection>();
mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray())
.ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray());
var args = new List<byte[]>();
mockConnection.Setup(x => x.SendAsync(Capture.In(args)))
.Returns(Task.FromResult(0));

var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), _configuration, CancellationToken.None);

// Act
connection.Connect(mockConnection.Object);
await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None);
await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.Right, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded});
await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded});
await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.UnintendedPosition, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded});
await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.NoEndPosition, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded});

// Assert
mockConnection.Verify(v => v.SendAsync(It.IsAny<byte[]>()), Times.Exactly(8));
Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[4]);
Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[5]);
Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[6]);
Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[7]);
}

[Fact]
public async Task Test_Receive_Position(){
// Arrange
var mockConnection = new Mock<IConnection>();
mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray())
.ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray())
.ReturnsAsync(new PointMovePointCommand("99W1", "100", PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving).ToByteArray())
.ReturnsAsync(new PointMovePointCommand("99W1", "100", PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving).ToByteArray());

var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), _configuration, CancellationToken.None);

// Act
connection.Connect(mockConnection.Object);
await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None);
var position1 = await connection.ReceivePointPosition(CancellationToken.None);
var position2 = await connection.ReceivePointPosition(CancellationToken.None);

// Assert
mockConnection.Verify(v => v.ReceiveAsync(It.IsAny<CancellationToken>()), Times.Exactly(4));
Assert.Equal(GenericPointPosition.Left, position1);
Assert.Equal(GenericPointPosition.Right, position2);
}

[Fact]
public async Task Test_TimeoutMessage(){
// Arrange
var mockConnection = new Mock<IConnection>();
mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray())
.ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray());
var args = new List<byte[]>();
mockConnection.Setup(x => x.SendAsync(Capture.In(args)))
.Returns(Task.FromResult(0));

var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), _configuration, CancellationToken.None);

// Act
connection.Connect(mockConnection.Object);
await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None);
await connection.SendTimeoutMessage();

// Assert
mockConnection.Verify(v => v.SendAsync(It.IsAny<byte[]>()), Times.Exactly(5));
Assert.Equal(new PointMovementFailedMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[4]);
}
}
5 changes: 3 additions & 2 deletions src/FieldElementSubsystems.Test/Point/PointTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ private EulynxLive.Point.Point CreateDefaultPoint(IPointToInterlockingConnection
return new(_logger, _configuration, connection ?? CreateDefaultMockConnection().Object, () => Task.CompletedTask);
}

private Mock<IPointToInterlockingConnection> CreateDefaultMockConnection() {
private static Mock<IPointToInterlockingConnection> CreateDefaultMockConnection() {
var mockConnection = new Mock<IPointToInterlockingConnection>();
mockConnection.Setup(x => x.Configuration).Returns(() => new PointConfiguration(
"99W1",
100,
"INTERLOCKING",
"http://localhost:50051",
true,
false
false,
ConnectionProtocol.EulynxBaseline4R1
));
mockConnection.Setup(x => x.TimeoutToken).Returns(() => CancellationToken.None);
mockConnection
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace EulynxLive.FieldElementSubsystems.Configuration;

public enum ConnectionProtocol {
EulynxBaseline4R1,
EulynxBaseline4R2
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ public record PointConfiguration(
string RemoteId,
string RemoteEndpoint,
bool? AllPointMachinesCrucial = null,
bool? SimulateRandomTimeouts = null
bool? SimulateRandomTimeouts = null,
ConnectionProtocol? ConnectionProtocol = null
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

namespace EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R1;

public record PointState(GenericPointState State)
public record PointState(GenericPointState State) : SpecificPointState<
PointPointPositionMessageReportedPointPosition,
PointPointPositionMessageReportedDegradedPointPosition
>(State)
{
public PointPointPositionMessageReportedPointPosition PointPosition => MapInterfacePointPositionToConcrete(State.PointPosition);
public PointPointPositionMessageReportedDegradedPointPosition DegradedPointPosition => MapInterfaceDegradedPointPositionToConcrete(State.DegradedPointPosition);

private static PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(GenericPointPosition value) => value switch
public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(GenericPointPosition value) => value switch
{
GenericPointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition,
GenericPointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition,
Expand All @@ -18,7 +18,7 @@ public record PointState(GenericPointState State)
_ => throw new NotImplementedException(),
};

private static PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(GenericDegradedPointPosition value) => value switch
public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(GenericDegradedPointPosition value) => value switch
{
GenericDegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition,
GenericDegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using EulynxLive.Messages.Baseline4R1;
using EulynxLive.FieldElementSubsystems.Interfaces;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using EulynxLive.FieldElementSubsystems.Configuration;
using EulynxLive.Messages.Baseline4R1;


namespace EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R1;
Expand All @@ -12,10 +12,8 @@ public class PointToInterlockingConnection : IPointToInterlockingConnection
private readonly ILogger _logger;
private readonly string _localId;
private readonly string _remoteId;

public PointConfiguration Configuration { get; }
public CancellationToken TimeoutToken => _timeout.Token;

IConnection? _currentConnection;
private CancellationTokenSource _timeout;
private readonly int _timeoutDuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

using EulynxLive.FieldElementSubsystems.Interfaces;
using EulynxLive.Messages.Baseline4R2;

namespace EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2;

public record PointState(GenericPointState State) : SpecificPointState<
PointPointPositionMessageReportedPointPosition,
PointPointPositionMessageReportedDegradedPointPosition
>(State)
{
public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(GenericPointPosition value) => value switch
{
GenericPointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition,
GenericPointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition,
GenericPointPosition.UnintendedPosition => PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition,
GenericPointPosition.NoEndPosition => PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition,
_ => throw new NotImplementedException(),
};

public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(GenericDegradedPointPosition value) => value switch
{
GenericDegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition,
GenericDegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition,
GenericDegradedPointPosition.NotDegraded => PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition,
GenericDegradedPointPosition.NotApplicable => PointPointPositionMessageReportedDegradedPointPosition.DegradedPointPositionIsNotApplicable,
_ => throw new NotImplementedException(),
};
}
Loading

0 comments on commit c1d72cc

Please sign in to comment.