Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show the current status in the UI #22

Merged
merged 10 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using EulynxLive.FieldElementSubsystems.Interfaces;
using EulynxLive.Messages.Baseline4R2;
using EulynxLive.Point;
using EulynxLive.Point.Hubs;

using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -70,10 +72,12 @@ private static (EulynxLive.Point.Point point, Task pointTask, List<byte[]> recei

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

var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, connection, connectionProvider.Object, () => Task.CompletedTask);
var mockHubContext = new Mock<IHubContext<StatusHub>>();
mockHubContext.Setup(x => x.Clients.All.SendCoreAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, connection, connectionProvider.Object, mockHubContext.Object);
if (simulateTimeouts) {
point.EnableTimeoutLeft();
point.EnableTimeoutRight();
point.EnableTimeoutLeft(true);
point.EnableTimeoutRight(true);
}

async Task SimulatePoint()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using EulynxLive.FieldElementSubsystems.Interfaces;
using EulynxLive.Messages.Baseline4R2;
using EulynxLive.Point;
using EulynxLive.Point.Hubs;

using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -57,7 +59,9 @@ private static (EulynxLive.Point.Point point, Task, List<byte[]> receivedBytes)
var connection = new PointToInterlockingConnection(Mock.Of<ILogger<PointToInterlockingConnection>>(), configuration, CancellationToken.None);
connection.Connect(mockConnection.Object);

var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, connection, connectionProvider.Object, () => Task.CompletedTask);
var mockHubContext = new Mock<IHubContext<StatusHub>>();
mockHubContext.Setup(x => x.Clients.All.SendCoreAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, connection, connectionProvider.Object, mockHubContext.Object);

async Task SimulatePoint()
{
Expand Down
240 changes: 240 additions & 0 deletions src/FieldElementSubsystems.Test/Point/PointServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
using EulynxLive.FieldElementSubsystems.Interfaces;
using EulynxLive.Point;
using EulynxLive.Point.Proto;
using EulynxLive.Point.Services;

using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;

using Grpc.Core;

using Moq;

namespace FieldElementSubsystems.Test;

public class PointServiceTest()
{
[Fact]
public void TestReset()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
pointService.Reset(new Empty(), Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.Reset(), Times.Once);
}

[Fact]
public void TestScheduleTimeoutRight()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
pointService.ScheduleTimeoutRight(new EnableMovementFailedMessage() { EnableMovementFailed = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.EnableTimeoutRight(true), Times.Once);
}

[Fact]
public void TestScheduleTimeoutLeft()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
pointService.ScheduleTimeoutLeft(new EnableMovementFailedMessage() { EnableMovementFailed = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.EnableTimeoutLeft(true), Times.Once);
}

[Fact]
public async Task TestSetAbilityToMove()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
await pointService.SetAbilityToMove(new AbilityToMoveMessage() { Ability = AbilityToMove.AbleToMove }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.SetAbilityToMove(It.IsAny<AbilityToMoveMessage>()), Times.Once);
}

[Fact]
public async Task TestSendSciMessage()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
await pointService.SendSciMessage(new SciMessage() { Message = ByteString.CopyFrom(new byte[] { 0x01 }) }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.SendSciMessage(It.IsAny<SciMessage>()), Times.Once);
}

[Fact]
public async Task TestOverrideSciMessage()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.Connection.OverrideNextSciMessage(It.IsAny<byte[]>()))
.Returns(Task.FromResult(0));
var pointService = new PointService(point.Object);

// Act
await pointService.OverrideSciMessage(new SciMessage() { Message = ByteString.CopyFrom(new byte[] { 0x01 }) }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.Connection.OverrideNextSciMessage(It.IsAny<byte[]>()), Times.Once);
}

[Fact]
public void TestSchedulePreventLeftEndPosition()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
pointService.SchedulePreventLeftEndPosition(new PreventedPositionMessage() { Position = PreventedPosition.SetNoEndPosition, DegradedPosition = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.PreventLeftEndPosition(It.IsAny<PreventedPositionMessage>()), Times.Once);
}

