Przeglądaj źródła

test: 修复 MqttFaultConsumerTest 和 MqttStatusConsumerTest 编译与测试失败

- MqttFaultConsumerTest: 同步主代码重构后的方法签名
  - insertAlarm 调用在主代码中已注释掉,移除对应 verify
  - insertFault → insertAlertData (9 参数)
  - updateFault → updateAlertData (7 参数)
- MqttStatusConsumerTest: 同步 MqttStatusConsumer 重构
  - ValueOperations mock → HashOperations mock
  - opsForValue().set() → opsForHash().putAll()
  - 移除 fleet_id 相关测试数据(主代码已不再使用)
- CLAUDE.md: 更新 Redis key patterns 和 TDengine 连接说明
master
humanleft 2 tygodni temu
rodzic
commit
3de775eed1

+ 11
- 6
CLAUDE.md Wyświetl plik

@@ -55,16 +55,18 @@ iot-platform/
55 55
 ### TDengine (Time-Series Database)
56 56
 - Used for high-frequency IoT telemetry ingestion
57 57
 - Connection pool: HikariCP via `TDengineService`
58
-- Connects to `jdbc:TAOS://172.21.185.173:6031/` (host network, via host IP)
58
+- Connects to `jdbc:TAOS://host.containers.internal:6031/` (container bridge network via host gateway)
59 59
 - Super-table pattern with column caching (`stableColumnCache`)
60 60
 
61 61
 ### Redis
62 62
 - Host: `${REDIS_HOST:localhost}:6379` (production overrides via `REDIS_HOST` env var)
63 63
 - Key patterns (defined in `common/RedisKeys.java`):
64
-  - `DSB:active:devices` — Set of active IoT device keys
65
-  - `DSB:<controllerId>:<metricName>` — Hash storing device telemetry
66
-  - `workorder:coordinate:<controllerId>` — GPS coordinates
67
-  - `<controllerId>:<topicName>` — MQTT topic metadata
64
+  - `iot:dsb:active:devices` — Set of active IoT device keys
65
+  - `iot:dsb:<controllerId>:<metricName>` — Hash storing device telemetry
66
+  - `iot:workorder:coordinate:<controllerId>` — GPS coordinates
67
+  - `iot:controller:<controllerId>:status` — Controller status hash (MqttStatusConsumer)
68
+  - `iot:controller:<controllerId>:<topicName>` — MQTT topic metadata
69
+  - `iot:controller:<controllerId>_fault:<topicName>` — Fault topic metadata
68 70
 
69 71
 ## Key Configuration Files
70 72
 
@@ -100,7 +102,10 @@ MQTT Broker (47.104.204.180:1883)
100 102
     ↓  subscribes to "+/generics", "+/status", "+/fault"
101 103
 MqttGenericConsumer / MqttStatusConsumer / MqttFaultConsumer
102 104
     ↓  parse JSON → ControllerData
103
-    ├─→ Redis (DSB:active:devices, DSB:<id>:<metric> hashes)
105
+    ├─→ Redis
106
+    │     ├─ iot:dsb:active:devices (active device set)
107
+    │     ├─ iot:dsb:<id>:<metric> (telemetry hashes)
108
+    │     └─ iot:controller:<id>:status (status hashes, MqttStatusConsumer)
104 109
     ├─→ MySQL (sys_controller, sys_device tables)
105 110
     └─→ TDengine (time-series telemetry tables)
106 111
 

+ 2
- 4
iot-platform/src/test/java/com/iot/platform/mqtt/MqttFaultConsumerTest.java Wyświetl plik

@@ -188,8 +188,7 @@ class MqttFaultConsumerTest {
188 188
 
189 189
         mqttFaultConsumer.triggerMethod(topic, faultData);
190 190
 
191
-        verify(sysAlarmService).insertAlarm(anyString(), eq("GJ123456789"), eq("overtemperature"), eq("0"), anyString(), eq("0"), eq("ctrl1"), eq("dev1"), eq("116.3974"), eq("39.9093"));
192
-        verify(sysFaultService).insertFault(eq("GJ123456789"), eq("overtemperature"), eq("0"), anyString(), eq("0"), eq("ctrl1"), eq("dev1"), eq("116.3974"), eq("39.9093"), eq(""));
191
+        verify(sysFaultService).insertAlertData(eq("GJ123456789"), eq("overtemperature"), eq("0"), anyString(), eq("0"), eq("ctrl1"), eq("dev1"), eq(""), anyString());
193 192
     }
194 193
 
195 194
     @Test
@@ -216,7 +215,6 @@ class MqttFaultConsumerTest {
216 215
 
217 216
         mqttFaultConsumer.triggerMethod(topic, faultData);
218 217
 
219
-        verify(sysAlarmService).insertAlarm(anyString(), eq("GJ987654321"), eq("overtemperature recovered"), eq("1"), anyString(), eq("0"), eq("ctrl1"), eq("dev1"), eq("116.3974"), eq("39.9093"));
220
-        verify(sysFaultService).updateFault(eq("1"), eq("0"), eq("116.3974"), eq("39.9093"), eq("overtemperature recovered"), eq("ctrl1"), eq("dev1"), anyString());
218
+        verify(sysFaultService).updateAlertData(eq("1"), eq("0"), eq("overtemperature recovered"), eq("ctrl1"), eq("dev1"), anyString(), anyString());
221 219
     }
222 220
 }

+ 19
- 18
iot-platform/src/test/java/com/iot/platform/mqtt/MqttStatusConsumerTest.java Wyświetl plik

