feat(接口测试): 任务中心-接口执行改造
--task=1016475 --user=陈建星 批量执行优化 https://www.tapd.cn/55049933/s/1589205
This commit is contained in:
parent
0fa54338dd
commit
cfa6bee542
|
@ -11,6 +11,13 @@ import java.util.Map;
|
|||
*/
|
||||
@Data
|
||||
public abstract class ParameterConfig {
|
||||
/**
|
||||
* 任务项的唯一ID
|
||||
*/
|
||||
private String taskItemId;
|
||||
/**
|
||||
* 报告ID
|
||||
*/
|
||||
private String reportId;
|
||||
/**
|
||||
* 解析时,是否解析 enable 为 false 的组件
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.metersphere.sdk.constants;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 接口执行时的资源类型
|
||||
*
|
||||
|
@ -27,5 +29,13 @@ public enum ApiExecuteRunMode {
|
|||
/**
|
||||
* 定时任务
|
||||
*/
|
||||
SCHEDULE
|
||||
SCHEDULE;
|
||||
|
||||
public static boolean isDebug(String runMode) {
|
||||
return StringUtils.equalsAny(runMode, ApiExecuteRunMode.FRONTEND_DEBUG.name(), ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||
}
|
||||
|
||||
public static boolean isFrontendDebug(String runMode) {
|
||||
return StringUtils.equals(runMode, ApiExecuteRunMode.FRONTEND_DEBUG.name());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,4 +38,14 @@ public class GetRunScriptRequest implements Serializable {
|
|||
* @see io.metersphere.sdk.constants.ApiExecuteResourceType
|
||||
*/
|
||||
private String resourceType;
|
||||
/**
|
||||
* 是否需要解析脚本
|
||||
* 接口详情页面,需要传试试详情,会其他解析脚本,needParseScript 为 false
|
||||
* 不传详情执行时,通过 task-runner 发起解析脚本请求,needParseScript 为 true
|
||||
*/
|
||||
private Boolean needParseScript = false;
|
||||
/**
|
||||
* 线程ID
|
||||
*/
|
||||
private String threadId;
|
||||
}
|
||||
|
|
|
@ -16,9 +16,21 @@ import java.util.List;
|
|||
public class TaskInfo implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private String taskId;
|
||||
private String msUrl;
|
||||
private String kafkaConfig;
|
||||
private String minioConfig;
|
||||
/**
|
||||
* 单个任务的并发数
|
||||
*/
|
||||
private int perTaskSize;
|
||||
/**
|
||||
* 资源池的并发数
|
||||
*/
|
||||
private int poolSize;
|
||||
/**
|
||||
* 批量执行时的队列ID
|
||||
|
|
|
@ -14,6 +14,12 @@ public class TaskItem implements Serializable {
|
|||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务项ID
|
||||
*/
|
||||
@NotBlank
|
||||
private String id;
|
||||
|
||||
@NotBlank
|
||||
private String reportId;
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,11 @@ public class ExecutionQueue implements Serializable {
|
|||
*/
|
||||
private String queueId;
|
||||
|
||||
/**
|
||||
* taskId
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 执行人
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,11 @@ public class ExecutionQueueDetail implements Serializable {
|
|||
*/
|
||||
private String resourceId;
|
||||
|
||||
/**
|
||||
* 资源id,每个资源在同一个运行队列中唯一
|
||||
*/
|
||||
private String taskItemId;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
|
|
|
@ -32,13 +32,16 @@ public class TestPlanExecutionQueue {
|
|||
private String prepareReportId;
|
||||
// 测试集Json
|
||||
private String testPlanCollectionJson;
|
||||
// 任务ID
|
||||
private String taskId;
|
||||
|
||||
// 是否是队列的最后一个
|
||||
private boolean isLastOne = false;
|
||||
// 是否执行完毕
|
||||
private boolean executeFinish = false;
|
||||
|
||||
public TestPlanExecutionQueue(long pos, String createUser, long createTime, String queueId, String queueType, String parentQueueId, String parentQueueType, String sourceID, String runMode, String executionSource, String prepareReportId) {
|
||||
public TestPlanExecutionQueue(long pos, String createUser, long createTime, String queueId, String queueType, String parentQueueId, String parentQueueType, String sourceID, String runMode,
|
||||
String executionSource, String prepareReportId, String taskId) {
|
||||
this.pos = pos;
|
||||
this.createUser = createUser;
|
||||
this.createTime = createTime;
|
||||
|
@ -50,5 +53,6 @@ public class TestPlanExecutionQueue {
|
|||
this.runMode = runMode;
|
||||
this.executionSource = executionSource;
|
||||
this.prepareReportId = prepareReportId;
|
||||
this.taskId = taskId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -448,6 +448,8 @@ api_definition.status.continuous=连调中
|
|||
api_test_case.clear.api_change=忽略本次变更差异
|
||||
api_test_case.ignore.api_change=忽略全部变更差异
|
||||
|
||||
api_batch_task_name=用例批量执行任务
|
||||
api_scenario_batch_task_name=场景批量执行
|
||||
# api doc share i18n
|
||||
api_doc_share.not_exist=接口文档分享不存在
|
||||
api_doc_share.id.not_blank=主键不能为空
|
||||
|
|
|
@ -458,6 +458,9 @@ curl_script_is_empty=Curl script cannot be empty
|
|||
curl_script_is_invalid=Curl script is invalid
|
||||
curl_raw_content_is_invalid=Raw content is invalid
|
||||
|
||||
api_batch_task_name=Api cases batch task
|
||||
api_scenario_batch_task_name=Scenarios batch task
|
||||
|
||||
# api doc share i18n
|
||||
api_doc_share.not_exist=api doc share not exist
|
||||
api_doc_share.id.not_blank=id cannot be empty
|
||||
|
|
|
@ -426,6 +426,9 @@ curl_script_is_empty=cURL脚本不能为空
|
|||
curl_script_is_invalid=cURL脚本格式不正确
|
||||
curl_raw_content_is_invalid=raw内容格式不正确
|
||||
|
||||
api_batch_task_name=用例批量执行任务
|
||||
api_scenario_batch_task_name=场景批量执行
|
||||
|
||||
# api doc share i18n
|
||||
api_doc_share.not_exist=接口文档分享不存在
|
||||
api_doc_share.id.not_blank=主键不能为空
|
||||
|
|
|
@ -426,6 +426,9 @@ curl_script_is_empty=curl脚本不能爲空
|
|||
curl_script_is_invalid=curl脚本格式不正確
|
||||
curl_raw_content_is_invalid=raw内容格式不正確
|
||||
|
||||
api_batch_task_name=用例批量執行任務
|
||||
api_scenario_batch_task_name=場景批量執行
|
||||
|
||||
# api doc share i18n
|
||||
api_doc_share.not_exist=接口文檔分享不存在
|
||||
api_doc_share.id.not_blank=主键不能為空
|
||||
|
|
|
@ -24,19 +24,6 @@ public class ApiExecuteResourceController {
|
|||
@Resource
|
||||
private ApiExecuteResourceService apiExecuteResourceService;
|
||||
|
||||
/**
|
||||
* 获取执行脚本
|
||||
*
|
||||
* @param reportId
|
||||
* @param testId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("script")
|
||||
@Operation(summary = "获取执行脚本")
|
||||
public String getScript(@RequestParam("reportId") String reportId, @RequestParam("testId") String testId) {
|
||||
return apiExecuteResourceService.getRunScript(reportId, testId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行脚本
|
||||
*
|
||||
|
@ -55,11 +42,10 @@ public class ApiExecuteResourceController {
|
|||
*/
|
||||
@PostMapping("/file")
|
||||
@Operation(summary = "下载执行所需的文件")
|
||||
public void downloadFile(@RequestParam("reportId") String reportId,
|
||||
@RequestParam("testId") String testId,
|
||||
public void downloadFile(@RequestParam("taskItemId") String taskItemId,
|
||||
@RequestBody FileRequest fileRequest,
|
||||
HttpServletResponse response) throws Exception {
|
||||
apiExecuteService.downloadFile(reportId, testId, fileRequest, response);
|
||||
apiExecuteService.downloadFile(taskItemId, fileRequest, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@ import java.util.Map;
|
|||
*/
|
||||
@Data
|
||||
public class ApiParamConfig extends ParameterConfig {
|
||||
/**
|
||||
* 报告ID
|
||||
*/
|
||||
private String reportId;
|
||||
/**
|
||||
* 使用全局cookie
|
||||
*/
|
||||
|
|
|
@ -7,11 +7,12 @@ import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
|||
import io.metersphere.api.dto.request.MsScenario;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioDetail;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioParseParam;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioRunService;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||
import io.metersphere.sdk.constants.TaskTriggerMode;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
|
||||
import io.metersphere.sdk.dto.api.task.TaskInfo;
|
||||
import io.metersphere.sdk.dto.api.task.TaskItem;
|
||||
|
@ -19,6 +20,8 @@ import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
|
|||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.schedule.BaseScheduleJob;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -31,6 +34,8 @@ public class ApiScenarioScheduleJob extends BaseScheduleJob {
|
|||
protected void businessExecute(JobExecutionContext context) {
|
||||
ApiExecuteService apiExecuteService = CommonBeanFactory.getBean(ApiExecuteService.class);
|
||||
ApiScenarioRunService apiScenarioRunService = CommonBeanFactory.getBean(ApiScenarioRunService.class);
|
||||
ApiCommonService apiCommonService = CommonBeanFactory.getBean(ApiCommonService.class);
|
||||
ProjectMapper projectMapper = CommonBeanFactory.getBean(ProjectMapper.class);
|
||||
ApiRunModeConfigDTO apiRunModeConfigDTO = JSON.parseObject(context.getJobDetail().getJobDataMap().get("config").toString(), ApiRunModeConfigDTO.class);
|
||||
|
||||
ApiScenarioDetail apiScenarioDetail = apiScenarioRunService.getForRun(resourceId);
|
||||
|
@ -58,18 +63,35 @@ public class ApiScenarioScheduleJob extends BaseScheduleJob {
|
|||
|
||||
ApiResourceRunRequest runRequest = apiScenarioRunService.getApiResourceRunRequest(msScenario, tmpParam);
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(apiScenarioDetail.getProjectId());
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(1L);
|
||||
execTask.setTaskName(apiScenarioDetail.getName());
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.SCHEDULE.name());
|
||||
execTask.setTaskType(ExecTaskType.API_SCENARIO.name());
|
||||
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(apiScenarioDetail.getId());
|
||||
execTaskItem.setResourceName(apiScenarioDetail.getName());
|
||||
|
||||
TaskRequestDTO taskRequest = apiScenarioRunService.getTaskRequest(IDGenerator.nextStr(), apiScenarioDetail.getId(), apiScenarioDetail.getProjectId(), ApiExecuteRunMode.SCHEDULE.name());
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskInfo.getRunModeConfig().setPoolId(apiRunModeConfigDTO.getPoolId());
|
||||
taskInfo.setTaskId(execTask.getId());
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(false);
|
||||
taskInfo.setUserId(userId);
|
||||
taskInfo.getRunModeConfig().setEnvironmentId(parseParam.getEnvironmentId());
|
||||
taskItem.setRequestCount(tmpParam.getRequestCount().get());
|
||||
taskItem.setId(execTaskItem.getId());
|
||||
|
||||
ApiScenarioParamConfig parseConfig = apiScenarioRunService.getApiScenarioParamConfig(msScenario.getProjectId(), parseParam, tmpParam.getScenarioParseEnvInfo());
|
||||
parseConfig.setReportId(taskItem.getReportId());
|
||||
parseConfig.setTaskItemId(taskItem.getId());
|
||||
|
||||
// 初始化报告
|
||||
ApiScenarioReport scenarioReport = apiScenarioRunService.getScenarioReport(userId);
|
||||
|
|
|
@ -96,4 +96,6 @@ public interface ExtApiScenarioMapper {
|
|||
List<ApiScenario> getListBySelectIds(@Param("projectId") String projectId, @Param("ids") List<String> ids, @Param("testPlanId") String testPlanId);
|
||||
|
||||
List<ApiScenario> selectBaseInfoByModuleId(String id);
|
||||
|
||||
List<ApiScenario> getNameInfo(@Param("ids") List<String> ids);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,14 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getNameInfo" resultType="io.metersphere.api.domain.ApiScenario">
|
||||
SELECT id, name
|
||||
FROM api_scenario
|
||||
WHERE id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="listByProviderRequest" resultMap="TestCaseProviderDTO">
|
||||
SELECT
|
||||
api_scenario.id,
|
||||
|
|
|
@ -59,9 +59,10 @@ public interface ExtApiTestCaseMapper {
|
|||
|
||||
List<ApiTestCase> getTestCaseByProvider(@Param("request") AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
|
||||
|
||||
|
||||
List<ApiTestCase> getTagsByIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
|
||||
|
||||
List<ApiTestCase> getNameInfo(@Param("ids") List<String> ids);
|
||||
|
||||
List<ExecuteReportDTO> getExecuteList(@Param("request") ExecutePageRequest request);
|
||||
|
||||
List<OptionDTO> selectVersionOptionByIds(@Param("ids") List<String> ids);
|
||||
|
|
|
@ -971,4 +971,12 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="getNameInfo" resultType="io.metersphere.api.domain.ApiTestCase">
|
||||
SELECT id,name
|
||||
FROM api_test_case
|
||||
WHERE id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
|
@ -111,7 +111,7 @@ public class JmeterTestElementParser implements TestElementParser {
|
|||
|
||||
ThreadGroup threadGroup = new ThreadGroup();
|
||||
threadGroup.setEnabled(true);
|
||||
threadGroup.setName(config.getReportId());
|
||||
threadGroup.setName(config.getTaskItemId());
|
||||
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
|
||||
threadGroup.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ThreadGroupGui"));
|
||||
threadGroup.setNumThreads(1);
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.sdk.dto.api.task.TaskInfo;
|
|||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -24,15 +25,15 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
public class ApiBatchRunBaseService {
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
|
||||
/**
|
||||
* 初始化执行队列
|
||||
*
|
||||
* @param resourceIds
|
||||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
public ExecutionQueue initExecutionqueue(List<String> resourceIds, ApiRunModeConfigDTO runModeConfig, String resourceType, String userId) {
|
||||
return initExecutionqueue(resourceIds, runModeConfig, resourceType, null, userId);
|
||||
public ExecutionQueue initExecutionqueue(List<String> resourceIds, String resourceType, String userId) {
|
||||
return initExecutionqueue(resourceIds, null, resourceType, null, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,22 +60,44 @@ public class ApiBatchRunBaseService {
|
|||
queue.setQueueId(queueId);
|
||||
}
|
||||
queue.setParentQueueId(parentQueueId);
|
||||
List<ExecutionQueueDetail> queueDetails = getExecutionQueueDetails(resourceIds);
|
||||
List<ExecutionQueueDetail> queueDetails = getExecutionQueueDetailsByIds(resourceIds);
|
||||
apiExecutionQueueService.insertQueue(queue, queueDetails);
|
||||
return queue;
|
||||
}
|
||||
|
||||
public ExecutionQueue initExecutionQueue(String taskId, ApiRunModeConfigDTO runModeConfig, String resourceType, String parentQueueId, String userId) {
|
||||
return initExecutionQueue(taskId, null, runModeConfig, resourceType, parentQueueId, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化执行队列
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
public ExecutionQueue initExecutionQueue(String taskId, String queueId, ApiRunModeConfigDTO runModeConfig, String resourceType, String parentQueueId, String userId) {
|
||||
ExecutionQueue queue = getExecutionQueue(runModeConfig, resourceType, userId);
|
||||
queue.setTaskId(taskId);
|
||||
if (StringUtils.isNotBlank(queueId)) {
|
||||
queue.setQueueId(queueId);
|
||||
}
|
||||
queue.setParentQueueId(parentQueueId);
|
||||
apiExecutionQueueService.insertQueue(queue);
|
||||
return queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化执行队列
|
||||
*
|
||||
* @param resourceIds
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public ExecutionQueue initExecutionqueue(List<String> resourceIds, String resourceType, String userId) {
|
||||
return initExecutionqueue(resourceIds, null, resourceType, null, userId);
|
||||
public void initExecutionQueueDetails(String queueId, List<ExecTaskItem> execTaskItems) {
|
||||
List<ExecutionQueueDetail> queueDetails = getExecutionQueueDetails(execTaskItems);
|
||||
apiExecutionQueueService.insertQueueDetail(queueId, queueDetails);
|
||||
}
|
||||
|
||||
public List<ExecutionQueueDetail> getExecutionQueueDetails(List<String> resourceIds) {
|
||||
public List<ExecutionQueueDetail> getExecutionQueueDetailsByIds(List<String> resourceIds) {
|
||||
List<ExecutionQueueDetail> queueDetails = new ArrayList<>();
|
||||
AtomicInteger sort = new AtomicInteger(1);
|
||||
for (String resourceId : resourceIds) {
|
||||
|
@ -86,6 +109,19 @@ public class ApiBatchRunBaseService {
|
|||
return queueDetails;
|
||||
}
|
||||
|
||||
public List<ExecutionQueueDetail> getExecutionQueueDetails(List<ExecTaskItem> execTaskItems) {
|
||||
List<ExecutionQueueDetail> queueDetails = new ArrayList<>();
|
||||
AtomicInteger sort = new AtomicInteger(1);
|
||||
execTaskItems.forEach(execTaskItem -> {
|
||||
ExecutionQueueDetail queueDetail = new ExecutionQueueDetail();
|
||||
queueDetail.setResourceId(execTaskItem.getResourceId());
|
||||
queueDetail.setTaskItemId(execTaskItem.getId());
|
||||
queueDetail.setSort(sort.getAndIncrement());
|
||||
queueDetails.add(queueDetail);
|
||||
});
|
||||
return queueDetails;
|
||||
}
|
||||
|
||||
private ExecutionQueue getExecutionQueue(ApiRunModeConfigDTO runModeConfig, String resourceType, String userId) {
|
||||
ExecutionQueue queue = new ExecutionQueue();
|
||||
queue.setQueueId(UUID.randomUUID().toString());
|
||||
|
@ -96,7 +132,7 @@ public class ApiBatchRunBaseService {
|
|||
return queue;
|
||||
}
|
||||
|
||||
public ApiScenarioReport computeRequestRate(ApiScenarioReport report , long total) {
|
||||
public ApiScenarioReport computeRequestRate(ApiScenarioReport report, long total) {
|
||||
// 计算各个概率
|
||||
double successRate = calculateRate(report.getSuccessCount(), total);
|
||||
double errorRate = calculateRate(report.getErrorCount(), total);
|
||||
|
|
|
@ -25,8 +25,14 @@ import io.metersphere.project.dto.CommonScriptInfo;
|
|||
import io.metersphere.project.service.CustomFunctionService;
|
||||
import io.metersphere.project.service.FileAssociationService;
|
||||
import io.metersphere.project.service.FileMetadataService;
|
||||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||
import io.metersphere.sdk.constants.ExecStatus;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
@ -389,4 +395,27 @@ public class ApiCommonService {
|
|||
public void setApiDefinitionExecuteInfo(AbstractMsTestElement msTestElement, ApiDefinition apiDefinition) {
|
||||
setApiDefinitionExecuteInfo(msTestElement, BeanUtils.copyBean(new ApiDefinitionExecuteInfo(), apiDefinition));
|
||||
}
|
||||
|
||||
public ExecTask newExecTask(String projectId, String userId) {
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setNum(NumGenerator.nextNum(projectId, ApplicationNumScope.TASK));
|
||||
execTask.setProjectId(projectId);
|
||||
execTask.setId(IDGenerator.nextStr());
|
||||
execTask.setCreateTime(System.currentTimeMillis());
|
||||
execTask.setCreateUser(userId);
|
||||
execTask.setStatus(ExecStatus.PENDING.name());
|
||||
return execTask;
|
||||
}
|
||||
|
||||
public ExecTaskItem newExecTaskItem(String taskId, String projectId, String userId) {
|
||||
ExecTaskItem execTaskItem = new ExecTaskItem();
|
||||
execTaskItem.setId(IDGenerator.nextStr());
|
||||
execTaskItem.setTaskId(taskId);
|
||||
execTaskItem.setProjectId(projectId);
|
||||
execTaskItem.setExecutor(userId);
|
||||
execTaskItem.setStatus(ExecStatus.PENDING.name());
|
||||
execTaskItem.setResourcePoolId(StringUtils.EMPTY);
|
||||
execTaskItem.setResourcePoolNode(StringUtils.EMPTY);
|
||||
return execTaskItem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ 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.sdk.dto.api.task.GetRunScriptRequest;
|
||||
import io.metersphere.sdk.dto.api.task.GetRunScriptResult;
|
||||
|
@ -11,7 +12,10 @@ 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.ExecTaskItem;
|
||||
import io.metersphere.system.mapper.ExecTaskItemMapper;
|
||||
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.Service;
|
||||
|
@ -24,7 +28,7 @@ import java.util.Optional;
|
|||
public class ApiExecuteResourceService {
|
||||
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
private ExecTaskItemMapper execTaskItemMapper;
|
||||
@Resource
|
||||
private ApiReportService apiReportService;
|
||||
@Resource
|
||||
|
@ -35,12 +39,22 @@ public class ApiExecuteResourceService {
|
|||
|
||||
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
|
||||
TaskItem taskItem = request.getTaskItem();
|
||||
String taskItemId = taskItem.getId();
|
||||
String reportId = taskItem.getReportId();
|
||||
String key = apiExecuteService.getTaskKey(reportId, taskItem.getResourceId());
|
||||
LogUtils.info("生成并获取执行脚本: {}", key);
|
||||
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.updateReportStatus(reportId, ExecStatus.RUNNING.name());
|
||||
|
@ -48,17 +62,17 @@ public class ApiExecuteResourceService {
|
|||
apiReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
|
||||
default -> throw new MSException("不支持的资源类型: " + request.getResourceType());
|
||||
}
|
||||
}
|
||||
|
||||
if (BooleanUtils.isFalse(request.getNeedParseScript())) {
|
||||
// 已经生成过脚本,直接获取
|
||||
String script = stringRedisTemplate.opsForValue().get(taskItemId);
|
||||
stringRedisTemplate.delete(taskItemId);
|
||||
GetRunScriptResult result = new GetRunScriptResult();
|
||||
result.setScript(Optional.ofNullable(script).orElse(StringUtils.EMPTY));
|
||||
return result;
|
||||
}
|
||||
|
||||
return ApiExecuteCallbackServiceInvoker.getRunScript(request.getResourceType(), request);
|
||||
}
|
||||
|
||||
public String getRunScript(String reportId, String testId) {
|
||||
String key = apiExecuteService.getTaskKey(reportId, testId);
|
||||
LogUtils.info("获取执行脚本: {}", key);
|
||||
String script = stringRedisTemplate.opsForValue().get(key);
|
||||
stringRedisTemplate.delete(key);
|
||||
apiReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
|
||||
apiScenarioReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
|
||||
return Optional.ofNullable(script).orElse(StringUtils.EMPTY);
|
||||
}
|
||||
}
|
|
@ -31,10 +31,12 @@ import io.metersphere.sdk.file.FileRequest;
|
|||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.config.MinioProperties;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.domain.TestResourcePool;
|
||||
import io.metersphere.system.dto.pool.TestResourceDTO;
|
||||
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
||||
import io.metersphere.system.dto.pool.TestResourcePoolReturnDTO;
|
||||
import io.metersphere.system.mapper.ExecTaskItemMapper;
|
||||
import io.metersphere.system.service.*;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
|
@ -43,7 +45,11 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -99,6 +105,10 @@ public class ApiExecuteService {
|
|||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private JdbcDriverPluginService jdbcDriverPluginService;
|
||||
@Resource
|
||||
private ExecTaskItemMapper execTaskItemMapper;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
|
@ -122,10 +132,6 @@ public class ApiExecuteService {
|
|||
}
|
||||
}
|
||||
|
||||
public String getTaskKey(String reportId, String testId) {
|
||||
return reportId + "_" + testId;
|
||||
}
|
||||
|
||||
public TaskRequestDTO execute(ApiResourceRunRequest runRequest, TaskRequestDTO taskRequest, ApiParamConfig parameterConfig) {
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
|
@ -136,12 +142,12 @@ public class ApiExecuteService {
|
|||
taskInfo.setNeedParseScript(false);
|
||||
|
||||
// 将测试脚本缓存到 redis
|
||||
String scriptRedisKey = getTaskKey(taskItem.getReportId(), taskItem.getResourceId());
|
||||
String scriptRedisKey = taskItem.getId();
|
||||
stringRedisTemplate.opsForValue().set(scriptRedisKey, executeScript, 1, TimeUnit.DAYS);
|
||||
|
||||
setTaskItemFileParam(runRequest, taskItem);
|
||||
|
||||
if (StringUtils.equals(taskInfo.getRunMode(), ApiExecuteRunMode.FRONTEND_DEBUG.name())) {
|
||||
if (ApiExecuteRunMode.isFrontendDebug(taskInfo.getRunMode())) {
|
||||
taskInfo = setTaskRequestParams(taskInfo);
|
||||
// 清空mino和kafka配置信息,避免前端获取
|
||||
taskInfo.setMinioConfig(null);
|
||||
|
@ -215,7 +221,6 @@ public class ApiExecuteService {
|
|||
// 获取资源池
|
||||
TestResourcePoolReturnDTO testResourcePoolDTO = getGetResourcePoolNodeDTO(taskInfo.getRunModeConfig(), taskInfo.getProjectId());
|
||||
|
||||
|
||||
if (StringUtils.isNotBlank(testResourcePoolDTO.getServerUrl())) {
|
||||
// 如果资源池配置了当前站点,则使用资源池的
|
||||
taskInfo.setMsUrl(testResourcePoolDTO.getServerUrl());
|
||||
|
@ -223,7 +228,7 @@ public class ApiExecuteService {
|
|||
|
||||
// 判断是否为 K8S 资源池
|
||||
boolean isK8SResourcePool = StringUtils.equals(testResourcePoolDTO.getType(), ResourcePoolTypeEnum.K8S.name());
|
||||
boolean isDebugMode = StringUtils.equalsAny(taskInfo.getRunMode(), ApiExecuteRunMode.FRONTEND_DEBUG.name(), ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||
boolean isDebugMode = ApiExecuteRunMode.isDebug(taskInfo.getRunMode());
|
||||
|
||||
if (isK8SResourcePool) {
|
||||
TestResourceDTO testResourceDTO = new TestResourceDTO();
|
||||
|
@ -237,6 +242,10 @@ public class ApiExecuteService {
|
|||
}
|
||||
} else {
|
||||
TestResourceNodeDTO testResourceNodeDTO = getNextExecuteNode(testResourcePoolDTO);
|
||||
if (!ApiExecuteRunMode.isDebug(taskInfo.getRunMode())) {
|
||||
updateTaskItemNodeInfo(taskItem, testResourcePoolDTO, testResourceNodeDTO, execTaskItemMapper);
|
||||
}
|
||||
taskInfo.setPerTaskSize(Optional.ofNullable(testResourceNodeDTO.getSingleTaskConcurrentNumber()).orElse(3));
|
||||
taskInfo.setPoolSize(testResourceNodeDTO.getConcurrentNumber());
|
||||
|
||||
String endpoint = MsHttpClient.getEndpoint(testResourceNodeDTO.getIp(), testResourceNodeDTO.getPort());
|
||||
|
@ -274,6 +283,15 @@ public class ApiExecuteService {
|
|||
return taskRequest;
|
||||
}
|
||||
|
||||
private void updateTaskItemNodeInfo(TaskItem taskItem, TestResourcePoolReturnDTO testResourcePoolDTO, TestResourceNodeDTO testResourceNodeDTO, ExecTaskItemMapper execTaskItemMapper) {
|
||||
// 非调试模式,更新任务项的资源池信息
|
||||
ExecTaskItem execTaskItem = new ExecTaskItem();
|
||||
execTaskItem.setId(taskItem.getId());
|
||||
execTaskItem.setResourcePoolId(testResourcePoolDTO.getId());
|
||||
execTaskItem.setResourcePoolNode(StringUtils.join(testResourceNodeDTO.getIp(), ":", testResourceNodeDTO.getPort()));
|
||||
execTaskItemMapper.updateByPrimaryKeySelective(execTaskItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送执行任务
|
||||
*/
|
||||
|
@ -321,9 +339,14 @@ public class ApiExecuteService {
|
|||
TestResourceNodeDTO testResourceNode = nodesList.get(i);
|
||||
TaskBatchRequestDTO subTaskRequest = distributeTasks.get(i);
|
||||
String endpoint = MsHttpClient.getEndpoint(testResourceNode.getIp(), testResourceNode.getPort());
|
||||
|
||||
if (!ApiExecuteRunMode.isDebug(taskInfo.getRunMode())) {
|
||||
batchUpdateTaskItemNodeInfo(testResourcePool, testResourceNode, subTaskRequest);
|
||||
}
|
||||
|
||||
try {
|
||||
List<String> taskKeys = subTaskRequest.getTaskItems().stream()
|
||||
.map(taskItem -> taskItem.getReportId() + "_" + taskItem.getResourceId())
|
||||
.map(TaskItem::getId)
|
||||
.toList();
|
||||
LogUtils.info("开始发送批量任务到 {} 节点执行:\n" + taskKeys, endpoint);
|
||||
MsHttpClient.batchRunApi(endpoint, subTaskRequest);
|
||||
|
@ -335,6 +358,22 @@ public class ApiExecuteService {
|
|||
}
|
||||
}
|
||||
|
||||
private void batchUpdateTaskItemNodeInfo(TestResourcePoolReturnDTO testResourcePool, TestResourceNodeDTO testResourceNode, TaskBatchRequestDTO batchRequest) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
try {
|
||||
if (CollectionUtils.isNotEmpty(batchRequest.getTaskItems())) {
|
||||
ExecTaskItemMapper batchExecTaskItemMapper = sqlSession.getMapper(ExecTaskItemMapper.class);
|
||||
batchRequest.getTaskItems().forEach(taskItem -> {
|
||||
// 非调试模式,更新任务项的资源池信息
|
||||
updateTaskItemNodeInfo(taskItem, testResourcePool, testResourceNode, batchExecTaskItemMapper);
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean validate() {
|
||||
try {
|
||||
LicenseService licenseService = CommonBeanFactory.getBean(LicenseService.class);
|
||||
|
@ -419,11 +458,13 @@ public class ApiExecuteService {
|
|||
// 设置执行参数
|
||||
TaskRequestDTO taskRequest = getTaskRequest(reportId, testId, runRequest.getProjectId());
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
taskInfo.setTaskId(reportId);
|
||||
setServerInfoParam(taskInfo);
|
||||
taskInfo.setRealTime(true);
|
||||
taskInfo.setSaveResult(false);
|
||||
taskInfo.setResourceType(ApiExecuteResourceType.API_DEBUG.name());
|
||||
taskInfo.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||
taskRequest.getTaskItem().setId(reportId);
|
||||
|
||||
return execute(apiRunRequest, taskRequest, new ApiParamConfig());
|
||||
}
|
||||
|
@ -644,9 +685,8 @@ public class ApiExecuteService {
|
|||
return (String) configMap.get(ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
||||
}
|
||||
|
||||
public void downloadFile(String reportId, String testId, FileRequest fileRequest, HttpServletResponse response) throws Exception {
|
||||
String key = getTaskKey(reportId, testId);
|
||||
if (BooleanUtils.isTrue(stringRedisTemplate.hasKey(key))) {
|
||||
public void downloadFile(String taskItemId, FileRequest fileRequest, HttpServletResponse response) throws Exception {
|
||||
if (BooleanUtils.isTrue(stringRedisTemplate.hasKey(taskItemId))) {
|
||||
FileRepository repository = StringUtils.isBlank(fileRequest.getStorage()) ? FileCenter.getDefaultRepository()
|
||||
: FileCenter.getRepository(fileRequest.getStorage());
|
||||
write2Response(repository.getFileAsStream(fileRequest), response);
|
||||
|
|
|
@ -215,10 +215,13 @@ public class ApiDebugService extends MoveNodeService {
|
|||
|
||||
TaskRequestDTO taskRequest = apiExecuteService.getTaskRequest(request.getReportId(), request.getId(), request.getProjectId());
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
taskInfo.setTaskId(request.getReportId());
|
||||
taskInfo.setSaveResult(false);
|
||||
taskInfo.setRealTime(true);
|
||||
taskInfo.setResourceType(ApiResourceType.API_DEBUG.name());
|
||||
taskInfo.setRunMode(apiExecuteService.getDebugRunModule(request.getFrontendDebug()));
|
||||
taskRequest.getTaskItem().setId(request.getReportId());
|
||||
apiParamConfig.setTaskItemId(taskRequest.getTaskItem().getId());
|
||||
return apiExecuteService.apiExecute(runRequest, taskRequest, apiParamConfig);
|
||||
}
|
||||
|
||||
|
|
|
@ -1195,10 +1195,12 @@ public class ApiDefinitionService extends MoveNodeService {
|
|||
|
||||
TaskRequestDTO taskRequest = apiExecuteService.getTaskRequest(request.getReportId(), request.getId(), request.getProjectId());
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
taskInfo.setTaskId(request.getReportId());
|
||||
taskInfo.setSaveResult(false);
|
||||
taskInfo.setRealTime(true);
|
||||
taskInfo.setResourceType(ApiResourceType.API.name());
|
||||
taskInfo.setRunMode(apiExecuteService.getDebugRunModule(request.getFrontendDebug()));
|
||||
taskRequest.getTaskItem().setId(request.getReportId());
|
||||
|
||||
AbstractMsTestElement msTestElement = runRequest.getTestElement();
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@ public class ApiReportService {
|
|||
@Resource
|
||||
private ApiReportNoticeService apiReportNoticeService;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertApiReport(ApiReport report) {
|
||||
apiReportMapper.insertSelective(report);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertApiReport(List<ApiReport> reports, List<ApiTestCaseRecord> records) {
|
||||
|
|
|
@ -4,27 +4,27 @@ import io.metersphere.api.domain.*;
|
|||
import io.metersphere.api.dto.definition.ApiTestCaseBatchRunRequest;
|
||||
import io.metersphere.api.mapper.*;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionSetService;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -39,6 +39,8 @@ public class ApiTestCaseBatchRunService {
|
|||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
|
@ -54,6 +56,12 @@ public class ApiTestCaseBatchRunService {
|
|||
private ApiReportDetailMapper apiReportDetailMapper;
|
||||
@Resource
|
||||
private ApiReportStepMapper apiReportStepMapper;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
public static final int TASK_BATCH_SIZE = 600;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
|
@ -92,24 +100,38 @@ public class ApiTestCaseBatchRunService {
|
|||
List<String> ids = apiTestCaseService.doSelectIds(request, false);
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(ids, runModeConfig, project, userId);
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 初始化集成报告
|
||||
initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
|
||||
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
|
||||
|
||||
// 初始化集成报告步骤
|
||||
initApiReportSteps(ids, apiCaseMap, runModeConfig.getCollectionReport().getReportId());
|
||||
initIntegratedReport(runModeConfig, userId, request.getProjectId());
|
||||
}
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_CASE.name(), userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(execTask.getId(), runModeConfig, ApiExecuteResourceType.API_CASE.name(), null, userId);
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, TASK_BATCH_SIZE, subIds -> {
|
||||
List<ApiTestCase> apiTestCases = getOrderApiTestCases(subIds, runModeConfig);
|
||||
|
||||
// 初始化任务项
|
||||
List<ExecTaskItem> execTaskItems = initExecTaskItem(apiTestCases, userId, project, execTask);
|
||||
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
String reportId = runModeConfig.getCollectionReport().getReportId();
|
||||
// 初始化集成报告和用例的关联关系
|
||||
initIntegratedReportCaseRecord(reportId, runModeConfig, subIds);
|
||||
|
||||
// 初始化集成报告步骤
|
||||
initApiReportSteps(apiTestCases, reportId);
|
||||
}
|
||||
});
|
||||
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
|
@ -120,6 +142,35 @@ public class ApiTestCaseBatchRunService {
|
|||
executeNextTask(queue, nextDetail);
|
||||
}
|
||||
|
||||
private List<ExecTaskItem> initExecTaskItem(List<ApiTestCase> apiTestCases, String userId, Project project, ExecTask execTask) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
|
||||
for (ApiTestCase apiTestCase : apiTestCases) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.API_CASE.name());
|
||||
execTaskItem.setResourceId(apiTestCase.getId());
|
||||
execTaskItem.setResourceName(apiTestCase.getName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
return execTaskItems;
|
||||
}
|
||||
|
||||
private ExecTask initExecTask(List<String> ids, ApiRunModeConfigDTO runModeConfig, Project project, String userId) {
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(Long.valueOf(ids.size()));
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
execTask.setTaskName(runModeConfig.getCollectionReport().getReportName());
|
||||
} else {
|
||||
execTask.setTaskName(Translator.get("api_batch_task_name"));
|
||||
}
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.API_CASE_BATCH.name());
|
||||
baseTaskHubService.insertExecTask(execTask);
|
||||
return execTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* 并行批量执行
|
||||
*
|
||||
|
@ -137,25 +188,65 @@ public class ApiTestCaseBatchRunService {
|
|||
apiExecutionSetService.initSet(apiReport.getId(), ids);
|
||||
}
|
||||
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
|
||||
// todo
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(ids, runModeConfig, project, userId);
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
SubListUtils.dealForSubList(ids, TASK_BATCH_SIZE, subIds -> {
|
||||
List<ApiTestCase> apiTestCases = getOrderApiTestCases(subIds, runModeConfig);
|
||||
// 初始化任务项
|
||||
Map<String, String> resourceExecTaskItemMap = initExecTaskItem(apiTestCases, userId, project, execTask)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ExecTaskItem::getResourceId, ExecTaskItem::getId));
|
||||
|
||||
// 初始化报告,返回用例和报告的 map
|
||||
Map<String, String> caseReportMap = initParallelReport(runModeConfig, apiTestCases, userId);
|
||||
|
||||
List<TaskItem> taskItems = new ArrayList<>(subIds.size());
|
||||
|
||||
for (ApiTestCase apiTestCase : apiTestCases) {
|
||||
// 如果是集成报告则生成唯一的虚拟ID,非集成报告使用单用例的报告ID
|
||||
String reportId = runModeConfig.isIntegratedReport()
|
||||
? runModeConfig.getCollectionReport().getReportId() + IDGenerator.nextStr()
|
||||
: caseReportMap.get(apiTestCase.getId());
|
||||
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, apiTestCase.getId());
|
||||
taskItem.setId(resourceExecTaskItemMap.get(apiTestCase.getId()));
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItems.add(taskItem);
|
||||
}
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(request.getProjectId(), runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(execTask.getId());
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有序的用例
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
private List<ApiTestCase> getOrderApiTestCases(List<String> ids, ApiRunModeConfigDTO runModeConfig) {
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(TASK_BATCH_SIZE);
|
||||
// 分批查询
|
||||
List<ApiTestCase> finalApiTestCases = apiTestCases;
|
||||
SubListUtils.dealForSubList(ids, 200, subIds -> finalApiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
|
||||
|
||||
// 初始化报告,返回用例和报告的 map
|
||||
Map<String, String> caseReportMap = initParallelReport(ids, runModeConfig, apiTestCases, apiCaseMap, userId);
|
||||
apiTestCases = new ArrayList<>(ids.size());
|
||||
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
List<TaskItem> taskItems = new ArrayList<>(ids.size());
|
||||
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
// 按照ID顺序排序
|
||||
ApiTestCase apiTestCase = apiCaseMap.get(id);
|
||||
|
||||
if (apiTestCase == null) {
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 用例不存在,则在执行集合中删除
|
||||
|
@ -164,21 +255,11 @@ public class ApiTestCaseBatchRunService {
|
|||
LogUtils.info("当前执行任务的用例已删除 {}", id);
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果是集成报告则生成唯一的虚拟ID,非集成报告使用单用例的报告ID
|
||||
String reportId = runModeConfig.isIntegratedReport()
|
||||
? runModeConfig.getCollectionReport().getReportId() + IDGenerator.nextStr()
|
||||
: caseReportMap.get(id);
|
||||
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, id);
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItems.add(taskItem);
|
||||
apiTestCases.add(apiTestCase);
|
||||
}
|
||||
return apiTestCases;
|
||||
}
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(request.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 集成报告,执行前先设置成 RUNNING
|
||||
|
@ -191,12 +272,12 @@ public class ApiTestCaseBatchRunService {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, String> initParallelReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, List<ApiTestCase> apiTestCases, Map<String, ApiTestCase> apiCaseMap, String userId) {
|
||||
private Map<String, String> initParallelReport(ApiRunModeConfigDTO runModeConfig, List<ApiTestCase> apiTestCases, String userId) {
|
||||
// 先初始化所有报告
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 获取集成报告ID
|
||||
String integratedReportId = runModeConfig.getCollectionReport().getReportId();
|
||||
initApiReportSteps(ids, apiCaseMap, integratedReportId);
|
||||
initApiReportSteps(apiTestCases, integratedReportId);
|
||||
return null;
|
||||
} else {
|
||||
// 初始化非集成报告
|
||||
|
@ -209,14 +290,12 @@ public class ApiTestCaseBatchRunService {
|
|||
/**
|
||||
* 初始化集成报告的报告步骤
|
||||
*
|
||||
* @param ids
|
||||
* @param apiCaseMap
|
||||
* @param reportId
|
||||
*/
|
||||
private void initApiReportSteps(List<String> ids, Map<String, ApiTestCase> apiCaseMap, String reportId) {
|
||||
private void initApiReportSteps(List<ApiTestCase> apiTestCases, String reportId) {
|
||||
AtomicLong sort = new AtomicLong(1);
|
||||
List<ApiReportStep> apiReportSteps = ids.stream()
|
||||
.map(id -> getApiReportStep(apiCaseMap.get(id), reportId, sort.getAndIncrement()))
|
||||
List<ApiReportStep> apiReportSteps = apiTestCases.stream()
|
||||
.map(apiTestCase -> getApiReportStep(apiTestCase, reportId, sort.getAndIncrement()))
|
||||
.collect(Collectors.toList());
|
||||
apiReportService.insertApiReportStep(apiReportSteps);
|
||||
}
|
||||
|
@ -265,6 +344,43 @@ public class ApiTestCaseBatchRunService {
|
|||
return apiReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
private ApiReport initIntegratedReport(ApiRunModeConfigDTO runModeConfig, String userId, String projectId) {
|
||||
ApiReport apiReport = getApiReport(runModeConfig, userId);
|
||||
apiReport.setName(runModeConfig.getCollectionReport().getReportName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiReport.setIntegrated(true);
|
||||
apiReport.setProjectId(projectId);
|
||||
apiReportService.insertApiReport(apiReport);
|
||||
// 设置集成报告执行参数
|
||||
runModeConfig.getCollectionReport().setReportId(apiReport.getId());
|
||||
return apiReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
private void initIntegratedReportCaseRecord(String reportId, ApiRunModeConfigDTO runModeConfig, List<String> ids) {
|
||||
// 初始化集成报告与用例的关联关系
|
||||
List<ApiTestCaseRecord> records = ids.stream().map(id -> {
|
||||
ApiTestCaseRecord record = new ApiTestCaseRecord();
|
||||
record.setApiReportId(reportId);
|
||||
record.setApiTestCaseId(id);
|
||||
return record;
|
||||
}).toList();
|
||||
apiReportService.insertApiReport(List.of(), records);
|
||||
// 设置集成报告执行参数
|
||||
runModeConfig.getCollectionReport().setReportId(reportId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行串行的下一个任务
|
||||
*
|
||||
|
@ -274,6 +390,7 @@ public class ApiTestCaseBatchRunService {
|
|||
public void executeNextTask(ExecutionQueue queue, ExecutionQueueDetail queueDetail) {
|
||||
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
|
||||
String resourceId = queueDetail.getResourceId();
|
||||
String taskItemId = queueDetail.getTaskItemId();
|
||||
|
||||
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(resourceId);
|
||||
|
||||
|
@ -291,9 +408,11 @@ public class ApiTestCaseBatchRunService {
|
|||
}
|
||||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiTestCase, runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskItem().setRequestCount(1L);
|
||||
taskRequest.getTaskItem().setId(taskItemId);
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import io.metersphere.sdk.dto.api.task.*;
|
|||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.dto.OperationHistoryDTO;
|
||||
import io.metersphere.system.dto.request.OperationHistoryRequest;
|
||||
|
@ -40,6 +42,7 @@ import io.metersphere.system.dto.sdk.request.PosRequest;
|
|||
import io.metersphere.system.log.constants.OperationLogModule;
|
||||
import io.metersphere.system.mapper.UserMapper;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.service.OperationHistoryService;
|
||||
import io.metersphere.system.service.UserLoginService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
|
@ -116,6 +119,8 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
private FunctionalCaseTestMapper functionalCaseTestMapper;
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
private static final String CASE_TABLE = "api_test_case";
|
||||
|
||||
|
@ -719,6 +724,22 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
*/
|
||||
public TaskRequestDTO executeRun(ApiResourceRunRequest runRequest, ApiTestCase apiTestCase, String reportId, String userId) {
|
||||
String poolId = apiExecuteService.getProjectApiResourcePoolId(apiTestCase.getProjectId());
|
||||
Project project = projectMapper.selectByPrimaryKey(apiTestCase.getProjectId());
|
||||
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(1L);
|
||||
execTask.setTaskName(apiTestCase.getName());
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.API_CASE.name());
|
||||
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.API_CASE.name());
|
||||
execTaskItem.setResourceId(apiTestCase.getId());
|
||||
execTaskItem.setResourceName(apiTestCase.getName());
|
||||
|
||||
baseTaskHubService.insertExecTaskAndDetail(execTask, execTaskItem);
|
||||
|
||||
TaskRequestDTO taskRequest = getTaskRequest(reportId, apiTestCase.getId(), apiTestCase.getProjectId(), ApiExecuteRunMode.RUN.name());
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
|
@ -726,6 +747,8 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
taskInfo.getRunModeConfig().setPoolId(poolId);
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setUserId(userId);
|
||||
taskInfo.setTaskId(execTask.getId());
|
||||
taskItem.setId(execTaskItem.getId());
|
||||
|
||||
if (StringUtils.isEmpty(taskItem.getReportId())) {
|
||||
taskInfo.setRealTime(false);
|
||||
|
@ -752,9 +775,11 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
public TaskRequestDTO debug(ApiCaseRunRequest request, String userId) {
|
||||
TaskRequestDTO taskRequest = getTaskRequest(request.getReportId(), request.getId(),
|
||||
request.getProjectId(), apiExecuteService.getDebugRunModule(request.getFrontendDebug()));
|
||||
taskRequest.getTaskInfo().setTaskId(UUID.randomUUID().toString());
|
||||
taskRequest.getTaskInfo().setSaveResult(false);
|
||||
taskRequest.getTaskInfo().setRealTime(true);
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
taskRequest.getTaskItem().setId(UUID.randomUUID().toString());
|
||||
|
||||
ApiResourceRunRequest runRequest = apiExecuteService.getApiResourceRunRequest(request);
|
||||
|
||||
|
@ -771,6 +796,7 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
apiParamConfig.setEnvConfig(environmentService.get(envId));
|
||||
|
||||
taskRequest.getTaskInfo().getRunModeConfig().setEnvironmentId(envId);
|
||||
apiParamConfig.setTaskItemId(taskRequest.getTaskItem().getId());
|
||||
// 设置 method 等信息
|
||||
apiCommonService.setApiDefinitionExecuteInfo(runRequest.getTestElement(), apiDefinition);
|
||||
|
||||
|
@ -872,8 +898,12 @@ public class ApiTestCaseService extends MoveNodeService {
|
|||
}
|
||||
|
||||
public ApiTestCaseRecord getApiTestCaseRecord(ApiTestCase apiTestCase, ApiReport apiReport) {
|
||||
return getApiTestCaseRecord(apiTestCase.getId(), apiReport);
|
||||
}
|
||||
|
||||
public ApiTestCaseRecord getApiTestCaseRecord(String caseId, ApiReport apiReport) {
|
||||
ApiTestCaseRecord apiTestCaseRecord = new ApiTestCaseRecord();
|
||||
apiTestCaseRecord.setApiTestCaseId(apiTestCase.getId());
|
||||
apiTestCaseRecord.setApiTestCaseId(caseId);
|
||||
apiTestCaseRecord.setApiReportId(apiReport.getId());
|
||||
return apiTestCaseRecord;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,20 @@ public class ApiExecutionQueueService {
|
|||
stringRedisTemplate.expire(QUEUE_DETAIL_PREFIX + queue.getQueueId(), 1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertQueue(ExecutionQueue queue) {
|
||||
// 保存队列信息
|
||||
stringRedisTemplate.opsForValue().setIfAbsent(QUEUE_PREFIX + queue.getQueueId(), JSON.toJSONString(queue), 1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertQueueDetail(String queueId, List<ExecutionQueueDetail> queueDetails) {
|
||||
// 保存队列详情信息
|
||||
List<String> queueStrItems = queueDetails.stream().map(JSON::toJSONString).toList();
|
||||
stringRedisTemplate.opsForList().rightPushAll(QUEUE_DETAIL_PREFIX + queueId, queueStrItems);
|
||||
stringRedisTemplate.expire(QUEUE_DETAIL_PREFIX + queueId, 1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一个节点
|
||||
*/
|
||||
|
|
|
@ -10,17 +10,20 @@ import io.metersphere.api.mapper.ApiScenarioMapper;
|
|||
import io.metersphere.api.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionSetService;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
@ -59,6 +62,14 @@ public class ApiScenarioBatchRunService {
|
|||
private ApiScenarioMapper apiScenarioMapper;
|
||||
@Resource
|
||||
private ApiScenarioRunService apiScenarioRunService;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
public static final int TASK_BATCH_SIZE = 600;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
|
@ -96,19 +107,46 @@ public class ApiScenarioBatchRunService {
|
|||
public void serialExecute(ApiScenarioBatchRunRequest request, String userId) {
|
||||
List<String> ids = apiScenarioService.doSelectIds(request, false);
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(ids, runModeConfig, project, userId);
|
||||
|
||||
// 初始化集成报告
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
|
||||
|
||||
// 初始化集合报告步骤
|
||||
initReport(ids, runModeConfig, userId);
|
||||
initIntegratedReport(runModeConfig, userId, request.getProjectId());
|
||||
}
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(execTask.getId(), runModeConfig,
|
||||
ApiExecuteResourceType.API_SCENARIO.name(), null, userId);
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, TASK_BATCH_SIZE, subIds -> {
|
||||
List<ApiScenario> apiScenarios = getOrderScenarios(subIds, runModeConfig);
|
||||
|
||||
// 初始化任务项
|
||||
List<ExecTaskItem> execTaskItems = initExecTaskItem(subIds, apiScenarios, userId, project, execTask);
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
String reportId = runModeConfig.getCollectionReport().getReportId();
|
||||
// 初始化集合报告和场景的关联关系
|
||||
initIntegratedReportCaseRecord(reportId, subIds);
|
||||
// 集合报告初始化一级步骤
|
||||
initApiScenarioReportStep(apiScenarios, reportId);
|
||||
} else {
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
initScenarioReport(runModeConfig, apiScenarios, userId);
|
||||
}
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
});
|
||||
|
||||
// todo
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_SCENARIO.name(), userId);
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
executeNextTask(queue, nextDetail);
|
||||
|
@ -124,63 +162,119 @@ public class ApiScenarioBatchRunService {
|
|||
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(ids, runModeConfig, project, userId);
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 初始化集成报告
|
||||
ApiScenarioReport apiScenarioReport = initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
|
||||
ApiScenarioReport apiScenarioReport = initIntegratedReport(runModeConfig, userId, request.getProjectId());
|
||||
// 集成报告才需要初始化执行集合,用于统计整体执行情况
|
||||
apiExecutionSetService.initSet(apiScenarioReport.getId(), ids);
|
||||
}
|
||||
|
||||
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
|
||||
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
List<TaskItem> taskItems = ids.stream()
|
||||
.map(id -> apiExecuteService.getTaskItem(
|
||||
runModeConfig.isIntegratedReport()
|
||||
? runModeConfig.getCollectionReport().getReportId() + IDGenerator.nextStr()
|
||||
: scenarioReportMap.get(id), id
|
||||
))
|
||||
.toList();
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(request.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, TASK_BATCH_SIZE, subIds -> {
|
||||
List<ApiScenario> apiScenarios = getOrderScenarios(subIds, runModeConfig);
|
||||
Map<String, String> caseReportMap = null;
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集合报告初始化一级步骤
|
||||
initApiScenarioReportStep(apiScenarios, runModeConfig.getCollectionReport().getReportId());
|
||||
} else {
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
caseReportMap = initScenarioReport(runModeConfig, apiScenarios, userId);
|
||||
}
|
||||
|
||||
// 初始化任务项
|
||||
Map<String, String> resourceExecTaskItemMap = initExecTaskItem(subIds, apiScenarios, userId, project, execTask)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ExecTaskItem::getResourceId, ExecTaskItem::getId));
|
||||
|
||||
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>(ids.size());
|
||||
List<TaskItem> taskItems = new ArrayList<>(ids.size());
|
||||
|
||||
for (ApiScenario apiScenario : apiScenarios) {
|
||||
// 如果是集成报告则生成唯一的虚拟ID,非集成报告使用单用例的报告ID
|
||||
String reportId = runModeConfig.isIntegratedReport()
|
||||
? runModeConfig.getCollectionReport().getReportId() + IDGenerator.nextStr()
|
||||
: caseReportMap.get(apiScenario.getId());
|
||||
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, apiScenario.getId());
|
||||
taskItem.setId(resourceExecTaskItemMap.get(apiScenario.getId()));
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItems.add(taskItem);
|
||||
}
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(request.getProjectId(), runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(execTask.getId());
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有序的用例
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
private List<ApiScenario> getOrderScenarios(List<String> ids, ApiRunModeConfigDTO runModeConfig) {
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>(TASK_BATCH_SIZE);
|
||||
// 分批查询
|
||||
List<ApiScenario> finalApiScenarios = apiScenarios;
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> finalApiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
SubListUtils.dealForSubList(ids, 200, subIds -> finalApiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
Map<String, ApiScenario> apiScenarioMap = apiScenarios.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, Function.identity()));
|
||||
|
||||
apiScenarios = new ArrayList<>(ids.size());
|
||||
|
||||
for (String id : ids) {
|
||||
// 按照ID顺序排序
|
||||
ApiScenario apiScenario = apiScenarioMap.get(id);
|
||||
if (apiScenario == null) {
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 用例不存在,则在执行集合中删除
|
||||
apiExecutionSetService.removeItem(runModeConfig.getCollectionReport().getReportId(), id);
|
||||
}
|
||||
LogUtils.info("当前执行任务的用例已删除 {}", id);
|
||||
break;
|
||||
}
|
||||
apiScenarios.add(apiScenario);
|
||||
}
|
||||
return apiScenarios;
|
||||
}
|
||||
|
||||
private ExecTask initExecTask(List<String> ids, ApiRunModeConfigDTO runModeConfig, Project project, String userId) {
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(Long.valueOf(ids.size()));
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集合报告初始化一级步骤
|
||||
initApiScenarioReportStep(apiScenarios, runModeConfig.getCollectionReport().getReportId());
|
||||
return null;
|
||||
execTask.setTaskName(runModeConfig.getCollectionReport().getReportName());
|
||||
} else {
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
return initScenarioReport(runModeConfig, apiScenarios, userId);
|
||||
execTask.setTaskName(Translator.get("api_scenario_batch_task_name"));
|
||||
}
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.API_SCENARIO_BATCH.name());
|
||||
baseTaskHubService.insertExecTask(execTask);
|
||||
return execTask;
|
||||
}
|
||||
|
||||
private List<ExecTaskItem> initExecTaskItem(List<String> ids, List<ApiScenario> apiScenarios, String userId, Project project, ExecTask execTask) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(ids.size());
|
||||
for (ApiScenario apiScenario : apiScenarios) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(apiScenario.getId());
|
||||
execTaskItem.setResourceName(apiScenario.getName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
return execTaskItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* 集成报告,执行前先设置成 RUNNING
|
||||
|
@ -223,27 +317,30 @@ public class ApiScenarioBatchRunService {
|
|||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
private ApiScenarioReport initIntegratedReport(ApiRunModeConfigDTO runModeConfig, List<String> ids, String userId, String projectId) {
|
||||
private ApiScenarioReport initIntegratedReport(ApiRunModeConfigDTO runModeConfig, String userId, String projectId) {
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, userId);
|
||||
apiScenarioReport.setName(runModeConfig.getCollectionReport().getReportName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiScenarioReport.setIntegrated(true);
|
||||
apiScenarioReport.setProjectId(projectId);
|
||||
// 初始化集成报告与用例的关联关系
|
||||
List<ApiScenarioRecord> records = ids.stream().map(id -> {
|
||||
ApiScenarioRecord scenarioRecord = new ApiScenarioRecord();
|
||||
scenarioRecord.setApiScenarioReportId(apiScenarioReport.getId());
|
||||
scenarioRecord.setApiScenarioId(id);
|
||||
return scenarioRecord;
|
||||
}).toList();
|
||||
apiScenarioReportService.insertApiScenarioReport(List.of(apiScenarioReport), records);
|
||||
apiScenarioReportMapper.insertSelective(apiScenarioReport);
|
||||
// 设置集成报告执行参数
|
||||
runModeConfig.getCollectionReport().setReportId(apiScenarioReport.getId());
|
||||
return apiScenarioReport;
|
||||
}
|
||||
|
||||
private void initIntegratedReportCaseRecord(String reportId, List<String> ids) {
|
||||
// 初始化集成报告与用例的关联关系
|
||||
List<ApiScenarioRecord> records = ids.stream().map(id -> {
|
||||
ApiScenarioRecord scenarioRecord = new ApiScenarioRecord();
|
||||
scenarioRecord.setApiScenarioReportId(reportId);
|
||||
scenarioRecord.setApiScenarioId(id);
|
||||
return scenarioRecord;
|
||||
}).toList();
|
||||
apiScenarioReportService.insertApiScenarioReport(List.of(), records);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行串行的下一个任务
|
||||
*
|
||||
|
@ -270,9 +367,11 @@ public class ApiScenarioBatchRunService {
|
|||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(apiScenario.getProjectId(), queue.getRunModeConfig());
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, queueDetail.getResourceId());
|
||||
taskItem.setId(queueDetail.getTaskItemId());
|
||||
taskRequest.setTaskItem(taskItem);
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,12 @@ import io.metersphere.api.service.queue.ApiExecutionSetService;
|
|||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.MsProcessor;
|
||||
import io.metersphere.project.api.processor.TimeWaitingProcessor;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfig;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfigModuleMatchRule;
|
||||
import io.metersphere.project.dto.environment.http.SelectModule;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.project.service.EnvironmentGroupService;
|
||||
import io.metersphere.project.service.EnvironmentService;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
|
@ -35,7 +37,10 @@ import io.metersphere.sdk.dto.api.task.*;
|
|||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.service.ApiPluginService;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
@ -81,6 +86,10 @@ public class ApiScenarioRunService {
|
|||
private ApiScenarioBlobMapper apiScenarioBlobMapper;
|
||||
@Resource
|
||||
private ApiExecutionSetService apiExecutionSetService;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
public TaskRequestDTO run(String id, String reportId, String userId) {
|
||||
ApiScenarioDetail apiScenarioDetail = getForRun(id);
|
||||
|
@ -179,6 +188,23 @@ public class ApiScenarioRunService {
|
|||
String reportId,
|
||||
String userId) {
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(apiScenario.getProjectId());
|
||||
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(1L);
|
||||
execTask.setTaskName(apiScenario.getName());
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.API_SCENARIO.name());
|
||||
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(apiScenario.getId());
|
||||
execTaskItem.setResourceName(apiScenario.getName());
|
||||
|
||||
baseTaskHubService.insertExecTaskAndDetail(execTask, execTaskItem);
|
||||
|
||||
msScenario.setResourceId(apiScenario.getId());
|
||||
|
||||
// 解析生成场景树,并保存临时变量
|
||||
|
@ -191,6 +217,8 @@ public class ApiScenarioRunService {
|
|||
TaskRequestDTO taskRequest = getTaskRequest(reportId, apiScenario.getId(), apiScenario.getProjectId(), ApiExecuteRunMode.RUN.name());
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskItem.setId(execTaskItem.getId());
|
||||
taskInfo.setTaskId(execTask.getId());
|
||||
taskInfo.getRunModeConfig().setPoolId(poolId);
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.getRunModeConfig().setEnvironmentId(parseParam.getEnvironmentId());
|
||||
|
@ -208,6 +236,7 @@ public class ApiScenarioRunService {
|
|||
|
||||
ApiScenarioParamConfig parseConfig = getApiScenarioParamConfig(apiScenario.getProjectId(), parseParam, tmpParam.getScenarioParseEnvInfo());
|
||||
parseConfig.setReportId(reportId);
|
||||
parseConfig.setTaskItemId(taskItem.getId());
|
||||
|
||||
// 初始化报告
|
||||
ApiScenarioReport scenarioReport = getScenarioReport(userId);
|
||||
|
@ -314,6 +343,7 @@ public class ApiScenarioRunService {
|
|||
|
||||
ApiScenarioParamConfig parseConfig = getApiScenarioParamConfig(apiScenarioDetail.getProjectId(), parseParam, tmpParam.getScenarioParseEnvInfo());
|
||||
parseConfig.setReportId(reportId);
|
||||
parseConfig.setTaskItemId(taskItem.getId());
|
||||
parseConfig.setRetryOnFail(request.getRunModeConfig().getRetryOnFail());
|
||||
parseConfig.setRetryConfig(request.getRunModeConfig().getRetryConfig());
|
||||
|
||||
|
@ -380,9 +410,11 @@ public class ApiScenarioRunService {
|
|||
msScenario.setProjectId(request.getProjectId());
|
||||
msScenario.setResourceId(request.getId());
|
||||
|
||||
if (!hasSave) {
|
||||
List<ApiScenarioCsv> dbCsv = apiScenarioService.getApiScenarioCsv(apiScenario.getId());
|
||||
List<CsvVariable> csvVariables = apiScenarioService.getCsvVariables(msScenario.getScenarioConfig());
|
||||
apiScenarioService.handleRefUpgradeFile(csvVariables, dbCsv);
|
||||
}
|
||||
|
||||
// 处理特殊的步骤详情
|
||||
apiScenarioService.addSpecialStepDetails(request.getSteps(), request.getStepDetails());
|
||||
|
@ -396,14 +428,16 @@ public class ApiScenarioRunService {
|
|||
TaskRequestDTO taskRequest = getTaskRequest(request.getReportId(), request.getId(), request.getProjectId(),
|
||||
apiExecuteService.getDebugRunModule(request.getFrontendDebug()));
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
taskInfo.setTaskId(request.getReportId());
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskItem.setId(request.getReportId());
|
||||
taskInfo.setSaveResult(false);
|
||||
taskInfo.setRealTime(true);
|
||||
taskItem.setRequestCount(tmpParam.getRequestCount().get());
|
||||
|
||||
ApiScenarioParamConfig parseConfig = getApiScenarioParamConfig(request.getProjectId(), request, tmpParam.getScenarioParseEnvInfo());
|
||||
parseConfig.setReportId(request.getReportId());
|
||||
|
||||
parseConfig.setTaskItemId(taskItem.getId());
|
||||
|
||||
return apiExecuteService.execute(runRequest, taskRequest, parseConfig);
|
||||
}
|
||||
|
@ -516,13 +550,16 @@ public class ApiScenarioRunService {
|
|||
}
|
||||
|
||||
public ApiScenarioRecord getApiScenarioRecord(ApiScenario apiScenario, ApiScenarioReport scenarioReport) {
|
||||
return getApiScenarioRecord(apiScenario.getId(), scenarioReport);
|
||||
}
|
||||
|
||||
public ApiScenarioRecord getApiScenarioRecord(String apiScenarioId, ApiScenarioReport scenarioReport) {
|
||||
ApiScenarioRecord scenarioRecord = new ApiScenarioRecord();
|
||||
scenarioRecord.setApiScenarioId(apiScenario.getId());
|
||||
scenarioRecord.setApiScenarioId(apiScenarioId);
|
||||
scenarioRecord.setApiScenarioReportId(scenarioReport.getId());
|
||||
return scenarioRecord;
|
||||
}
|
||||
|
||||
|
||||
public ApiScenarioReport getScenarioReport(String userId) {
|
||||
ApiScenarioReport scenarioReport = new ApiScenarioReport();
|
||||
scenarioReport.setId(IDGenerator.nextStr());
|
||||
|
|
|
@ -1434,12 +1434,6 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
*/
|
||||
|
||||
public Map<String, String> getPartialRefStepDetailMap(List<? extends ApiScenarioStepCommonDTO> steps) {
|
||||
steps.forEach(step -> {
|
||||
if (isPartialRef(step)) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
List<String> needBlobStepIds = steps.stream()
|
||||
.filter(this::isPartialRef)
|
||||
.map(ApiScenarioStepCommonDTO::getId)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package io.metersphere.api.controller;
|
||||
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.ApiFileResourceService;
|
||||
import io.metersphere.api.service.debug.ApiDebugService;
|
||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.constants.StorageType;
|
||||
import io.metersphere.sdk.file.FileCopyRequest;
|
||||
|
@ -33,15 +31,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
public class ApiExecuteResourceControllerTest extends BaseTest {
|
||||
|
||||
private static final String BASE_PATH = "/api/execute/resource/";
|
||||
private static final String SCRIPT = "script?reportId={0}&testId={1}";
|
||||
private static final String FILE = "file?reportId={0}&testId={1}";
|
||||
private static final String FILE = "file?taskItemId={0}";
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
@Resource
|
||||
private ApiDebugService apiDebugService;
|
||||
@Resource
|
||||
private ApiFileResourceService apiFileResourceService;
|
||||
|
||||
@Override
|
||||
|
@ -49,11 +42,6 @@ public class ApiExecuteResourceControllerTest extends BaseTest {
|
|||
return BASE_PATH;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getScript() throws Exception {
|
||||
this.requestGetWithOk(SCRIPT, "reportId", "testId");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downloadFile() throws Exception {
|
||||
String fileName = IDGenerator.nextStr() + "_file_upload.JPG";
|
||||
|
@ -62,18 +50,17 @@ public class ApiExecuteResourceControllerTest extends BaseTest {
|
|||
FileRequest fileRequest = new FileCopyRequest();
|
||||
fileRequest.setFileName(fileName);
|
||||
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempDir() + "/" + fileId);
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, "reportId", "testId"))
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, "reportId"))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
String reportId = UUID.randomUUID().toString();
|
||||
String testId = UUID.randomUUID().toString();
|
||||
String scriptRedisKey = apiExecuteService.getTaskKey(reportId, testId);
|
||||
String scriptRedisKey = reportId;
|
||||
stringRedisTemplate.opsForValue().set(scriptRedisKey, "aaa");
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, reportId, testId))
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, reportId))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
fileRequest.setStorage(StorageType.MINIO.name());
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, reportId, testId))
|
||||
mockMvc.perform(getPostRequestBuilder(FILE, fileRequest, reportId))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package io.metersphere.system.mapper;
|
||||
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.dto.sdk.BasePageRequest;
|
||||
import io.metersphere.system.dto.taskhub.TaskHubDTO;
|
||||
import io.metersphere.system.dto.taskhub.TaskHubItemDTO;
|
||||
import io.metersphere.system.dto.taskhub.request.TaskHubItemRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -18,4 +16,6 @@ public interface ExtExecTaskItemMapper {
|
|||
List<ExecTaskItem> selectItemByTaskIds(@Param("taskIds") List<String> taskIds, @Param("orgId") String orgId, @Param("projectId") String projectId);
|
||||
|
||||
List<ExecTaskItem> selectPoolNodeByIds(@Param("ids") List<String> ids);
|
||||
|
||||
List<ExecTaskItem> selectExecInfoByResourceIds(@Param("resourceIds") List<String> resourceIds);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,14 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectExecInfoByResourceIds" resultType="io.metersphere.system.domain.ExecTaskItem">
|
||||
SELECT id, resource_id
|
||||
FROM exec_task_item
|
||||
WHERE resource_id IN
|
||||
<foreach collection="resourceIds" item="resourceId" open="(" separator="," close=")">
|
||||
#{resourceId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="selectItemByTaskIds" resultType="io.metersphere.system.domain.ExecTaskItem">
|
||||
select id, task_id, `status`, result
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.ibatis.session.SqlSession;
|
|||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -136,22 +137,45 @@ public class BaseTaskHubService {
|
|||
return extOrganizationMapper.getOrgListByProjectIds(projectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务详情数据入库接口
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertExecTaskAndDetail(ExecTask task, ExecTaskItem item) {
|
||||
execTaskMapper.insertSelective(task);
|
||||
execTaskItemMapper.insertSelective(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务详情数据入库接口
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertExecTask(ExecTask task) {
|
||||
execTaskMapper.insertSelective(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务详情数据入库接口
|
||||
*
|
||||
* @param items
|
||||
*/
|
||||
public void insertExecTaskAndDetail(List<ExecTaskItem> items) {
|
||||
if (CollectionUtils.isNotEmpty(items)) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ExecTaskItemMapper itemMapper = sqlSession.getMapper(ExecTaskItemMapper.class);
|
||||
SubListUtils.dealForSubList(items, 1000, subList -> {
|
||||
subList.forEach(itemMapper::insertSelective);
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertExecTaskDetail(List<ExecTaskItem> items) {
|
||||
insertExecTaskAndDetail(List.of(), items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务详情数据入库接口
|
||||
*
|
||||
* @param items
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertExecTaskAndDetail(ExecTask task, List<ExecTaskItem> items) {
|
||||
insertExecTaskAndDetail(List.of(task), items);
|
||||
}
|
||||
|
||||
|
||||
|
@ -161,6 +185,7 @@ public class BaseTaskHubService {
|
|||
* @param tasks
|
||||
* @param items
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public void insertExecTaskAndDetail(List<ExecTask> tasks, List<ExecTaskItem> items) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (CollectionUtils.isNotEmpty(tasks)) {
|
||||
|
|
|
@ -218,7 +218,6 @@ public class BaseTaskHubControllerTests extends BaseTest {
|
|||
Assertions.assertNotNull(resultHolder);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void getOrgStatistics() throws Exception {
|
||||
|
@ -261,10 +260,10 @@ public class BaseTaskHubControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
@Order(21)
|
||||
public void testInsert() throws Exception {
|
||||
baseTaskHubService.insertExecTaskAndDetail(new ArrayList<>());
|
||||
ExecTaskItem execTaskItem = new ExecTaskItem();
|
||||
execTaskItem.setId("1111");
|
||||
execTaskItem.setTaskId("1");
|
||||
|
@ -276,10 +275,9 @@ public class BaseTaskHubControllerTests extends BaseTest {
|
|||
execTaskItem.setOrganizationId("1234123");
|
||||
execTaskItem.setExecutor("admin");
|
||||
execTaskItem.setResourceName("测试");
|
||||
baseTaskHubService.insertExecTaskAndDetail(List.of(execTaskItem));
|
||||
|
||||
|
||||
baseTaskHubService.insertExecTaskAndDetail(new ArrayList<>(), new ArrayList<>());
|
||||
|
||||
execTaskItem.setId("2333");
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setId("121321");
|
||||
|
@ -293,6 +291,9 @@ public class BaseTaskHubControllerTests extends BaseTest {
|
|||
execTask.setOrganizationId("123432");
|
||||
execTask.setCreateTime(System.currentTimeMillis());
|
||||
execTask.setCreateUser("admin");
|
||||
baseTaskHubService.insertExecTaskAndDetail(execTask, List.of(execTaskItem));
|
||||
execTask.setId("121329");
|
||||
execTaskItem.setId("2333555");
|
||||
baseTaskHubService.insertExecTaskAndDetail(List.of(execTask), List.of(execTaskItem));
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.plan.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TestPlanApiCaseBatchRunDTO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String apiCaseId;
|
||||
private String environmentId;
|
||||
private String testPlanCollectionId;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package io.metersphere.plan.dto;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlanApiCase;
|
||||
|
||||
public class TestPlanApiCaseDTO extends TestPlanApiCase {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.plan.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TestPlanApiScenarioBatchRunDTO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String apiScenarioId;
|
||||
private String environmentId;
|
||||
private String testPlanCollectionId;
|
||||
}
|
|
@ -41,4 +41,7 @@ public class TestPlanReportGenPreParam {
|
|||
|
||||
@Schema(description = "是否手动生成报告")
|
||||
private Boolean useManual;
|
||||
|
||||
@Schema(description = "执行的任务ID")
|
||||
private String taskId;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,7 @@ import io.metersphere.api.dto.definition.ApiDefinitionDTO;
|
|||
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||
import io.metersphere.functional.dto.ProjectOptionDTO;
|
||||
import io.metersphere.plan.domain.TestPlanApiCase;
|
||||
import io.metersphere.plan.dto.ApiCaseModuleDTO;
|
||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||
import io.metersphere.plan.dto.*;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
|
||||
|
@ -74,12 +71,15 @@ public interface ExtTestPlanApiCaseMapper {
|
|||
|
||||
List<TestPlanApiCase> getApiCaseExecuteInfoByIds(@Param("ids") List<String> ids);
|
||||
|
||||
List<TestPlanApiCaseBatchRunDTO> getSelectIdAndCollectionId(@Param("request") TestPlanApiCaseBatchRequest request);
|
||||
|
||||
List<TestPlanApiCase> getSelectIdAndCollectionId(@Param("request") TestPlanApiCaseBatchRequest request);
|
||||
List<TestPlanApiCaseBatchRunDTO> getBatchRunInfoByIds(@Param("ids") List<String> ids);
|
||||
|
||||
List<TestPlanApiCase> getPlanApiCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
||||
|
||||
List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||
|
||||
List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
|
||||
|
||||
Integer countByPlanId(@Param("planId") String planId);
|
||||
}
|
||||
|
|
|
@ -238,7 +238,6 @@
|
|||
and t.test_plan_id = #{request.testPlanId}
|
||||
<include refid="queryApiCaseWhereCondition"/>
|
||||
</select>
|
||||
|
||||
<select id="selectByTestPlanIdAndNotDeleted" resultType="io.metersphere.plan.domain.TestPlanApiCase">
|
||||
SELECT t.*
|
||||
FROM test_plan_api_case t
|
||||
|
@ -665,8 +664,8 @@
|
|||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getSelectIdAndCollectionId" resultType="io.metersphere.plan.domain.TestPlanApiCase">
|
||||
SELECT t.id as id, t.test_plan_collection_id as test_plan_collection_id
|
||||
<select id="getSelectIdAndCollectionId" resultType="io.metersphere.plan.dto.TestPlanApiCaseBatchRunDTO">
|
||||
SELECT t.id as id, t.test_plan_collection_id as test_plan_collection_id, atc.name as name, t.environment_id, atc.id as api_case_id
|
||||
FROM test_plan_api_case t
|
||||
INNER JOIN api_test_case atc ON t.api_case_id = atc.id
|
||||
INNER JOIN api_definition a ON atc.api_definition_id = a.id
|
||||
|
@ -717,4 +716,20 @@
|
|||
</foreach>
|
||||
AND test_plan.status != 'ARCHIVED'
|
||||
</select>
|
||||
<select id="getBatchRunInfoByIds" resultType="io.metersphere.plan.dto.TestPlanApiCaseBatchRunDTO">
|
||||
SELECT id, test_plan_collection_id, environment_id, api_case_id as api_case_id
|
||||
FROM test_plan_api_case
|
||||
where
|
||||
id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="countByPlanId" resultType="java.lang.Integer">
|
||||
select count(0)
|
||||
from test_plan_api_case tpac join api_test_case atc on atc.id = tpac.api_case_id
|
||||
<where>
|
||||
atc.deleted = false and tpac.test_plan_id = #{planId}
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
|
@ -3,10 +3,7 @@ package io.metersphere.plan.mapper;
|
|||
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||
import io.metersphere.functional.dto.ProjectOptionDTO;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.dto.ApiScenarioModuleDTO;
|
||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||
import io.metersphere.plan.dto.*;
|
||||
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
|
@ -68,7 +65,7 @@ public interface ExtTestPlanApiScenarioMapper {
|
|||
|
||||
void batchUpdateExecutor(@Param("ids") List<String> ids, @Param("userId") String userId);
|
||||
|
||||
List<TestPlanApiScenario> getSelectIdAndCollectionId(@Param("request") TestPlanApiScenarioBatchRunRequest request);
|
||||
List<TestPlanApiScenarioBatchRunDTO> getSelectIdAndCollectionId(@Param("request") TestPlanApiScenarioBatchRunRequest request);
|
||||
|
||||
List<String> getIdsByReportIdAndCollectionId(@Param("testPlanReportId") String testPlanReportId, @Param("collectionId") String collectionId);
|
||||
|
||||
|
@ -77,4 +74,8 @@ public interface ExtTestPlanApiScenarioMapper {
|
|||
List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||
|
||||
List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
|
||||
|
||||
List<TestPlanApiScenarioBatchRunDTO> getBatchRunInfoByIds(@Param("ids") List<String> ids);
|
||||
|
||||
Integer countByPlanId(@Param("planId") String planId);
|
||||
}
|
||||
|
|
|
@ -456,9 +456,12 @@
|
|||
AND api_scenario.deleted = #{deleted}
|
||||
<include refid="queryWhereConditionByBatchQueryRequest"/>
|
||||
</select>
|
||||
<select id="getSelectIdAndCollectionId" resultType="io.metersphere.plan.domain.TestPlanApiScenario">
|
||||
<select id="getSelectIdAndCollectionId" resultType="io.metersphere.plan.dto.TestPlanApiScenarioBatchRunDTO">
|
||||
SELECT
|
||||
test_plan_api_scenario.id as id, test_plan_api_scenario.test_plan_collection_id as testPlanCollectionId
|
||||
test_plan_api_scenario.id as id, test_plan_api_scenario.test_plan_collection_id as testPlanCollectionId,
|
||||
test_plan_api_scenario.environment_id as environmentId,
|
||||
api_scenario.name as name,
|
||||
api_scenario.id as apiScenarioId,
|
||||
FROM
|
||||
test_plan_api_scenario
|
||||
INNER JOIN api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id
|
||||
|
@ -556,6 +559,15 @@
|
|||
AND test_plan.status != 'ARCHIVED'
|
||||
</select>
|
||||
|
||||
<select id="getBatchRunInfoByIds" resultType="io.metersphere.plan.dto.TestPlanApiScenarioBatchRunDTO">
|
||||
SELECT id, test_plan_collection_id, environment_id, api_scenario_id
|
||||
FROM test_plan_api_scenario
|
||||
where
|
||||
id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<update id="batchUpdateExecutor">
|
||||
update test_plan_api_scenario
|
||||
|
@ -565,4 +577,12 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="countByPlanId" resultType="java.lang.Integer">
|
||||
select count(0)
|
||||
from test_plan_api_scenario tpas join api_scenario asce on asce.id = tpas.api_scenario_id
|
||||
<where>
|
||||
asce.deleted = false and tpas.test_plan_id = #{planId}
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
|
@ -28,6 +28,8 @@ import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
|
|||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.mapper.ExtExecTaskItemMapper;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import jodd.util.StringUtil;
|
||||
|
@ -71,6 +73,8 @@ public class PlanRunTestPlanApiCaseService {
|
|||
private TestPlanApiBatchRunBaseService testPlanApiBatchRunBaseService;
|
||||
@Resource
|
||||
private ExtTestPlanReportApiCaseMapper extTestPlanReportApiCaseMapper;
|
||||
@Resource
|
||||
private ExtExecTaskItemMapper extExecTaskItemMapper;
|
||||
|
||||
/**
|
||||
* 串行批量执行
|
||||
|
@ -89,9 +93,14 @@ public class PlanRunTestPlanApiCaseService {
|
|||
return true;
|
||||
}
|
||||
|
||||
String queueId = testPlanExecutionQueue.getPrepareReportId() + "_" + collection.getId();
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(queueId, ids, runModeConfig, ApiExecuteResourceType.PLAN_RUN_API_CASE.name(), parentQueueId, userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(testPlanExecutionQueue.getTaskId(), runModeConfig, ApiExecuteResourceType.PLAN_RUN_API_CASE.name(), parentQueueId, userId);
|
||||
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> {
|
||||
List<ExecTaskItem> execTaskItems = extExecTaskItemMapper.selectExecInfoByResourceIds(subIds);
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
});
|
||||
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
|
@ -119,12 +128,19 @@ public class PlanRunTestPlanApiCaseService {
|
|||
}
|
||||
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(testPlanReportApiCases.size());
|
||||
Map<String, String> resourceTaskItemMap = new HashMap<>();
|
||||
|
||||
List<String> caseIds = testPlanReportApiCases.stream()
|
||||
.map(TestPlanReportApiCase::getApiCaseId).collect(Collectors.toList());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(caseIds, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
SubListUtils.dealForSubList(testPlanReportApiCases, 100,
|
||||
subTestPlanReportApiCases-> {
|
||||
List<String> subIds = subTestPlanReportApiCases.stream().map(TestPlanReportApiCase::getId).toList();
|
||||
extExecTaskItemMapper.selectExecInfoByResourceIds(subIds)
|
||||
.forEach(execTaskItem -> resourceTaskItemMap.put(execTaskItem.getResourceId(), execTaskItem.getId()));
|
||||
});
|
||||
|
||||
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
|
||||
|
@ -146,6 +162,7 @@ public class PlanRunTestPlanApiCaseService {
|
|||
continue;
|
||||
}
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, id);
|
||||
taskItem.setId(resourceTaskItemMap.get(testPlanReportApiCase.getId()));
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItems.add(taskItem);
|
||||
}
|
||||
|
@ -158,6 +175,7 @@ public class PlanRunTestPlanApiCaseService {
|
|||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
TaskBatchRequestDTO taskRequest = apiTestCaseBatchRunService.getTaskBatchRequestDTO(testPlan.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
taskRequest.getTaskInfo().setTaskId(testPlanExecutionQueue.getTaskId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(parentQueueId);
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
taskRequest.getTaskInfo().setResourceType(ApiExecuteResourceType.PLAN_RUN_API_CASE.name());
|
||||
|
@ -197,11 +215,13 @@ public class PlanRunTestPlanApiCaseService {
|
|||
// 独立报告,执行到当前任务时初始化报告
|
||||
String reportId = initApiReport(runModeConfig, List.of(testPlanReportApiCase), Map.of(apiTestCase.getId(), apiTestCase), queue.getUserId()).get(resourceId);
|
||||
TaskRequestDTO taskRequest = testPlanApiCaseBatchRunService.getTaskRequestDTO(reportId, testPlanReportApiCase.getId(), apiTestCase, runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
taskRequest.getTaskInfo().setResourceType(ApiExecuteResourceType.PLAN_RUN_API_CASE.name());
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(queue.getParentQueueId());
|
||||
taskRequest.getTaskItem().setRequestCount(1L);
|
||||
taskRequest.getTaskItem().setId(queueDetail.getTaskItemId());
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
}
|
||||
|
@ -234,7 +254,7 @@ public class PlanRunTestPlanApiCaseService {
|
|||
// 创建报告和用例的关联关系
|
||||
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport);
|
||||
apiTestCaseRecords.add(apiTestCaseRecord);
|
||||
apiReportSteps.add(testPlanApiCaseBatchRunService.getApiReportStep(testPlanReportApiCase.getId(), apiTestCase, apiReport.getId(), 1));
|
||||
apiReportSteps.add(testPlanApiCaseBatchRunService.getApiReportStep(testPlanReportApiCase.getId(), apiTestCase.getName(), apiReport.getId(), 1));
|
||||
resourceReportMap.put(testPlanReportApiCase.getId(), apiReport.getId());
|
||||
}
|
||||
apiReportService.insertApiReport(apiReports, apiTestCaseRecords);
|
||||
|
|
|
@ -12,21 +12,22 @@ import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
|||
import io.metersphere.api.service.queue.ApiExecutionSetService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioRunService;
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanCollection;
|
||||
import io.metersphere.plan.domain.TestPlanReportApiScenario;
|
||||
import io.metersphere.plan.domain.TestPlanReportApiScenarioExample;
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanReportApiScenarioMapper;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.constants.TaskTriggerMode;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.mapper.ExtExecTaskItemMapper;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -66,6 +67,8 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
@Resource
|
||||
private ApiScenarioReportService apiScenarioReportService;
|
||||
@Resource
|
||||
private ExtExecTaskItemMapper extExecTaskItemMapper;
|
||||
|
||||
/**
|
||||
* 串行批量执行
|
||||
|
@ -84,10 +87,15 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
return true;
|
||||
}
|
||||
|
||||
String queueId = testPlanExecutionQueue.getPrepareReportId() + "_" + collection.getId();
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(queueId, ids, runModeConfig, ApiExecuteResourceType.PLAN_RUN_API_SCENARIO.name(), parentQueueId, userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(testPlanExecutionQueue.getTaskId(), runModeConfig, ApiExecuteResourceType.PLAN_RUN_API_SCENARIO.name(), parentQueueId, userId);
|
||||
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> {
|
||||
List<ExecTaskItem> execTaskItems = extExecTaskItemMapper.selectExecInfoByResourceIds(subIds);
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
});
|
||||
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
executeNextTask(queue, nextDetail);
|
||||
|
@ -109,18 +117,31 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(collection);
|
||||
TaskBatchRequestDTO taskRequest = testPlanApiScenarioBatchRunService.getTaskBatchRequestDTO(testPlan.getProjectId(), runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(testPlanExecutionQueue.getTaskId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(parentQueueId);
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
taskRequest.getTaskInfo().setResourceType(ApiExecuteResourceType.PLAN_RUN_API_SCENARIO.name());
|
||||
Map<String, String> resourceTaskItemMap = new HashMap<>();
|
||||
|
||||
List<TestPlanReportApiScenario> testPlanReportApiScenarios = getTestPlanReportApiScenarios(testPlanReportId, collection);
|
||||
if (CollectionUtils.isEmpty(testPlanReportApiScenarios)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubListUtils.dealForSubList(testPlanReportApiScenarios, 100,
|
||||
subTestPlanReportApiCases-> {
|
||||
List<String> subIds = subTestPlanReportApiCases.stream().map(TestPlanReportApiScenario::getId).toList();
|
||||
extExecTaskItemMapper.selectExecInfoByResourceIds(subIds)
|
||||
.forEach(execTaskItem -> resourceTaskItemMap.put(execTaskItem.getResourceId(), execTaskItem.getId()));
|
||||
});
|
||||
|
||||
Map<String, String> scenarioReportMap = initReport(testPlanReportApiScenarios, runModeConfig, userId);
|
||||
List<TaskItem> taskItems = testPlanReportApiScenarios.stream()
|
||||
.map(item -> apiExecuteService.getTaskItem(scenarioReportMap.get(item.getId()), item.getId())).toList();
|
||||
.map(item -> {
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(scenarioReportMap.get(item.getId()), item.getId());
|
||||
taskItem.setId(resourceTaskItemMap.get(item.getId()));
|
||||
return taskItem;
|
||||
}).toList();
|
||||
// 如果有父队列,则初始化执行集合,以便判断是否执行完毕
|
||||
apiExecutionSetService.initSet(parentQueueId, testPlanReportApiScenarios.stream().map(TestPlanReportApiScenario::getId).toList());
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
|
@ -150,10 +171,11 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
List<ApiScenarioReport> apiScenarioReports = new ArrayList<>(testPlanReportApiScenarios.size());
|
||||
List<ApiScenarioRecord> apiScenarioRecords = new ArrayList<>(testPlanReportApiScenarios.size());
|
||||
Map<String, String> resourceReportMap = new HashMap<>();
|
||||
String projectId = "";
|
||||
for (TestPlanReportApiScenario testPlanReportApiScenario : testPlanReportApiScenarios) {
|
||||
ApiScenario apiScenario = apiScenarioMap.get(testPlanReportApiScenario.getApiScenarioId());
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = testPlanApiScenarioBatchRunService.getScenarioReport(runModeConfig, apiScenario, userId);
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanReportApiScenario, projectId, userId);
|
||||
apiScenarioReport.setTestPlanScenarioId(testPlanReportApiScenario.getTestPlanApiScenarioId());
|
||||
// 报告预生成,方便停止测试计划时直接更新报告状态
|
||||
apiScenarioReport.setId(testPlanReportApiScenario.getApiScenarioExecuteReportId());
|
||||
|
@ -172,6 +194,19 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
return resourceReportMap;
|
||||
}
|
||||
|
||||
private ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanReportApiScenario testPlanReportApiScenario, String projectId, String userId) {
|
||||
ApiScenarioReport apiScenarioReport = apiScenarioRunService.getScenarioReport(userId);
|
||||
apiScenarioReport.setName(testPlanReportApiScenario.getApiScenarioName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiScenarioReport.setProjectId(projectId);
|
||||
apiScenarioReport.setEnvironmentId(runModeConfig.getEnvironmentId());
|
||||
apiScenarioReport.setRunMode(runModeConfig.getRunMode());
|
||||
apiScenarioReport.setPoolId(runModeConfig.getPoolId());
|
||||
apiScenarioReport.setTriggerMode(TaskTriggerMode.BATCH.name());
|
||||
apiScenarioReport.setTestPlanScenarioId(testPlanReportApiScenario.getId());
|
||||
apiScenarioReport.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanReportApiScenario.getEnvironmentId()));
|
||||
return apiScenarioReport;
|
||||
}
|
||||
|
||||
private List<TestPlanReportApiScenario> getTestPlanReportApiScenarios(String testPlanReportId, TestPlanCollection collection) {
|
||||
TestPlanReportApiScenarioExample example = new TestPlanReportApiScenarioExample();
|
||||
example.createCriteria()
|
||||
|
@ -205,7 +240,9 @@ public class PlanRunTestPlanApiScenarioService {
|
|||
String reportId = initScenarioReport(runModeConfig, List.of(testPlanReportApiScenario), Map.of(apiScenario.getId(), apiScenario), queue.getUserId()).get(resourceId);
|
||||
TaskRequestDTO taskRequest = testPlanApiScenarioBatchRunService.getTaskRequestDTO(apiScenario.getProjectId(), queue.getRunModeConfig());
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, queueDetail.getResourceId());
|
||||
taskItem.setId(queueDetail.getTaskItemId());
|
||||
taskRequest.setTaskItem(taskItem);
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(queue.getParentQueueId());
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.api.domain.ApiTestCaseRecord;
|
|||
import io.metersphere.api.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.api.mapper.ExtApiTestCaseMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.definition.ApiReportService;
|
||||
import io.metersphere.api.service.definition.ApiTestCaseBatchRunService;
|
||||
|
@ -17,20 +18,24 @@ import io.metersphere.plan.domain.TestPlan;
|
|||
import io.metersphere.plan.domain.TestPlanApiCase;
|
||||
import io.metersphere.plan.domain.TestPlanCollection;
|
||||
import io.metersphere.plan.domain.TestPlanCollectionExample;
|
||||
import io.metersphere.plan.dto.TestPlanApiCaseBatchRunDTO;
|
||||
import io.metersphere.plan.dto.request.ApiExecutionMapService;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRunRequest;
|
||||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.constants.CaseType;
|
||||
import io.metersphere.sdk.constants.CommonConstants;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jodd.util.StringUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -51,8 +56,6 @@ public class TestPlanApiCaseBatchRunService {
|
|||
@Resource
|
||||
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
|
||||
@Resource
|
||||
private TestPlanApiCaseService testPlanApiCaseService;
|
||||
@Resource
|
||||
private TestPlanCollectionMapper testPlanCollectionMapper;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
|
@ -75,7 +78,11 @@ public class TestPlanApiCaseBatchRunService {
|
|||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private ExtTestPlanMapper extTestPlanMapper;
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
|
@ -97,9 +104,9 @@ public class TestPlanApiCaseBatchRunService {
|
|||
*/
|
||||
private void batchRun(TestPlanApiCaseBatchRunRequest request, String userId) {
|
||||
try {
|
||||
List<TestPlanApiCase> testPlanApiCases = testPlanApiCaseService.getSelectIdAndCollectionId(request);
|
||||
List<TestPlanApiCaseBatchRunDTO> testPlanApiCases = getSelectIdAndCollectionId(request);
|
||||
// 按照 testPlanCollectionId 分组, value 为测试计划用例 ID 列表
|
||||
Map<String, List<String>> collectionMap = getCollectionMap(testPlanApiCases);
|
||||
Map<String, List<TestPlanApiCaseBatchRunDTO>> collectionMap = getCollectionMap(testPlanApiCases);
|
||||
|
||||
List<TestPlanCollection> testPlanCollections = getTestPlanCollections(request.getTestPlanId());
|
||||
Iterator<TestPlanCollection> iterator = testPlanCollections.iterator();
|
||||
|
@ -122,18 +129,19 @@ public class TestPlanApiCaseBatchRunService {
|
|||
.collect(Collectors.toList());
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
|
||||
if (apiBatchRunBaseService.isParallel(rootCollection.getExecuteMethod())) {
|
||||
// 并行执行测试集
|
||||
for (TestPlanCollection collection : testPlanCollections) {
|
||||
List<String> ids = collectionMap.get(collection.getId());
|
||||
List<TestPlanApiCaseBatchRunDTO> collectionCases = collectionMap.get(collection.getId());
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(rootCollection, collection);
|
||||
if (apiBatchRunBaseService.isParallel(runModeConfig.getRunMode())) {
|
||||
// 并行执行测试集中的用例
|
||||
parallelExecute(ids, runModeConfig, null, testPlan.getProjectId(), userId);
|
||||
parallelExecute(collectionCases, runModeConfig, null, project, userId);
|
||||
} else {
|
||||
// 串行执行测试集中的用例
|
||||
serialExecute(ids, runModeConfig, null, userId);
|
||||
serialExecute(collectionCases, runModeConfig, null, project, userId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -142,8 +150,12 @@ public class TestPlanApiCaseBatchRunService {
|
|||
// 生成测试集队列
|
||||
ExecutionQueue collectionQueue = apiBatchRunBaseService.initExecutionqueue(serialCollectionIds,
|
||||
ApiExecuteResourceType.TEST_PLAN_API_CASE.name(), userId);
|
||||
|
||||
Map<String, List<String>> collectionIdMap = collectionMap.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream().map(TestPlanApiCaseBatchRunDTO::getId).toList()));
|
||||
|
||||
// 记录各测试集中要执行的用例
|
||||
apiExecutionMapService.initMap(collectionQueue.getQueueId(), collectionMap);
|
||||
apiExecutionMapService.initMap(collectionQueue.getQueueId(), collectionIdMap);
|
||||
|
||||
executeNextCollection(collectionQueue.getQueueId());
|
||||
}
|
||||
|
@ -163,14 +175,17 @@ public class TestPlanApiCaseBatchRunService {
|
|||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queueId);
|
||||
String collectionId = nextDetail.getResourceId();
|
||||
List<String> ids = apiExecutionMapService.getAndRemove(queueId, collectionId);
|
||||
List<TestPlanApiCaseBatchRunDTO> testPlanApiCases = getBatchRunInfo(ids);
|
||||
TestPlanCollection collection = testPlanCollectionMapper.selectByPrimaryKey(collectionId);
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(collection.getTestPlanId());
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(collection);
|
||||
if (apiBatchRunBaseService.isParallel(runModeConfig.getRunMode())) {
|
||||
String testPlanId = collection.getTestPlanId();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
parallelExecute(ids, runModeConfig, queueId, testPlan.getProjectId(), userId);
|
||||
parallelExecute(testPlanApiCases, runModeConfig, queueId, project, userId);
|
||||
} else {
|
||||
serialExecute(ids, runModeConfig, queueId, userId);
|
||||
serialExecute(testPlanApiCases, runModeConfig, queueId, project, userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,14 +193,9 @@ public class TestPlanApiCaseBatchRunService {
|
|||
apiExecutionQueueService.deleteQueue(collectionQueueId);
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getCollectionMap(List<TestPlanApiCase> testPlanApiCases) {
|
||||
Map<String, List<String>> collectionMap = new HashMap<>();
|
||||
for (TestPlanApiCase testPlanApiCase : testPlanApiCases) {
|
||||
collectionMap.putIfAbsent(testPlanApiCase.getTestPlanCollectionId(), new ArrayList<>());
|
||||
List<String> ids = collectionMap.get(testPlanApiCase.getTestPlanCollectionId());
|
||||
ids.add(testPlanApiCase.getId());
|
||||
}
|
||||
return collectionMap;
|
||||
private Map<String, List<TestPlanApiCaseBatchRunDTO>> getCollectionMap(List<TestPlanApiCaseBatchRunDTO> testPlanApiCases) {
|
||||
return testPlanApiCases.stream()
|
||||
.collect(Collectors.groupingBy(TestPlanApiCaseBatchRunDTO::getTestPlanCollectionId));
|
||||
}
|
||||
|
||||
private List<TestPlanCollection> getTestPlanCollections(String testPlanId) {
|
||||
|
@ -200,9 +210,16 @@ public class TestPlanApiCaseBatchRunService {
|
|||
* 串行批量执行
|
||||
*
|
||||
*/
|
||||
public void serialExecute(List<String> ids, ApiRunModeConfigDTO runModeConfig, String parentQueueId, String userId) {
|
||||
public void serialExecute(List<TestPlanApiCaseBatchRunDTO> testPlanApiCases, ApiRunModeConfigDTO runModeConfig, String parentQueueId, Project project, String userId) {
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(testPlanApiCases.size(), runModeConfig, project, userId);
|
||||
// 初始化任务项
|
||||
List<ExecTaskItem> execTaskItems = initExecTaskItem(testPlanApiCases, userId, project, execTask);
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.TEST_PLAN_API_CASE.name(), parentQueueId, userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(execTask.getId(), runModeConfig, ApiExecuteResourceType.TEST_PLAN_API_CASE.name(), parentQueueId, userId);
|
||||
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
|
@ -214,61 +231,121 @@ public class TestPlanApiCaseBatchRunService {
|
|||
* 并行批量执行
|
||||
*
|
||||
*/
|
||||
public void parallelExecute(List<String> ids, ApiRunModeConfigDTO runModeConfig, String parentQueueId, String projectId, String userId) {
|
||||
|
||||
List<TestPlanApiCase> testPlanApiCases = new ArrayList<>(ids.size());
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> testPlanApiCases.addAll(extTestPlanApiCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
|
||||
List<String> caseIds = testPlanApiCases.stream()
|
||||
.map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(caseIds, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
|
||||
|
||||
public void parallelExecute(List<TestPlanApiCaseBatchRunDTO> testPlanApiCases, ApiRunModeConfigDTO runModeConfig, String parentQueueId, Project project, String userId) {
|
||||
// 初始化报告,返回用例和报告的 map
|
||||
Map<String, String> caseReportMap = initApiReport(runModeConfig, testPlanApiCases, apiCaseMap, userId);
|
||||
Map<String, String> caseReportMap = initApiReport(runModeConfig, testPlanApiCases, project.getId(), userId);
|
||||
|
||||
List<TaskItem> taskItems = new ArrayList<>(ids.size());
|
||||
List<TaskItem> taskItems = new ArrayList<>(testPlanApiCases.size());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(testPlanApiCases.size(), runModeConfig, project, userId);
|
||||
|
||||
// 初始化任务项
|
||||
Map<String, String> resourceExecTaskItemMap = initExecTaskItem(testPlanApiCases, userId, project, execTask)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ExecTaskItem::getResourceId, ExecTaskItem::getId));
|
||||
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
|
||||
Iterator<String> iterator = ids.iterator();
|
||||
Iterator<TestPlanApiCaseBatchRunDTO> iterator = testPlanApiCases.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String id = iterator.next();
|
||||
String reportId = caseReportMap.get(id);
|
||||
TestPlanApiCaseBatchRunDTO testPlanApiCase = iterator.next();
|
||||
String reportId = caseReportMap.get(testPlanApiCase.getId());
|
||||
if (StringUtil.isBlank(reportId)) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, id);
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, testPlanApiCase.getId());
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItem.setId(resourceExecTaskItemMap.get(testPlanApiCase.getId()));
|
||||
taskItems.add(taskItem);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parentQueueId)) {
|
||||
// 如果有父队列,则初始化执行集合,以便判断是否执行完毕
|
||||
apiExecutionSetService.initSet(parentQueueId, ids);
|
||||
apiExecutionSetService.initSet(parentQueueId, testPlanApiCases.stream().map(TestPlanApiCaseBatchRunDTO::getId).toList());
|
||||
}
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(projectId, runModeConfig);
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(project.getId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
taskRequest.getTaskInfo().setTaskId(execTask.getId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(parentQueueId);
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
}
|
||||
|
||||
public ApiReportStep getApiReportStep(String resourceId, ApiTestCase apiTestCase, String reportId, long sort) {
|
||||
private ExecTask initExecTask(int caseSize, ApiRunModeConfigDTO runModeConfig, Project project, String userId) {
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(Long.valueOf(caseSize));
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
execTask.setTaskName(runModeConfig.getCollectionReport().getReportName());
|
||||
} else {
|
||||
execTask.setTaskName(Translator.get("api_batch_task_name"));
|
||||
}
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.TEST_PLAN_API_CASE.name());
|
||||
baseTaskHubService.insertExecTask(execTask);
|
||||
return execTask;
|
||||
}
|
||||
|
||||
public List<TestPlanApiCaseBatchRunDTO> getSelectIdAndCollectionId(TestPlanApiCaseBatchRequest request) {
|
||||
if (request.isSelectAll()) {
|
||||
List<TestPlanApiCaseBatchRunDTO> testPlanApiCases = extTestPlanApiCaseMapper.getSelectIdAndCollectionId(request);
|
||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
testPlanApiCases.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return testPlanApiCases;
|
||||
} else {
|
||||
return getBatchRunInfo(request.getSelectIds());
|
||||
}
|
||||
}
|
||||
|
||||
private List<TestPlanApiCaseBatchRunDTO> getBatchRunInfo(List<String> ids) {
|
||||
List<TestPlanApiCaseBatchRunDTO> testPlanApiCases = new ArrayList<>();
|
||||
SubListUtils.dealForSubList(ids, 200, (subIds) -> testPlanApiCases.addAll(extTestPlanApiCaseMapper.getBatchRunInfoByIds(subIds)));
|
||||
|
||||
// 查询用例名称信息
|
||||
List<String> caseIds = testPlanApiCases.stream().map(TestPlanApiCaseBatchRunDTO::getApiCaseId).collect(Collectors.toList());
|
||||
Map<String, String> apiTestCaseNameMap = extApiTestCaseMapper.getNameInfo(caseIds)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, ApiTestCase::getName));
|
||||
|
||||
Map<String, TestPlanApiCaseBatchRunDTO> testPlanApiCaseMap = testPlanApiCases
|
||||
.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiCaseBatchRunDTO::getId, Function.identity()));
|
||||
|
||||
testPlanApiCases.clear();
|
||||
// 按ID的顺序排序
|
||||
for (String id : ids) {
|
||||
TestPlanApiCaseBatchRunDTO testPlanApiCase = testPlanApiCaseMap.get(id);
|
||||
if (testPlanApiCase != null) {
|
||||
testPlanApiCase.setName(apiTestCaseNameMap.get(testPlanApiCase.getApiCaseId()));
|
||||
testPlanApiCases.add(testPlanApiCase);
|
||||
}
|
||||
}
|
||||
return testPlanApiCases;
|
||||
}
|
||||
|
||||
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiCaseBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
|
||||
for (TestPlanApiCaseBatchRunDTO apiTestCase : apiTestCases) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
|
||||
execTaskItem.setResourceId(apiTestCase.getId());
|
||||
execTaskItem.setResourceName(apiTestCase.getName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
return execTaskItems;
|
||||
}
|
||||
|
||||
public ApiReportStep getApiReportStep(String resourceId, String name, String reportId, long sort) {
|
||||
ApiReportStep apiReportStep = new ApiReportStep();
|
||||
apiReportStep.setReportId(reportId);
|
||||
apiReportStep.setStepId(resourceId);
|
||||
apiReportStep.setSort(sort);
|
||||
apiReportStep.setName(apiTestCase.getName());
|
||||
apiReportStep.setName(name);
|
||||
apiReportStep.setStepType(ApiExecuteResourceType.API_CASE.name());
|
||||
return apiReportStep;
|
||||
}
|
||||
|
@ -291,13 +368,18 @@ public class TestPlanApiCaseBatchRunService {
|
|||
}
|
||||
|
||||
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
||||
String testPlanId = testPlanApiCase.getTestPlanId();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
|
||||
// 独立报告,执行到当前任务时初始化报告
|
||||
String reportId = initApiReport(runModeConfig, List.of(testPlanApiCase), Map.of(apiTestCase.getId(), apiTestCase), queue.getUserId()).get(testPlanApiCase.getId());
|
||||
String reportId = initApiReport(runModeConfig, List.of(BeanUtils.copyBean(new TestPlanApiCaseBatchRunDTO(), testPlanApiCase)),
|
||||
testPlan.getProjectId(), queue.getUserId()).get(testPlanApiCase.getId());
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, testPlanApiCase.getId(), apiTestCase, runModeConfig);
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(queue.getParentQueueId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskItem().setId(queueDetail.getTaskItemId());
|
||||
taskRequest.getTaskItem().setRequestCount(1L);
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
|
@ -331,22 +413,21 @@ public class TestPlanApiCaseBatchRunService {
|
|||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
public Map<String, String> initApiReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiCase> testPlanApiCases,
|
||||
Map<String, ApiTestCase> caseMap, String userId) {
|
||||
public Map<String, String> initApiReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiCaseBatchRunDTO> testPlanApiCases,
|
||||
String projectId, String userId) {
|
||||
List<ApiReport> apiReports = new ArrayList<>();
|
||||
List<ApiTestCaseRecord> apiTestCaseRecords = new ArrayList<>();
|
||||
List<ApiReportStep> apiReportSteps = new ArrayList<>();
|
||||
Map<String, String> resourceReportMap = new HashMap<>();
|
||||
|
||||
for (TestPlanApiCase testPlanApiCase : testPlanApiCases) {
|
||||
ApiTestCase apiTestCase = caseMap.get(testPlanApiCase.getApiCaseId());
|
||||
for (TestPlanApiCaseBatchRunDTO testPlanApiCase : testPlanApiCases) {
|
||||
// 初始化报告
|
||||
ApiReport apiReport = getApiReport(runModeConfig, testPlanApiCase, apiTestCase, userId);
|
||||
ApiReport apiReport = getApiReport(runModeConfig, testPlanApiCase, projectId, userId);
|
||||
apiReports.add(apiReport);
|
||||
// 创建报告和用例的关联关系
|
||||
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport);
|
||||
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(testPlanApiCase.getApiCaseId(), apiReport);
|
||||
apiTestCaseRecords.add(apiTestCaseRecord);
|
||||
apiReportSteps.add(getApiReportStep(testPlanApiCase.getId(), apiTestCase, apiReport.getId(), 1));
|
||||
apiReportSteps.add(getApiReportStep(testPlanApiCase.getId(), testPlanApiCase.getName(), apiReport.getId(), 1));
|
||||
resourceReportMap.put(testPlanApiCase.getId(), apiReport.getId());
|
||||
}
|
||||
apiReportService.insertApiReport(apiReports, apiTestCaseRecords);
|
||||
|
@ -354,9 +435,12 @@ public class TestPlanApiCaseBatchRunService {
|
|||
return resourceReportMap;
|
||||
}
|
||||
|
||||
private ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiCase testPlanApiCase, ApiTestCase apiTestCase, String userId) {
|
||||
ApiReport apiReport = apiTestCaseBatchRunService.getApiReport(runModeConfig, apiTestCase, userId);
|
||||
apiReport.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiCase.getEnvironmentId()));
|
||||
private ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiCaseBatchRunDTO testPlanApiCase, String projectId, String userId) {
|
||||
ApiReport apiReport = apiTestCaseBatchRunService.getApiReport(runModeConfig, userId);
|
||||
apiReport.setEnvironmentId(apiTestCaseService.getEnvId(runModeConfig, testPlanApiCase.getEnvironmentId()));
|
||||
apiReport.setName(testPlanApiCase.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiReport.setProjectId(projectId);
|
||||
apiReport.setTriggerMode(TaskTriggerMode.BATCH.name());
|
||||
apiReport.setTestPlanCaseId(testPlanApiCase.getId());
|
||||
return apiReport;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import io.metersphere.api.mapper.ApiTestCaseMapper;
|
|||
import io.metersphere.api.mapper.ExtApiDefinitionModuleMapper;
|
||||
import io.metersphere.api.mapper.ExtApiTestCaseMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.definition.ApiDefinitionModuleService;
|
||||
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||
|
@ -45,6 +46,8 @@ import io.metersphere.sdk.util.BeanUtils;
|
|||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.dto.ModuleSelectDTO;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
|
@ -122,6 +125,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
|||
private static final String DEBUG_MODULE_COUNT_ALL = "all";
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
|
||||
private static final String EXECUTOR = "executeUserName";
|
||||
|
||||
|
@ -557,32 +562,6 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<TestPlanApiCase> getSelectIdAndCollectionId(TestPlanApiCaseBatchRequest request) {
|
||||
if (request.isSelectAll()) {
|
||||
List<TestPlanApiCase> testPlanApiCases = extTestPlanApiCaseMapper.getSelectIdAndCollectionId(request);
|
||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
testPlanApiCases.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return testPlanApiCases;
|
||||
} else {
|
||||
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
|
||||
example.createCriteria().andIdIn(request.getSelectIds());
|
||||
Map<String, TestPlanApiCase> testPlanApiCaseMap = testPlanApiCaseMapper.selectByExample(example)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiCase::getId, Function.identity()));
|
||||
List<TestPlanApiCase> testPlanApiCases = new ArrayList<>(request.getSelectIds().size());
|
||||
// 按ID的顺序排序
|
||||
for (String id : request.getSelectIds()) {
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMap.get(id);
|
||||
if (testPlanApiCase != null) {
|
||||
testPlanApiCases.add(testPlanApiCase);
|
||||
}
|
||||
}
|
||||
return testPlanApiCases;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量更新执行人
|
||||
*
|
||||
|
@ -772,12 +751,30 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
|||
runModeConfig.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiCase.getEnvironmentId()));
|
||||
runModeConfig.setRunMode(ApiBatchRunMode.PARALLEL.name());
|
||||
TaskRequestDTO taskRequest = getTaskRequest(reportId, id, apiTestCase.getProjectId(), ApiExecuteRunMode.RUN.name());
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(apiTestCase.getProjectId());
|
||||
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(1L);
|
||||
execTask.setTaskName(apiTestCase.getName());
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.TEST_PLAN_API_CASE.name());
|
||||
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
|
||||
execTaskItem.setResourceId(apiTestCase.getId());
|
||||
execTaskItem.setResourceName(apiTestCase.getName());
|
||||
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskInfo.setTaskId(execTask.getId());
|
||||
taskInfo.setRunModeConfig(runModeConfig);
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(true);
|
||||
taskInfo.setUserId(userId);
|
||||
taskItem.setId(execTaskItem.getId());
|
||||
|
||||
if (StringUtils.isEmpty(taskItem.getReportId())) {
|
||||
taskInfo.setRealTime(false);
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.api.domain.ApiScenarioReport;
|
|||
import io.metersphere.api.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioBatchRunService;
|
||||
|
@ -15,22 +16,23 @@ import io.metersphere.plan.domain.TestPlan;
|
|||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.domain.TestPlanCollection;
|
||||
import io.metersphere.plan.domain.TestPlanCollectionExample;
|
||||
import io.metersphere.plan.dto.TestPlanApiScenarioBatchRunDTO;
|
||||
import io.metersphere.plan.dto.request.ApiExecutionMapService;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.constants.CaseType;
|
||||
import io.metersphere.sdk.constants.CommonConstants;
|
||||
import io.metersphere.sdk.constants.TaskTriggerMode;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -43,8 +45,6 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanApiScenarioBatchRunService {
|
||||
@Resource
|
||||
private TestPlanApiScenarioService testPlanApiScenarioService;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
@Resource
|
||||
|
@ -68,6 +68,8 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private TestPlanApiBatchRunBaseService testPlanApiBatchRunBaseService;
|
||||
@Resource
|
||||
private ApiExecutionMapService apiExecutionMapService;
|
||||
|
@ -75,6 +77,10 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
private TestPlanCollectionMapper testPlanCollectionMapper;
|
||||
@Resource
|
||||
private ExtTestPlanMapper extTestPlanMapper;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
|
@ -96,9 +102,9 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
*/
|
||||
private void batchRun(TestPlanApiScenarioBatchRunRequest request, String userId) {
|
||||
try {
|
||||
List<TestPlanApiScenario> testPlanApiCases = testPlanApiScenarioService.getSelectIdAndCollectionId(request);
|
||||
List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios = getSelectIdAndCollectionId(request);
|
||||
// 按照 testPlanCollectionId 分组, value 为测试计划用例 ID 列表
|
||||
Map<String, List<String>> collectionMap = getCollectionMap(testPlanApiCases);
|
||||
Map<String, List<TestPlanApiScenarioBatchRunDTO>> collectionMap = getCollectionMap(testPlanApiScenarios);
|
||||
|
||||
List<TestPlanCollection> testPlanCollections = getTestPlanCollections(request.getTestPlanId());
|
||||
Iterator<TestPlanCollection> iterator = testPlanCollections.iterator();
|
||||
|
@ -121,18 +127,19 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
.collect(Collectors.toList());
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
|
||||
if (apiBatchRunBaseService.isParallel(rootCollection.getExecuteMethod())) {
|
||||
// 并行执行测试集
|
||||
for (TestPlanCollection collection : testPlanCollections) {
|
||||
List<String> ids = collectionMap.get(collection.getId());
|
||||
List<TestPlanApiScenarioBatchRunDTO> collectionCases = collectionMap.get(collection.getId());
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(rootCollection, collection);
|
||||
if (apiBatchRunBaseService.isParallel(runModeConfig.getRunMode())) {
|
||||
// 并行执行测试集中的用例
|
||||
parallelExecute(ids, runModeConfig, testPlan.getProjectId(), null, userId);
|
||||
parallelExecute(collectionCases, runModeConfig, null, project, userId);
|
||||
} else {
|
||||
// 串行执行测试集中的用例
|
||||
serialExecute(ids, runModeConfig, null, userId);
|
||||
serialExecute(collectionCases, runModeConfig, null, project, userId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -141,8 +148,12 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
// 生成测试集队列
|
||||
ExecutionQueue collectionQueue = apiBatchRunBaseService.initExecutionqueue(serialCollectionIds,
|
||||
ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name(), userId);
|
||||
|
||||
Map<String, List<String>> collectionIdMap = collectionMap.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream().map(TestPlanApiScenarioBatchRunDTO::getId).toList()));
|
||||
|
||||
// 记录各测试集中要执行的用例
|
||||
apiExecutionMapService.initMap(collectionQueue.getQueueId(), collectionMap);
|
||||
apiExecutionMapService.initMap(collectionQueue.getQueueId(), collectionIdMap);
|
||||
|
||||
executeNextCollection(collectionQueue.getQueueId());
|
||||
}
|
||||
|
@ -160,12 +171,12 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
return testPlanCollections;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getCollectionMap(List<TestPlanApiScenario> testPlanApiScenarios) {
|
||||
Map<String, List<String>> collectionMap = new HashMap<>();
|
||||
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
|
||||
private Map<String, List<TestPlanApiScenarioBatchRunDTO>> getCollectionMap(List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios) {
|
||||
Map<String, List<TestPlanApiScenarioBatchRunDTO>> collectionMap = new HashMap<>();
|
||||
for (TestPlanApiScenarioBatchRunDTO testPlanApiScenario : testPlanApiScenarios) {
|
||||
collectionMap.putIfAbsent(testPlanApiScenario.getTestPlanCollectionId(), new ArrayList<>());
|
||||
List<String> ids = collectionMap.get(testPlanApiScenario.getTestPlanCollectionId());
|
||||
ids.add(testPlanApiScenario.getId());
|
||||
collectionMap.get(testPlanApiScenario.getTestPlanCollectionId())
|
||||
.add(testPlanApiScenario);
|
||||
}
|
||||
return collectionMap;
|
||||
}
|
||||
|
@ -180,14 +191,17 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(collectionQueueId);
|
||||
String collectionId = nextDetail.getResourceId();
|
||||
List<String> ids = apiExecutionMapService.getAndRemove(collectionQueueId, collectionId);
|
||||
List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios = getBatchRunInfo(ids);
|
||||
|
||||
TestPlanCollection collection = testPlanCollectionMapper.selectByPrimaryKey(collectionId);
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(collection.getTestPlanId());
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(collection);
|
||||
if (apiBatchRunBaseService.isParallel(runModeConfig.getRunMode())) {
|
||||
String testPlanId = collection.getTestPlanId();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
parallelExecute(ids, runModeConfig, testPlan.getProjectId(), collectionQueueId, userId);
|
||||
parallelExecute(testPlanApiScenarios, runModeConfig, collectionQueueId, project, userId);
|
||||
} else {
|
||||
serialExecute(ids, runModeConfig, collectionQueueId, userId);
|
||||
serialExecute(testPlanApiScenarios, runModeConfig, collectionQueueId, project, userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,9 +213,15 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
* 串行批量执行
|
||||
*
|
||||
*/
|
||||
public void serialExecute(List<String> ids, ApiRunModeConfigDTO runModeConfig, String parentQueueId, String userId) {
|
||||
public void serialExecute(List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios, ApiRunModeConfigDTO runModeConfig, String parentQueueId, Project project, String userId) {
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(testPlanApiScenarios.size(), runModeConfig, project, userId);
|
||||
// 初始化任务项
|
||||
List<ExecTaskItem> execTaskItems = initExecTaskItem(testPlanApiScenarios, userId, project, execTask);
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name(), parentQueueId, userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionQueue(execTask.getId(), runModeConfig, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name(), parentQueueId, userId);
|
||||
// 初始化队列项
|
||||
apiBatchRunBaseService.initExecutionQueueDetails(queue.getQueueId(), execTaskItems);
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
executeNextTask(queue, nextDetail);
|
||||
|
@ -211,65 +231,76 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
* 并行批量执行
|
||||
*
|
||||
*/
|
||||
public void parallelExecute(List<String> ids, ApiRunModeConfigDTO runModeConfig, String projectId, String parentQueueId, String userId) {
|
||||
public void parallelExecute(List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios, ApiRunModeConfigDTO runModeConfig, String parentQueueId, Project project, String userId) {
|
||||
|
||||
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
|
||||
Map<String, String> scenarioReportMap = initReport(testPlanApiScenarios, runModeConfig, project.getId(), userId);
|
||||
|
||||
List<TaskItem> taskItems = ids.stream()
|
||||
.map(id -> apiExecuteService.getTaskItem(scenarioReportMap.get(id), id)).toList();
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(testPlanApiScenarios.size(), runModeConfig, project, userId);
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(projectId, runModeConfig);
|
||||
// 初始化任务项
|
||||
Map<String, String> resourceExecTaskItemMap = initExecTaskItem(testPlanApiScenarios, userId, project, execTask)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ExecTaskItem::getResourceId, ExecTaskItem::getId));
|
||||
|
||||
List<TaskItem> taskItems = testPlanApiScenarios.stream()
|
||||
.map(testPlanApiScenario -> {
|
||||
String id = testPlanApiScenario.getId();
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(scenarioReportMap.get(id), id);
|
||||
taskItem.setId(resourceExecTaskItemMap.get(id));
|
||||
return taskItem;
|
||||
}).toList();
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(project.getId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
taskRequest.getTaskInfo().setTaskId(execTask.getId());
|
||||
taskRequest.getTaskInfo().setUserId(userId);
|
||||
taskRequest.getTaskInfo().setParentQueueId(parentQueueId);
|
||||
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
}
|
||||
|
||||
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
List<TestPlanApiScenario> testPlanApiScenarios = new ArrayList<>(ids.size());
|
||||
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>(ids.size());
|
||||
// 分批查询
|
||||
List<TestPlanApiScenario> finalTestPlanApiScenarios = testPlanApiScenarios;
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> finalTestPlanApiScenarios.addAll(extTestPlanApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
List<String> caseIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getApiScenarioId).toList();
|
||||
List<ApiScenario> finalApiScenarios = apiScenarios;
|
||||
SubListUtils.dealForSubList(caseIds, 100, subIds -> finalApiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiScenario> apiScenarioMap = apiScenarios.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, Function.identity()));
|
||||
|
||||
Map<String, TestPlanApiScenario> testPlanApiScenarioMap = testPlanApiScenarios.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiScenario::getId, Function.identity()));
|
||||
|
||||
testPlanApiScenarios = new ArrayList<>(ids.size());
|
||||
for (String id : ids) {
|
||||
// 按照ID顺序排序
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMap.get(id);
|
||||
if (testPlanApiScenario == null) {
|
||||
break;
|
||||
private ExecTask initExecTask(int caseSize, ApiRunModeConfigDTO runModeConfig, Project project, String userId) {
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(Long.valueOf(caseSize));
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
execTask.setTaskName(runModeConfig.getCollectionReport().getReportName());
|
||||
} else {
|
||||
execTask.setTaskName(Translator.get("api_batch_task_name"));
|
||||
}
|
||||
testPlanApiScenarios.add(testPlanApiScenario);
|
||||
}
|
||||
// 初始化独立报告,执行时初始化步骤
|
||||
return initScenarioReport(runModeConfig, testPlanApiScenarios, apiScenarioMap, userId);
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.TEST_PLAN_API_SCENARIO.name());
|
||||
baseTaskHubService.insertExecTask(execTask);
|
||||
return execTask;
|
||||
}
|
||||
|
||||
public Map<String, String> initScenarioReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiScenario> testPlanApiScenarios,
|
||||
Map<String, ApiScenario> apiScenarioMap, String userId) {
|
||||
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiScenarioBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
|
||||
for (TestPlanApiScenarioBatchRunDTO testPlanApiScenario : apiTestCases) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(testPlanApiScenario.getId());
|
||||
execTaskItem.setResourceName(testPlanApiScenario.getName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
return execTaskItems;
|
||||
}
|
||||
|
||||
public Map<String, String> initReport( List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios,
|
||||
ApiRunModeConfigDTO runModeConfig, String projectId, String userId) {
|
||||
List<ApiScenarioReport> apiScenarioReports = new ArrayList<>(testPlanApiScenarios.size());
|
||||
List<ApiScenarioRecord> apiScenarioRecords = new ArrayList<>(testPlanApiScenarios.size());
|
||||
Map<String, String> resourceReportMap = new HashMap<>();
|
||||
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
|
||||
ApiScenario apiScenario = apiScenarioMap.get(testPlanApiScenario.getApiScenarioId());
|
||||
for (TestPlanApiScenarioBatchRunDTO testPlanApiScenario : testPlanApiScenarios) {
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, userId);
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, projectId, userId);
|
||||
apiScenarioReport.setId(IDGenerator.nextStr());
|
||||
apiScenarioReports.add(apiScenarioReport);
|
||||
// 创建报告和用例的关联关系
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(apiScenario, apiScenarioReport);
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(testPlanApiScenario.getApiScenarioId(), apiScenarioReport);
|
||||
apiScenarioRecords.add(apiScenarioRecord);
|
||||
resourceReportMap.put(testPlanApiScenario.getId(), apiScenarioReport.getId());
|
||||
}
|
||||
|
@ -287,14 +318,19 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(queueDetail.getResourceId());
|
||||
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||
String testPlanId = testPlanApiScenario.getTestPlanId();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
|
||||
// 独立报告,执行到当前任务时初始化报告
|
||||
String reportId = initScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, queue.getUserId()).getApiScenarioReportId();
|
||||
String reportId = initScenarioReport(runModeConfig, BeanUtils.copyBean(new TestPlanApiScenarioBatchRunDTO(), testPlanApiScenario), testPlan.getId(), queue.getUserId())
|
||||
.getApiScenarioReportId();
|
||||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(apiScenario.getProjectId(), queue.getRunModeConfig());
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, queueDetail.getResourceId());
|
||||
taskItem.setId(queueDetail.getTaskItemId());
|
||||
taskRequest.setTaskItem(taskItem);
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskInfo().setTaskId(queue.getTaskId());
|
||||
taskRequest.getTaskInfo().setUserId(queue.getUserId());
|
||||
taskRequest.getTaskInfo().setParentQueueId(queue.getParentQueueId());
|
||||
|
||||
|
@ -308,6 +344,44 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
return taskRequest;
|
||||
}
|
||||
|
||||
public List<TestPlanApiScenarioBatchRunDTO> getSelectIdAndCollectionId(TestPlanApiScenarioBatchRunRequest request) {
|
||||
if (request.isSelectAll()) {
|
||||
List<TestPlanApiScenarioBatchRunDTO> testPlanApiCases = extTestPlanApiScenarioMapper.getSelectIdAndCollectionId(request);
|
||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
testPlanApiCases.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return testPlanApiCases;
|
||||
} else {
|
||||
return getBatchRunInfo(request.getSelectIds());
|
||||
}
|
||||
}
|
||||
|
||||
private List<TestPlanApiScenarioBatchRunDTO> getBatchRunInfo(List<String> ids) {
|
||||
List<TestPlanApiScenarioBatchRunDTO> testPlanApiScenarios = new ArrayList<>();
|
||||
SubListUtils.dealForSubList(ids, 200, (subIds) -> testPlanApiScenarios.addAll(extTestPlanApiScenarioMapper.getBatchRunInfoByIds(subIds)));
|
||||
|
||||
// 查询用例名称信息
|
||||
List<String> caseIds = testPlanApiScenarios.stream().map(TestPlanApiScenarioBatchRunDTO::getApiScenarioId).collect(Collectors.toList());
|
||||
Map<String, String> apiScenarioNameMap = extApiScenarioMapper.getNameInfo(caseIds)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, ApiScenario::getName));
|
||||
|
||||
Map<String, TestPlanApiScenarioBatchRunDTO> testPlanApiCaseMap = testPlanApiScenarios
|
||||
.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiScenarioBatchRunDTO::getId, Function.identity()));
|
||||
|
||||
testPlanApiScenarios.clear();
|
||||
// 按ID的顺序排序
|
||||
for (String id : ids) {
|
||||
TestPlanApiScenarioBatchRunDTO testPlanApiCase = testPlanApiCaseMap.get(id);
|
||||
if (testPlanApiCase != null) {
|
||||
testPlanApiCase.setName(apiScenarioNameMap.get(testPlanApiCase.getApiScenarioId()));
|
||||
testPlanApiScenarios.add(testPlanApiCase);
|
||||
}
|
||||
}
|
||||
return testPlanApiScenarios;
|
||||
}
|
||||
|
||||
public TaskBatchRequestDTO getTaskBatchRequestDTO(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskBatchRequestDTO taskRequest = new TaskBatchRequestDTO();
|
||||
TaskInfo taskInfo = getTaskInfo(projectId, runModeConfig);
|
||||
|
@ -325,35 +399,29 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @param apiScenario
|
||||
* @param testPlanApiScenario
|
||||
* @return
|
||||
*/
|
||||
public ApiScenarioRecord initScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenario testPlanApiScenario,
|
||||
ApiScenario apiScenario, String userId) {
|
||||
public ApiScenarioRecord initScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenarioBatchRunDTO testPlanApiScenario, String projectId, String userId) {
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, userId);
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, projectId, userId);
|
||||
apiScenarioReport.setId(IDGenerator.nextStr());
|
||||
// 创建报告和用例的关联关系
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(apiScenario, apiScenarioReport);
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(testPlanApiScenario.getApiScenarioId(), apiScenarioReport);
|
||||
apiScenarioReportService.insertApiScenarioReport(List.of(apiScenarioReport), List.of(apiScenarioRecord));
|
||||
return apiScenarioRecord;
|
||||
}
|
||||
|
||||
private ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenario testPlanApiScenario, ApiScenario apiScenario, String userId) {
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, apiScenario, userId);
|
||||
apiScenarioReport.setTestPlanScenarioId(testPlanApiScenario.getId());
|
||||
apiScenarioReport.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiScenario.getEnvironmentId()));
|
||||
return apiScenarioReport;
|
||||
}
|
||||
|
||||
public ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, ApiScenario apiScenario, String userId) {
|
||||
private ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenarioBatchRunDTO testPlanApiScenario, String projectId, String userId) {
|
||||
ApiScenarioReport apiScenarioReport = apiScenarioRunService.getScenarioReport(userId);
|
||||
apiScenarioReport.setName(apiScenario.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiScenarioReport.setProjectId(apiScenario.getProjectId());
|
||||
apiScenarioReport.setName(testPlanApiScenario.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiScenarioReport.setProjectId(projectId);
|
||||
apiScenarioReport.setEnvironmentId(runModeConfig.getEnvironmentId());
|
||||
apiScenarioReport.setRunMode(runModeConfig.getRunMode());
|
||||
apiScenarioReport.setPoolId(runModeConfig.getPoolId());
|
||||
apiScenarioReport.setTriggerMode(TaskTriggerMode.BATCH.name());
|
||||
apiScenarioReport.setTestPlanScenarioId(testPlanApiScenario.getId());
|
||||
apiScenarioReport.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiScenario.getEnvironmentId()));
|
||||
return apiScenarioReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.mapper.ApiScenarioModuleMapper;
|
|||
import io.metersphere.api.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioModuleService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioReportService;
|
||||
|
@ -43,6 +44,8 @@ import io.metersphere.sdk.util.BeanUtils;
|
|||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.dto.ModuleSelectDTO;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
|
@ -113,6 +116,8 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
@Resource
|
||||
private TestPlanConfigService testPlanConfigService;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
|
||||
private static final String EXECUTOR = "executeUserName";
|
||||
|
||||
|
@ -331,13 +336,33 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(testPlanApiScenario.getTestPlanCollectionId());
|
||||
runModeConfig.setEnvironmentId(apiBatchRunBaseService.getEnvId(runModeConfig, testPlanApiScenario.getEnvironmentId()));
|
||||
TaskRequestDTO taskRequest = getTaskRequest(reportId, id, apiScenario.getProjectId(), ApiExecuteRunMode.RUN.name());
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanApiScenario.getTestPlanId());
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setCaseCount(1L);
|
||||
execTask.setTaskName(apiScenario.getName());
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.TEST_PLAN_API_SCENARIO.name());
|
||||
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(testPlanApiScenario.getId());
|
||||
execTaskItem.setResourceName(apiScenario.getName());
|
||||
|
||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskInfo.setTaskId(execTask.getId());
|
||||
taskInfo.setRunModeConfig(runModeConfig);
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(true);
|
||||
taskInfo.setUserId(userId);
|
||||
|
||||
TaskItem taskItem = taskRequest.getTaskItem();
|
||||
taskItem.setId(execTaskItem.getId());
|
||||
|
||||
if (StringUtils.isEmpty(taskItem.getReportId())) {
|
||||
taskInfo.setRealTime(false);
|
||||
reportId = IDGenerator.nextStr();
|
||||
|
@ -748,31 +773,6 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
public List<TestPlanApiScenario> getSelectIdAndCollectionId(TestPlanApiScenarioBatchRunRequest request) {
|
||||
if (request.isSelectAll()) {
|
||||
List<TestPlanApiScenario> testPlanApiCases = extTestPlanApiScenarioMapper.getSelectIdAndCollectionId(request);
|
||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
testPlanApiCases.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return testPlanApiCases;
|
||||
} else {
|
||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||
example.createCriteria().andIdIn(request.getSelectIds());
|
||||
Map<String, TestPlanApiScenario> testPlanApiScenarioMap = testPlanApiScenarioMapper.selectByExample(example)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiScenario::getId, Function.identity()));
|
||||
List<TestPlanApiScenario> testPlanApiScenarios = new ArrayList<>(request.getSelectIds().size());
|
||||
// 按ID的顺序排序
|
||||
for (String id : request.getSelectIds()) {
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMap.get(id);
|
||||
if (testPlanApiScenario != null) {
|
||||
testPlanApiScenarios.add(testPlanApiScenario);
|
||||
}
|
||||
}
|
||||
return testPlanApiScenarios;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理执行人为空过滤参数
|
||||
*
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
|
||||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.domain.ExecTask;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
@ -52,6 +57,16 @@ public class TestPlanExecuteService {
|
|||
private TestPlanReportMapper testPlanReportMapper;
|
||||
@Resource
|
||||
private TestPlanExecuteSupportService testPlanExecuteSupportService;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
|
||||
@Resource
|
||||
private ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
|
||||
|
||||
// 停止测试计划的执行
|
||||
public void stopTestPlanRunning(String testPlanReportId) {
|
||||
|
@ -139,7 +154,8 @@ public class TestPlanExecuteService {
|
|||
request.getExecuteId(),
|
||||
request.getRunMode(),
|
||||
request.getExecutionSource(),
|
||||
reportId
|
||||
reportId,
|
||||
IDGenerator.nextStr()
|
||||
);
|
||||
|
||||
testPlanExecuteSupportService.setRedisForList(
|
||||
|
@ -180,6 +196,7 @@ public class TestPlanExecuteService {
|
|||
testPlanId,
|
||||
runMode,
|
||||
TaskTriggerMode.BATCH.name(),
|
||||
IDGenerator.nextStr(),
|
||||
IDGenerator.nextStr()
|
||||
)
|
||||
);
|
||||
|
@ -208,6 +225,12 @@ public class TestPlanExecuteService {
|
|||
throw new MSException("test_plan.error");
|
||||
}
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(testPlan.getProjectId());
|
||||
Integer caseTotal = extTestPlanApiCaseMapper.countByPlanId(testPlan.getId()) + extTestPlanApiScenarioMapper.countByPlanId(testPlan.getId());
|
||||
|
||||
// 初始化任务
|
||||
ExecTask execTask = initExecTask(executionQueue.getTaskId(), caseTotal, testPlan.getName(), project, executionQueue.getCreateUser(), executionQueue.getExecutionSource());
|
||||
|
||||
TestPlanReportGenRequest genReportRequest = new TestPlanReportGenRequest();
|
||||
genReportRequest.setTriggerMode(executionQueue.getExecutionSource());
|
||||
genReportRequest.setTestPlanId(executionQueue.getSourceID());
|
||||
|
@ -216,7 +239,7 @@ public class TestPlanExecuteService {
|
|||
|
||||
List<TestPlan> children = testPlanService.selectNotArchivedChildren(testPlan.getId());
|
||||
// 预生成计划组报告
|
||||
Map<String, String> reportMap = testPlanReportService.genReportByExecution(executionQueue.getPrepareReportId(), genReportRequest, executionQueue.getCreateUser());
|
||||
Map<String, String> reportMap = testPlanReportService.genReportByExecution(executionQueue.getPrepareReportId(), execTask.getId(), genReportRequest, executionQueue.getCreateUser());
|
||||
|
||||
long pos = 0;
|
||||
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
|
||||
|
@ -235,7 +258,8 @@ public class TestPlanExecuteService {
|
|||
child.getId(),
|
||||
executionQueue.getRunMode(),
|
||||
executionQueue.getExecutionSource(),
|
||||
reportMap.get(child.getId())
|
||||
reportMap.get(child.getId()),
|
||||
executionQueue.getTaskId()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -265,7 +289,7 @@ public class TestPlanExecuteService {
|
|||
|
||||
return executionQueue.getPrepareReportId();
|
||||
} else {
|
||||
Map<String, String> reportMap = testPlanReportService.genReportByExecution(executionQueue.getPrepareReportId(), genReportRequest, executionQueue.getCreateUser());
|
||||
Map<String, String> reportMap = testPlanReportService.genReportByExecution(executionQueue.getPrepareReportId(), execTask.getId(), genReportRequest, executionQueue.getCreateUser());
|
||||
executionQueue.setPrepareReportId(reportMap.get(executionQueue.getSourceID()));
|
||||
testPlanService.setExecuteConfig(executionQueue.getSourceID(), executionQueue.getPrepareReportId());
|
||||
this.executeTestPlan(executionQueue);
|
||||
|
@ -273,6 +297,18 @@ public class TestPlanExecuteService {
|
|||
}
|
||||
}
|
||||
|
||||
private ExecTask initExecTask(String taskId, int caseSize, String name, Project project, String userId, String triggerMode) {
|
||||
ExecTask execTask = apiCommonService.newExecTask(project.getId(), userId);
|
||||
execTask.setId(taskId);
|
||||
execTask.setCaseCount(Long.valueOf(caseSize));
|
||||
execTask.setTaskName(name);
|
||||
execTask.setOrganizationId(project.getOrganizationId());
|
||||
execTask.setTriggerMode(TaskTriggerMode.MANUAL.name());
|
||||
execTask.setTaskType(ExecTaskType.TEST_PLAN.name());
|
||||
baseTaskHubService.insertExecTask(execTask);
|
||||
return execTask;
|
||||
}
|
||||
|
||||
//执行测试计划里不同类型的用例 回调:caseTypeExecuteQueueFinish
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public void executeTestPlan(TestPlanExecutionQueue executionQueue) {
|
||||
|
@ -310,7 +346,8 @@ public class TestPlanExecuteService {
|
|||
collection.getId(),
|
||||
runMode,
|
||||
executionQueue.getExecutionSource(),
|
||||
executionQueue.getPrepareReportId())
|
||||
executionQueue.getPrepareReportId(),
|
||||
executionQueue.getTaskId())
|
||||
);
|
||||
}
|
||||
LogUtils.info("测试计划执行节点 --- 队列ID[{}],队列类型[{}],父队列ID[{}],父队列类型[{}],执行模式[{}]", queueId, queueType, executionQueue.getParentQueueId(), executionQueue.getParentQueueType(), runMode);
|
||||
|
@ -362,7 +399,8 @@ public class TestPlanExecuteService {
|
|||
collection.getId(),
|
||||
runMode,
|
||||
executionQueue.getExecutionSource(),
|
||||
executionQueue.getPrepareReportId()) {{
|
||||
executionQueue.getPrepareReportId(),
|
||||
executionQueue.getTaskId()) {{
|
||||
this.setTestPlanCollectionJson(JSON.toJSONString(collection));
|
||||
}}
|
||||
);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.metersphere.api.service.ApiCommonService;
|
||||
import io.metersphere.bug.dto.response.BugDTO;
|
||||
import io.metersphere.bug.service.BugCommonService;
|
||||
import io.metersphere.plan.constants.AssociateCaseType;
|
||||
|
@ -16,6 +17,8 @@ import io.metersphere.plan.enums.TestPlanReportAttachmentSourceType;
|
|||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.plan.utils.CountUtils;
|
||||
import io.metersphere.plugin.platform.dto.SelectOption;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.file.FileCenter;
|
||||
|
@ -23,11 +26,13 @@ import io.metersphere.sdk.file.FileCopyRequest;
|
|||
import io.metersphere.sdk.file.FileRepository;
|
||||
import io.metersphere.sdk.file.FileRequest;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ExecTaskItem;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.mapper.BaseUserMapper;
|
||||
import io.metersphere.system.mapper.UserMapper;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
import io.metersphere.system.service.BaseTaskHubService;
|
||||
import io.metersphere.system.service.CommonFileService;
|
||||
import io.metersphere.system.service.FileService;
|
||||
import io.metersphere.system.service.SimpleUserService;
|
||||
|
@ -110,6 +115,12 @@ public class TestPlanReportService {
|
|||
private TestPlanReportComponentMapper componentMapper;
|
||||
@Resource
|
||||
private CommonFileService commonFileService;
|
||||
@Resource
|
||||
private ApiCommonService apiCommonService;
|
||||
@Resource
|
||||
private BaseTaskHubService baseTaskHubService;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
private static final int MAX_REPORT_NAME_LENGTH = 300;
|
||||
|
||||
|
@ -308,8 +319,13 @@ public class TestPlanReportService {
|
|||
* @param currentUser 当前用户
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public Map<String, String> genReportByExecution(String prepareReportId, TestPlanReportGenRequest request, String currentUser) {
|
||||
return genReport(prepareReportId, request, false, currentUser, null);
|
||||
public Map<String, String> genReportByExecution(String prepareReportId, String taskId, TestPlanReportGenRequest request, String currentUser) {
|
||||
return genReport(prepareReportId, taskId, request, false, currentUser, null);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public Map<String, String> genReport(String prepareReportId, TestPlanReportGenRequest request, boolean manual, String currentUser, String manualReportName) {
|
||||
return genReport(prepareReportId, null, request, manual, currentUser, manualReportName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,7 +337,7 @@ public class TestPlanReportService {
|
|||
* @param currentUser 当前用户
|
||||
* @param manualReportName 手动生成报告名称
|
||||
*/
|
||||
public Map<String, String> genReport(String prepareReportId, TestPlanReportGenRequest request, boolean manual, String currentUser, String manualReportName) {
|
||||
public Map<String, String> genReport(String prepareReportId, String taskId, TestPlanReportGenRequest request, boolean manual, String currentUser, String manualReportName) {
|
||||
Map<String, String> preReportMap = Maps.newHashMapWithExpectedSize(8);
|
||||
TestPlanReportManualParam reportManualParam = TestPlanReportManualParam.builder().manualName(manualReportName).targetId(request.getTestPlanId()).build();
|
||||
try {
|
||||
|
@ -345,6 +361,7 @@ public class TestPlanReportService {
|
|||
genPreParam.setStartTime(null);
|
||||
}
|
||||
genPreParam.setUseManual(manual);
|
||||
genPreParam.setTaskId(taskId);
|
||||
// 如果是测试计划的独立报告,使用参数中的预生成的报告id。否则只有测试计划组报告使用该id
|
||||
String prepareItemReportId = isGroupReports ? IDGenerator.nextStr() : prepareReportId;
|
||||
TestPlanReport preReport = preGenReport(prepareItemReportId, genPreParam, currentUser, childPlanIds, reportManualParam);
|
||||
|
@ -437,6 +454,8 @@ public class TestPlanReportService {
|
|||
List<ReportBugCountDTO> bugCountList = extTestPlanReportBugMapper.countPlanBug(genParam.getTestPlanId());
|
||||
Map<String, Long> bugCountMap = bugCountList.stream().collect(Collectors.toMap(ReportBugCountDTO::getRefCaseId, ReportBugCountDTO::getBugCount));
|
||||
|
||||
Project project = projectMapper.selectByPrimaryKey(genParam.getProjectId());
|
||||
|
||||
AtomicLong funcCaseCount = new AtomicLong();
|
||||
AtomicLong apiCaseCount = new AtomicLong();
|
||||
AtomicLong apiScenarioCount = new AtomicLong();
|
||||
|
@ -525,6 +544,11 @@ public class TestPlanReportService {
|
|||
TestPlanReportApiCaseMapper batchMapper = sqlSession.getMapper(TestPlanReportApiCaseMapper.class);
|
||||
batchMapper.batchInsert(reportApiCases);
|
||||
sqlSession.flushStatements();
|
||||
|
||||
if (StringUtils.isNotBlank(genParam.getTaskId())) {
|
||||
reportApiCases.sort(Comparator.comparing(TestPlanReportApiCase::getPos).reversed());
|
||||
initApiCaseExecTaskItem(genParam.getTaskId(), reportApiCases, report.getCreateUser(), project);
|
||||
}
|
||||
});
|
||||
}
|
||||
testPlanReportApiCaseIdList = null;
|
||||
|
@ -563,6 +587,11 @@ public class TestPlanReportService {
|
|||
TestPlanReportApiScenarioMapper batchMapper = sqlSession.getMapper(TestPlanReportApiScenarioMapper.class);
|
||||
batchMapper.batchInsert(reportApiScenarios);
|
||||
sqlSession.flushStatements();
|
||||
|
||||
if (StringUtils.isNotBlank(genParam.getTaskId())) {
|
||||
reportApiScenarios.sort(Comparator.comparing(TestPlanReportApiScenario::getPos).reversed());
|
||||
initScenarioExecTaskItem(genParam.getTaskId(), reportApiScenarios, report.getCreateUser(), project);
|
||||
}
|
||||
});
|
||||
}
|
||||
reportApiScenarioIdList = null;
|
||||
|
@ -611,6 +640,31 @@ public class TestPlanReportService {
|
|||
.functionCaseCount(funcCaseCount.get()).apiCaseCount(apiCaseCount.get()).apiScenarioCount(apiScenarioCount.get()).bugCount(bugCount.get()).build();
|
||||
}
|
||||
|
||||
private void initApiCaseExecTaskItem(String taskId, List<TestPlanReportApiCase> apiTestCases, String userId, Project project) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
|
||||
for (TestPlanReportApiCase apiTestCase : apiTestCases) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(taskId, project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.PLAN_RUN_API_CASE.name());
|
||||
execTaskItem.setResourceId(apiTestCase.getId());
|
||||
execTaskItem.setResourceName(apiTestCase.getApiCaseName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
}
|
||||
|
||||
private void initScenarioExecTaskItem(String taskId, List<TestPlanReportApiScenario> testPlanReportApiScenarios, String userId, Project project) {
|
||||
List<ExecTaskItem> execTaskItems = new ArrayList<>(testPlanReportApiScenarios.size());
|
||||
for (TestPlanReportApiScenario testPlanReportApiScenario : testPlanReportApiScenarios) {
|
||||
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(taskId, project.getId(), userId);
|
||||
execTaskItem.setOrganizationId(project.getOrganizationId());
|
||||
execTaskItem.setResourceType(ApiExecuteResourceType.PLAN_RUN_API_SCENARIO.name());
|
||||
execTaskItem.setResourceId(testPlanReportApiScenario.getId());
|
||||
execTaskItem.setResourceName(testPlanReportApiScenario.getApiScenarioName());
|
||||
execTaskItems.add(execTaskItem);
|
||||
}
|
||||
baseTaskHubService.insertExecTaskDetail(execTaskItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* 报告结果后置处理 (汇总操作结束后调用)
|
||||
|
|
Loading…
Reference in New Issue