thingsboard-client-demo/src/test/java/com/tuoheng/machine/ComplexTreeTest.java

174 lines
6.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<String, Object> params = new HashMap<>();
params.put("complexRootShouldFail", false);
CompletableFuture<CommandResult> 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<String, Object> params = new HashMap<>();
params.put("complexRootShouldFail", true);
CompletableFuture<CommandResult> 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();
}
}