Files

103 lines
4.0 KiB
C#

using StandardScene.Magnetic.Protocol;
using StandardScene.Magnetic.Tasking;
using System.Collections.Generic;
using Xunit;
namespace StandardScene.Magnetic.Tests.Tasking
{
public class Fass2ControlStopStateMachineTests
{
[Fact]
public void ControlStop_TruncatesWindow_WaitsOccupancy_ThenReleases()
{
Fass2NodeMessage[] lastWindow = null;
Fass2NodeMessage lastPatch = null;
var canRelease = false;
var nodes = new List<Fass2NodeMessage>
{
new Fass2NodeMessage { Node = 1, StartStop = Fass2TaskBuilder.StartStopPass, Distance = 100 },
new Fass2NodeMessage { Node = 2, StartStop = Fass2TaskBuilder.StartStopControlStop },
new Fass2NodeMessage { Node = 3, StartStop = Fass2TaskBuilder.StartStopPass }
};
var plan = new Fass2TaskPlan
{
StartSiteId = 10,
GoalSiteId = 12,
SiteIds = new List<int>(),
Nodes = nodes,
FieldsSignature = "keep"
};
var machine = new Fass2TaskStateMachine(new Fass2TaskCallbacks
{
BuildPlan = (_, __, ___) => plan,
SendNodes = (window, _) => lastWindow = window,
SendAction = (patch, _) => lastPatch = patch,
SendControl = (_, __) => { },
ResolveNodeId = id => (ushort)id,
AllocateTaskId = () => 1UL,
AllocateActionId = () => 9UL,
CheckControlRelease = _ => new Fass2ControlReleaseCheck
{
CanRelease = canRelease,
AreaId = "DockA",
Capacity = 1,
OthersInArea = canRelease ? 0 : 1,
ReleaseStartStop = Fass2TaskBuilder.StartStopControlStart,
Reason = canRelease ? "area clear" : "area occupied"
}
})
{
StartBeforeMove = false,
LockCount = 4,
ResendIntervalMs = 60_000,
ActionRetryIntervalMs = 0
};
machine.Begin(10, 12);
machine.Tick(Report(1, moving: true, startStop: 1));
Assert.Equal(Fass2TaskPhase.Moving, machine.Context.Phase);
Assert.NotNull(lastWindow);
Assert.Equal(2, lastWindow.Length);
Assert.Equal(Fass2TaskBuilder.StartStopControlStop, lastWindow[1].StartStop);
machine.Tick(Report(2, moving: false, startStop: 12));
Assert.Equal(Fass2TaskPhase.AtStation, machine.Context.Phase);
Assert.Equal(1, machine.Context.CurrentIndex);
lastPatch = null;
machine.Tick(Report(2, moving: false, startStop: 12));
Assert.True(machine.Context.WaitingForRelease);
Assert.Null(lastPatch);
Assert.Equal(-1, machine.Context.ControlReleasedIndex);
canRelease = true;
machine.Tick(Report(2, moving: false, startStop: 12));
Assert.NotNull(lastPatch);
Assert.Equal(Fass2TaskBuilder.StartStopControlStart, lastPatch.StartStop);
Assert.Equal(1, machine.Context.ControlReleasedIndex);
Assert.Equal(Fass2TaskBuilder.StartStopControlStart, nodes[1].StartStop);
Assert.True(lastWindow.Length >= 2);
Assert.Equal((ushort)3, lastWindow[lastWindow.Length - 1].Node);
machine.Tick(Report(2, moving: false, startStop: 11));
Assert.Equal(Fass2TaskPhase.AtStation, machine.Context.Phase);
Assert.Equal(1, machine.Context.CurrentIndex);
}
private static Fass2StateReport Report(ushort node, bool moving, byte startStop)
{
return new Fass2StateReport
{
State = (byte)(moving ? 1 : 2),
Node = new Fass2NodeMessage
{
Node = node,
StartStop = startStop
}
};
}
}
}