test(javaTest): require all history tasks to complete
This commit is contained in:
@@ -90,26 +90,33 @@ public final class HistoricalDispatchSimulator {
|
||||
clearanceMoves, executions, terminal, planner, assignment, plc,
|
||||
reservations, events);
|
||||
Set<String> traversedEdges = new LinkedHashSet<String>();
|
||||
advanceClearanceMoves(tick, now, input, config, vehicles, clearanceMoves,
|
||||
ClearanceProgress clearanceProgress = advanceClearanceMoves(
|
||||
tick, now, input, config, vehicles, clearanceMoves,
|
||||
ledger, plc, events, traversedEdges);
|
||||
advanceActiveTasks(tick, now, input, config, queue, vehicles,
|
||||
boolean businessProgress = advanceActiveTasks(
|
||||
tick, now, input, config, queue, vehicles,
|
||||
active, executions, terminal, planner, ledger, plc, archive, wms,
|
||||
invariants, reservations, clearanceMoves, clearancePlanner,
|
||||
events, traversedEdges);
|
||||
verifyLedger(ledger, invariants);
|
||||
|
||||
if (watchdog.observe(terminal.size())) {
|
||||
if (watchdog.observe(terminal.size(),
|
||||
businessProgress || clearanceProgress.moved,
|
||||
clearanceProgress.completed)) {
|
||||
invariants.deadlock();
|
||||
snapshotWaiting(queue, active, executions, terminal, plc,
|
||||
"DEADLOCK_TIMEOUT", now);
|
||||
break;
|
||||
throw new IllegalStateException("simulation made no physical progress at tick "
|
||||
+ tick + ", terminal=" + terminal.size()
|
||||
+ ", queued=" + queue.size() + ", active=" + active.keySet()
|
||||
+ ", clearance=" + clearanceMoves.keySet());
|
||||
}
|
||||
now += STEP_MILLIS;
|
||||
tick++;
|
||||
}
|
||||
if (terminal.size() < expected) {
|
||||
snapshotWaiting(queue, active, executions, terminal, plc,
|
||||
"TICK_LIMIT", now);
|
||||
throw new IllegalStateException("simulation tick limit reached: tick=" + tick
|
||||
+ ", terminal=" + terminal.size() + ", expected=" + expected
|
||||
+ ", queued=" + queue.size() + ", active=" + active.keySet()
|
||||
+ ", clearance=" + clearanceMoves.keySet());
|
||||
}
|
||||
|
||||
List<SimulationTaskResult> results = new ArrayList<SimulationTaskResult>(terminal.values());
|
||||
@@ -212,7 +219,6 @@ public final class HistoricalDispatchSimulator {
|
||||
terminal.put(task.getSimulationTaskId(), result(executions.get(
|
||||
task.getSimulationTaskId()), SimulationTaskStatus.FAILED,
|
||||
"NO_ROUTE", plc, now));
|
||||
progress = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -398,7 +404,6 @@ public final class HistoricalDispatchSimulator {
|
||||
current.execution.task.getSimulationTaskId(), vehicleId,
|
||||
"RETRY_EXHAUSTED_REDISPATCH", from, to));
|
||||
}
|
||||
progress = true;
|
||||
continue;
|
||||
}
|
||||
Site nextSite = input.getGridMap().getSite(to);
|
||||
@@ -421,7 +426,7 @@ public final class HistoricalDispatchSimulator {
|
||||
return progress;
|
||||
}
|
||||
|
||||
private void advanceClearanceMoves(long tick, long now,
|
||||
private ClearanceProgress advanceClearanceMoves(long tick, long now,
|
||||
HistoricalSimulationInput input,
|
||||
SimulationConfig config,
|
||||
Map<String, SimulatedVehicleRuntime> vehicles,
|
||||
@@ -430,6 +435,8 @@ public final class HistoricalDispatchSimulator {
|
||||
SimulatedPlcGateway plc,
|
||||
List<SimulationTickEvent> events,
|
||||
Set<String> traversedEdges) {
|
||||
boolean moved = false;
|
||||
boolean completed = false;
|
||||
List<String> vehicleIds = new ArrayList<String>(clearanceMoves.keySet());
|
||||
Collections.sort(vehicleIds);
|
||||
for (String vehicleId : vehicleIds) {
|
||||
@@ -495,15 +502,18 @@ public final class HistoricalDispatchSimulator {
|
||||
ledger.release(vehicleId, Arrays.asList(ResourceKey.node(from), edge));
|
||||
traversedEdges.add(direction);
|
||||
clearance.moved();
|
||||
moved = true;
|
||||
events.add(event(tick, now, "CLEARANCE_MOVE", clearance.getOwnerTaskId(),
|
||||
vehicleId, "ACK", from, to));
|
||||
if (clearance.isComplete()) {
|
||||
clearanceMoves.remove(vehicleId);
|
||||
completed = true;
|
||||
events.add(event(tick, now, "CLEARANCE_COMPLETE",
|
||||
clearance.getOwnerTaskId(), vehicleId, "ROUTE_CLEARED",
|
||||
to, to));
|
||||
}
|
||||
}
|
||||
return new ClearanceProgress(moved, completed);
|
||||
}
|
||||
|
||||
private boolean planClearanceForIdleBlockers(
|
||||
@@ -714,4 +724,14 @@ public final class HistoricalDispatchSimulator {
|
||||
this.route = Collections.unmodifiableList(new ArrayList<String>(route));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClearanceProgress {
|
||||
private final boolean moved;
|
||||
private final boolean completed;
|
||||
|
||||
private ClearanceProgress(boolean moved, boolean completed) {
|
||||
this.moved = moved;
|
||||
this.completed = completed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,15 @@ public final class SimulationProgressWatchdog {
|
||||
}
|
||||
|
||||
public boolean observe(int terminalCount) {
|
||||
return observe(terminalCount, false, false);
|
||||
}
|
||||
|
||||
public boolean observe(int terminalCount, boolean vehicleMoved,
|
||||
boolean clearanceCompleted) {
|
||||
if (terminalCount < lastTerminalCount) {
|
||||
throw new IllegalArgumentException("terminal count must be monotonic");
|
||||
}
|
||||
if (terminalCount > lastTerminalCount) {
|
||||
if (terminalCount > lastTerminalCount || vehicleMoved || clearanceCompleted) {
|
||||
lastTerminalCount = terminalCount;
|
||||
unchangedEvents = 0;
|
||||
return false;
|
||||
|
||||
@@ -18,12 +18,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
class HistoricalDispatchSimulationRealDataTest {
|
||||
private static HistoricalDispatchSimulationResult result;
|
||||
private static HistoricalDispatchSimulationResult secondRun;
|
||||
private static HistoricalSimulationInput simulationInput;
|
||||
|
||||
@BeforeAll
|
||||
static void simulateRealHistoryTwice() {
|
||||
HistoricalQueueDataset dataset = new HistoricalQueueLoader().load(
|
||||
HistoricalDispatchSimulationRealDataTest.class.getClassLoader(), "shadow/history");
|
||||
HistoricalSimulationInput input = new HistoricalSimulationInputFactory().create(dataset);
|
||||
simulationInput = input;
|
||||
DeterministicFaultPlan.Builder faults = DeterministicFaultPlan.builder();
|
||||
for (int i = 0; i < input.getTasks().size(); i += 37) {
|
||||
faults.plcFailure(input.getTasks().get(i).getSimulationTaskId(), 1, SEND_FAILURE);
|
||||
@@ -46,22 +48,30 @@ class HistoricalDispatchSimulationRealDataTest {
|
||||
assertNotNull(task.getRecord().getTaskNo());
|
||||
assertNotNull(task.getRecord().getStartSite());
|
||||
assertNotNull(task.getRecord().getEndSite());
|
||||
for (int i = 1; i < task.getPlannedPath().size(); i++) {
|
||||
assertTrue(simulationInput.getGridMap()
|
||||
.getNeighbors(task.getPlannedPath().get(i - 1))
|
||||
.contains(task.getPlannedPath().get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void completesTheRealWorkloadDeterministicallyWithoutSafetyViolations() {
|
||||
assertEquals(240, result.getTaskResults().size());
|
||||
assertEquals(240, result.getCompletedCount()
|
||||
+ result.getWaitingCount() + result.getFailedCount());
|
||||
assertTrue(result.getCompletedCount() > 0);
|
||||
if (result.getWaitingCount() > 0) {
|
||||
assertTrue(result.getInvariants().getDeadlocks() > 0);
|
||||
}
|
||||
assertEquals(240, result.getCompletedCount());
|
||||
assertEquals(0, result.getWaitingCount());
|
||||
assertEquals(0, result.getFailedCount());
|
||||
assertTrue(result.getReassignmentCount() > 0);
|
||||
assertTrue(result.getRetryCount() > 0);
|
||||
assertEquals(result.getCompletedCount(), result.getArchiveCount());
|
||||
assertEquals(result.getCompletedCount(), result.getWmsBusinessEffects());
|
||||
assertEquals(result.getCompletedCount() * 2, result.getWmsDeliveryAttempts());
|
||||
assertEquals(240, result.getArchiveCount());
|
||||
assertEquals(240, result.getWmsBusinessEffects());
|
||||
assertEquals(480, result.getWmsDeliveryAttempts());
|
||||
assertEquals(0, result.getInvariants().getDeadlocks());
|
||||
assertEquals(0, result.getInvariants().getCapacityViolations());
|
||||
assertEquals(0, result.getInvariants().getNodeDoubleOccupancyViolations());
|
||||
assertEquals(0, result.getInvariants().getOppositeEdgeViolations());
|
||||
assertEquals(0, result.getInvariants().getDuplicateArchiveAttempts());
|
||||
assertEquals(0, result.getInvariants().getDuplicateWmsBusinessEffects());
|
||||
assertEquals(0, result.getInvariants().totalSafetyViolations());
|
||||
assertEquals(result.canonicalView(), secondRun.canonicalView());
|
||||
}
|
||||
|
||||
@@ -24,4 +24,20 @@ class SimulationProgressWatchdogTest {
|
||||
assertFalse(watchdog.observe(1));
|
||||
assertTrue(watchdog.observe(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resetsOnlyForTerminalMovementOrCompletedClearanceProgress() {
|
||||
SimulationProgressWatchdog watchdog = new SimulationProgressWatchdog(3, 0);
|
||||
|
||||
assertFalse(watchdog.observe(0, false, false));
|
||||
assertFalse(watchdog.observe(0, false, false));
|
||||
assertFalse(watchdog.observe(0, true, false));
|
||||
assertFalse(watchdog.observe(0, false, false));
|
||||
assertFalse(watchdog.observe(0, false, true));
|
||||
assertFalse(watchdog.observe(0, false, false));
|
||||
assertFalse(watchdog.observe(1, false, false));
|
||||
assertFalse(watchdog.observe(1, false, false));
|
||||
assertFalse(watchdog.observe(1, false, false));
|
||||
assertTrue(watchdog.observe(1, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user