[Fact]
public void TestSchedulePreventRightEndPosition()
{
// Arrange
var point = new Mock<IPoint>();
var pointService = new PointService(point.Object);

// Act
pointService.SchedulePreventRightEndPosition(new PreventedPositionMessage() { Position = PreventedPosition.SetNoEndPosition, DegradedPosition = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.PreventRightEndPosition(It.IsAny<PreventedPositionMessage>()), Times.Once);
}

[Fact]
public async Task TestPutIntoTrailedPosition()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.ConnectionProtocol)
.Returns(EulynxLive.FieldElementSubsystems.Configuration.ConnectionProtocol.EulynxBaseline4R1);
point.Setup(x => x.PointState)
.Returns(new GenericPointState(LastCommandedPointPosition: null,
PointPosition: GenericPointPosition.Left,
DegradedPointPosition: GenericDegradedPointPosition.NotApplicable,
AbilityToMove: GenericAbilityToMove.AbleToMove
));
var pointService = new PointService(point.Object);

// Act
await pointService.PutIntoTrailedPosition(new DegradedPositionMessage() { DegradedPosition = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.PutIntoUnintendedPosition(It.IsAny<DegradedPositionMessage>()), Times.Once);
}

[Fact]
public async Task TestPutIntoTrailedPositionThrowsIfNotSupported()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.ConnectionProtocol)
.Returns(EulynxLive.FieldElementSubsystems.Configuration.ConnectionProtocol.EulynxBaseline4R2);
point.Setup(x => x.PointState)
.Returns(new GenericPointState(LastCommandedPointPosition: null,
PointPosition: GenericPointPosition.Left,
DegradedPointPosition: GenericDegradedPointPosition.NotApplicable,
AbilityToMove: GenericAbilityToMove.AbleToMove
));
var pointService = new PointService(point.Object);

// Assert
await Assert.ThrowsAsync<RpcException>(() => pointService.PutIntoTrailedPosition(new DegradedPositionMessage() { DegradedPosition = true }, Mock.Of<ServerCallContext>()));
}

[Fact]
public async Task TestPutIntoUnintendedPosition()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.ConnectionProtocol)
.Returns(EulynxLive.FieldElementSubsystems.Configuration.ConnectionProtocol.EulynxBaseline4R2);
var pointService = new PointService(point.Object);

// Act
await pointService.PutIntoUnintendedPosition(new DegradedPositionMessage() { DegradedPosition = true }, Mock.Of<ServerCallContext>());

// Assert
point.Verify(x => x.PutIntoUnintendedPosition(It.IsAny<DegradedPositionMessage>()), Times.Once);
}

[Fact]
public async Task TestPutIntoUnintendedPositionThrowsIfNotSupported()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.ConnectionProtocol)
.Returns(EulynxLive.FieldElementSubsystems.Configuration.ConnectionProtocol.EulynxBaseline4R1);
var pointService = new PointService(point.Object);

// Assert
await Assert.ThrowsAsync<RpcException>(() => pointService.PutIntoUnintendedPosition(new DegradedPositionMessage() { DegradedPosition = true }, Mock.Of<ServerCallContext>()));
}

[Fact]
public async Task TestGetDegradedPointPosition()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.PointState)
.Returns(new GenericPointState(LastCommandedPointPosition: null,
PointPosition: GenericPointPosition.Left,
DegradedPointPosition: GenericDegradedPointPosition.NotApplicable,
AbilityToMove: GenericAbilityToMove.AbleToMove
));
var pointService = new PointService(point.Object);

// Act
var result = await pointService.GetDegradedPointPosition(new Empty(), Mock.Of<ServerCallContext>());

// Assert
Assert.Equal(PointDegradedPosition.NotApplicable, result.Position);
}

[Fact]
public async Task TestGetPointPosition()
{
// Arrange
var point = new Mock<IPoint>();
point.Setup(x => x.PointState)
.Returns(new GenericPointState(LastCommandedPointPosition: null,
PointPosition: GenericPointPosition.Left,
DegradedPointPosition: GenericDegradedPointPosition.NotApplicable,
AbilityToMove: GenericAbilityToMove.AbleToMove
));
var pointService = new PointService(point.Object);

// Act
var result = await pointService.GetPointPosition(new Empty(), Mock.Of<ServerCallContext>());

// Assert
Assert.Equal(PointPosition.Left, result.Position);
}
}
12 changes: 8 additions & 4 deletions src/FieldElementSubsystems.Test/Point/PointTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using EulynxLive.Point.Proto;
using Google.Protobuf;
using EulynxLive.Point;
using EulynxLive.Point.Hubs;
using Microsoft.AspNetCore.SignalR;

