package com.tuoheng.old; import com.tuoheng.machine.MachineCommandManager; import com.tuoheng.machine.command.CommandResult; import com.tuoheng.machine.command.CommandType; import com.tuoheng.machine.mqtt.MqttCallbackRegistry; import com.tuoheng.machine.state.*; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.junit.jupiter.api.*; import org.springframework.util.Assert; import java.util.HashMap; import java.util.concurrent.*; import static org.junit.jupiter.api.Assertions.*; /** * DRC状态机测试 * 测试DRC模式的完整状态转换流程 */ @SpringBootTest @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class DrcStateMachineTest { @Autowired MachineCommandManager machineCommandManager; @Autowired MqttCallbackRegistry mqttCallbackRegistry; private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); private Boolean initState = false; private static final String SN = "SN9527"; @BeforeEach public void init(){ if(initState){ return; } initState = true; machineCommandManager.bindMachine(SN,"DJI"); } @Test @Order(1) public void checkInitState(){ MachineStates machineStates = machineCommandManager.getMachineStates(SN); assertNotNull(machineStates); assertEquals(AirportState.UNKNOWN, machineStates.getAirportState()); assertEquals(DrcState.UNKNOWN, machineStates.getDrcState()); assertEquals(CoverState.UNKNOWN, machineStates.getCoverState()); assertEquals(DroneState.UNKNOWN, machineStates.getDroneState()); assertEquals(StopState.UNKNOWN, machineStates.getStopState()); } /** * 非在线状态下不可起飞 * @throws ExecutionException * @throws InterruptedException */ @Test @Order(2) public void checkTakeOffCommand() throws ExecutionException, InterruptedException { CompletableFuture future = machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); assertFalse(future.get().isSuccess()); } @Test @Order(3) public void setState() { MachineStates machineStates = new MachineStates(); machineStates.setAirportState(AirportState.ONLINE); machineStates.setDroneState(DroneState.ONLINE); machineCommandManager.updateMachineStates(SN, machineStates); machineStates = machineCommandManager.getMachineStates(SN); assertNotNull(machineStates); assertEquals(AirportState.ONLINE, machineStates.getAirportState()); assertEquals(DroneState.ONLINE, machineStates.getDroneState()); assertEquals(DrcState.UNKNOWN, machineStates.getDrcState()); assertEquals(CoverState.UNKNOWN, machineStates.getCoverState()); assertEquals(StopState.UNKNOWN, machineStates.getStopState()); } // @Test // @Order(4) // public void checkTakeOffOverTime1() throws ExecutionException, InterruptedException, TimeoutException { // /** // * 指令执行超时;因为缺乏指令成功的回调 // */ // CompletableFuture future = // machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); // assertFalse(future.get().isSuccess()); // // } /** * 指令执行成功,因为mqttCallbackRegistry模拟了发送回调 * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中直接返回null */ // @Test // @Order(5) // public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { // // CompletableFuture future = // machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); // // scheduler.schedule(new Runnable() { // @Override // public void run() { // String response = "{\"data\":{\"result\":\"takeoff\"}}"; // mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); // } // },100,TimeUnit.MILLISECONDS); // // assertTrue(future.get().isSuccess()); // // } /** * 指令执行失败 * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中的注释放开 */ // @Test // @Order(5) // public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { // // CompletableFuture future = // machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); // // scheduler.schedule(new Runnable() { // @Override // public void run() { // String response = "{\"data\":{\"result\":\"takeoff\"}}"; // mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); // } // },100,TimeUnit.MILLISECONDS); // // assertFalse(future.get().isSuccess()); // } /** * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中的注释放开 * @throws ExecutionException * @throws InterruptedException * @throws TimeoutException */ @Test @Order(5) public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture future = machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); scheduler.schedule(new Runnable() { @Override public void run() { String response = "{\"data\":{\"result\":\"takeoff\"}}"; mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); // 添加延迟,等待状态回调监听器注册 try { Thread.sleep(50); // 等待50ms } catch (InterruptedException e) { e.printStackTrace(); } response = "{\"droneState\":\"FLYING\"}"; mqttCallbackRegistry.handleMessage("dji/SN9527/state",response); } },100,TimeUnit.MILLISECONDS); assertTrue(future.get().isSuccess()); } }