package com.zy.core.utils; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.zy.asrs.entity.BasCrnp; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.LocMastService; import com.zy.asrs.service.WrkAnalysisService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.NotifyUtils; import com.zy.common.service.CommonService; import com.zy.common.utils.RedisUtil; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.CrnModeType; import com.zy.core.enums.CrnStatusType; import com.zy.core.enums.SlaveType; import com.zy.core.enums.WrkIoType; import com.zy.core.enums.WrkStsType; import com.zy.core.model.Task; import com.zy.core.model.command.CrnCommand; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.thread.CrnThread; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.springframework.test.util.ReflectionTestUtils; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class CrnOperateProcessUtilsTest { @AfterEach void tearDown() { safeClearQueue(1); safeClearQueue(2); SlaveConnection.remove(SlaveType.Crn, 1); SlaveConnection.remove(SlaveType.Crn, 2); SlaveConnection.remove(SlaveType.Devp, 101); } @Test void dispatchCrnMove_createsFormalTaskOnly() { CrnOperateProcessUtils utils = new CrnOperateProcessUtils(); WrkMastService wrkMastService = mock(WrkMastService.class); CommonService commonService = mock(CommonService.class); WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class); CrnThread crnThread = mock(CrnThread.class); ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService); ReflectionTestUtils.setField(utils, "commonService", commonService); ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService); when(wrkMastService.count(any())).thenReturn(0L); when(wrkMastService.getOne(any())).thenReturn(null); when(commonService.getWorkNo(WrkIoType.CRN_MOVE.id)).thenReturn(30001); AtomicReference savedSnapshot = new AtomicReference<>(); when(wrkMastService.save(any(WrkMast.class))).thenAnswer(invocation -> { WrkMast source = invocation.getArgument(0); WrkMast snapshot = new WrkMast(); snapshot.setWrkNo(source.getWrkNo()); snapshot.setIoType(source.getIoType()); snapshot.setWrkSts(source.getWrkSts()); snapshot.setLocNo(source.getLocNo()); snapshot.setCrnNo(source.getCrnNo()); savedSnapshot.set(snapshot); return true; }); MessageQueue.init(SlaveType.Crn, 1); CrnProtocol protocol = buildProtocol(1, CrnStatusType.IDLE.id, 0); protocol.setBay(8); protocol.setLevel(3); when(crnThread.getStatus()).thenReturn(protocol); SlaveConnection.put(SlaveType.Crn, 1, crnThread); boolean dispatched = utils.dispatchCrnMove(1, "2-1-1"); assertTrue(dispatched); verify(wrkMastService).save(any(WrkMast.class)); WrkMast saved = savedSnapshot.get(); assertNotNull(saved); assertEquals(30001, saved.getWrkNo()); assertEquals(WrkIoType.CRN_MOVE.id, saved.getIoType()); assertEquals(WrkStsType.NEW_CRN_MOVE.sts, saved.getWrkSts()); assertEquals("2-1-1", saved.getLocNo()); assertEquals(1, saved.getCrnNo()); verify(wrkMastService, never()).updateById(any(WrkMast.class)); verify(wrkAnalysisService, never()).markCraneStart(any(WrkMast.class), any()); assertNull(MessageQueue.peek(SlaveType.Crn, 1)); } @Test void dispatchCrnMove_returnsFalseWhenOtherTaskRunning() { CrnOperateProcessUtils utils = new CrnOperateProcessUtils(); WrkMastService wrkMastService = mock(WrkMastService.class); CommonService commonService = mock(CommonService.class); WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class); ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService); ReflectionTestUtils.setField(utils, "commonService", commonService); ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService); when(wrkMastService.count(any())).thenReturn(1L); when(wrkMastService.getOne(any())).thenReturn(null); when(wrkMastService.save(any(WrkMast.class))).thenReturn(true); when(commonService.getWorkNo(WrkIoType.CRN_MOVE.id)).thenReturn(30001); boolean dispatched = utils.dispatchCrnMove(1, "2-1-1"); assertFalse(dispatched); verify(wrkMastService, never()).save(any(WrkMast.class)); verify(commonService, never()).getWorkNo(anyInt()); verify(wrkAnalysisService, never()).initForTask(any(WrkMast.class)); } @Test void crnIoExecuteNormal_prioritizesCrnMoveTask() { CrnOperateProcessUtils utils = new CrnOperateProcessUtils(); BasCrnpService basCrnpService = mock(BasCrnpService.class); WrkMastService wrkMastService = mock(WrkMastService.class); RedisUtil redisUtil = mock(RedisUtil.class); LocMastService locMastService = mock(LocMastService.class); NotifyUtils notifyUtils = mock(NotifyUtils.class); WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class); CrnThread crnThread = mock(CrnThread.class); ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService); ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService); ReflectionTestUtils.setField(utils, "redisUtil", redisUtil); ReflectionTestUtils.setField(utils, "locMastService", locMastService); ReflectionTestUtils.setField(utils, "notifyUtils", notifyUtils); ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService); when(basCrnpService.list(anyWrapper())).thenReturn(List.of(buildBasCrnp(1, "[[2,3]]", "[2]"))); when(redisUtil.get(anyString())).thenReturn(null); when(wrkMastService.count(any())).thenReturn(0L); when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true); WrkMast crnMoveTask = new WrkMast(); crnMoveTask.setWrkNo(30001); crnMoveTask.setCrnNo(1); crnMoveTask.setIoType(WrkIoType.CRN_MOVE.id); crnMoveTask.setWrkSts(WrkStsType.NEW_CRN_MOVE.sts); crnMoveTask.setLocNo("2-1-1"); crnMoveTask.setIoPri(999D); WrkMast locMoveTask = new WrkMast(); locMoveTask.setWrkNo(20001); locMoveTask.setCrnNo(1); locMoveTask.setIoType(WrkIoType.LOC_MOVE.id); locMoveTask.setWrkSts(WrkStsType.NEW_LOC_MOVE.sts); locMoveTask.setSourceLocNo("3-1-1"); locMoveTask.setLocNo("4-1-1"); locMoveTask.setIoPri(1D); when(wrkMastService.list(anyWrapper())) .thenReturn(new ArrayList<>(List.of(crnMoveTask))) .thenReturn(new ArrayList<>(List.of(locMoveTask, crnMoveTask))); LocMast sourceLoc = new LocMast(); sourceLoc.setLocNo("3-1-1"); sourceLoc.setLocSts("R"); LocMast targetLoc = new LocMast(); targetLoc.setLocNo("4-1-1"); targetLoc.setLocSts("S"); when(locMastService.getById("3-1-1")).thenReturn(sourceLoc); when(locMastService.getById("4-1-1")).thenReturn(targetLoc); CrnProtocol protocol = buildProtocol(1, CrnStatusType.IDLE.id, 0); protocol.setBay(1); protocol.setLevel(1); when(crnThread.getStatus()).thenReturn(protocol); CrnCommand moveCommand = new CrnCommand(); moveCommand.setCrnNo(1); moveCommand.setTaskNo(30001); when(crnThread.getMoveCommand("2-1-1", 30001, 1)).thenReturn(moveCommand); CrnCommand locMoveCommand = new CrnCommand(); locMoveCommand.setCrnNo(1); locMoveCommand.setTaskNo(20001); when(crnThread.getPickAndPutCommand("3-1-1", "4-1-1", 20001, 1)).thenReturn(locMoveCommand); MessageQueue.init(SlaveType.Crn, 1); SlaveConnection.put(SlaveType.Crn, 1, crnThread); utils.crnIoExecuteNormal(); ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(WrkMast.class); verify(wrkMastService).updateById(updateCaptor.capture()); assertEquals(30001, updateCaptor.getValue().getWrkNo()); assertEquals(WrkStsType.CRN_MOVE_RUN.sts, updateCaptor.getValue().getWrkSts()); verify(wrkAnalysisService).markCraneStart(any(WrkMast.class), any()); Task task = MessageQueue.peek(SlaveType.Crn, 1); assertNotNull(task); assertSame(moveCommand, task.getData()); } @Test void crnIoExecuteNormal_allowsOtherCraneToRunWhenOneCraneHasMoveTask() { CrnOperateProcessUtils utils = new CrnOperateProcessUtils(); BasCrnpService basCrnpService = mock(BasCrnpService.class); WrkMastService wrkMastService = mock(WrkMastService.class); RedisUtil redisUtil = mock(RedisUtil.class); LocMastService locMastService = mock(LocMastService.class); NotifyUtils notifyUtils = mock(NotifyUtils.class); WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class); CrnThread crnThread1 = mock(CrnThread.class); CrnThread crnThread2 = mock(CrnThread.class); ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService); ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService); ReflectionTestUtils.setField(utils, "redisUtil", redisUtil); ReflectionTestUtils.setField(utils, "locMastService", locMastService); ReflectionTestUtils.setField(utils, "notifyUtils", notifyUtils); ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService); when(basCrnpService.list(anyWrapper())).thenReturn(List.of( buildBasCrnp(1, "[[2,3]]", "[2]"), buildBasCrnp(2, "[[4,5]]", "[4]") )); when(redisUtil.get(anyString())).thenReturn(null); when(wrkMastService.count(any())).thenReturn(0L); when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true); WrkMast crnMoveTask = new WrkMast(); crnMoveTask.setWrkNo(30001); crnMoveTask.setCrnNo(1); crnMoveTask.setIoType(WrkIoType.CRN_MOVE.id); crnMoveTask.setWrkSts(WrkStsType.NEW_CRN_MOVE.sts); crnMoveTask.setLocNo("2-1-1"); WrkMast locMoveTask = new WrkMast(); locMoveTask.setWrkNo(20002); locMoveTask.setCrnNo(2); locMoveTask.setIoType(WrkIoType.LOC_MOVE.id); locMoveTask.setWrkSts(WrkStsType.NEW_LOC_MOVE.sts); locMoveTask.setSourceLocNo("4-1-1"); locMoveTask.setLocNo("5-1-1"); locMoveTask.setIoPri(1D); when(wrkMastService.list(anyWrapper())) .thenReturn(new ArrayList<>(List.of(crnMoveTask))) .thenReturn(new ArrayList<>(List.of(crnMoveTask))) .thenReturn(new ArrayList<>(List.of(locMoveTask))); LocMast sourceLoc = new LocMast(); sourceLoc.setLocNo("4-1-1"); sourceLoc.setLocSts("R"); LocMast targetLoc = new LocMast(); targetLoc.setLocNo("5-1-1"); targetLoc.setLocSts("S"); when(locMastService.getById("4-1-1")).thenReturn(sourceLoc); when(locMastService.getById("5-1-1")).thenReturn(targetLoc); CrnProtocol protocol1 = buildProtocol(1, CrnStatusType.IDLE.id, 0); when(crnThread1.getStatus()).thenReturn(protocol1); CrnProtocol protocol2 = buildProtocol(2, CrnStatusType.IDLE.id, 0); when(crnThread2.getStatus()).thenReturn(protocol2); CrnCommand moveCommand = new CrnCommand(); moveCommand.setCrnNo(1); moveCommand.setTaskNo(30001); when(crnThread1.getMoveCommand("2-1-1", 30001, 1)).thenReturn(moveCommand); CrnCommand locMoveCommand = new CrnCommand(); locMoveCommand.setCrnNo(2); locMoveCommand.setTaskNo(20002); when(crnThread2.getPickAndPutCommand("4-1-1", "5-1-1", 20002, 2)).thenReturn(locMoveCommand); MessageQueue.init(SlaveType.Crn, 1); MessageQueue.init(SlaveType.Crn, 2); SlaveConnection.put(SlaveType.Crn, 1, crnThread1); SlaveConnection.put(SlaveType.Crn, 2, crnThread2); utils.crnIoExecuteNormal(); ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(WrkMast.class); verify(wrkMastService, times(2)).updateById(updateCaptor.capture()); List updatedList = updateCaptor.getAllValues(); assertEquals(30001, updatedList.get(0).getWrkNo()); assertEquals(WrkStsType.CRN_MOVE_RUN.sts, updatedList.get(0).getWrkSts()); assertEquals(20002, updatedList.get(1).getWrkNo()); assertEquals(WrkStsType.LOC_MOVE_RUN.sts, updatedList.get(1).getWrkSts()); Task task1 = MessageQueue.peek(SlaveType.Crn, 1); assertNotNull(task1); assertSame(moveCommand, task1.getData()); Task task2 = MessageQueue.peek(SlaveType.Crn, 2); assertNotNull(task2); assertSame(locMoveCommand, task2.getData()); } @Test void crnIoExecuteFinish_marksCrnMoveTaskComplete() { CrnOperateProcessUtils utils = new CrnOperateProcessUtils(); BasCrnpService basCrnpService = mock(BasCrnpService.class); WrkMastService wrkMastService = mock(WrkMastService.class); RedisUtil redisUtil = mock(RedisUtil.class); WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class); CrnThread crnThread = mock(CrnThread.class); ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService); ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService); ReflectionTestUtils.setField(utils, "redisUtil", redisUtil); ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService); when(basCrnpService.list(anyWrapper())).thenReturn(List.of(buildBasCrnp(1, "[[2,3]]", "[2]"))); when(redisUtil.get(anyString())).thenReturn(null); when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true); CrnProtocol protocol = buildProtocol(1, CrnStatusType.WAITING.id, 30001); when(crnThread.getStatus()).thenReturn(protocol); WrkMast wrkMast = new WrkMast(); wrkMast.setWrkNo(30001); wrkMast.setIoType(WrkIoType.CRN_MOVE.id); wrkMast.setWrkSts(WrkStsType.CRN_MOVE_RUN.sts); wrkMast.setCrnNo(1); when(wrkMastService.selectByWorkNo(30001)).thenReturn(wrkMast); CrnCommand resetCommand = new CrnCommand(); resetCommand.setCrnNo(1); resetCommand.setTaskNo(30001); when(crnThread.getResetCommand(30001, 1)).thenReturn(resetCommand); MessageQueue.init(SlaveType.Crn, 1); SlaveConnection.put(SlaveType.Crn, 1, crnThread); utils.crnIoExecuteFinish(); ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(WrkMast.class); verify(wrkMastService, times(1)).updateById(updateCaptor.capture()); assertEquals(WrkStsType.COMPLETE_CRN_MOVE.sts, updateCaptor.getValue().getWrkSts()); verify(wrkAnalysisService).markCraneComplete(any(WrkMast.class), any(), eq(WrkStsType.COMPLETE_CRN_MOVE.sts)); Task task = MessageQueue.peek(SlaveType.Crn, 1); assertNotNull(task); assertSame(resetCommand, task.getData()); } private BasCrnp buildBasCrnp(int crnNo, String controlRows, String deepRows) { BasCrnp basCrnp = new BasCrnp(); basCrnp.setCrnNo(crnNo); basCrnp.setControlRows(controlRows); basCrnp.setDeepRows(deepRows); return basCrnp; } private CrnProtocol buildProtocol(int crnNo, int status, int taskNo) { CrnProtocol protocol = new CrnProtocol(); protocol.setCrnNo(crnNo); protocol.setMode(CrnModeType.AUTO.id); protocol.setTaskNo(taskNo); protocol.setStatus(status); protocol.setLoaded(0); protocol.setForkPos(0); protocol.setAlarm(0); return protocol; } private void safeClearQueue(int crnNo) { try { MessageQueue.clear(SlaveType.Crn, crnNo); } catch (Exception ignore) { } } @SuppressWarnings("unchecked") private Wrapper anyWrapper() { return any(Wrapper.class); } }