package com.tuoheng.machine; import com.tuoheng.machine.events.DrcEvent; import com.tuoheng.machine.platform.PlatformType; import com.tuoheng.machine.platform.factory.PlatformStrategyFactory; import com.tuoheng.machine.repository.AirportPlatformRepository; import com.tuoheng.machine.service.DrcMachineService; import com.tuoheng.machine.status.DrcState; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; /** * DRC状态机测试 * 测试DRC模式的完整状态转换流程 */ @SpringBootTest public class DrcStateMachineTest { @Autowired private DrcMachineService drcMachineService; @Autowired private PlatformStrategyFactory platformStrategyFactory; @MockBean private AirportPlatformRepository airportPlatformRepository; private static final String TEST_AIRPORT_SN = "test-airport-001"; /** * 测试 Spring Boot 依赖注入是否正常工作 */ @Test public void testAutowiredInjection() { System.out.println("\n========== 测试依赖注入 =========="); // 验证 PlatformStrategyFactory 是否成功注入 assertNotNull(platformStrategyFactory, "PlatformStrategyFactory 应该被成功注入"); System.out.println("✓ PlatformStrategyFactory 注入成功: " + platformStrategyFactory.getClass().getName()); // 验证 DrcMachineService 是否成功注入 assertNotNull(drcMachineService, "DrcMachineService 应该被成功注入"); System.out.println("✓ DrcMachineService 注入成功: " + drcMachineService.getClass().getName()); // 验证 AirportPlatformRepository Mock 是否成功 assertNotNull(airportPlatformRepository, "AirportPlatformRepository Mock 应该被成功创建"); System.out.println("✓ AirportPlatformRepository Mock 创建成功"); // 配置 Mock 行为 when(airportPlatformRepository.getPlatformType(anyString())).thenReturn(PlatformType.DJI); // 测试 Mock 是否工作 PlatformType platformType = airportPlatformRepository.getPlatformType(TEST_AIRPORT_SN); assertEquals(PlatformType.DJI, platformType, "Mock 应该返回 DJI 平台类型"); System.out.println("✓ Mock 行为配置成功,返回平台类型: " + platformType.getName()); System.out.println("\n========== 依赖注入测试通过 ✓ ==========\n"); } // private DrcMachineService drcMachineService; // private PlatformStrategyFactory platformStrategyFactory; // private AnnotationConfigApplicationContext context; // // private static final String TEST_AIRPORT_SN = "test-airport-001"; // // /** // * 测试配置类 // */ // @Configuration // static class TestConfig { // @Bean // public RedisStateStore redisStateStore() { // return new RedisStateStore(); // } // // @Bean // public DjiCanEnterGuard djiCanEnterGuard() { // return new DjiCanEnterGuard(); // } // // @Bean // public DjiCanExitGuard djiCanExitGuard() { // return new DjiCanExitGuard(); // } // // @Bean // public DjiEnterAction djiEnterAction() { // return new DjiEnterAction(); // } // // @Bean // public DjiEnteredAction djiEnteredAction() { // return new DjiEnteredAction(); // } // // @Bean // public DjiExitAction djiExitAction() { // return new DjiExitAction(); // } // // @Bean // public DjiExitedAction djiExitedAction() { // return new DjiExitedAction(); // } // // @Bean // public DjiDrcListener djiDrcListener() { // return new DjiDrcListener(); // } // // @Bean // public DjiDrcPlatformStrategy djiDrcPlatformStrategy() { // return new DjiDrcPlatformStrategy(); // } // // @Bean // public AirportPlatformRepository airportPlatformRepository() { // // Mock实现,返回DJI平台类型 // return new AirportPlatformRepository() { // @Override // public PlatformType getPlatformType(String sn) { // return PlatformType.DJI; // } // // @Override // public void registerAirport(String sn, PlatformType platformType) { // } // }; // } // // @Bean // public PlatformStrategyFactory platformStrategyFactory() { // return new PlatformStrategyFactory(); // } // // @Bean // public DrcMachineConfig drcMachineConfig() { // return new DrcMachineConfig(); // } // // @Bean // public DrcMachineService drcMachineService() { // return new DrcMachineService(); // } // } // // @Override // protected void setUp() throws Exception { // super.setUp(); // System.out.println("========== 开始DRC状态机测试 =========="); // // // 初始化Spring上下文 // context = new AnnotationConfigApplicationContext(TestConfig.class); // drcMachineService = context.getBean(DrcMachineService.class); // platformStrategyFactory = context.getBean(PlatformStrategyFactory.class); // } // // @Override // protected void tearDown() throws Exception { // if (context != null) { // context.close(); // } // super.tearDown(); // } // // /** // * 测试DRC状态机的完整流程: // * UNKNOWN -> EXITED -> ENTERING -> ENTERED -> EXITING -> EXITED // */ // @Test // public void testDrcCompleteFlow() { // System.out.println("\n========== 测试DRC完整流程 =========="); // // // 1. 初始状态应该是 UNKNOWN // DrcState initialState = drcMachineService.getCurrentState(TEST_AIRPORT_SN); // assertNotNull("状态机应该已创建", initialState); // assertEquals("初始状态应该是UNKNOWN", DrcState.UNKNOWN, initialState); // System.out.println("✓ 步骤1: 初始状态验证通过 - UNKNOWN"); // // // 2. 从 UNKNOWN 同步到 EXITED(退出状态) // boolean syncResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertTrue("同步到EXITED应该成功", syncResult); // assertEquals("当前状态应该是EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 步骤2: UNKNOWN -> EXITED 转换成功"); // // // 3. 进入DRC模式:EXITED -> ENTERING // boolean enterResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTER); // assertTrue("进入DRC模式应该成功", enterResult); // assertEquals("当前状态应该是ENTERING", DrcState.ENTERING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 步骤3: EXITED -> ENTERING 转换成功"); // // // 4. 进入完成:ENTERING -> ENTERED // boolean enteredResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTERED); // assertTrue("进入完成应该成功", enteredResult); // assertEquals("当前状态应该是ENTERED", DrcState.ENTERED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 步骤4: ENTERING -> ENTERED 转换成功"); // // // 5. 退出DRC模式:ENTERED -> EXITING // boolean exitResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXIT); // assertTrue("退出DRC模式应该成功", exitResult); // assertEquals("当前状态应该是EXITING", DrcState.EXITING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 步骤5: ENTERED -> EXITING 转换成功"); // // // 6. 退出完成:EXITING -> EXITED // boolean exitedResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertTrue("退出完成应该成功", exitedResult); // assertEquals("当前状态应该是EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 步骤6: EXITING -> EXITED 转换成功"); // // System.out.println("\n========== DRC完整流程测试通过 ✓ ==========\n"); // } // // /** // * 测试DRC状态机的循环流程: // * 可以多次进入和退出DRC模式 // */ // @Test // public void testDrcCycleFlow() { // System.out.println("\n========== 测试DRC循环流程 =========="); // // // 初始化到EXITED状态 // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertEquals("初始状态应该是EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // // 第一次循环:进入 -> 退出 // System.out.println("\n--- 第一次循环 ---"); // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTER); // assertEquals("应该进入ENTERING状态", DrcState.ENTERING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTERED); // assertEquals("应该进入ENTERED状态", DrcState.ENTERED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXIT); // assertEquals("应该进入EXITING状态", DrcState.EXITING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertEquals("应该回到EXITED状态", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 第一次循环完成"); // // // 第二次循环:再次进入 -> 退出 // System.out.println("\n--- 第二次循环 ---"); // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTER); // assertEquals("应该再次进入ENTERING状态", DrcState.ENTERING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTERED); // assertEquals("应该再次进入ENTERED状态", DrcState.ENTERED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXIT); // assertEquals("应该再次进入EXITING状态", DrcState.EXITING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertEquals("应该再次回到EXITED状态", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 第二次循环完成"); // // System.out.println("\n========== DRC循环流程测试通过 ✓ ==========\n"); // } // // /** // * 测试非法状态转换 // * 验证状态机会拒绝不合法的状态转换 // */ // @Test // public void testInvalidStateTransitions() { // System.out.println("\n========== 测试非法状态转换 =========="); // // // 初始化到EXITED状态 // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // assertEquals("初始状态应该是EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // // 尝试从EXITED直接到ENTERED(应该失败) // boolean invalidResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTERED); // assertFalse("从EXITED直接到ENTERED应该失败", invalidResult); // assertEquals("状态应该保持EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 非法转换被正确拒绝: EXITED -X-> ENTERED"); // // // 进入ENTERING状态 // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.ENTER); // assertEquals("应该进入ENTERING状态", DrcState.ENTERING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // // // 尝试从ENTERING直接到EXITING(应该失败) // invalidResult = drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXIT); // assertFalse("从ENTERING直接到EXITING应该失败", invalidResult); // assertEquals("状态应该保持ENTERING", DrcState.ENTERING, // drcMachineService.getCurrentState(TEST_AIRPORT_SN)); // System.out.println("✓ 非法转换被正确拒绝: ENTERING -X-> EXITING"); // // System.out.println("\n========== 非法状态转换测试通过 ✓ ==========\n"); // } // // /** // * 测试状态机的状态查询功能 // */ // @Test // public void testStateQuery() { // System.out.println("\n========== 测试状态查询功能 =========="); // // // 初始化到EXITED状态 // drcMachineService.sendEvent(TEST_AIRPORT_SN, DrcEvent.EXITED); // // // 测试getCurrentState // DrcState currentState = drcMachineService.getCurrentState(TEST_AIRPORT_SN); // assertNotNull("当前状态不应该为null", currentState); // assertEquals("当前状态应该是EXITED", DrcState.EXITED, currentState); // System.out.println("✓ getCurrentState() 工作正常"); // // // 测试getCurrentStates(获取状态字符串) // String statesString = drcMachineService.getCurrentStates(TEST_AIRPORT_SN); // assertNotNull("状态字符串不应该为null", statesString); // assertTrue("状态字符串应该包含EXITED", statesString.contains("EXITED")); // System.out.println("✓ getCurrentStates() 工作正常: " + statesString); // // // 测试isInState // boolean isInExited = drcMachineService.isInState(TEST_AIRPORT_SN, DrcState.EXITED); // assertTrue("应该处于EXITED状态", isInExited); // System.out.println("✓ isInState() 工作正常"); // // boolean isInEntered = drcMachineService.isInState(TEST_AIRPORT_SN, DrcState.ENTERED); // assertFalse("不应该处于ENTERED状态", isInEntered); // System.out.println("✓ isInState() 负面测试通过"); // // System.out.println("\n========== 状态查询功能测试通过 ✓ ==========\n"); // } // // /** // * 测试状态机管理功能 // */ // @Test // public void testStateMachineManagement() { // System.out.println("\n========== 测试状态机管理功能 =========="); // // String testAirport = "test-airport-mgmt"; // // // 测试状态机创建 // assertFalse("状态机应该不存在", drcMachineService.hasStateMachine(testAirport)); // drcMachineService.getOrCreateStateMachine(testAirport); // assertTrue("状态机应该已创建", drcMachineService.hasStateMachine(testAirport)); // System.out.println("✓ 状态机创建成功"); // // // 测试状态机计数 // int count = drcMachineService.getStateMachineCount(); // assertTrue("状态机数量应该大于0", count > 0); // System.out.println("✓ 状态机计数: " + count); // // // 测试状态机重启 // drcMachineService.sendEvent(testAirport, DrcEvent.EXITED); // assertEquals("状态应该是EXITED", DrcState.EXITED, // drcMachineService.getCurrentState(testAirport)); // // drcMachineService.restartStateMachine(testAirport); // assertEquals("重启后状态应该回到UNKNOWN", DrcState.UNKNOWN, // drcMachineService.getCurrentState(testAirport)); // System.out.println("✓ 状态机重启成功"); // // // 测试状态机移除 // drcMachineService.removeStateMachine(testAirport); // assertFalse("状态机应该已移除", drcMachineService.hasStateMachine(testAirport)); // System.out.println("✓ 状态机移除成功"); // // System.out.println("\n========== 状态机管理功能测试通过 ✓ ==========\n"); // } }