|
|
@@ -3,7 +3,6 @@ package com.water.iot.service;
|
|
3
|
3
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
4
|
4
|
import com.water.iot.entity.OtaFirmware;
|
|
5
|
5
|
import com.water.iot.entity.OtaTask;
|
|
6
|
|
-import com.water.iot.entity.OtaUpgradeRecord;
|
|
7
|
6
|
import org.junit.jupiter.api.BeforeEach;
|
|
8
|
7
|
import org.junit.jupiter.api.Test;
|
|
9
|
8
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
|
@@ -13,22 +12,19 @@ import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
13
|
12
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
14
|
13
|
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
|
15
|
14
|
|
|
16
|
|
-import java.util.*;
|
|
|
15
|
+import java.util.Collections;
|
|
|
16
|
+import java.util.List;
|
|
|
17
|
+import java.util.Map;
|
|
17
|
18
|
|
|
18
|
19
|
import static org.junit.jupiter.api.Assertions.*;
|
|
19
|
20
|
import static org.mockito.ArgumentMatchers.*;
|
|
20
|
21
|
import static org.mockito.Mockito.*;
|
|
21
|
22
|
|
|
22
|
|
-/**
|
|
23
|
|
- * OtaService 单元测试
|
|
24
|
|
- * Mock JdbcTemplate
|
|
25
|
|
- */
|
|
26
|
23
|
@ExtendWith(MockitoExtension.class)
|
|
27
|
24
|
class OtaServiceTest {
|
|
28
|
25
|
|
|
29
|
26
|
@Mock
|
|
30
|
27
|
private JdbcTemplate jdbcTemplate;
|
|
31
|
|
-
|
|
32
|
28
|
@Mock
|
|
33
|
29
|
private DeviceShadowService shadowService;
|
|
34
|
30
|
|
|
|
@@ -41,270 +37,288 @@ class OtaServiceTest {
|
|
41
|
37
|
}
|
|
42
|
38
|
|
|
43
|
39
|
@Test
|
|
44
|
|
- void createFirmware_shouldSetDraftStatusAndReturn() {
|
|
|
40
|
+ void testCreateFirmware() {
|
|
|
41
|
+ // given
|
|
45
|
42
|
OtaFirmware firmware = new OtaFirmware();
|
|
46
|
43
|
firmware.setModelId(1L);
|
|
47
|
44
|
firmware.setFirmwareVersion("v2.0.0");
|
|
48
|
|
- firmware.setFileUrl("http://oss.example.com/firmware/v2.0.0.bin");
|
|
49
|
|
- firmware.setDescription("压力传感器固件升级");
|
|
50
|
|
- firmware.setMd5("d41d8cd98f00b204e9800998ecf8427e");
|
|
|
45
|
+ firmware.setFileUrl("https://oss.example.com/firmware/v2.0.0.bin");
|
|
|
46
|
+ firmware.setDescription("新增水质检测功能");
|
|
|
47
|
+ firmware.setMd5("abc123def456");
|
|
51
|
48
|
firmware.setFileSize(1024000L);
|
|
52
|
49
|
|
|
53
|
|
- when(jdbcTemplate.update(any(org.springframework.jdbc.core.PreparedStatementCreator.class),
|
|
54
|
|
- any(GeneratedKeyHolder.class))).thenReturn(1);
|
|
|
50
|
+ // Mock INSERT with key holder
|
|
|
51
|
+ doAnswer(invocation -> {
|
|
|
52
|
+ GeneratedKeyHolder kh = invocation.getArgument(1);
|
|
|
53
|
+ // Simulate key generation
|
|
|
54
|
+ kh.getKeyList().add(Map.of("id", 100L));
|
|
|
55
|
+ return 1;
|
|
|
56
|
+ }).when(jdbcTemplate).update(any(java.sql.PreparedStatementCreator.class), any(GeneratedKeyHolder.class));
|
|
55
|
57
|
|
|
|
58
|
+ // when
|
|
56
|
59
|
OtaFirmware result = otaService.createFirmware(firmware);
|
|
57
|
60
|
|
|
|
61
|
+ // then
|
|
58
|
62
|
assertNotNull(result);
|
|
59
|
63
|
assertEquals("draft", result.getStatus());
|
|
60
|
64
|
assertEquals("v2.0.0", result.getFirmwareVersion());
|
|
61
|
|
- verify(jdbcTemplate).update(any(org.springframework.jdbc.core.PreparedStatementCreator.class),
|
|
62
|
|
- any(GeneratedKeyHolder.class));
|
|
63
|
65
|
}
|
|
64
|
66
|
|
|
65
|
67
|
@Test
|
|
66
|
|
- void publishFirmware_shouldUpdateStatus() {
|
|
|
68
|
+ void testPublishFirmware() {
|
|
|
69
|
+ // given
|
|
67
|
70
|
when(jdbcTemplate.update(anyString(), anyString(), anyLong())).thenReturn(1);
|
|
|
71
|
+
|
|
|
72
|
+ // when
|
|
68
|
73
|
otaService.publishFirmware(1L, "admin");
|
|
69
|
|
- verify(jdbcTemplate).update(contains("UPDATE iot_ota_firmware"), eq("admin"), eq(1L));
|
|
|
74
|
+
|
|
|
75
|
+ // then
|
|
|
76
|
+ verify(jdbcTemplate).update(contains("status = 'published'"), eq("admin"), eq(1L));
|
|
70
|
77
|
}
|
|
71
|
78
|
|
|
72
|
79
|
@Test
|
|
73
|
|
- void publishFirmware_notFound_shouldThrow() {
|
|
|
80
|
+ void testPublishFirmware_NotFound() {
|
|
|
81
|
+ // given
|
|
74
|
82
|
when(jdbcTemplate.update(anyString(), anyString(), anyLong())).thenReturn(0);
|
|
|
83
|
+
|
|
|
84
|
+ // when/then
|
|
75
|
85
|
assertThrows(RuntimeException.class, () -> otaService.publishFirmware(999L, "admin"));
|
|
76
|
86
|
}
|
|
77
|
87
|
|
|
78
|
88
|
@Test
|
|
79
|
|
- void getFirmware_shouldReturnFirmware() {
|
|
|
89
|
+ void testGetFirmware() {
|
|
|
90
|
+ // given
|
|
80
|
91
|
OtaFirmware fw = new OtaFirmware();
|
|
81
|
92
|
fw.setId(1L);
|
|
82
|
|
- fw.setFirmwareVersion("v2.0.0");
|
|
|
93
|
+ fw.setFirmwareVersion("v1.0.0");
|
|
|
94
|
+ fw.setStatus("published");
|
|
|
95
|
+
|
|
83
|
96
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
84
|
97
|
.thenReturn(List.of(fw));
|
|
85
|
98
|
|
|
|
99
|
+ // when
|
|
86
|
100
|
OtaFirmware result = otaService.getFirmware(1L);
|
|
|
101
|
+
|
|
|
102
|
+ // then
|
|
87
|
103
|
assertNotNull(result);
|
|
88
|
|
- assertEquals("v2.0.0", result.getFirmwareVersion());
|
|
|
104
|
+ assertEquals(1L, result.getId());
|
|
|
105
|
+ assertEquals("v1.0.0", result.getFirmwareVersion());
|
|
89
|
106
|
}
|
|
90
|
107
|
|
|
91
|
108
|
@Test
|
|
92
|
|
- void getFirmware_notFound_shouldReturnNull() {
|
|
|
109
|
+ void testGetFirmware_NotFound() {
|
|
|
110
|
+ // given
|
|
93
|
111
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
94
|
112
|
.thenReturn(Collections.emptyList());
|
|
95
|
|
- assertNull(otaService.getFirmware(999L));
|
|
|
113
|
+
|
|
|
114
|
+ // when
|
|
|
115
|
+ OtaFirmware result = otaService.getFirmware(999L);
|
|
|
116
|
+
|
|
|
117
|
+ // then
|
|
|
118
|
+ assertNull(result);
|
|
96
|
119
|
}
|
|
97
|
120
|
|
|
98
|
121
|
@Test
|
|
99
|
|
- void listAllFirmware_shouldReturnPaged() {
|
|
|
122
|
+ void testListFirmwareByModel() {
|
|
|
123
|
+ // given
|
|
100
|
124
|
OtaFirmware fw1 = new OtaFirmware();
|
|
101
|
125
|
fw1.setId(1L);
|
|
|
126
|
+ fw1.setFirmwareVersion("v1.0.0");
|
|
102
|
127
|
OtaFirmware fw2 = new OtaFirmware();
|
|
103
|
128
|
fw2.setId(2L);
|
|
104
|
|
- when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyInt(), anyInt()))
|
|
105
|
|
- .thenReturn(List.of(fw1, fw2));
|
|
|
129
|
+ fw2.setFirmwareVersion("v2.0.0");
|
|
|
130
|
+
|
|
|
131
|
+ when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
|
132
|
+ .thenReturn(List.of(fw2, fw1));
|
|
106
|
133
|
|
|
107
|
|
- List<OtaFirmware> result = otaService.listAllFirmware(1, 10);
|
|
|
134
|
+ // when
|
|
|
135
|
+ List<OtaFirmware> result = otaService.listFirmwareByModel(1L);
|
|
|
136
|
+
|
|
|
137
|
+ // then
|
|
108
|
138
|
assertEquals(2, result.size());
|
|
109
|
139
|
}
|
|
110
|
140
|
|
|
111
|
141
|
@Test
|
|
112
|
|
- void getAvailableFirmware_shouldReturnLatestPublished() {
|
|
113
|
|
- // Device has model_id = 1
|
|
114
|
|
- when(jdbcTemplate.queryForList(anyString(), eq(Long.class), anyString()))
|
|
|
142
|
+ void testGetAvailableFirmware() {
|
|
|
143
|
+ // given
|
|
|
144
|
+ String deviceSn = "DEV-001";
|
|
|
145
|
+ when(jdbcTemplate.queryForList(anyString(), eq(Long.class), eq(deviceSn)))
|
|
115
|
146
|
.thenReturn(List.of(1L));
|
|
116
|
147
|
|
|
117
|
148
|
OtaFirmware fw = new OtaFirmware();
|
|
118
|
|
- fw.setFirmwareVersion("v2.0.0");
|
|
|
149
|
+ fw.setId(10L);
|
|
|
150
|
+ fw.setFirmwareVersion("v3.0.0");
|
|
119
|
151
|
fw.setStatus("published");
|
|
120
|
|
- when(jdbcTemplate.query(contains("published"), any(BeanPropertyRowMapper.class), anyLong()))
|
|
|
152
|
+
|
|
|
153
|
+ when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
121
|
154
|
.thenReturn(List.of(fw));
|
|
122
|
155
|
|
|
123
|
|
- OtaFirmware result = otaService.getAvailableFirmware("FM-001");
|
|
|
156
|
+ // when
|
|
|
157
|
+ OtaFirmware result = otaService.getAvailableFirmware(deviceSn);
|
|
|
158
|
+
|
|
|
159
|
+ // then
|
|
124
|
160
|
assertNotNull(result);
|
|
125
|
|
- assertEquals("v2.0.0", result.getFirmwareVersion());
|
|
|
161
|
+ assertEquals("v3.0.0", result.getFirmwareVersion());
|
|
126
|
162
|
}
|
|
127
|
163
|
|
|
128
|
164
|
@Test
|
|
129
|
|
- void getAvailableFirmware_noModel_shouldReturnNull() {
|
|
130
|
|
- when(jdbcTemplate.queryForList(anyString(), eq(Long.class), anyString()))
|
|
|
165
|
+ void testGetAvailableFirmware_NoModel() {
|
|
|
166
|
+ // given
|
|
|
167
|
+ when(jdbcTemplate.queryForList(anyString(), eq(Long.class), eq("UNKNOWN")))
|
|
131
|
168
|
.thenReturn(Collections.emptyList());
|
|
132
|
|
- assertNull(otaService.getAvailableFirmware("FM-001"));
|
|
133
|
|
- }
|
|
134
|
|
-
|
|
135
|
|
- @Test
|
|
136
|
|
- void createUpgradeTask_shouldCreateTaskAndRecords() {
|
|
137
|
|
- // Mock firmware exists and is published
|
|
138
|
|
- OtaFirmware fw = new OtaFirmware();
|
|
139
|
|
- fw.setId(1L);
|
|
140
|
|
- fw.setFirmwareVersion("v2.0.0");
|
|
141
|
|
- fw.setStatus("published");
|
|
142
|
|
- when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
143
|
|
- .thenReturn(List.of(fw));
|
|
144
|
|
-
|
|
145
|
|
- // Mock insert task
|
|
146
|
|
- when(jdbcTemplate.update(any(org.springframework.jdbc.core.PreparedStatementCreator.class),
|
|
147
|
|
- any(GeneratedKeyHolder.class))).thenReturn(1);
|
|
148
|
|
-
|
|
149
|
|
- // Mock device info query
|
|
150
|
|
- Map<String, Object> deviceInfo = new HashMap<>();
|
|
151
|
|
- deviceInfo.put("device_sn", "FM-001");
|
|
152
|
|
- deviceInfo.put("firmware_version", "v1.0.0");
|
|
153
|
|
- when(jdbcTemplate.queryForList(contains("SELECT device_sn"), anyLong()))
|
|
154
|
|
- .thenReturn(List.of(deviceInfo));
|
|
155
|
|
-
|
|
156
|
|
- // Mock batch insert
|
|
157
|
|
- when(jdbcTemplate.batchUpdate(anyString(), anyList())).thenReturn(new int[]{1});
|
|
158
|
169
|
|
|
159
|
|
- OtaTask task = otaService.createUpgradeTask(1L, List.of(1L, 2L), 5, "admin");
|
|
|
170
|
+ // when
|
|
|
171
|
+ OtaFirmware result = otaService.getAvailableFirmware("UNKNOWN");
|
|
160
|
172
|
|
|
161
|
|
- assertNotNull(task);
|
|
162
|
|
- assertEquals("v2.0.0", task.getFirmwareVersion());
|
|
163
|
|
- assertEquals("pending", task.getTaskStatus());
|
|
164
|
|
- assertEquals(2, task.getTotalDevices());
|
|
165
|
|
- assertEquals(5, task.getBatchSize());
|
|
|
173
|
+ // then
|
|
|
174
|
+ assertNull(result);
|
|
166
|
175
|
}
|
|
167
|
176
|
|
|
168
|
177
|
@Test
|
|
169
|
|
- void createUpgradeTask_unpublishedFirmware_shouldThrow() {
|
|
170
|
|
- OtaFirmware fw = new OtaFirmware();
|
|
171
|
|
- fw.setId(1L);
|
|
172
|
|
- fw.setStatus("draft");
|
|
|
178
|
+ void testGetTask() {
|
|
|
179
|
+ // given
|
|
|
180
|
+ OtaTask task = new OtaTask();
|
|
|
181
|
+ task.setId(1L);
|
|
|
182
|
+ task.setTaskStatus("executing");
|
|
|
183
|
+ task.setTotalDevices(100);
|
|
|
184
|
+
|
|
173
|
185
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
174
|
|
- .thenReturn(List.of(fw));
|
|
|
186
|
+ .thenReturn(List.of(task));
|
|
|
187
|
+
|
|
|
188
|
+ // when
|
|
|
189
|
+ OtaTask result = otaService.getTask(1L);
|
|
175
|
190
|
|
|
176
|
|
- assertThrows(RuntimeException.class,
|
|
177
|
|
- () -> otaService.createUpgradeTask(1L, List.of(1L), 5, "admin"));
|
|
|
191
|
+ // then
|
|
|
192
|
+ assertNotNull(result);
|
|
|
193
|
+ assertEquals("executing", result.getTaskStatus());
|
|
178
|
194
|
}
|
|
179
|
195
|
|
|
180
|
196
|
@Test
|
|
181
|
|
- void startTask_shouldUpdateStatusAndFirstBatch() {
|
|
182
|
|
- // Mock task exists
|
|
183
|
|
- OtaTask task = new OtaTask();
|
|
184
|
|
- task.setId(1L);
|
|
185
|
|
- task.setTaskStatus("pending");
|
|
186
|
|
- task.setBatchSize(5);
|
|
187
|
|
- when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
188
|
|
- .thenReturn(List.of(task));
|
|
189
|
|
- when(jdbcTemplate.update(anyString(), any())).thenReturn(1);
|
|
|
197
|
+ void testListTasks() {
|
|
|
198
|
+ // given
|
|
|
199
|
+ OtaTask t1 = new OtaTask();
|
|
|
200
|
+ t1.setId(1L);
|
|
|
201
|
+ OtaTask t2 = new OtaTask();
|
|
|
202
|
+ t2.setId(2L);
|
|
|
203
|
+
|
|
|
204
|
+ when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyInt(), anyInt()))
|
|
|
205
|
+ .thenReturn(List.of(t1, t2));
|
|
190
|
206
|
|
|
191
|
|
- otaService.startTask(1L);
|
|
|
207
|
+ // when
|
|
|
208
|
+ List<OtaTask> result = otaService.listTasks(1, 10);
|
|
192
|
209
|
|
|
193
|
|
- verify(jdbcTemplate, atLeast(2)).update(anyString(), any());
|
|
|
210
|
+ // then
|
|
|
211
|
+ assertEquals(2, result.size());
|
|
194
|
212
|
}
|
|
195
|
213
|
|
|
196
|
214
|
@Test
|
|
197
|
|
- void cancelTask_shouldUpdateStatusAndRecords() {
|
|
|
215
|
+ void testCancelTask() {
|
|
|
216
|
+ // given
|
|
198
|
217
|
when(jdbcTemplate.update(anyString(), anyLong())).thenReturn(1);
|
|
|
218
|
+
|
|
|
219
|
+ // when
|
|
199
|
220
|
otaService.cancelTask(1L);
|
|
|
221
|
+
|
|
|
222
|
+ // then
|
|
200
|
223
|
verify(jdbcTemplate, times(2)).update(anyString(), anyLong());
|
|
201
|
224
|
}
|
|
202
|
225
|
|
|
203
|
226
|
@Test
|
|
204
|
|
- void getTaskStatistics_shouldReturnStats() {
|
|
|
227
|
+ void testUpdateProgress() {
|
|
|
228
|
+ // given
|
|
|
229
|
+ when(jdbcTemplate.update(anyString(), anyInt(), anyLong())).thenReturn(1);
|
|
|
230
|
+
|
|
|
231
|
+ // when
|
|
|
232
|
+ otaService.updateProgress(100L, 75);
|
|
|
233
|
+
|
|
|
234
|
+ // then
|
|
|
235
|
+ verify(jdbcTemplate).update(contains("progress"), eq(75), eq(100L));
|
|
|
236
|
+ }
|
|
|
237
|
+
|
|
|
238
|
+ @Test
|
|
|
239
|
+ void testGetTaskStatistics() {
|
|
|
240
|
+ // given
|
|
205
|
241
|
OtaTask task = new OtaTask();
|
|
206
|
242
|
task.setId(1L);
|
|
207
|
243
|
task.setTaskStatus("executing");
|
|
208
|
|
- task.setTotalDevices(10);
|
|
209
|
|
- task.setSuccessCount(5);
|
|
210
|
|
- task.setFailedCount(1);
|
|
211
|
|
- task.setExecutingCount(2);
|
|
|
244
|
+ task.setTotalDevices(100);
|
|
|
245
|
+ task.setSuccessCount(60);
|
|
|
246
|
+ task.setFailedCount(5);
|
|
|
247
|
+ task.setExecutingCount(10);
|
|
|
248
|
+
|
|
212
|
249
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
213
|
250
|
.thenReturn(List.of(task));
|
|
214
|
|
-
|
|
215
|
|
- List<Map<String, Object>> statusBreakdown = List.of(
|
|
216
|
|
- Map.of("status", "success", "count", 5L),
|
|
217
|
|
- Map.of("status", "failed", "count", 1L),
|
|
218
|
|
- Map.of("status", "executing", "count", 2L)
|
|
219
|
|
- );
|
|
220
|
|
- when(jdbcTemplate.queryForList(anyString(), anyLong())).thenReturn(statusBreakdown);
|
|
221
|
|
-
|
|
|
251
|
+ when(jdbcTemplate.queryForList(anyString(), anyLong()))
|
|
|
252
|
+ .thenReturn(List.of(
|
|
|
253
|
+ Map.of("status", "success", "count", 60L),
|
|
|
254
|
+ Map.of("status", "failed", "count", 5L),
|
|
|
255
|
+ Map.of("status", "executing", "count", 10L),
|
|
|
256
|
+ Map.of("status", "pending", "count", 25L)
|
|
|
257
|
+ ));
|
|
|
258
|
+
|
|
|
259
|
+ // when
|
|
222
|
260
|
Map<String, Object> stats = otaService.getTaskStatistics(1L);
|
|
223
|
261
|
|
|
|
262
|
+ // then
|
|
224
|
263
|
assertNotNull(stats);
|
|
225
|
|
- assertEquals(10, stats.get("totalDevices"));
|
|
226
|
|
- assertEquals(5, stats.get("successCount"));
|
|
227
|
|
- assertEquals(60.0, stats.get("progressPercent"));
|
|
228
|
|
- assertNotNull(stats.get("statusBreakdown"));
|
|
|
264
|
+ assertEquals(100, stats.get("totalDevices"));
|
|
|
265
|
+ assertEquals(60, stats.get("successCount"));
|
|
|
266
|
+ assertEquals(5, stats.get("failedCount"));
|
|
|
267
|
+ assertTrue((Double) stats.get("progressPercent") > 0);
|
|
229
|
268
|
}
|
|
230
|
269
|
|
|
231
|
270
|
@Test
|
|
232
|
|
- void getTaskRecords_shouldReturnRecords() {
|
|
233
|
|
- OtaUpgradeRecord record = new OtaUpgradeRecord();
|
|
234
|
|
- record.setId(1L);
|
|
235
|
|
- record.setTaskId(1L);
|
|
236
|
|
- record.setStatus("success");
|
|
|
271
|
+ void testGetTaskStatistics_NotFound() {
|
|
|
272
|
+ // given
|
|
237
|
273
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
238
|
|
- .thenReturn(List.of(record));
|
|
|
274
|
+ .thenReturn(Collections.emptyList());
|
|
|
275
|
+
|
|
|
276
|
+ // when
|
|
|
277
|
+ Map<String, Object> stats = otaService.getTaskStatistics(999L);
|
|
239
|
278
|
|
|
240
|
|
- List<OtaUpgradeRecord> records = otaService.getTaskRecords(1L);
|
|
241
|
|
- assertEquals(1, records.size());
|
|
242
|
|
- assertEquals("success", records.get(0).getStatus());
|
|
|
279
|
+ // then
|
|
|
280
|
+ assertTrue(stats.isEmpty());
|
|
243
|
281
|
}
|
|
244
|
282
|
|
|
245
|
283
|
@Test
|
|
246
|
|
- void markSuccess_shouldUpdateRecordAndTask() {
|
|
247
|
|
- when(jdbcTemplate.update(anyString(), any())).thenReturn(1);
|
|
248
|
|
- when(jdbcTemplate.queryForObject(anyString(), eq(Long.class), anyLong())).thenReturn(1L);
|
|
249
|
|
-
|
|
250
|
|
- // Mock task for triggerNextBatch
|
|
251
|
|
- OtaTask task = new OtaTask();
|
|
252
|
|
- task.setId(1L);
|
|
253
|
|
- task.setTaskStatus("executing");
|
|
254
|
|
- task.setBatchSize(5);
|
|
255
|
|
- when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
256
|
|
- .thenReturn(List.of(task));
|
|
257
|
|
- when(jdbcTemplate.queryForObject(contains("COUNT"), eq(Integer.class), anyLong()))
|
|
258
|
|
- .thenReturn(0, 3); // 0 executing, 3 pending
|
|
|
284
|
+ void testDeprecateFirmware() {
|
|
|
285
|
+ // given
|
|
|
286
|
+ when(jdbcTemplate.update(anyString(), anyLong())).thenReturn(1);
|
|
259
|
287
|
|
|
260
|
|
- otaService.markSuccess(1L, 1L, "v2.0.0");
|
|
|
288
|
+ // when
|
|
|
289
|
+ otaService.deprecateFirmware(1L);
|
|
261
|
290
|
|
|
262
|
|
- verify(jdbcTemplate, atLeast(3)).update(anyString(), any());
|
|
|
291
|
+ // then
|
|
|
292
|
+ verify(jdbcTemplate).update(contains("deprecated"), eq(1L));
|
|
263
|
293
|
}
|
|
264
|
294
|
|
|
265
|
295
|
@Test
|
|
266
|
|
- void markFailed_shouldUpdateWithReason() {
|
|
267
|
|
- when(jdbcTemplate.update(anyString(), any())).thenReturn(1);
|
|
|
296
|
+ void testMarkSuccess() {
|
|
|
297
|
+ // given
|
|
|
298
|
+ when(jdbcTemplate.update(anyString(), anyLong())).thenReturn(1);
|
|
268
|
299
|
when(jdbcTemplate.queryForObject(anyString(), eq(Long.class), anyLong())).thenReturn(1L);
|
|
269
|
|
-
|
|
270
|
|
- OtaTask task = new OtaTask();
|
|
271
|
|
- task.setId(1L);
|
|
272
|
|
- task.setTaskStatus("executing");
|
|
273
|
|
- task.setBatchSize(5);
|
|
274
|
300
|
when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
275
|
|
- .thenReturn(List.of(task));
|
|
276
|
|
- when(jdbcTemplate.queryForObject(contains("COUNT"), eq(Integer.class), anyLong()))
|
|
277
|
|
- .thenReturn(0, 0); // 0 executing, 0 pending -> task completed
|
|
|
301
|
+ .thenReturn(Collections.emptyList()); // task not found for triggerNextBatch
|
|
278
|
302
|
|
|
279
|
|
- otaService.markFailed(1L, "设备连接超时");
|
|
|
303
|
+ // when
|
|
|
304
|
+ otaService.markSuccess(100L, 5L, "v2.0.0");
|
|
280
|
305
|
|
|
281
|
|
- verify(jdbcTemplate).update(contains("fail_reason"), eq("设备连接超时"), eq(1L));
|
|
|
306
|
+ // then
|
|
|
307
|
+ verify(jdbcTemplate, atLeastOnce()).update(anyString(), anyLong());
|
|
282
|
308
|
}
|
|
283
|
309
|
|
|
284
|
310
|
@Test
|
|
285
|
|
- void updateProgress_shouldUpdateRecord() {
|
|
286
|
|
- when(jdbcTemplate.update(anyString(), anyInt(), anyLong())).thenReturn(1);
|
|
287
|
|
- otaService.updateProgress(1L, 50);
|
|
288
|
|
- verify(jdbcTemplate).update(contains("progress"), eq(50), eq(1L));
|
|
289
|
|
- }
|
|
290
|
|
-
|
|
291
|
|
- @Test
|
|
292
|
|
- void deprecateFirmware_shouldUpdateStatus() {
|
|
293
|
|
- when(jdbcTemplate.update(anyString(), anyLong())).thenReturn(1);
|
|
294
|
|
- otaService.deprecateFirmware(1L);
|
|
295
|
|
- verify(jdbcTemplate).update(contains("deprecated"), eq(1L));
|
|
296
|
|
- }
|
|
|
311
|
+ void testMarkFailed() {
|
|
|
312
|
+ // given
|
|
|
313
|
+ when(jdbcTemplate.update(anyString(), any(), anyLong())).thenReturn(1);
|
|
|
314
|
+ when(jdbcTemplate.queryForObject(anyString(), eq(Long.class), anyLong())).thenReturn(1L);
|
|
|
315
|
+ when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyLong()))
|
|
|
316
|
+ .thenReturn(Collections.emptyList());
|
|
297
|
317
|
|
|
298
|
|
- @Test
|
|
299
|
|
- void listTasks_shouldReturnPaged() {
|
|
300
|
|
- OtaTask t1 = new OtaTask();
|
|
301
|
|
- t1.setId(1L);
|
|
302
|
|
- OtaTask t2 = new OtaTask();
|
|
303
|
|
- t2.setId(2L);
|
|
304
|
|
- when(jdbcTemplate.query(anyString(), any(BeanPropertyRowMapper.class), anyInt(), anyInt()))
|
|
305
|
|
- .thenReturn(List.of(t1, t2));
|
|
|
318
|
+ // when
|
|
|
319
|
+ otaService.markFailed(100L, "Download timeout");
|
|
306
|
320
|
|
|
307
|
|
- List<OtaTask> result = otaService.listTasks(1, 10);
|
|
308
|
|
- assertEquals(2, result.size());
|
|
|
321
|
+ // then
|
|
|
322
|
+ verify(jdbcTemplate, atLeastOnce()).update(anyString(), any(), anyLong());
|
|
309
|
323
|
}
|
|
310
|
324
|
}
|