package com.zy.core.dispatch; import com.zy.common.utils.RedisUtil; import com.zy.core.cache.MessageQueue; import com.zy.core.enums.SlaveType; import com.zy.core.enums.StationCommandType; import com.zy.core.model.command.StationCommand; import com.zy.core.move.StationMoveCoordinator; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; class StationCommandDispatcherTest { @Test void dispatch_acceptsMoveCommandAndReturnsQueueDepth() { StationCommandDispatcher dispatcher = new StationCommandDispatcher(); StationCommand command = new StationCommand(); command.setCommandType(StationCommandType.MOVE); command.setTaskNo(100); command.setStationId(10); command.setTargetStaNo(20); MessageQueue.init(SlaveType.Devp, 1); try { StationCommandDispatchResult result = dispatcher.dispatch(1, command, "unit-test", "move"); assertTrue(result.isAccepted()); assertEquals("accepted", result.getReason()); assertEquals(1, result.getQueueDepth()); assertEquals("unit-test", result.getSource()); assertEquals("move", result.getScene()); } finally { MessageQueue.clear(SlaveType.Devp, 1); } } @Test void dispatch_suppressesDuplicateMoveCommandWithinDedupWindow() { RedisUtil redisUtil = mock(RedisUtil.class); StationMoveCoordinator coordinator = mock(StationMoveCoordinator.class); StationCommandDispatcher dispatcher = new StationCommandDispatcher(redisUtil, coordinator); Map dedupStore = new HashMap<>(); when(redisUtil.get(anyString())).thenAnswer(invocation -> dedupStore.get(invocation.getArgument(0))); when(redisUtil.set(anyString(), eq("lock"), anyLong())).thenAnswer(invocation -> { dedupStore.put(invocation.getArgument(0), invocation.getArgument(1)); return true; }); when(coordinator.buildPathSignatureHash(org.mockito.ArgumentMatchers.any(StationCommand.class))) .thenReturn("same-path"); StationCommand command = new StationCommand(); command.setCommandType(StationCommandType.MOVE); command.setTaskNo(100); command.setStationId(10); command.setTargetStaNo(20); MessageQueue.init(SlaveType.Devp, 1); try { StationCommandDispatchResult first = dispatcher.dispatch(1, command, "unit-test", "move"); StationCommandDispatchResult second = dispatcher.dispatch(1, command, "unit-test", "move"); assertTrue(first.isAccepted()); assertFalse(second.isAccepted()); assertEquals("dedup-suppressed", second.getReason()); assertEquals(1, second.getQueueDepth()); } finally { MessageQueue.clear(SlaveType.Devp, 1); } } @Test void dispatch_rejectsWhenDevpQueueIsNotInitialized() { StationCommandDispatcher dispatcher = new StationCommandDispatcher(); StationCommand command = new StationCommand(); command.setCommandType(StationCommandType.MOVE); command.setTaskNo(100); command.setStationId(10); command.setTargetStaNo(20); StationCommandDispatchResult result = dispatcher.dispatch(999, command, "unit-test", "move"); assertFalse(result.isAccepted()); assertEquals("queue-not-initialized", result.getReason()); assertEquals(0, result.getQueueDepth()); } }