package com.tuoheng.machine; import com.tuoheng.machine.command.CommandResult; import com.tuoheng.machine.command.CommandType; import com.tuoheng.machine.mqtt.MqttCallbackRegistry; import com.tuoheng.machine.state.*; import com.tuoheng.machine.vendor.VendorRegistry; import com.tuoheng.machine.vendor.test.TestVendorConfig; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.HashMap; import java.util.Map; import java.util.concurrent.*; import static org.junit.jupiter.api.Assertions.*; /** * 复杂指令树测试 * 测试9-10: 复杂指令树(成功路径/失败路径) */ @SpringBootTest @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class ComplexTreeTest { @Autowired MachineCommandManager machineCommandManager; @Autowired MqttCallbackRegistry mqttCallbackRegistry; @Autowired VendorRegistry vendorRegistry; private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); private static final String TEST_SN = "COMPLEX_TREE_TEST_SN"; @BeforeAll public static void setupAll() { log.info("=== 复杂指令树测试初始化 ==="); } @BeforeEach public void beforeEach(TestInfo testInfo) { log.info("\n========================================"); log.info("开始测试: {}", testInfo.getDisplayName()); log.info("========================================"); // 注册测试厂家配置 TestVendorConfig testVendorConfig = new TestVendorConfig(); vendorRegistry.registerVendor(testVendorConfig); // 绑定SN到测试厂家 vendorRegistry.bindSnToVendor(TEST_SN, "TEST"); // 初始化机器状态 MachineStates initialStates = new MachineStates(); initialStates.setAirportState(AirportState.ONLINE); initialStates.setDroneState(DroneState.ONLINE); machineCommandManager.updateMachineStates(TEST_SN, initialStates, true); } @AfterEach public void afterEach(TestInfo testInfo) { log.info("完成测试: {}", testInfo.getDisplayName()); log.info("========================================\n"); try { Thread.sleep(500); } catch (InterruptedException e) { log.warn("等待时被中断", e); } } /** * 测试9: 复杂指令树场景(成功路径) */ @Test @Order(9) @DisplayName("测试9: 复杂指令树场景(成功路径)") public void testComplexInstructionTreeSuccess() throws ExecutionException, InterruptedException { log.info(">>> 场景:复杂的多层嵌套指令树,走成功分支"); Map params = new HashMap<>(); params.put("complexRootShouldFail", false); CompletableFuture future = machineCommandManager.executeCommand(TEST_SN, CommandType.ENTER_DRC_MODE, params); scheduler.schedule(() -> { try { Thread.sleep(100); String response = "{\"result\":\"success\"}"; mqttCallbackRegistry.handleMessage("test/" + TEST_SN + "/response", response); log.info(">>> 模拟发送根指令方法回调(成功): {}", response); Thread.sleep(100); response = "{\"result\":\"complexSuccess\"}"; mqttCallbackRegistry.handleMessage("test/" + TEST_SN + "/response", response); log.info(">>> 模拟发送成功分支指令方法回调: {}", response); Thread.sleep(100); response = "{\"result\":\"complexCleanup\"}"; mqttCallbackRegistry.handleMessage("test/" + TEST_SN + "/response", response); log.info(">>> 模拟发送清理指令方法回调: {}", response); } catch (InterruptedException e) { e.printStackTrace(); } }, 200, TimeUnit.MILLISECONDS); CommandResult result = future.get(); assertTrue(result.isSuccess(), "复杂指令树应该执行成功"); log.info(">>> 测试通过:复杂指令树成功路径执行成功"); } /** * 测试10: 复杂指令树场景(失败路径) * 注意:通过让根指令超时来触发失败分支 */ @Test @Order(10) @DisplayName("测试10: 复杂指令树场景(失败路径)") public void testComplexInstructionTreeFailure() throws ExecutionException, InterruptedException { log.info(">>> 场景:复杂的多层嵌套指令树,走失败分支"); log.info(">>> 策略:让根指令超时失败,触发失败分支"); Map params = new HashMap<>(); params.put("complexRootShouldFail", true); CompletableFuture future = machineCommandManager.executeCommand(TEST_SN, CommandType.ENTER_DRC_MODE, params); scheduler.schedule(() -> { try { // 不发送根指令的回调,让它超时(5秒后) // 等待根指令超时后,发送失败分支的回调 log.info(">>> 等待根指令超时,触发失败分支..."); Thread.sleep(6000); // 等待超过5秒超时时间 // 发送失败分支指令的回调 String response = "{\"result\":\"complexFailure\"}"; mqttCallbackRegistry.handleMessage("test/" + TEST_SN + "/response", response); log.info(">>> 模拟发送失败分支指令方法回调: {}", response); Thread.sleep(100); // 发送清理指令的回调 response = "{\"result\":\"complexCleanup\"}"; mqttCallbackRegistry.handleMessage("test/" + TEST_SN + "/response", response); log.info(">>> 模拟发送清理指令方法回调: {}", response); } catch (InterruptedException e) { e.printStackTrace(); } }, 200, TimeUnit.MILLISECONDS); CommandResult result = future.get(); assertTrue(result.isSuccess(), "复杂指令树应该通过失败分支和清理成功"); log.info(">>> 测试通过:复杂指令树失败路径执行成功"); } @AfterAll public static void cleanupAll() { log.info("=== 复杂指令树测试完成 ==="); scheduler.shutdown(); } }