修改测试用例

This commit is contained in:
孙小云 2025-12-18 16:19:55 +08:00
parent 7ff9c5780c
commit eabf668229
4 changed files with 62 additions and 46 deletions

View File

@ -64,8 +64,8 @@ public class MachineCommandManager {
* @param sn 设备SN号
* @param newStates 新状态
*/
public void updateMachineStates(String sn, MachineStates newStates) {
stateManager.updateStates(sn, newStates);
public void updateMachineStates(String sn, MachineStates newStates,Boolean force) {
stateManager.updateStates(sn, newStates,force);
}
/**

View File

@ -1,3 +1,4 @@
单节点部署(默认)
# 使用内存存储(默认配置)
@ -8,7 +9,8 @@
machine.state.store.type=redis
# 配置节点ID可选不配置会自动生成
machine.node.id=node-1
#本地启动redis
#docker run --name some-redis -d -p 6379:6379 redi
# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

View File

@ -1,81 +1,92 @@
package com.tuoheng.machine.statemachine.store;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tuoheng.machine.state.MachineStates;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 基于 Redis 的设备状态存储实现
* 适用于多节点部署的生产环境
*
* Redis 数据结构
* - Key: machine:state:{sn}
* - Value: MachineStates (JSON)
* - TTL: 86400 24小时
*
* 使用方式
* 1. application.properties 中配置machine.state.store.type=redis
* 2. 实现 Redis 相关的序列化和反序列化逻辑
* 3. 配置 Redis 连接信息
*
* 注意当前为空实现需要在生产环境部署时完善
* 2. 配置 Redis 连接信息
*/
@Slf4j
@Component
@ConditionalOnProperty(name = "machine.state.store.type", havingValue = "redis")
public class RedisMachineStateStore implements MachineStateStore {
// TODO: 注入 RedisTemplate StringRedisTemplate
// private final RedisTemplate<String, MachineStates> redisTemplate;
private final StringRedisTemplate redisTemplate;
private final ObjectMapper objectMapper;
// TODO: 配置 Redis key 前缀
// private static final String KEY_PREFIX = "machine:state:";
// Redis key 前缀
private static final String KEY_PREFIX = "machine:state:";
// TODO: 配置状态的过期时间可选
// private static final long EXPIRE_SECONDS = 86400; // 24小时
// 配置状态的过期时间
private static final long EXPIRE_SECONDS = 86400; // 24小时
public RedisMachineStateStore() {
log.warn("使用 Redis 状态存储实现,但当前为空实现,请在生产环境部署前完善");
public RedisMachineStateStore(StringRedisTemplate redisTemplate, ObjectMapper objectMapper) {
this.redisTemplate = redisTemplate;
this.objectMapper = objectMapper;
log.info("使用 Redis 设备状态存储实现");
}
@Override
public MachineStates getStates(String sn) {
// TODO: 实现从 Redis 获取状态
// String key = KEY_PREFIX + sn;
// MachineStates states = redisTemplate.opsForValue().get(key);
// if (states == null) {
// states = new MachineStates();
// saveStates(sn, states);
// }
// return states;
String key = KEY_PREFIX + sn;
String json = redisTemplate.opsForValue().get(key);
log.warn("Redis 状态存储未实现,返回默认状态: sn={}", sn);
return new MachineStates();
if (json == null) {
log.debug("Redis 中不存在设备状态,返回默认状态: sn={}", sn);
MachineStates states = new MachineStates();
saveStates(sn, states);
return states;
}
try {
MachineStates states = objectMapper.readValue(json, MachineStates.class);
log.debug("从 Redis 获取设备状态: sn={}", sn);
return states;
} catch (JsonProcessingException e) {
log.error("反序列化设备状态失败: sn={}", sn, e);
return new MachineStates();
}
}
@Override
public void saveStates(String sn, MachineStates states) {
// TODO: 实现保存状态到 Redis
// String key = KEY_PREFIX + sn;
// redisTemplate.opsForValue().set(key, states, EXPIRE_SECONDS, TimeUnit.SECONDS);
// log.debug("保存设备状态到 Redis: sn={}", sn);
log.warn("Redis 状态存储未实现,跳过保存: sn={}", sn);
try {
String key = KEY_PREFIX + sn;
String json = objectMapper.writeValueAsString(states);
redisTemplate.opsForValue().set(key, json, EXPIRE_SECONDS, TimeUnit.SECONDS);
log.debug("保存设备状态到 Redis: sn={}", sn);
} catch (JsonProcessingException e) {
log.error("序列化设备状态失败: sn={}", sn, e);
}
}
@Override
public void removeStates(String sn) {
// TODO: 实现从 Redis 删除状态
// String key = KEY_PREFIX + sn;
// redisTemplate.delete(key);
// log.debug("从 Redis 中移除设备状态: sn={}", sn);
log.warn("Redis 状态存储未实现,跳过删除: sn={}", sn);
String key = KEY_PREFIX + sn;
redisTemplate.delete(key);
log.debug("从 Redis 中移除设备状态: sn={}", sn);
}
@Override
public boolean exists(String sn) {
// TODO: 实现检查 Redis 中是否存在状态
// String key = KEY_PREFIX + sn;
// return Boolean.TRUE.equals(redisTemplate.hasKey(key));
log.warn("Redis 状态存储未实现,返回 false: sn={}", sn);
return false;
String key = KEY_PREFIX + sn;
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}
}

View File

@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DrcStateMachineTest {
@ -57,6 +58,7 @@ public class DrcStateMachineTest {
initState = true;
// 使用 VendorRegistry 绑定 SN 到厂家
vendorRegistry.bindSnToVendor(SN, "DJI");
machineCommandManager.updateMachineStates(SN,new MachineStates(),true);
}
@Test
@ -81,7 +83,8 @@ public class DrcStateMachineTest {
public void checkTakeOffCommand() throws ExecutionException, InterruptedException {
CompletableFuture<CommandResult> future =
machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>());
assertFalse(future.get().isSuccess());
CommandResult result = future.get();
assertFalse(result.isSuccess());
}
@Test
@ -91,7 +94,7 @@ public class DrcStateMachineTest {
MachineStates machineStates = new MachineStates();
machineStates.setAirportState(AirportState.ONLINE);
machineStates.setDroneState(DroneState.ONLINE);
machineCommandManager.updateMachineStates(SN, machineStates);
machineCommandManager.updateMachineStates(SN, machineStates,false);
machineStates = machineCommandManager.getMachineStates(SN);
assertNotNull(machineStates);
@ -181,7 +184,7 @@ public class DrcStateMachineTest {
// 添加延迟等待状态回调监听器注册
try {
Thread.sleep(50); // 等待50ms
Thread.sleep(200); // 等待200ms
} catch (InterruptedException e) {
e.printStackTrace();
}