96 lines
3.0 KiB
C#
96 lines
3.0 KiB
C#
using StandardScene.Magnetic.Protocol;
|
|
using StandardScene.Magnetic.Tests.TestHelpers;
|
|
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using Xunit;
|
|
|
|
namespace StandardScene.Magnetic.Tests.Protocol
|
|
{
|
|
public sealed class Fass2UdpHubMultiCarTests : IDisposable
|
|
{
|
|
private readonly int _hubPort;
|
|
private readonly TestUdpCar _car1;
|
|
private readonly TestUdpCar _car2;
|
|
|
|
public Fass2UdpHubMultiCarTests()
|
|
{
|
|
_hubPort = AllocateUdpPort();
|
|
_car1 = new TestUdpCar(1, AllocateUdpPort());
|
|
_car2 = new TestUdpCar(2, AllocateUdpPort());
|
|
|
|
Fass2UdpHub.Register(_car1);
|
|
Fass2UdpHub.Register(_car2);
|
|
Fass2UdpHub.EnsureStarted(_hubPort);
|
|
Thread.Sleep(100);
|
|
}
|
|
|
|
[Fact]
|
|
public void Hub_RoutesStateToRegisteredCar_AndRepliesWith0x10()
|
|
{
|
|
SendState(_car1.VehicleCode, 2, 10, 100);
|
|
var ack1 = _car1.WaitForAck();
|
|
Assert.NotNull(ack1);
|
|
Assert.Equal(Fass2Protocol.ControlFrameLength, ack1.Length);
|
|
Assert.Equal(Fass2Protocol.CmdStateResponse, ack1[1]);
|
|
Assert.Equal(0x01, ack1[2]);
|
|
Assert.Single(_car1.Reports);
|
|
Assert.Equal((ushort)10, _car1.Reports[0].Node.Node);
|
|
Assert.Empty(_car2.Reports);
|
|
}
|
|
|
|
[Fact]
|
|
public void Hub_DispatchesMultipleCarsIndependently()
|
|
{
|
|
SendState(1, 1, 11, 201);
|
|
SendState(2, 2, 22, 202);
|
|
|
|
Assert.NotNull(_car1.WaitForAck());
|
|
Assert.NotNull(_car2.WaitForAck());
|
|
|
|
Assert.Single(_car1.Reports);
|
|
Assert.Single(_car2.Reports);
|
|
Assert.Equal((ushort)11, _car1.Reports[0].Node.Node);
|
|
Assert.Equal((ushort)22, _car2.Reports[0].Node.Node);
|
|
Assert.Equal((ulong)201, _car1.Reports[0].Task);
|
|
Assert.Equal((ulong)202, _car2.Reports[0].Task);
|
|
}
|
|
|
|
[Fact]
|
|
public void Hub_IgnoresUnregisteredCarCode()
|
|
{
|
|
SendState(99, 2, 30, 0);
|
|
Thread.Sleep(300);
|
|
Assert.Empty(_car1.Reports);
|
|
Assert.Empty(_car2.Reports);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Fass2UdpHub.Unregister(_car1);
|
|
Fass2UdpHub.Unregister(_car2);
|
|
Fass2UdpHub.Stop();
|
|
_car1.Dispose();
|
|
_car2.Dispose();
|
|
}
|
|
|
|
private void SendState(ushort carCode, byte state, ushort nodeId, ulong taskId)
|
|
{
|
|
var frame = Fass2TestFrameBuilder.BuildStateFrame(carCode, state, nodeId, taskId);
|
|
using var sender = new UdpClient();
|
|
sender.Send(frame, frame.Length, new IPEndPoint(IPAddress.Loopback, _hubPort));
|
|
Thread.Sleep(80);
|
|
}
|
|
|
|
private static int AllocateUdpPort()
|
|
{
|
|
var listener = new TcpListener(IPAddress.Loopback, 0);
|
|
listener.Start();
|
|
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
|
listener.Stop();
|
|
return port;
|
|
}
|
|
}
|
|
}
|