task-159: 已完成任务活跃 Job 巡检(终态任务 RUNNING/PENDING Job 检出、运行中任务正常、只读、可重复)+ 8 条测试
This commit is contained in:
+170
@@ -0,0 +1,170 @@
|
||||
package com.nanri.aiimage.modules.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.nanri.aiimage.modules.task.mapper.FileTaskMapper;
|
||||
import com.nanri.aiimage.modules.task.mapper.TaskFileJobMapper;
|
||||
import com.nanri.aiimage.modules.task.model.entity.FileTaskEntity;
|
||||
import com.nanri.aiimage.modules.task.model.entity.TaskFileJobEntity;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* task-159:已完成任务活跃 Job 巡检契约(plan 09)。
|
||||
* 终态任务仍有 RUNNING/PENDING Job → 检出;运行中任务的活跃 Job 正常不报;
|
||||
* 只读;可重复。
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CompletedTaskActiveJobInspectorTest {
|
||||
|
||||
private static final Long TERMINAL_TASK_ID = 5001L;
|
||||
private static final Long RUNNING_TASK_ID = 5101L;
|
||||
|
||||
@Mock private FileTaskMapper fileTaskMapper;
|
||||
@Mock private TaskFileJobMapper taskFileJobMapper;
|
||||
|
||||
private CompletedTaskActiveJobInspector inspector;
|
||||
|
||||
@BeforeAll
|
||||
static void initializeMybatisMetadata() {
|
||||
MapperBuilderAssistant assistant = new MapperBuilderAssistant(new MybatisConfiguration(), "");
|
||||
TableInfoHelper.initTableInfo(assistant, FileTaskEntity.class);
|
||||
TableInfoHelper.initTableInfo(assistant, TaskFileJobEntity.class);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
inspector = new CompletedTaskActiveJobInspector(fileTaskMapper, taskFileJobMapper);
|
||||
lenient().when(taskFileJobMapper.selectList(any())).thenReturn(List.of());
|
||||
}
|
||||
|
||||
private FileTaskEntity task(Long id, String status) {
|
||||
FileTaskEntity task = new FileTaskEntity();
|
||||
task.setId(id);
|
||||
task.setModuleType("SIMILAR_ASIN");
|
||||
task.setStatus(status);
|
||||
return task;
|
||||
}
|
||||
|
||||
private TaskFileJobEntity job(Long id, Long taskId, String status) {
|
||||
TaskFileJobEntity job = new TaskFileJobEntity();
|
||||
job.setId(id);
|
||||
job.setTaskId(taskId);
|
||||
job.setStatus(status);
|
||||
job.setJobType("ASSEMBLE_RESULT");
|
||||
return job;
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeJobAfterTerminalTaskDetected() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "SUCCESS")));
|
||||
when(taskFileJobMapper.selectList(any()))
|
||||
.thenReturn(List.of(job(901L, TERMINAL_TASK_ID, "RUNNING")));
|
||||
|
||||
var report = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
assertEquals(1, report.entries().size());
|
||||
assertEquals(TERMINAL_TASK_ID, report.entries().getFirst().taskId());
|
||||
assertEquals("RUNNING", report.entries().getFirst().jobStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void terminalTaskWithoutJobsIsFine() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "SUCCESS")));
|
||||
|
||||
var report = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
assertTrue(report.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void runningTaskWithActiveJobIsNormal() {
|
||||
// 巡检只查终态任务:RUNNING 任务的活跃 Job 不在报表范围
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of());
|
||||
inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
var wrapper = org.mockito.ArgumentCaptor.forClass(com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper.class);
|
||||
verify(fileTaskMapper).selectList(wrapper.capture());
|
||||
assertTrue(wrapper.getValue().getSqlSegment().contains("IN"), "只查终态任务");
|
||||
assertFalse(wrapper.getValue().getSqlSegment().contains("RUNNING"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void stuckJobAfterTerminalReported() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "FAILED")));
|
||||
when(taskFileJobMapper.selectList(any()))
|
||||
.thenReturn(List.of(job(902L, TERMINAL_TASK_ID, "PENDING")));
|
||||
|
||||
var report = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
assertEquals(1, report.entries().size(), "卡死 PENDING Job 同样检出");
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyReportWhenNoTerminalTasks() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of());
|
||||
|
||||
var report = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
assertTrue(report.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void readOnlyDoesNotModifyAnything() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "SUCCESS")));
|
||||
when(taskFileJobMapper.selectList(any()))
|
||||
.thenReturn(List.of(job(903L, TERMINAL_TASK_ID, "RUNNING")));
|
||||
|
||||
inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
verify(taskFileJobMapper, never()).update(any(), any());
|
||||
verify(taskFileJobMapper, never()).updateById(any(TaskFileJobEntity.class));
|
||||
verify(taskFileJobMapper, never()).delete(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportIncludesDetails() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "SUCCESS")));
|
||||
when(taskFileJobMapper.selectList(any()))
|
||||
.thenReturn(List.of(job(904L, TERMINAL_TASK_ID, "RUNNING")));
|
||||
|
||||
var report = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
CompletedTaskActiveJobInspector.ActiveJobEntry entry = report.entries().getFirst();
|
||||
assertEquals(TERMINAL_TASK_ID, entry.taskId());
|
||||
assertEquals("SIMILAR_ASIN", entry.moduleType());
|
||||
assertEquals(904L, entry.jobId());
|
||||
assertEquals("ASSEMBLE_RESULT", entry.jobType());
|
||||
assertNotNull(entry.jobStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rerunIsSafeAndStable() {
|
||||
when(fileTaskMapper.selectList(any())).thenReturn(List.of(task(TERMINAL_TASK_ID, "SUCCESS")));
|
||||
when(taskFileJobMapper.selectList(any()))
|
||||
.thenReturn(List.of(job(905L, TERMINAL_TASK_ID, "PENDING")));
|
||||
|
||||
var first = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
var second = inspector.inspectTerminalTasksWithActiveJobs(50);
|
||||
|
||||
assertEquals(first.entries().size(), second.entries().size());
|
||||
assertEquals(first.entries().getFirst().jobId(), second.entries().getFirst().jobId());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user