103 lines
4.0 KiB
C#
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
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|