Skip to content

Commit

Permalink
Merge pull request #22 from eulynx-live/ui-status
Browse files Browse the repository at this point in the history
Show the current status in the UI
  • Loading branch information
rs22 authored Dec 18, 2023
2 parents 58962ee + ccd6230 commit 276ea83
Show file tree
Hide file tree
Showing 34 changed files with 2,063 additions and 738 deletions.
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 @@ private static (EulynxLive.Point.Point, Func<Task> simulatePoint, Mock<IPointToI
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 @@ public async Task Test_TimeoutLeft()
.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 @@ public async Task Test_TimeoutRight()
.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 @@ public async Task Test_PutIntoUnintendedPosition(bool simulatedDegradedPosition,
{
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

0 comments on commit 276ea83

Please sign in to comment.