385 lines
16 KiB
Java
385 lines
16 KiB
Java
|
|
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");
|
|||
|
|
// }
|
|||
|
|
}
|