fix(接口测试): 执行任务开始执行时,没有设置开始时间和状态
This commit is contained in:
parent
6536efdc96
commit
23092f013c
|
@ -6,4 +6,5 @@ package io.metersphere.sdk.constants;
|
|||
*/
|
||||
public class CommonConstants {
|
||||
public static final String DEFAULT_NULL_VALUE = "NONE";
|
||||
public static final String RUNNING_TASK_PREFIX = "RUNNING_TASK:";
|
||||
}
|
||||
|
|
|
@ -48,4 +48,14 @@ public class GetRunScriptRequest implements Serializable {
|
|||
* 线程ID
|
||||
*/
|
||||
private String threadId;
|
||||
/**
|
||||
* 是否是批量执行
|
||||
* 包括用例的批量执行
|
||||
* 测试计划的执行
|
||||
*/
|
||||
private Boolean batch;
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private String taskId;
|
||||
}
|
||||
|
|
|
@ -102,4 +102,11 @@ public class TaskInfo implements Serializable {
|
|||
* 记录执行时的环境变量
|
||||
*/
|
||||
private List<String> environmentVariables;
|
||||
|
||||
/**
|
||||
* 是否是批量执行
|
||||
* 包括用例的批量执行
|
||||
* 测试计划的执行
|
||||
*/
|
||||
private Boolean batch = false;
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@ package io.metersphere.api.service;
|
|||
import io.metersphere.api.invoker.ApiExecuteCallbackServiceInvoker;
|
||||
import io.metersphere.api.service.definition.ApiReportService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||
import io.metersphere.sdk.constants.ExecStatus;
|
||||
import io.metersphere.api.utils.TaskRunningCache;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
|
||||
import io.metersphere.sdk.dto.api.task.GetRunScriptResult;
|
||||
import io.metersphere.sdk.dto.api.task.TaskItem;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.EnumValidator;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.mapper.ExecTaskItemMapper;
|
||||
import io.metersphere.system.mapper.ExecTaskMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -27,6 +28,8 @@ import java.util.Optional;
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiExecuteResourceService {
|
||||
|
||||
@Resource
|
||||
private ExecTaskMapper execTaskMapper;
|
||||
@Resource
|
||||
private ExecTaskItemMapper execTaskItemMapper;
|
||||
@Resource
|
||||
|
@ -35,33 +38,17 @@ public class ApiExecuteResourceService {
|
|||
private ApiScenarioReportService apiScenarioReportService;
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
private TaskRunningCache taskRunningCache;
|
||||
|
||||
|
||||
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
|
||||
TaskItem taskItem = request.getTaskItem();
|
||||
String taskItemId = taskItem.getId();
|
||||
String reportId = taskItem.getReportId();
|
||||
LogUtils.info("生成并获取执行脚本: {}", taskItem.getId());
|
||||
|
||||
ApiExecuteResourceType apiExecuteResourceType = EnumValidator.validateEnum(ApiExecuteResourceType.class, request.getResourceType());
|
||||
|
||||
if (!ApiExecuteRunMode.isDebug(request.getRunMode())) {
|
||||
// 更新任务项状态
|
||||
ExecTaskItem execTaskItem = new ExecTaskItem();
|
||||
execTaskItem.setId(taskItem.getId());
|
||||
execTaskItem.setStartTime(System.currentTimeMillis());
|
||||
execTaskItem.setStatus(ExecStatus.RUNNING.name());
|
||||
execTaskItem.setThreadId(request.getThreadId());
|
||||
execTaskItemMapper.updateByPrimaryKeySelective(execTaskItem);
|
||||
|
||||
// 非调试执行,更新报告状态
|
||||
switch (apiExecuteResourceType) {
|
||||
case API_SCENARIO, TEST_PLAN_API_SCENARIO, PLAN_RUN_API_SCENARIO ->
|
||||
apiScenarioReportService.updateReportRunningStatus(reportId);
|
||||
case API_CASE, TEST_PLAN_API_CASE, PLAN_RUN_API_CASE ->
|
||||
apiReportService.updateReportRunningStatus(reportId);
|
||||
default -> throw new MSException("不支持的资源类型: " + request.getResourceType());
|
||||
}
|
||||
updateRunningReportStatus(request);
|
||||
}
|
||||
|
||||
if (BooleanUtils.isFalse(request.getNeedParseScript())) {
|
||||
|
@ -75,4 +62,54 @@ public class ApiExecuteResourceService {
|
|||
|
||||
return ApiExecuteCallbackServiceInvoker.getRunScript(request.getResourceType(), request);
|
||||
}
|
||||
|
||||
private void updateRunningReportStatus(GetRunScriptRequest request) {
|
||||
TaskItem taskItem = request.getTaskItem();
|
||||
String taskId = request.getTaskId();
|
||||
|
||||
String reportId = taskItem.getReportId();
|
||||
ApiExecuteResourceType apiExecuteResourceType = EnumValidator.validateEnum(ApiExecuteResourceType.class, request.getResourceType());
|
||||
|
||||
if (request.getBatch()) {
|
||||
// 设置缓存成功说明是第一个任务,则设置任务的开始时间和运行状态
|
||||
if (taskRunningCache.setIfAbsent(taskId)) {
|
||||
// 将任务状态更新为运行中
|
||||
updateTaskRunningStatus(taskId);
|
||||
}
|
||||
} else {
|
||||
// 非批量时,直接更新任务状态
|
||||
updateTaskRunningStatus(taskId);
|
||||
}
|
||||
|
||||
// 更新任务项状态
|
||||
updateTaskItemRunningStatus(request);
|
||||
|
||||
// 非调试执行,更新报告状态
|
||||
switch (apiExecuteResourceType) {
|
||||
case API_SCENARIO, TEST_PLAN_API_SCENARIO, PLAN_RUN_API_SCENARIO ->
|
||||
apiScenarioReportService.updateReportRunningStatus(reportId);
|
||||
case API_CASE, TEST_PLAN_API_CASE, PLAN_RUN_API_CASE ->
|
||||
apiReportService.updateReportRunningStatus(reportId);
|
||||
default -> throw new MSException("不支持的资源类型: " + request.getResourceType());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTaskRunningStatus(String taskId) {
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setId(taskId);
|
||||
execTask.setStartTime(System.currentTimeMillis());
|
||||
execTask.setStatus(ExecStatus.RUNNING.name());
|
||||
execTaskMapper.updateByPrimaryKeySelective(execTask);
|
||||
}
|
||||
|
||||
private void updateTaskItemRunningStatus(GetRunScriptRequest request) {
|
||||
TaskItem taskItem = request.getTaskItem();
|
||||
// 更新任务项状态
|
||||
ExecTaskItem execTaskItem = new ExecTaskItem();
|
||||
execTaskItem.setId(taskItem.getId());
|
||||
execTaskItem.setStartTime(System.currentTimeMillis());
|
||||
execTaskItem.setStatus(ExecStatus.RUNNING.name());
|
||||
execTaskItem.setThreadId(request.getThreadId());
|
||||
execTaskItemMapper.updateByPrimaryKeySelective(execTaskItem);
|
||||
}
|
||||
}
|
|
@ -435,6 +435,7 @@ public class ApiTestCaseBatchRunService {
|
|||
|
||||
public TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiTestCaseService.getTaskInfo(projectId, ApiExecuteRunMode.RUN.name());
|
||||
taskInfo.setBatch(true);
|
||||
return apiBatchRunBaseService.setBatchRunTaskInfoParam(runModeConfig, taskInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -392,6 +392,7 @@ public class ApiScenarioBatchRunService {
|
|||
|
||||
public TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiScenarioRunService.getTaskInfo(projectId, ApiExecuteRunMode.RUN.name());
|
||||
taskInfo.setBatch(true);
|
||||
return apiBatchRunBaseService.setBatchRunTaskInfoParam(runModeConfig, taskInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package io.metersphere.api.utils;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import io.metersphere.sdk.constants.CommonConstants;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 记录正在运行的任务
|
||||
* runningTasks 作为内存级别的一级缓存,减少网络交互
|
||||
* redis 作为分布式的二级缓存
|
||||
* 执行结束后,result-hub 清除二级缓存
|
||||
*
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-10-09 10:57
|
||||
*/
|
||||
@Component
|
||||
public class TaskRunningCache {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
/**
|
||||
* 记录正在运行的任务
|
||||
*/
|
||||
private final Cache<String, Boolean> runningTasks = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 如果没有缓存则设置缓存
|
||||
* 设置成功,则返回 true,说明没有缓存
|
||||
* 设置失败,则返回 false,说明有缓存
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
public boolean setIfAbsent(String taskId) {
|
||||
Boolean hasCache = BooleanUtils.isTrue(runningTasks.getIfPresent(taskId));
|
||||
if (!hasCache) {
|
||||
// 原子操作,没有线程安全问题
|
||||
// 一级缓存没有,则查询二级缓存
|
||||
Boolean success = stringRedisTemplate.opsForValue()
|
||||
.setIfAbsent(
|
||||
getKey(taskId),
|
||||
StringUtils.EMPTY,
|
||||
1,
|
||||
TimeUnit.DAYS
|
||||
);
|
||||
|
||||
// 设置二级缓存
|
||||
runningTasks.put(taskId, true);
|
||||
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getKey(String taskId) {
|
||||
return CommonConstants.RUNNING_TASK_PREFIX + taskId;
|
||||
}
|
||||
}
|
|
@ -403,6 +403,7 @@ public class TestPlanApiCaseBatchRunService {
|
|||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiTestCaseBatchRunService.getTaskInfo(projectId, runModeConfig);
|
||||
taskInfo.setBatch(true);
|
||||
taskInfo.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
|
||||
return taskInfo;
|
||||
}
|
||||
|
|
|
@ -391,6 +391,7 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiScenarioBatchRunService.getTaskInfo(projectId, runModeConfig);
|
||||
taskInfo.setBatch(true);
|
||||
taskInfo.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
|
||||
return taskInfo;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue