定时任务执行及报告核心

This commit is contained in:
liangdaliang
2025-02-24 16:00:20 +08:00
parent 142252d7c6
commit 8f3e32840a
4 changed files with 204 additions and 23 deletions

View File

@@ -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;
}
}

View File

@@ -42,10 +42,10 @@ public interface ITestTaskService {
/**
* 根据测试任务id执行测试定时任务
* @param id 测试定时任务id
* @param isImmediateRun 是否立即执行
* @param triggerType 触发方式1-定时任务2-手动
* @param environment 环境
* @param jmeterHomePath jmeter安装路径
* @return 是否成功
*/
boolean executeTestTaskById(Long id, boolean isImmediateRun, Integer triggerType, String environment);
boolean executeTestTaskById(Long id, Integer triggerType, String environment, String jmeterHomePath);
}

View File

@@ -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;
}
}
}

View File

@@ -3,10 +3,14 @@ package com.test.test.service.impl;
import com.test.common.utils.DateUtils;
import com.test.test.domain.*;
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 jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -31,8 +35,8 @@ public class TestTaskServiceImpl implements ITestTaskService {
@Resource
private TestCaseStepMapper testCaseStepMapper;
@Resource
private TestTaskResultMapper testTaskResultMapper;
@Autowired
private TaskManagerService taskManagerService;
/**
* 查询自动化测试
@@ -86,13 +90,13 @@ public class TestTaskServiceImpl implements ITestTaskService {
/**
* 根据测试任务id执行测试定时任务
* @param id 测试定时任务id
* @param isImmediateRun 是否立即执行
* @param triggerType 触发方式1-定时任务2-手动
* @param environment 环境
* @return 是否成功
* @param jmeterHomePath jmeter安装路径
* @return 是否执行完成(注:是否成功得看任务结果表)
*/
@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);
if (testTask == null || testTask.getStatus() == null
|| testTask.getStatus() > 0 || "2".equals(testTask.getDelFlag())) {
@@ -104,10 +108,7 @@ public class TestTaskServiceImpl implements ITestTaskService {
testTaskResult.setTriggerTime(DateUtils.getNowDate());
testTaskResult.setTriggerType(triggerType);
testTaskResult.setEnvironment(environment);
String crontab = testTask.getCrontab();
Integer async = testTask.getAsync();
Integer retry = testTask.getRetry();
Long retryCount = testTask.getRetryCount();
// 测试步骤总数
int caseStepCount = 0;
// 查询关联的测试用例列表
List<TestTaskCase> testTaskCaseList = testTaskCaseMapper.selectTestTaskCaseListByTaskId(id);
@@ -122,19 +123,18 @@ public class TestTaskServiceImpl implements ITestTaskService {
caseStepCount += testCaseStepMapper.selectTestCaseStepList(testCaseStep).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.setCaseStepCount(caseStepCount);
String result_desc = "";
testTaskResult.setResultDesc(result_desc);
testTaskResult.setCreateTime(DateUtils.getNowDate());
testTaskResultMapper.insertTestTaskResult(testTaskResult);
return false;
// 开始执行定时任务逻辑。。。
if (triggerType == 1) {
// 添加定时任务定时执行
taskManagerService.addTask(testTask, jmeterHomePath, testTaskCaseList, testTaskResult);
} else {
// 手动立即执行
taskManagerService.executeTaskWithTestCases(testTask, jmeterHomePath, testTaskCaseList, testTaskResult);
}
return true;
}
}