定时任务执行及报告核心
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
package com.test.common.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liangdaliang
|
||||||
|
* @Description:自定义定时任务配置
|
||||||
|
* @date 2025-02-24 10:27
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SchedulerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ThreadPoolTaskScheduler taskScheduler() {
|
||||||
|
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
|
||||||
|
scheduler.setPoolSize(60); // 设置线程池大小
|
||||||
|
scheduler.setThreadNamePrefix("TestTaskScheduler-");
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,10 +42,10 @@ public interface ITestTaskService {
|
|||||||
/**
|
/**
|
||||||
* 根据测试任务id执行测试定时任务
|
* 根据测试任务id执行测试定时任务
|
||||||
* @param id 测试定时任务id
|
* @param id 测试定时任务id
|
||||||
* @param isImmediateRun 是否立即执行
|
|
||||||
* @param triggerType 触发方式:1-定时任务;2-手动
|
* @param triggerType 触发方式:1-定时任务;2-手动
|
||||||
* @param environment 环境
|
* @param environment 环境
|
||||||
|
* @param jmeterHomePath jmeter安装路径
|
||||||
* @return 是否成功
|
* @return 是否成功
|
||||||
*/
|
*/
|
||||||
boolean executeTestTaskById(Long id, boolean isImmediateRun, Integer triggerType, String environment);
|
boolean executeTestTaskById(Long id, Integer triggerType, String environment, String jmeterHomePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
package com.test.test.service.impl;
|
||||||
|
|
||||||
|
import com.test.common.utils.DateUtils;
|
||||||
|
import com.test.test.domain.TestTask;
|
||||||
|
import com.test.test.domain.TestTaskCase;
|
||||||
|
import com.test.test.domain.TestTaskResult;
|
||||||
|
import com.test.test.mapper.TestTaskResultMapper;
|
||||||
|
import com.test.test.service.ITestCaseService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
|
import org.springframework.scheduling.support.CronTrigger;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liangdaliang
|
||||||
|
* @Description:定时任务管理服务
|
||||||
|
* @date 2025-02-24 12:52
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class TaskManagerService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TestTaskResultMapper testTaskResultMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ThreadPoolTaskScheduler taskScheduler;
|
||||||
|
@Autowired
|
||||||
|
private ITestCaseService testCaseService;
|
||||||
|
|
||||||
|
// 存储任务和其对应的 ScheduledFuture
|
||||||
|
private final Map<Long, ScheduledFuture<?>> taskMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加定时任务
|
||||||
|
*
|
||||||
|
* @param testTask 任务
|
||||||
|
* @param jmeterHomePath jmeter安装路径
|
||||||
|
* @param testTaskCaseList 待执行测试用例列表
|
||||||
|
* @param testTaskResult 定时任务结果
|
||||||
|
*/
|
||||||
|
public void addTask(TestTask testTask, String jmeterHomePath, List<TestTaskCase> testTaskCaseList, TestTaskResult testTaskResult) {
|
||||||
|
Long id = testTask.getId();
|
||||||
|
String crontab = testTask.getCrontab();
|
||||||
|
// 如果任务已存在,先取消
|
||||||
|
if (taskMap.containsKey(id)) {
|
||||||
|
taskMap.get(id).cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建定时任务
|
||||||
|
ScheduledFuture<?> future = taskScheduler.schedule(
|
||||||
|
() -> executeTaskWithTestCases(testTask, jmeterHomePath, testTaskCaseList, testTaskResult),
|
||||||
|
new CronTrigger(crontab)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 将任务添加到 Map 中
|
||||||
|
taskMap.put(id, future);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行定时任务,并处理测试用例
|
||||||
|
*
|
||||||
|
* @param testTask 任务
|
||||||
|
* @param jmeterHomePath jmeter安装路径
|
||||||
|
* @param testTaskCaseList 待执行测试用例列表
|
||||||
|
* @param testTaskResult 定时任务结果
|
||||||
|
*/
|
||||||
|
public void executeTaskWithTestCases(TestTask testTask, String jmeterHomePath, List<TestTaskCase> testTaskCaseList, TestTaskResult testTaskResult) {
|
||||||
|
Long id = testTask.getId();
|
||||||
|
List<Boolean> results = new ArrayList<>();
|
||||||
|
// 并行开关:0打开;2关闭
|
||||||
|
Integer async = testTask.getAsync();
|
||||||
|
log.info("Starting task with ID: {}", id);
|
||||||
|
testTaskResult.setStartTime(DateUtils.getNowDate());
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
if (async == 0) {
|
||||||
|
// 创建任务关联所有测试用例的 CompletableFuture
|
||||||
|
List<CompletableFuture<Boolean>> testCaseFutures = new ArrayList<>();
|
||||||
|
for (TestTaskCase testTaskCase : testTaskCaseList) {
|
||||||
|
CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> executeTestCase(testTask, testTaskCase.getCaseId(), jmeterHomePath));
|
||||||
|
testCaseFutures.add(future);
|
||||||
|
}
|
||||||
|
// 等待所有测试用例完成
|
||||||
|
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
||||||
|
testCaseFutures.toArray(new CompletableFuture[0])
|
||||||
|
);
|
||||||
|
// 阻塞等待所有测试用例完成
|
||||||
|
allFutures.join();
|
||||||
|
// 收集每个测试用例的执行结果
|
||||||
|
results = testCaseFutures.stream()
|
||||||
|
.map(CompletableFuture::join) // 获取每个测试用例的结果
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
for (TestTaskCase testTaskCase : testTaskCaseList) {
|
||||||
|
results.add(executeTestCase(testTask, testTaskCase.getCaseId(), jmeterHomePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testTaskResult.setCostTime(System.currentTimeMillis() - startTime);
|
||||||
|
long trueCount = results.stream().filter(result -> result) // 过滤出 true
|
||||||
|
.count(); // 统计数量
|
||||||
|
long falseCount = results.stream().filter(result -> !result) // 过滤出 false
|
||||||
|
.count(); // 统计数量
|
||||||
|
if (falseCount > 0L) {
|
||||||
|
testTaskResult.setStatus(2);
|
||||||
|
} else {
|
||||||
|
testTaskResult.setStatus(1);
|
||||||
|
}
|
||||||
|
String result_desc = "总数:" + results.size() + " 成功:" + trueCount + " 失败:" + falseCount;
|
||||||
|
testTaskResult.setResultDesc(result_desc);
|
||||||
|
testTaskResult.setCreateTime(DateUtils.getNowDate());
|
||||||
|
testTaskResultMapper.insertTestTaskResult(testTaskResult);
|
||||||
|
// 所有测试用例完成后,标记任务执行结束
|
||||||
|
log.info("Task with ID {} completed.", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行单个测试用例
|
||||||
|
*
|
||||||
|
* @param testTask 任务
|
||||||
|
* @param testCaseId 测试用例ID
|
||||||
|
* @param jmeterHomePath jmeter安装路径
|
||||||
|
* @return 测试用例执行结果(true 表示成功,false 表示失败)
|
||||||
|
*/
|
||||||
|
public boolean executeTestCase(TestTask testTask, Long testCaseId, String jmeterHomePath) {
|
||||||
|
Long taskId = testTask.getId();
|
||||||
|
// 失败重试开关:0打开;2关闭
|
||||||
|
Integer retry = testTask.getRetry();
|
||||||
|
Long retryCount = testTask.getRetryCount();
|
||||||
|
try {
|
||||||
|
// 测试用例执行逻辑
|
||||||
|
log.info("Executing test case {} for task {}", testCaseId, taskId);
|
||||||
|
boolean result = testCaseService.executeTestCaseById(testCaseId, jmeterHomePath);
|
||||||
|
if (!result && retry == 0) {
|
||||||
|
if (retryCount != null && retryCount > 0) {
|
||||||
|
for (int i = 0; i < retryCount; i++) {
|
||||||
|
result = testCaseService.executeTestCaseById(testCaseId, jmeterHomePath);
|
||||||
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Test case {} for task {} failed: ", testCaseId, taskId, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,10 +3,14 @@ package com.test.test.service.impl;
|
|||||||
import com.test.common.utils.DateUtils;
|
import com.test.common.utils.DateUtils;
|
||||||
import com.test.test.domain.*;
|
import com.test.test.domain.*;
|
||||||
import com.test.test.domain.qo.GroupIdQO;
|
import com.test.test.domain.qo.GroupIdQO;
|
||||||
import com.test.test.mapper.*;
|
import com.test.test.mapper.TestCaseMapper;
|
||||||
|
import com.test.test.mapper.TestCaseStepMapper;
|
||||||
|
import com.test.test.mapper.TestTaskCaseMapper;
|
||||||
|
import com.test.test.mapper.TestTaskMapper;
|
||||||
import com.test.test.service.ITestTaskService;
|
import com.test.test.service.ITestTaskService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -31,8 +35,8 @@ public class TestTaskServiceImpl implements ITestTaskService {
|
|||||||
@Resource
|
@Resource
|
||||||
private TestCaseStepMapper testCaseStepMapper;
|
private TestCaseStepMapper testCaseStepMapper;
|
||||||
|
|
||||||
@Resource
|
@Autowired
|
||||||
private TestTaskResultMapper testTaskResultMapper;
|
private TaskManagerService taskManagerService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询自动化测试
|
* 查询自动化测试
|
||||||
@@ -86,13 +90,13 @@ public class TestTaskServiceImpl implements ITestTaskService {
|
|||||||
/**
|
/**
|
||||||
* 根据测试任务id执行测试定时任务
|
* 根据测试任务id执行测试定时任务
|
||||||
* @param id 测试定时任务id
|
* @param id 测试定时任务id
|
||||||
* @param isImmediateRun 是否立即执行
|
|
||||||
* @param triggerType 触发方式:1-定时任务;2-手动
|
* @param triggerType 触发方式:1-定时任务;2-手动
|
||||||
* @param environment 环境
|
* @param environment 环境
|
||||||
* @return 是否成功
|
* @param jmeterHomePath jmeter安装路径
|
||||||
|
* @return 是否执行完成(注:是否成功得看任务结果表)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean executeTestTaskById(Long id, boolean isImmediateRun, Integer triggerType, String environment) {
|
public boolean executeTestTaskById(Long id, Integer triggerType, String environment, String jmeterHomePath) {
|
||||||
TestTask testTask = this.selectTestTaskById(id);
|
TestTask testTask = this.selectTestTaskById(id);
|
||||||
if (testTask == null || testTask.getStatus() == null
|
if (testTask == null || testTask.getStatus() == null
|
||||||
|| testTask.getStatus() > 0 || "2".equals(testTask.getDelFlag())) {
|
|| testTask.getStatus() > 0 || "2".equals(testTask.getDelFlag())) {
|
||||||
@@ -104,10 +108,7 @@ public class TestTaskServiceImpl implements ITestTaskService {
|
|||||||
testTaskResult.setTriggerTime(DateUtils.getNowDate());
|
testTaskResult.setTriggerTime(DateUtils.getNowDate());
|
||||||
testTaskResult.setTriggerType(triggerType);
|
testTaskResult.setTriggerType(triggerType);
|
||||||
testTaskResult.setEnvironment(environment);
|
testTaskResult.setEnvironment(environment);
|
||||||
String crontab = testTask.getCrontab();
|
// 测试步骤总数
|
||||||
Integer async = testTask.getAsync();
|
|
||||||
Integer retry = testTask.getRetry();
|
|
||||||
Long retryCount = testTask.getRetryCount();
|
|
||||||
int caseStepCount = 0;
|
int caseStepCount = 0;
|
||||||
// 查询关联的测试用例列表
|
// 查询关联的测试用例列表
|
||||||
List<TestTaskCase> testTaskCaseList = testTaskCaseMapper.selectTestTaskCaseListByTaskId(id);
|
List<TestTaskCase> testTaskCaseList = testTaskCaseMapper.selectTestTaskCaseListByTaskId(id);
|
||||||
@@ -122,19 +123,18 @@ public class TestTaskServiceImpl implements ITestTaskService {
|
|||||||
caseStepCount += testCaseStepMapper.selectTestCaseStepList(testCaseStep).size();
|
caseStepCount += testCaseStepMapper.selectTestCaseStepList(testCaseStep).size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 用例总数
|
||||||
int caseCount = testCaseList.size();
|
int caseCount = testCaseList.size();
|
||||||
testTaskResult.setStartTime(DateUtils.getNowDate());
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
// 开始执行定时任务逻辑。。。
|
|
||||||
|
|
||||||
testTaskResult.setStatus(1);
|
|
||||||
testTaskResult.setCostTime(System.currentTimeMillis() - startTime);
|
|
||||||
testTaskResult.setCaseCount(caseCount);
|
testTaskResult.setCaseCount(caseCount);
|
||||||
testTaskResult.setCaseStepCount(caseStepCount);
|
testTaskResult.setCaseStepCount(caseStepCount);
|
||||||
String result_desc = "";
|
// 开始执行定时任务逻辑。。。
|
||||||
testTaskResult.setResultDesc(result_desc);
|
if (triggerType == 1) {
|
||||||
testTaskResult.setCreateTime(DateUtils.getNowDate());
|
// 添加定时任务定时执行
|
||||||
testTaskResultMapper.insertTestTaskResult(testTaskResult);
|
taskManagerService.addTask(testTask, jmeterHomePath, testTaskCaseList, testTaskResult);
|
||||||
return false;
|
} else {
|
||||||
|
// 手动立即执行
|
||||||
|
taskManagerService.executeTaskWithTestCases(testTask, jmeterHomePath, testTaskCaseList, testTaskResult);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user