test(ft546): verify standard WCS end to end

This commit is contained in:
zgw
2026-08-12 08:27:40 +08:00
parent ceba465675
commit f66585f717
31 changed files with 2560 additions and 16 deletions

View File

@@ -107,6 +107,40 @@ class Ft546StandardRuntimeTest {
assertEquals(1L, scheduler.getCompletedTickCount());
}
@Test
void wmsOutboxStillDispatchesWhenCoreTickFails() {
AtomicInteger notificationDispatches = new AtomicInteger();
Ft546WcsScheduler scheduler = new Ft546WcsScheduler(() -> {
throw new IllegalStateException("core tick failed");
}, notificationDispatches::incrementAndGet);
IllegalStateException failure = assertThrows(
IllegalStateException.class, scheduler::runScheduledTick);
assertEquals("core tick failed", failure.getMessage());
assertEquals(1, notificationDispatches.get());
assertEquals(0L, scheduler.getCompletedTickCount());
assertFalse(scheduler.isTickInProgress());
}
@Test
void coreTickFailureRemainsPrimaryWhenNotificationDispatchAlsoFails() {
Ft546WcsScheduler scheduler = new Ft546WcsScheduler(() -> {
throw new IllegalStateException("core tick failed");
}, () -> {
throw new IllegalArgumentException("notification dispatch failed");
});
IllegalStateException failure = assertThrows(
IllegalStateException.class, scheduler::runScheduledTick);
assertEquals("core tick failed", failure.getMessage());
assertEquals(1, failure.getSuppressed().length);
assertEquals("notification dispatch failed",
failure.getSuppressed()[0].getMessage());
assertFalse(scheduler.isTickInProgress());
}
@Test
void legacyModeDoesNotRequireStandardRuntimePorts() {
new ApplicationContextRunner()

View File

@@ -6,6 +6,7 @@ import com.ruoyi.wcs.domain.shared.WcsClock;
import com.ruoyi.wcs.infrastructure.persistence.task.MyBatisTransportOrderRepository;
import com.ruoyi.wcs.port.in.TransportOrderUseCase;
import com.ruoyi.wcs.port.out.TransportOrderRepository;
import com.ruoyi.wcs.port.out.TransportOrderExecutionRepository;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -28,6 +29,8 @@ class WcsCoreWiringTest {
instanceof TransportOrderApplicationService);
assertTrue(context.getBean(TransportOrderRepository.class)
instanceof MyBatisTransportOrderRepository);
assertTrue(context.getBean(TransportOrderExecutionRepository.class)
instanceof MyBatisTransportOrderRepository);
assertTrue(context.containsBeanDefinition("transportOrderMapper"));
WcsClock clock = context.getBean(WcsClock.class);

View File

@@ -0,0 +1,48 @@
{
"endpoint": "/wcs2Wms/api/receiveInMydoJob",
"request": {
"taskNo": "30001",
"cargoSpaceId": "070502",
"targetCargoSpaceId": null,
"exitId": null,
"trayCode": "TRAY-30001",
"entranceId": "070501",
"inOrOut": "10",
"jobId": "JOB-30001",
"roadwayId": "R1",
"classId": "7",
"priority": 5
},
"warehouseCode": "FT546",
"topologyVersion": 7,
"snapshotVersion": 11,
"vehicle": {
"deviceId": "1",
"floorCode": "F7",
"locationNodeId": "070501",
"batteryPercent": 80
},
"nodes": [
{"nodeId": "070501", "floorCode": "F7", "x": 0, "y": 0},
{"nodeId": "070502", "floorCode": "F7", "x": 1, "y": 0}
],
"edges": [
{"from": "070501", "to": "070502", "distanceCost": 1, "capacity": 1}
],
"commandParameters": {
"taskNo": "30001",
"taskType": "1"
},
"expectedCommandPayloadSuffix": "|vehicleId=1|route=070501>070502|taskNo=30001|taskType=1",
"expectedProtectedResources": [
"NODE:070501",
"EDGE:070501:070502",
"NODE:070502"
],
"expectedPlcWrites": [
{"address": "4004", "kind": "INT32", "values": [70501, 70502, 0, 0, 0, 0, 0, 0]},
{"address": "4000", "kind": "INT32", "values": [30001]},
{"address": "4002", "kind": "INT16", "values": [1]},
{"address": "4021", "kind": "INT16", "values": [1]}
]
}

View File

@@ -0,0 +1,49 @@
{
"endpoint": "/wcs2Wms/api/receiveInMydoJob",
"request": {
"taskNo": "30003",
"cargoSpaceId": "070503",
"targetCargoSpaceId": null,
"exitId": null,
"trayCode": "TRAY-30003",
"entranceId": "070501",
"inOrOut": "10",
"jobId": "JOB-30003",
"roadwayId": "R1",
"classId": "7",
"priority": 5
},
"warehouseCode": "FT546",
"topologyVersion": 9,
"snapshotVersion": 13,
"vehicle": {
"deviceId": "1",
"floorCode": "F7",
"locationNodeId": "070501",
"batteryPercent": 80
},
"nodes": [
{"nodeId": "070501", "floorCode": "F7", "x": 0, "y": 0},
{"nodeId": "070503", "floorCode": "F7", "x": 1, "y": 0}
],
"edges": [
{"from": "070501", "to": "070503", "distanceCost": 1, "capacity": 1}
],
"commandParameters": {
"taskNo": "30003",
"taskType": "1",
"stage": "1"
},
"expectedCommandPayloadSuffix": "|vehicleId=1|route=070501>070503|stage=1|taskNo=30003|taskType=1",
"expectedProtectedResources": [
"NODE:070501",
"EDGE:070501:070503",
"NODE:070503"
],
"expectedPlcWrites": [
{"address": "4404", "kind": "INT32", "values": [70501, 70503, 0, 0, 0, 0, 0, 0]},
{"address": "4422", "kind": "INT16", "values": [1]},
{"address": "4402", "kind": "INT16", "values": [1]},
{"address": "4400", "kind": "INT32", "values": [30003]}
]
}

View File

@@ -0,0 +1,50 @@
{
"endpoint": "/wcs2Wms/api/receiveInMydoJob",
"request": {
"taskNo": "30004",
"cargoSpaceId": "070504",
"targetCargoSpaceId": null,
"exitId": null,
"trayCode": "TRAY-30004",
"entranceId": "070503",
"inOrOut": "10",
"jobId": "JOB-30004",
"roadwayId": "R1",
"classId": "7",
"priority": 5
},
"warehouseCode": "FT546",
"topologyVersion": 10,
"snapshotVersion": 14,
"vehicle": {
"deviceId": "1",
"floorCode": "F7",
"locationNodeId": "070503",
"batteryPercent": 80
},
"nodes": [
{"nodeId": "070503", "floorCode": "F7", "x": 0, "y": 0},
{"nodeId": "070504", "floorCode": "F7", "x": 1, "y": 0}
],
"edges": [
{"from": "070503", "to": "070504", "distanceCost": 1, "capacity": 1}
],
"commandParameters": {
"taskNo": "30004",
"taskType": "9",
"stage": "2"
},
"expectedCommandPayloadSuffix": "|vehicleId=1|route=070503>070504|stage=2|taskNo=30004|taskType=9",
"expectedProtectedResources": [
"NODE:070503",
"EDGE:070503:070504",
"NODE:070504"
],
"expectedPlcWrites": [
{"address": "4404", "kind": "INT32", "values": [70503, 70504, 0, 0, 0, 0, 0, 0]},
{"address": "4422", "kind": "INT16", "values": [2]},
{"address": "4423", "kind": "INT16", "values": [99]},
{"address": "4402", "kind": "INT16", "values": [9]},
{"address": "4400", "kind": "INT32", "values": [30004]}
]
}

View File

@@ -0,0 +1,59 @@
{
"endpoint": "/wcs2Wms/api/receiveOutMydoJob",
"request": {
"taskNo": "30002",
"cargoSpaceId": "070501",
"targetCargoSpaceId": null,
"exitId": "080501",
"trayCode": "TRAY-30002",
"entranceId": null,
"inOrOut": "20",
"jobId": "JOB-30002",
"roadwayId": "R1",
"classId": "7",
"priority": 6
},
"warehouseCode": "FT546",
"topologyVersion": 8,
"snapshotVersion": 12,
"vehicle": {
"deviceId": "1",
"floorCode": "F7",
"locationNodeId": "070501",
"batteryPercent": 82
},
"nodes": [
{"nodeId": "070501", "floorCode": "F7", "x": 0, "y": 0},
{"nodeId": "070507", "floorCode": "F7", "x": 1, "y": 0},
{"nodeId": "080507", "floorCode": "F8", "x": 1, "y": 0},
{"nodeId": "080501", "floorCode": "F8", "x": 2, "y": 0}
],
"edges": [
{"from": "070501", "to": "070507", "distanceCost": 1, "capacity": 1},
{"from": "070507", "to": "080507", "distanceCost": 1, "capacity": 1},
{"from": "080507", "to": "080501", "distanceCost": 1, "capacity": 1}
],
"commandParameters": {
"taskNo": "30002",
"taskType": "8",
"crossFloorTarget": "8"
},
"expectedCommandPayloadSuffix": "|vehicleId=1|route=070501>070507>080507>080501|crossFloorTarget=8|taskNo=30002|taskType=8",
"expectedProtectedResources": [
"NODE:070501",
"EDGE:070501:070507",
"NODE:070507",
"EDGE:070507:080507",
"NODE:080507",
"EDGE:080501:080507",
"NODE:080501"
],
"expectedPlcWrites": [
{"address": "4004", "kind": "INT32", "values": [70501, 70507, 80507, 80501, 0, 0, 0, 0]},
{"address": "4000", "kind": "INT32", "values": [30002]},
{"address": "4002", "kind": "INT16", "values": [8]},
{"address": "4021", "kind": "INT16", "values": [1]},
{"address": "4020", "kind": "INT16", "values": [1]},
{"address": "4022", "kind": "INT16", "values": [8]}
]
}