feat(javaTest): scope PLC retries by business phase
This commit is contained in:
@@ -44,7 +44,8 @@ public final class DeterministicFaultPlan {
|
|||||||
public VehicleEventType getType() { return type; }
|
public VehicleEventType getType() { return type; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcFailures;
|
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcTaskFailures;
|
||||||
|
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcCommandFailures;
|
||||||
private final Map<Long, List<VehicleEvent>> vehicleEvents;
|
private final Map<Long, List<VehicleEvent>> vehicleEvents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,9 +56,11 @@ public final class DeterministicFaultPlan {
|
|||||||
* @param vehicleEvents 执行该处理所需的 vehicle events 输入。
|
* @param vehicleEvents 执行该处理所需的 vehicle events 输入。
|
||||||
*/
|
*/
|
||||||
private DeterministicFaultPlan(
|
private DeterministicFaultPlan(
|
||||||
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcFailures,
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcTaskFailures,
|
||||||
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcCommandFailures,
|
||||||
Map<Long, List<VehicleEvent>> vehicleEvents) {
|
Map<Long, List<VehicleEvent>> vehicleEvents) {
|
||||||
this.plcFailures = plcFailures;
|
this.plcTaskFailures = plcTaskFailures;
|
||||||
|
this.plcCommandFailures = plcCommandFailures;
|
||||||
this.vehicleEvents = vehicleEvents;
|
this.vehicleEvents = vehicleEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +89,23 @@ public final class DeterministicFaultPlan {
|
|||||||
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
||||||
*/
|
*/
|
||||||
SimulatedPlcGateway.PlcReason plcReason(String taskId, int attempt) {
|
SimulatedPlcGateway.PlcReason plcReason(String taskId, int attempt) {
|
||||||
Map<Integer, SimulatedPlcGateway.PlcReason> byAttempt = plcFailures.get(taskId);
|
Map<Integer, SimulatedPlcGateway.PlcReason> byAttempt = plcTaskFailures.get(taskId);
|
||||||
return byAttempt == null ? null : byAttempt.get(attempt);
|
return byAttempt == null ? null : byAttempt.get(attempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 先匹配具体业务阶段命令的第 N 次发送;没有阶段配置时,再按父任务总发送次数兼容旧故障计划。
|
||||||
|
*/
|
||||||
|
SimulatedPlcGateway.PlcReason plcReason(String parentTaskId, String commandId,
|
||||||
|
int commandAttempt, int taskAttempt) {
|
||||||
|
Map<Integer, SimulatedPlcGateway.PlcReason> byCommand =
|
||||||
|
plcCommandFailures.get(commandId);
|
||||||
|
SimulatedPlcGateway.PlcReason commandReason = byCommand == null
|
||||||
|
? null : byCommand.get(commandAttempt);
|
||||||
|
return commandReason == null
|
||||||
|
? plcReason(parentTaskId, taskAttempt) : commandReason;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行“events at”所表示的处理流程。
|
* 执行“events at”所表示的处理流程。
|
||||||
*
|
*
|
||||||
@@ -103,7 +119,9 @@ public final class DeterministicFaultPlan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcFailures =
|
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcTaskFailures =
|
||||||
|
new LinkedHashMap<String, Map<Integer, SimulatedPlcGateway.PlcReason>>();
|
||||||
|
private final Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plcCommandFailures =
|
||||||
new LinkedHashMap<String, Map<Integer, SimulatedPlcGateway.PlcReason>>();
|
new LinkedHashMap<String, Map<Integer, SimulatedPlcGateway.PlcReason>>();
|
||||||
private final Map<Long, List<VehicleEvent>> vehicleEvents =
|
private final Map<Long, List<VehicleEvent>> vehicleEvents =
|
||||||
new LinkedHashMap<Long, List<VehicleEvent>>();
|
new LinkedHashMap<Long, List<VehicleEvent>>();
|
||||||
@@ -119,18 +137,31 @@ public final class DeterministicFaultPlan {
|
|||||||
*/
|
*/
|
||||||
public Builder plcFailure(String taskId, int attempt,
|
public Builder plcFailure(String taskId, int attempt,
|
||||||
SimulatedPlcGateway.PlcReason reason) {
|
SimulatedPlcGateway.PlcReason reason) {
|
||||||
if (taskId == null || attempt <= 0 || reason == null
|
addPlcFailure(plcTaskFailures, taskId, attempt, reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 为某一业务阶段命令配置独立失败,不消耗其他阶段的重试序号。 */
|
||||||
|
public Builder plcCommandFailure(String commandId, int attempt,
|
||||||
|
SimulatedPlcGateway.PlcReason reason) {
|
||||||
|
addPlcFailure(plcCommandFailures, commandId, attempt, reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPlcFailure(
|
||||||
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> failures,
|
||||||
|
String key, int attempt, SimulatedPlcGateway.PlcReason reason) {
|
||||||
|
if (key == null || key.trim().isEmpty() || attempt <= 0 || reason == null
|
||||||
|| reason == SimulatedPlcGateway.PlcReason.ACK
|
|| reason == SimulatedPlcGateway.PlcReason.ACK
|
||||||
|| reason == SimulatedPlcGateway.PlcReason.STALE_BOOT_ID) {
|
|| reason == SimulatedPlcGateway.PlcReason.STALE_BOOT_ID) {
|
||||||
throw new IllegalArgumentException("valid PLC failure is required");
|
throw new IllegalArgumentException("valid PLC failure is required");
|
||||||
}
|
}
|
||||||
Map<Integer, SimulatedPlcGateway.PlcReason> byAttempt = plcFailures.get(taskId);
|
Map<Integer, SimulatedPlcGateway.PlcReason> byAttempt = failures.get(key);
|
||||||
if (byAttempt == null) {
|
if (byAttempt == null) {
|
||||||
byAttempt = new LinkedHashMap<Integer, SimulatedPlcGateway.PlcReason>();
|
byAttempt = new LinkedHashMap<Integer, SimulatedPlcGateway.PlcReason>();
|
||||||
plcFailures.put(taskId, byAttempt);
|
failures.put(key, byAttempt);
|
||||||
}
|
}
|
||||||
byAttempt.put(attempt, reason);
|
byAttempt.put(attempt, reason);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,21 +193,30 @@ public final class DeterministicFaultPlan {
|
|||||||
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
||||||
*/
|
*/
|
||||||
public DeterministicFaultPlan build() {
|
public DeterministicFaultPlan build() {
|
||||||
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> plc =
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> taskPlc =
|
||||||
new LinkedHashMap<String, Map<Integer, SimulatedPlcGateway.PlcReason>>();
|
immutableFailures(plcTaskFailures);
|
||||||
for (Map.Entry<String, Map<Integer, SimulatedPlcGateway.PlcReason>> entry
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> commandPlc =
|
||||||
: plcFailures.entrySet()) {
|
immutableFailures(plcCommandFailures);
|
||||||
plc.put(entry.getKey(), Collections.unmodifiableMap(
|
|
||||||
new LinkedHashMap<Integer, SimulatedPlcGateway.PlcReason>(entry.getValue())));
|
|
||||||
}
|
|
||||||
Map<Long, List<VehicleEvent>> vehicles =
|
Map<Long, List<VehicleEvent>> vehicles =
|
||||||
new LinkedHashMap<Long, List<VehicleEvent>>();
|
new LinkedHashMap<Long, List<VehicleEvent>>();
|
||||||
for (Map.Entry<Long, List<VehicleEvent>> entry : vehicleEvents.entrySet()) {
|
for (Map.Entry<Long, List<VehicleEvent>> entry : vehicleEvents.entrySet()) {
|
||||||
vehicles.put(entry.getKey(), Collections.unmodifiableList(
|
vehicles.put(entry.getKey(), Collections.unmodifiableList(
|
||||||
new ArrayList<VehicleEvent>(entry.getValue())));
|
new ArrayList<VehicleEvent>(entry.getValue())));
|
||||||
}
|
}
|
||||||
return new DeterministicFaultPlan(Collections.unmodifiableMap(plc),
|
return new DeterministicFaultPlan(taskPlc, commandPlc,
|
||||||
Collections.unmodifiableMap(vehicles));
|
Collections.unmodifiableMap(vehicles));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> immutableFailures(
|
||||||
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> source) {
|
||||||
|
Map<String, Map<Integer, SimulatedPlcGateway.PlcReason>> copy =
|
||||||
|
new LinkedHashMap<String, Map<Integer, SimulatedPlcGateway.PlcReason>>();
|
||||||
|
for (Map.Entry<String, Map<Integer, SimulatedPlcGateway.PlcReason>> entry
|
||||||
|
: source.entrySet()) {
|
||||||
|
copy.put(entry.getKey(), Collections.unmodifiableMap(
|
||||||
|
new LinkedHashMap<Integer, SimulatedPlcGateway.PlcReason>(entry.getValue())));
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableMap(copy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ public final class SimulatedPlcGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class PlcResponse {
|
public static final class PlcResponse {
|
||||||
private final String taskId;
|
private final String parentTaskId;
|
||||||
|
private final String commandId;
|
||||||
private final String vehicleId;
|
private final String vehicleId;
|
||||||
private final String from;
|
private final String from;
|
||||||
private final String to;
|
private final String to;
|
||||||
@@ -30,9 +31,11 @@ public final class SimulatedPlcGateway {
|
|||||||
* @param bootId 执行该处理所需的 boot id 输入。
|
* @param bootId 执行该处理所需的 boot id 输入。
|
||||||
* @param reason 执行该处理所需的 reason 输入。
|
* @param reason 执行该处理所需的 reason 输入。
|
||||||
*/
|
*/
|
||||||
private PlcResponse(String taskId, String vehicleId, String from, String to,
|
private PlcResponse(String parentTaskId, String commandId,
|
||||||
|
String vehicleId, String from, String to,
|
||||||
int attempt, long bootId, PlcReason reason) {
|
int attempt, long bootId, PlcReason reason) {
|
||||||
this.taskId = taskId;
|
this.parentTaskId = parentTaskId;
|
||||||
|
this.commandId = commandId;
|
||||||
this.vehicleId = vehicleId;
|
this.vehicleId = vehicleId;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
@@ -47,7 +50,13 @@ public final class SimulatedPlcGateway {
|
|||||||
* <p>该方法属于 {@code PlcResponse},用于保持当前模块的职责边界清晰。
|
* <p>该方法属于 {@code PlcResponse},用于保持当前模块的职责边界清晰。
|
||||||
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
||||||
*/
|
*/
|
||||||
public String getTaskId() { return taskId; }
|
public String getTaskId() { return parentTaskId; }
|
||||||
|
|
||||||
|
/** 返回归档和 WMS 幂等使用的业务父任务 ID。 */
|
||||||
|
public String getParentTaskId() { return parentTaskId; }
|
||||||
|
|
||||||
|
/** 返回包含业务阶段和路线版本的 PLC 命令 ID。 */
|
||||||
|
public String getCommandId() { return commandId; }
|
||||||
/**
|
/**
|
||||||
* 返回当前对象保存的“vehicle id”信息。
|
* 返回当前对象保存的“vehicle id”信息。
|
||||||
*
|
*
|
||||||
@@ -93,7 +102,8 @@ public final class SimulatedPlcGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final DeterministicFaultPlan faults;
|
private final DeterministicFaultPlan faults;
|
||||||
private final Map<String, Integer> attempts = new LinkedHashMap<String, Integer>();
|
private final Map<String, Integer> taskAttempts = new LinkedHashMap<String, Integer>();
|
||||||
|
private final Map<String, Integer> commandAttempts = new LinkedHashMap<String, Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 PLC 协议模拟器,并绑定确定性故障计划以便重复测试发送、超时和丢 ACK 场景。
|
* 创建 PLC 协议模拟器,并绑定确定性故障计划以便重复测试发送、超时和丢 ACK 场景。
|
||||||
@@ -116,13 +126,27 @@ public final class SimulatedPlcGateway {
|
|||||||
*/
|
*/
|
||||||
public PlcResponse send(String taskId, SimulatedVehicleRuntime vehicle,
|
public PlcResponse send(String taskId, SimulatedVehicleRuntime vehicle,
|
||||||
String from, String to) {
|
String from, String to) {
|
||||||
// 按任务累计协议尝试次数,使故障计划能精确指定第 N 次发送失败或超时。
|
return send(taskId, taskId, vehicle, from, to);
|
||||||
int attempt = attempts.containsKey(taskId) ? attempts.get(taskId) + 1 : 1;
|
}
|
||||||
attempts.put(taskId, attempt);
|
|
||||||
PlcReason reason = faults.plcReason(taskId, attempt);
|
/**
|
||||||
|
* 向 PLC 发送某个父任务的阶段命令;命令尝试次数用于阶段重试,任务尝试次数只用于汇总和旧故障配置。
|
||||||
|
*/
|
||||||
|
public PlcResponse send(String parentTaskId, String commandId,
|
||||||
|
SimulatedVehicleRuntime vehicle, String from, String to) {
|
||||||
|
if (blank(parentTaskId) || blank(commandId) || vehicle == null
|
||||||
|
|| blank(from) || blank(to)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"parent task, command, vehicle and movement endpoints are required");
|
||||||
|
}
|
||||||
|
// 每个阶段命令从 1 独立计数,因此载货阶段的首发失败不会继承空车阶段的次数。
|
||||||
|
int commandAttempt = increment(commandAttempts, commandId);
|
||||||
|
int taskAttempt = increment(taskAttempts, parentTaskId);
|
||||||
|
PlcReason reason = faults.plcReason(
|
||||||
|
parentTaskId, commandId, commandAttempt, taskAttempt);
|
||||||
if (reason == null) reason = PlcReason.ACK;
|
if (reason == null) reason = PlcReason.ACK;
|
||||||
return new PlcResponse(taskId, vehicle.getVehicleId(), from, to,
|
return new PlcResponse(parentTaskId, commandId, vehicle.getVehicleId(), from, to,
|
||||||
attempt, vehicle.getBootId(), reason);
|
commandAttempt, vehicle.getBootId(), reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +159,8 @@ public final class SimulatedPlcGateway {
|
|||||||
if (response.getReason() != PlcReason.ACK) return response;
|
if (response.getReason() != PlcReason.ACK) return response;
|
||||||
// 车辆重启后 bootId 会变化,旧 ACK 即使迟到也不能再提交路线索引和车位。
|
// 车辆重启后 bootId 会变化,旧 ACK 即使迟到也不能再提交路线索引和车位。
|
||||||
if (response.getBootId() != vehicle.getBootId()) {
|
if (response.getBootId() != vehicle.getBootId()) {
|
||||||
return new PlcResponse(response.getTaskId(), response.getVehicleId(),
|
return new PlcResponse(response.getParentTaskId(), response.getCommandId(),
|
||||||
|
response.getVehicleId(),
|
||||||
response.getFrom(), response.getTo(), response.getAttempt(),
|
response.getFrom(), response.getTo(), response.getAttempt(),
|
||||||
response.getBootId(), PlcReason.STALE_BOOT_ID);
|
response.getBootId(), PlcReason.STALE_BOOT_ID);
|
||||||
}
|
}
|
||||||
@@ -148,7 +173,18 @@ public final class SimulatedPlcGateway {
|
|||||||
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
||||||
*/
|
*/
|
||||||
public int attemptsFor(String taskId) {
|
public int attemptsFor(String taskId) {
|
||||||
Integer value = attempts.get(taskId);
|
return attemptsForTask(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 返回父任务跨所有阶段累计发送 PLC 指令的次数。 */
|
||||||
|
public int attemptsForTask(String parentTaskId) {
|
||||||
|
Integer value = taskAttempts.get(parentTaskId);
|
||||||
|
return value == null ? 0 : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 返回单个阶段命令自己的发送次数,供当前阶段的重试上限判断。 */
|
||||||
|
public int attemptsForCommand(String commandId) {
|
||||||
|
Integer value = commandAttempts.get(commandId);
|
||||||
return value == null ? 0 : value;
|
return value == null ? 0 : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +195,21 @@ public final class SimulatedPlcGateway {
|
|||||||
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
* @return 本次处理产生的结果;调用方据此继续后续流程。
|
||||||
*/
|
*/
|
||||||
public Map<String, Integer> getAttempts() {
|
public Map<String, Integer> getAttempts() {
|
||||||
return Collections.unmodifiableMap(attempts);
|
return Collections.unmodifiableMap(taskAttempts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 返回只读的阶段命令尝试次数,供报告按阶段汇总。 */
|
||||||
|
public Map<String, Integer> getCommandAttempts() {
|
||||||
|
return Collections.unmodifiableMap(commandAttempts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int increment(Map<String, Integer> values, String key) {
|
||||||
|
int next = values.containsKey(key) ? values.get(key) + 1 : 1;
|
||||||
|
values.put(key, next);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean blank(String value) {
|
||||||
|
return value == null || value.trim().isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.ft546.wcs.shadow.history.simulation;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static com.ft546.wcs.shadow.history.simulation.SimulatedPlcGateway.PlcReason.ACK;
|
||||||
|
import static com.ft546.wcs.shadow.history.simulation.SimulatedPlcGateway.PlcReason.ACK_TIMEOUT;
|
||||||
|
import static com.ft546.wcs.shadow.history.simulation.SimulatedPlcGateway.PlcReason.SEND_FAILURE;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class PhaseAwarePlcGatewayTest {
|
||||||
|
/** 载货阶段自己的首发失败,不得继承空车阶段已经使用过的尝试序号。 */
|
||||||
|
@Test
|
||||||
|
void failureOnLoadedPhaseDoesNotConsumeEmptyPhaseAttemptNumbers() {
|
||||||
|
String emptyCommand = "B1:EMPTY_TO_PICKUP:v1:e0";
|
||||||
|
String loadedCommand = "B1:LOADED_TO_PLACE:v1:e0";
|
||||||
|
DeterministicFaultPlan plan = DeterministicFaultPlan.builder()
|
||||||
|
.plcCommandFailure(loadedCommand, 1, SEND_FAILURE)
|
||||||
|
.build();
|
||||||
|
SimulatedPlcGateway gateway = new SimulatedPlcGateway(plan);
|
||||||
|
SimulatedVehicleRuntime vehicle = new SimulatedVehicleRuntime("1", "A", 1);
|
||||||
|
|
||||||
|
assertEquals(ACK, gateway.send("B1", emptyCommand,
|
||||||
|
vehicle, "A", "B").getReason());
|
||||||
|
SimulatedPlcGateway.PlcResponse failed = gateway.send(
|
||||||
|
"B1", loadedCommand, vehicle, "B", "C");
|
||||||
|
|
||||||
|
assertEquals(SEND_FAILURE, failed.getReason());
|
||||||
|
assertEquals("B1", failed.getParentTaskId());
|
||||||
|
assertEquals(loadedCommand, failed.getCommandId());
|
||||||
|
assertEquals(1, failed.getAttempt());
|
||||||
|
assertEquals(2, gateway.attemptsForTask("B1"));
|
||||||
|
assertEquals(1, gateway.attemptsForCommand(emptyCommand));
|
||||||
|
assertEquals(1, gateway.attemptsForCommand(loadedCommand));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 旧的任务级故障配置仍按父任务总发送次数生效,可继续驱动原始回放测试。 */
|
||||||
|
@Test
|
||||||
|
void taskWideFailureRemainsACompatibleFallbackAcrossCommands() {
|
||||||
|
DeterministicFaultPlan plan = DeterministicFaultPlan.builder()
|
||||||
|
.plcFailure("B1", 2, ACK_TIMEOUT)
|
||||||
|
.build();
|
||||||
|
SimulatedPlcGateway gateway = new SimulatedPlcGateway(plan);
|
||||||
|
SimulatedVehicleRuntime vehicle = new SimulatedVehicleRuntime("1", "A", 1);
|
||||||
|
|
||||||
|
assertEquals(ACK, gateway.send("B1", "B1:EMPTY_TO_PICKUP:v1:e0",
|
||||||
|
vehicle, "A", "B").getReason());
|
||||||
|
assertEquals(ACK_TIMEOUT, gateway.send("B1", "B1:LOADED_TO_PLACE:v1:e0",
|
||||||
|
vehicle, "B", "C").getReason());
|
||||||
|
assertEquals(2, gateway.attemptsForTask("B1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,10 @@ class SimulationAdaptersTest {
|
|||||||
assertEquals(SEND_FAILURE, plc.send("T1", vehicle, "A", "B").getReason());
|
assertEquals(SEND_FAILURE, plc.send("T1", vehicle, "A", "B").getReason());
|
||||||
SimulatedPlcGateway.PlcResponse ack = plc.send("T1", vehicle, "A", "B");
|
SimulatedPlcGateway.PlcResponse ack = plc.send("T1", vehicle, "A", "B");
|
||||||
assertEquals(ACK, ack.getReason());
|
assertEquals(ACK, ack.getReason());
|
||||||
|
assertEquals("T1", ack.getParentTaskId());
|
||||||
|
assertEquals("T1", ack.getCommandId());
|
||||||
|
assertEquals(2, plc.attemptsForTask("T1"));
|
||||||
|
assertEquals(2, plc.attemptsForCommand("T1"));
|
||||||
assertEquals(ACK, plc.accept(ack, vehicle).getReason());
|
assertEquals(ACK, plc.accept(ack, vehicle).getReason());
|
||||||
|
|
||||||
vehicle.restart();
|
vehicle.restart();
|
||||||
|
|||||||
Reference in New Issue
Block a user