namespace FieldElementSubsystems.Test;

Expand Down Expand Up @@ -36,7 +38,9 @@
var config = configuration.GetSection("PointSettings").Get<PointConfiguration>()!;
var mockConnection = CreateDefaultMockConnection(config);

var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, mockConnection.Object, Mock.Of<IConnectionProvider>(), () => Task.CompletedTask);
var mockHubContext = new Mock<IHubContext<StatusHub>>();
mockHubContext.Setup(x => x.Clients.All.SendCoreAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
var point = new EulynxLive.Point.Point(Mock.Of<ILogger<EulynxLive.Point.Point>>(), configuration, mockConnection.Object, Mock.Of<IConnectionProvider>(), mockHubContext.Object);

async Task SimulatePoint()
{
Expand Down Expand Up @@ -93,7 +97,7 @@
.SetupSequence(m => m.ReceiveMovePointCommand(It.IsAny<CancellationToken>()))
.Returns(() =>
{
point.EnableTimeoutLeft();
point.EnableTimeoutLeft(true);
return Task.FromResult(GenericPointPosition.Left);
})
.Returns(() =>
Expand Down Expand Up @@ -121,7 +125,7 @@
.SetupSequence(m => m.ReceiveMovePointCommand(It.IsAny<CancellationToken>()))
.Returns(() =>
{
point.EnableTimeoutRight();
point.EnableTimeoutRight(true);
return Task.FromResult(GenericPointPosition.Right);
})
.Returns(() =>
Expand Down Expand Up @@ -334,7 +338,7 @@
{
DegradedPosition = simulatedDegradedPosition
};
await point.PutIntoUnintendedPosition(message);
point.PutIntoUnintendedPosition(message);

Check warning on line 341 in src/FieldElementSubsystems.Test/Point/PointTest.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

cancel.Cancel();
return await new TaskCompletionSource<GenericPointPosition>().Task;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using EulynxLive.FieldElementSubsystems.Configuration;
using Grpc.Core;
using EulynxLive.Messages.Baseline4R1;
using System.Threading.Channels;


namespace EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R1;
Expand All @@ -14,6 +15,9 @@ public class PointToInterlockingConnection : IPointToInterlockingConnection
private readonly string _localId;
private readonly string _remoteId;
public PointConfiguration Configuration { get; }

private readonly Channel<byte[]> _overrideMessages;

public CancellationToken TimeoutToken => _timeout.Token;

public IConnection? CurrentConnection { get; private set; }
Expand All @@ -37,6 +41,7 @@ public PointToInterlockingConnection(
_localId = config.LocalId;
_remoteId = config.RemoteId;
Configuration = config;
_overrideMessages = Channel.CreateUnbounded<byte[]>();
}

public void Connect(IConnection connection)
Expand Down Expand Up @@ -108,13 +113,13 @@ public async Task<GenericPointPosition> ReceiveMovePointCommand(CancellationToke

private async Task SendMessage(Message message)
{
if (CurrentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?");
await CurrentConnection.SendAsync(message.ToByteArray());
await SendMessage(message.ToByteArray());
}

private async Task SendMessage(byte[] message)
{
if (CurrentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?");
if (_overrideMessages.Reader.TryRead(out var overrideMessage)) message = overrideMessage;
await CurrentConnection.SendAsync(message);
}

Expand Down Expand Up @@ -142,6 +147,11 @@ public async Task SendSciMessage(byte[] message)
await SendMessage(message);
}

public async Task OverrideNextSciMessage(byte[] message)
{
await _overrideMessages.Writer.WriteAsync(message);
}

public async Task SendAbilityToMove(GenericPointState pointState)
{
var abilityToMove = new AbilityToMove(pointState);
Expand Down
Loading
Loading