@@ -9,14 +9,17 @@ import org.junit.jupiter.api.Test;
9 9
 import org.junit.jupiter.api.extension.ExtendWith;
10 10
 import org.mockito.Mock;
11 11
 import org.mockito.junit.jupiter.MockitoExtension;
12
+import org.springframework.data.redis.core.HashOperations;
12 13
 import org.springframework.data.redis.core.StringRedisTemplate;
13
-import org.springframework.data.redis.core.ValueOperations;
14 14
 
15
+import java.util.Collections;
15 16
 import java.util.concurrent.ExecutorService;
16 17
 import java.util.concurrent.Executors;
17 18
 
18 19
 import static org.assertj.core.api.Assertions.assertThat;
20
+import static org.mockito.ArgumentMatchers.any;
19 21
 import static org.mockito.ArgumentMatchers.anyString;
22
+import static org.mockito.ArgumentMatchers.eq;
20 23
 import static org.mockito.Mockito.lenient;
21 24
 import static org.mockito.Mockito.never;
22 25
 import static org.mockito.Mockito.verify;
@@ -29,7 +32,7 @@ class MqttStatusConsumerTest {
29 32
     private StringRedisTemplate stringRedisTemplate;
30 33
 
31 34
     @Mock
32
-    private ValueOperations<String, String> valueOperations;
35
+    private HashOperations<String, Object, Object> hashOperations;
33 36
 
34 37
     @Mock
35 38
     private IotProperties iotProperties;
@@ -44,7 +47,8 @@ class MqttStatusConsumerTest {
44 47
     @BeforeEach
45 48
     void setUp() {
46 49
         mqttStatusConsumer = new MqttStatusConsumer(executorService, iotProperties, stringRedisTemplate, sysStatusService);
47
-        lenient().when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
50
+        lenient().when(stringRedisTemplate.opsForHash()).thenReturn(hashOperations);
51
+        lenient().when(hashOperations.entries(anyString())).thenReturn(Collections.emptyMap());
48 52
     }
49 53
 
50 54
     @Test
@@ -68,11 +72,11 @@ class MqttStatusConsumerTest {
68 72
     @Test
69 73
     @DisplayName("handleMessage with valid JSON writes status to Redis")
70 74
     void handleMessage_validJson_writesStatusToRedis() throws Exception {
71
-        String json = "{\"controller_id\":\"CTRL_001\",\"fleet_id\":\"FLEET_001\",\"status\":\"online\"}";
75
+        String json = "{\"controller_id\":\"CTRL_001\",\"status\":\"online\"}";
72 76
 
73 77
         mqttStatusConsumer.handleMessage("+/status", json);
74 78
 
75
-        verify(valueOperations).set("CTRL_001_FLEET_001", "online");
79
+        verify(hashOperations).putAll(eq("status_CTRL_001"), any());
76 80
     }
77 81
 
78 82
     @Test
@@ -82,39 +86,36 @@ class MqttStatusConsumerTest {
82 86
 
83 87
         mqttStatusConsumer.handleMessage("+/status", invalidJson);
84 88
 
85
-        verify(valueOperations, never()).set(anyString(), anyString());
89
+        verify(hashOperations, never()).putAll(anyString(), any());
86 90
     }
87 91
 
88 92
     @Test
89 93
     @DisplayName("handleMessage with blank controllerId skips processing")
90 94
     void handleMessage_blankControllerId_skipsProcessing() throws Exception {
91
-        String json = "{\"controller_id\":\"\",\"fleet_id\":\"FLEET_001\",\"status\":\"online\"}";
95
+        String json = "{\"controller_id\":\"\",\"status\":\"online\"}";
92 96
 
93 97
         mqttStatusConsumer.handleMessage("+/status", json);
94 98
 
95
-        verify(valueOperations, never()).set(anyString(), anyString());
99
+        verify(hashOperations, never()).putAll(anyString(), any());
96 100
     }
97 101
 
98 102
     @Test
99
-    @DisplayName("handleMessage with null fleetId skips processing")
100
-    void handleMessage_nullFleetId_skipsProcessing() throws Exception {
101
-        JSONObject payload = new JSONObject();
102
-        payload.put("controller_id", "CTRL_001");
103
-        payload.put("fleet_id", null);
104
-        payload.put("status", "online");
103
+    @DisplayName("handleMessage without fleetId still processes normally")
104
+    void handleMessage_withoutFleetId_stillProcesses() throws Exception {
105
+        String json = "{\"controller_id\":\"CTRL_001\",\"status\":\"online\"}";
105 106
 
106
-        mqttStatusConsumer.handleMessage("+/status", payload.toJSONString());
107
+        mqttStatusConsumer.handleMessage("+/status", json);
107 108
 
108
-        verify(valueOperations, never()).set(anyString(), anyString());
109
+        verify(hashOperations).putAll(eq("status_CTRL_001"), any());
109 110
     }
110 111
 
111 112
     @Test
112 113
     @DisplayName("handleMessage with blank status skips processing")
113 114
     void handleMessage_blankStatus_skipsProcessing() throws Exception {
114
-        String json = "{\"controller_id\":\"CTRL_001\",\"fleet_id\":\"FLEET_001\",\"status\":\"   \"}";
115
+        String json = "{\"controller_id\":\"CTRL_001\",\"status\":\"   \"}";
115 116
 
116 117
         mqttStatusConsumer.handleMessage("+/status", json);
117 118
 
118
-        verify(valueOperations, never()).set(anyString(), anyString());
119
+        verify(hashOperations, never()).putAll(anyString(), any());
119 120
     }
120 121
 }

Ładowanie…
Anuluj
Zapisz