diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java index 57b9cdbbc7..0a2c88dda3 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java @@ -15,5 +15,9 @@ public class TestPlanExecutionQueue implements Serializable { private String testPlanId; + private String resourceId; + + private Integer num; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java index e870bc43eb..79411fe851 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java @@ -443,6 +443,136 @@ public class TestPlanExecutionQueueExample { addCriterion("test_plan_id not between", value1, value2, "testPlanId"); return (Criteria) this; } + + public Criteria andResourceIdIsNull() { + addCriterion("resource_id is null"); + return (Criteria) this; + } + + public Criteria andResourceIdIsNotNull() { + addCriterion("resource_id is not null"); + return (Criteria) this; + } + + public Criteria andResourceIdEqualTo(String value) { + addCriterion("resource_id =", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdNotEqualTo(String value) { + addCriterion("resource_id <>", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdGreaterThan(String value) { + addCriterion("resource_id >", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdGreaterThanOrEqualTo(String value) { + addCriterion("resource_id >=", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdLessThan(String value) { + addCriterion("resource_id <", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdLessThanOrEqualTo(String value) { + addCriterion("resource_id <=", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdLike(String value) { + addCriterion("resource_id like", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdNotLike(String value) { + addCriterion("resource_id not like", value, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdIn(List values) { + addCriterion("resource_id in", values, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdNotIn(List values) { + addCriterion("resource_id not in", values, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdBetween(String value1, String value2) { + addCriterion("resource_id between", value1, value2, "resourceId"); + return (Criteria) this; + } + + public Criteria andResourceIdNotBetween(String value1, String value2) { + addCriterion("resource_id not between", value1, value2, "resourceId"); + return (Criteria) this; + } + + public Criteria andNumIsNull() { + addCriterion("num is null"); + return (Criteria) this; + } + + public Criteria andNumIsNotNull() { + addCriterion("num is not null"); + return (Criteria) this; + } + + public Criteria andNumEqualTo(Integer value) { + addCriterion("num =", value, "num"); + return (Criteria) this; + } + + public Criteria andNumNotEqualTo(Integer value) { + addCriterion("num <>", value, "num"); + return (Criteria) this; + } + + public Criteria andNumGreaterThan(Integer value) { + addCriterion("num >", value, "num"); + return (Criteria) this; + } + + public Criteria andNumGreaterThanOrEqualTo(Integer value) { + addCriterion("num >=", value, "num"); + return (Criteria) this; + } + + public Criteria andNumLessThan(Integer value) { + addCriterion("num <", value, "num"); + return (Criteria) this; + } + + public Criteria andNumLessThanOrEqualTo(Integer value) { + addCriterion("num <=", value, "num"); + return (Criteria) this; + } + + public Criteria andNumIn(List values) { + addCriterion("num in", values, "num"); + return (Criteria) this; + } + + public Criteria andNumNotIn(List values) { + addCriterion("num not in", values, "num"); + return (Criteria) this; + } + + public Criteria andNumBetween(Integer value1, Integer value2) { + addCriterion("num between", value1, value2, "num"); + return (Criteria) this; + } + + public Criteria andNumNotBetween(Integer value1, Integer value2) { + addCriterion("num not between", value1, value2, "num"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml index 66aff003a0..795dbe5182 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml @@ -7,6 +7,8 @@ + + @@ -67,7 +69,7 @@ - id, report_id, run_mode, create_time, test_plan_id + id, report_id, run_mode, create_time, test_plan_id, resource_id, num @@ -166,6 +182,12 @@ test_plan_id = #{record.testPlanId,jdbcType=VARCHAR}, + + resource_id = #{record.resourceId,jdbcType=VARCHAR}, + + + num = #{record.num,jdbcType=INTEGER}, + @@ -177,7 +199,9 @@ report_id = #{record.reportId,jdbcType=VARCHAR}, run_mode = #{record.runMode,jdbcType=VARCHAR}, create_time = #{record.createTime,jdbcType=BIGINT}, - test_plan_id = #{record.testPlanId,jdbcType=VARCHAR} + test_plan_id = #{record.testPlanId,jdbcType=VARCHAR}, + resource_id = #{record.resourceId,jdbcType=VARCHAR}, + num = #{record.num,jdbcType=INTEGER} @@ -197,6 +221,12 @@ test_plan_id = #{testPlanId,jdbcType=VARCHAR}, + + resource_id = #{resourceId,jdbcType=VARCHAR}, + + + num = #{num,jdbcType=INTEGER}, + where id = #{id,jdbcType=VARCHAR} @@ -205,7 +235,9 @@ set report_id = #{reportId,jdbcType=VARCHAR}, run_mode = #{runMode,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=BIGINT}, - test_plan_id = #{testPlanId,jdbcType=VARCHAR} + test_plan_id = #{testPlanId,jdbcType=VARCHAR}, + resource_id = #{resourceId,jdbcType=VARCHAR}, + num = #{num,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java index 7a0251ebaf..44d51d8f50 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java @@ -1,7 +1,9 @@ package io.metersphere.base.mapper.ext; +import io.metersphere.base.domain.ApiDefinition; import io.metersphere.base.domain.TestPlanExecutionQueue; import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -9,4 +11,6 @@ public interface ExtTestPlanExecutionQueueMapper { @InsertProvider(type = ExtTestPlanExecutionQueueProvider.class, method = "insertListSql") void sqlInsert(List list); + + TestPlanExecutionQueue getNextNum(@Param("resourceId") String resourceId); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.xml new file mode 100644 index 0000000000..e3f6e5580b --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java index de2d7922aa..ebf2ca4afb 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java @@ -7,7 +7,7 @@ import java.util.List; public class ExtTestPlanExecutionQueueProvider { public String insertListSql(List list) { StringBuffer sqlList = new StringBuffer(); - sqlList.append("insert into test_plan_execution_queue (id,report_id, run_mode, create_time, test_plan_id) values "); + sqlList.append("insert into test_plan_execution_queue (id,report_id, run_mode, create_time, test_plan_id, resource_id, num) values "); for (int i = 0; i < list.size(); i++) { TestPlanExecutionQueue result = list.get(i); sqlList.append(" (") @@ -21,7 +21,10 @@ public class ExtTestPlanExecutionQueueProvider { .append(result.getCreateTime()) .append("','") .append(result.getTestPlanId()) - .append("'") + .append("','") + .append(result.getResourceId()) + .append("',") + .append(result.getNum()) .append(")"); if (i < list.size() - 1) { sqlList.append(","); diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 5ef7294cd8..9e2bf5f555 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -10,7 +10,6 @@ import io.metersphere.base.domain.*; import io.metersphere.commons.constants.*; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; -import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.service.CheckPermissionService; @@ -229,9 +228,9 @@ public class TestPlanController { @PostMapping(value = "/run/batch") @MsAuditLog(module = OperLogModule.TRACK_TEST_PLAN, type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.ids)", msClass = TestPlanService.class) - public List runBatch(@RequestBody TestplanRunRequest request) { + public void runBatch(@RequestBody TestplanRunRequest request) { request.setTriggerMode(TriggerMode.BATCH.name()); - return testPlanService.runBatch(request); + testPlanService.runBatch(request); } @GetMapping("/report/export/{planId}") diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanScheduleReportInfoDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanScheduleReportInfoDTO.java index f368c76348..866aca6b61 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestPlanScheduleReportInfoDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanScheduleReportInfoDTO.java @@ -1,11 +1,9 @@ package io.metersphere.track.dto; import io.metersphere.base.domain.TestPlanReport; -import io.metersphere.base.domain.TestPlanReportContent; import lombok.Getter; import lombok.Setter; -import java.util.LinkedHashMap; import java.util.Map; /** @@ -16,7 +14,7 @@ import java.util.Map; @Setter public class TestPlanScheduleReportInfoDTO { private TestPlanReport testPlanReport; - private Map planScenarioIdMap = new LinkedHashMap<>(); - private Map apiTestCaseDataMap = new LinkedHashMap<>(); - private Map performanceIdMap = new LinkedHashMap<>(); + private Map planScenarioIdMap; + private Map apiTestCaseDataMap; + private Map performanceIdMap; } diff --git a/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java b/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java index bba8fb292a..3fd272fd3f 100644 --- a/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java @@ -1,7 +1,5 @@ package io.metersphere.track.request.testplan; - -import io.metersphere.track.dto.TestPlanScheduleReportInfoDTO; import io.metersphere.track.request.testcase.QueryTestPlanRequest; import lombok.Getter; import lombok.Setter; @@ -26,7 +24,7 @@ public class TestplanRunRequest { private String environmentGroupId; private List testPlanIds; private Boolean isAll; - private TestPlanScheduleReportInfoDTO planScheduleReportInfoDTO; + private String reportId; private QueryTestPlanRequest queryTestPlanRequest; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanExecutionQueueService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanExecutionQueueService.java new file mode 100644 index 0000000000..f6addd904a --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanExecutionQueueService.java @@ -0,0 +1,34 @@ +package io.metersphere.track.service; + +import io.metersphere.base.domain.TestPlanExecutionQueue; +import io.metersphere.base.mapper.ext.ExtTestPlanExecutionQueueMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.util.List; +import java.util.Optional; + +@Service +public class TestPlanExecutionQueueService { + + @Resource + private ExtTestPlanExecutionQueueMapper extTestPlanExecutionQueueMapper; + + @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) + public void batchSave(List planExecutionQueues) { + if (!planExecutionQueues.isEmpty()) { + extTestPlanExecutionQueueMapper.sqlInsert(planExecutionQueues); + } + } + + public int getNextNum(String resourceId) { + TestPlanExecutionQueue testPlanExecutionQueue = extTestPlanExecutionQueueMapper.getNextNum(resourceId); + if (testPlanExecutionQueue == null || testPlanExecutionQueue.getNum() == null) { + return 100001; + } else { + return Optional.of(testPlanExecutionQueue.getNum() + 1).orElse(100001); + } + } + +} diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java index b6d628b41a..81c8a67604 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java @@ -221,6 +221,12 @@ public class TestPlanReportService { } public TestPlanScheduleReportInfoDTO genTestPlanReportBySchedule(String planReportId, String planId, String userId, String triggerMode) { + TestPlanReport testPlanReport = this.getTestPlanReport(planReportId); + TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO(); + if (testPlanReport != null) { + returnDTO.setTestPlanReport(testPlanReport); + } + Map planScenarioIdMap = new LinkedHashMap<>(); Map planTestCaseIdMap = new LinkedHashMap<>(); Map performanceIdMap = new LinkedHashMap<>(); @@ -239,7 +245,6 @@ public class TestPlanReportService { performanceIdMap.put(dto.getId(), dto.getLoadCaseId()); } - Map apiCaseInfoMap = new HashMap<>(); for (String id : planTestCaseIdMap.keySet()) { apiCaseInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name()); @@ -253,26 +258,17 @@ public class TestPlanReportService { performanceInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name()); } - TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO(); - TestPlanReport testPlanReport; - if(StringUtils.isBlank(planReportId)){ - planReportId = UUID.randomUUID().toString(); - testPlanReport = null; - }else{ - testPlanReport= this.getTestPlanReport(planReportId); - returnDTO.setTestPlanReport(testPlanReport); - } - TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, planId, userId, triggerMode, planTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0, apiCaseInfoMap, scenarioInfoMap, performanceInfoMap); - if(testPlanReport==null){ + if (testPlanReport == null) { returnDTO = this.genTestPlanReport(saveRequest); } returnDTO.setPlanScenarioIdMap(planScenarioIdMap); returnDTO.setApiTestCaseDataMap(planTestCaseIdMap); returnDTO.setPerformanceIdMap(performanceIdMap); + return returnDTO; } @@ -464,7 +460,7 @@ public class TestPlanReportService { contentExample.createCriteria().andTestPlanReportIdEqualTo(testPlanReportId); List contents = testPlanReportContentMapper.selectByExampleWithBLOBs(contentExample); TestPlanReportContentWithBLOBs content = null; - if(CollectionUtils.isNotEmpty(contents)){ + if (CollectionUtils.isNotEmpty(contents)) { content = contents.get(0); } boolean hasErrorCase = false; @@ -497,16 +493,16 @@ public class TestPlanReportService { } } content.setPlanApiCaseReportStruct(JSONObject.toJSONString(apiTestCases)); - }catch (Exception e){ - LogUtil.error("update test plan api error! "+e.getMessage()); + } catch (Exception e) { + LogUtil.error("update test plan api error! " , e.getMessage()); } } - if(StringUtils.isNotEmpty(content.getPlanScenarioReportStruct())){ + if (StringUtils.isNotEmpty(content.getPlanScenarioReportStruct())) { try { - List scenarioCases = JSONArray.parseArray(content.getPlanScenarioReportStruct(),TestPlanFailureScenarioDTO.class); + List scenarioCases = JSONArray.parseArray(content.getPlanScenarioReportStruct(), TestPlanFailureScenarioDTO.class); List reportIdList = new ArrayList<>(); - scenarioCases.forEach( item -> { - if(StringUtils.isNotEmpty(item.getReportId())){ + scenarioCases.forEach(item -> { + if (StringUtils.isNotEmpty(item.getReportId())) { reportIdList.add(item.getReportId()); } }); @@ -532,8 +528,8 @@ public class TestPlanReportService { } } content.setPlanScenarioReportStruct(JSONObject.toJSONString(scenarioCases)); - }catch (Exception e){ - LogUtil.error("update test plan api error! "+e.getMessage()); + } catch (Exception e) { + LogUtil.error("update test plan api error! " , e.getMessage()); } } //更新content表对结束日期 @@ -559,24 +555,26 @@ public class TestPlanReportService { TestPlanExecutionQueueExample testPlanExecutionQueueExample = new TestPlanExecutionQueueExample(); testPlanExecutionQueueExample.createCriteria().andReportIdEqualTo(testPlanReportId); List planExecutionQueues = testPlanExecutionQueueMapper.selectByExample(testPlanExecutionQueueExample); - String runMode=null; - if(CollectionUtils.isNotEmpty(planExecutionQueues)){ + String runMode = null; + String resourceId = null; + if (CollectionUtils.isNotEmpty(planExecutionQueues)) { runMode = planExecutionQueues.get(0).getRunMode(); + resourceId = planExecutionQueues.get(0).getResourceId(); testPlanExecutionQueueMapper.deleteByExample(testPlanExecutionQueueExample); } - if(runMode!=null&&StringUtils.equalsIgnoreCase(runMode, RunModeConstants.SERIAL.name())){ + if (runMode != null && StringUtils.equalsIgnoreCase(runMode, RunModeConstants.SERIAL.name()) && resourceId != null) { TestPlanExecutionQueueExample queueExample = new TestPlanExecutionQueueExample(); - queueExample.createCriteria().andReportIdIsNotNull(); + queueExample.createCriteria().andReportIdIsNotNull().andResourceIdEqualTo(resourceId); + queueExample.setOrderByClause("`num` ASC"); List planExecutionQueueList = testPlanExecutionQueueMapper.selectByExample(queueExample); - if(CollectionUtils.isEmpty(planExecutionQueueList)){ + if (CollectionUtils.isEmpty(planExecutionQueueList)) { return testPlanReport; } TestPlanExecutionQueue testPlanExecutionQueue = planExecutionQueueList.get(0); TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanExecutionQueue.getTestPlanId()); JSONObject jsonObject = JSONObject.parseObject(testPlan.getRunModeConfig()); - TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); - TestPlanScheduleReportInfoDTO testPlanScheduleReportInfoDTO = this.genTestPlanReportBySchedule( testPlanExecutionQueue.getReportId(), testPlanExecutionQueue.getTestPlanId(), runRequest.getUserId(), runRequest.getTriggerMode()); - runRequest.setPlanScheduleReportInfoDTO(testPlanScheduleReportInfoDTO); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject, TestplanRunRequest.class); + runRequest.setReportId(testPlanExecutionQueue.getReportId()); testPlanService.runPlan(runRequest); } } @@ -689,10 +687,10 @@ public class TestPlanReportService { if (reportDTO.getErrorReportScenarios() != null) { testPlanReportContentWithBLOBs.setErrorReportScenarios(JSONObject.toJSONString(reportDTO.getErrorReportScenarios())); } - if(reportDTO.getUnExecuteCases() != null){ + if (reportDTO.getUnExecuteCases() != null) { testPlanReportContentWithBLOBs.setUnExecuteCases(JSONObject.toJSONString(reportDTO.getUnExecuteCases())); } - if(reportDTO.getUnExecuteScenarios() != null){ + if (reportDTO.getUnExecuteScenarios() != null) { testPlanReportContentWithBLOBs.setUnExecuteScenarios(JSONObject.toJSONString(reportDTO.getUnExecuteScenarios())); } @@ -1007,9 +1005,9 @@ public class TestPlanReportService { return null; } if (this.isDynamicallyGenerateReports(testPlanReportContent)) { - Log.info("----> GenerateReports: "+ JSONObject.toJSONString(testPlanReportContent)); + LogUtil.info("----> GenerateReports: " + JSONObject.toJSONString(testPlanReportContent)); testPlanReportContent = this.dynamicallyGenerateReports(testPlanReportContent); - Log.info("----> GenerateReports OVER: "+ JSONObject.toJSONString(testPlanReportContent)); + LogUtil.info("----> GenerateReports OVER: " + JSONObject.toJSONString(testPlanReportContent)); } TestPlanSimpleReportDTO testPlanReportDTO = new TestPlanSimpleReportDTO(); BeanUtils.copyBean(testPlanReportDTO, testPlanReportContent); @@ -1084,7 +1082,7 @@ public class TestPlanReportService { content.setTestPlanReportId(testPlanReportID); if (MapUtils.isNotEmpty(apiCaseReportMap)) { - List apiTestCases = extTestPlanApiCaseMapper.getFailureListByIds(apiCaseReportMap.keySet(),null); + List apiTestCases = extTestPlanApiCaseMapper.getFailureListByIds(apiCaseReportMap.keySet(), null); for (TestPlanFailureApiDTO dto : apiTestCases) { dto.setReportId(apiCaseReportMap.get(dto.getId())); } @@ -1114,30 +1112,35 @@ public class TestPlanReportService { if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getPlanApiCaseReportStruct())) { try { apiCaseInfoDTOList = JSONArray.parseArray(testPlanReportContentWithBLOBs.getPlanApiCaseReportStruct(), TestPlanFailureApiDTO.class); - }catch (Exception ignore){} - if(apiCaseInfoDTOList == null){ + } catch (Exception e) { + LogUtil.error(e); + } + if (apiCaseInfoDTOList == null) { try { testPlanApiCaseIdAndReportIdMap = JSONObject.parseObject(testPlanReportContentWithBLOBs.getPlanApiCaseReportStruct(), Map.class); - } catch (Exception ignore) { + } catch (Exception e) { + LogUtil.error(e); } - }else { + } else { for (TestPlanFailureApiDTO item : apiCaseInfoDTOList) { - testPlanApiCaseIdAndReportIdMap.put(item.getId(),item.getReportId()); + testPlanApiCaseIdAndReportIdMap.put(item.getId(), item.getReportId()); } } } if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getPlanScenarioReportStruct())) { try { scenarioInfoDTOList = JSONArray.parseArray(testPlanReportContentWithBLOBs.getPlanScenarioReportStruct(), TestPlanFailureScenarioDTO.class); - }catch (Exception ignore){} - if(scenarioInfoDTOList == null){ + } catch (Exception e) { + LogUtil.error(e); + } + if (scenarioInfoDTOList == null) { try { testPlanScenarioIdAndReportIdMap = JSONObject.parseObject(testPlanReportContentWithBLOBs.getPlanScenarioReportStruct(), Map.class); } catch (Exception ignore) { } - }else { + } else { for (TestPlanFailureScenarioDTO item : scenarioInfoDTOList) { - testPlanScenarioIdAndReportIdMap.put(item.getId(),item.getReportId()); + testPlanScenarioIdAndReportIdMap.put(item.getId(), item.getReportId()); } } } @@ -1148,7 +1151,7 @@ public class TestPlanReportService { } } } - TestPlanExecuteReportDTO returnDTO = new TestPlanExecuteReportDTO(testPlanApiCaseIdAndReportIdMap, testPlanScenarioIdAndReportIdMap, testPlanLoadCaseIdAndReportIdMap,apiCaseInfoDTOList,scenarioInfoDTOList); + TestPlanExecuteReportDTO returnDTO = new TestPlanExecuteReportDTO(testPlanApiCaseIdAndReportIdMap, testPlanScenarioIdAndReportIdMap, testPlanLoadCaseIdAndReportIdMap, apiCaseInfoDTOList, scenarioInfoDTOList); return returnDTO; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index d31ffb593d..faa7d3cf9f 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -176,8 +176,7 @@ public class TestPlanService { @Resource private ProjectService projectService; @Resource - private ExtTestPlanExecutionQueueMapper extTestPlanExecutionQueueMapper; - + private TestPlanExecutionQueueService testPlanExecutionQueueService; public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) { if (getTestPlanByName(testPlan.getName()).size() > 0) { @@ -937,12 +936,12 @@ public class TestPlanService { } @Transactional(propagation = Propagation.NOT_SUPPORTED) - TestPlanScheduleReportInfoDTO genTestPlanReport(String projectID, String planId, String userId, String triggerMode) { - TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(null, planId, userId, triggerMode); + TestPlanScheduleReportInfoDTO genTestPlanReport(String planReportId, String planId, String userId, String triggerMode) { + TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(planReportId, planId, userId, triggerMode); return reportInfoDTO; } - public String run(String testPlanID, String projectID, String userId, String triggerMode, TestPlanScheduleReportInfoDTO reportInfoDTO, String apiRunConfig) { + public String run(String testPlanID, String projectID, String userId, String triggerMode, String planReportId, String apiRunConfig) { RunModeConfigDTO runModeConfig = null; try { runModeConfig = JSONObject.parseObject(apiRunConfig, RunModeConfigDTO.class); @@ -960,28 +959,41 @@ public class TestPlanService { runModeConfig.setEnvMap(new HashMap<>()); } } - //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 - if (reportInfoDTO == null) { - reportInfoDTO = this.genTestPlanReport(projectID, testPlanID, userId, triggerMode); + if (planReportId == null) { + planReportId = UUID.randomUUID().toString(); } + + //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 + TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(planReportId, testPlanID, userId, triggerMode); //测试计划准备执行,取消测试计划的实际结束时间 extTestPlanMapper.updateActualEndTimeIsNullById(testPlanID); - String planReportId = reportInfoDTO.getTestPlanReport().getId(); testPlanLog.info("ReportId[" + planReportId + "] created. TestPlanID:[" + testPlanID + "]. " + "API Run Config:【" + apiRunConfig + "】"); + Map apiCaseReportMap = null; + Map scenarioReportMap = null; + Map loadCaseReportMap = null; + if(reportInfoDTO.getApiTestCaseDataMap()!=null){ + //执行接口案例任务 + LoggerUtil.info("开始执行测试计划接口用例 " + planReportId); + apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, new ArrayList<>(reportInfoDTO.getApiTestCaseDataMap().keySet()), runModeConfig); + } + if(reportInfoDTO.getPlanScenarioIdMap()!=null){ + //执行场景执行任务 + LoggerUtil.info("开始执行测试计划场景用例 " + planReportId); + scenarioReportMap = this.executeScenarioCase(planReportId, testPlanID, projectID, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap()); + } + + if(reportInfoDTO.getPerformanceIdMap()!=null){ + //执行性能测试任务 + LoggerUtil.info("开始执行测试计划性能用例 " + planReportId); + loadCaseReportMap = this.executeLoadCaseTask(planReportId,runModeConfig, triggerMode, reportInfoDTO.getPerformanceIdMap()); + } + if(apiCaseReportMap!=null&&scenarioReportMap!=null&&loadCaseReportMap!=null){ + LoggerUtil.info("开始生成测试计划报告 " + planReportId); + testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiCaseReportMap, scenarioReportMap, loadCaseReportMap); + } - //执行接口案例任务 - LoggerUtil.info("开始执行测试计划接口用例 " + planReportId); - Map apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, new ArrayList<>(reportInfoDTO.getApiTestCaseDataMap().keySet()), runModeConfig); - //执行场景执行任务 - LoggerUtil.info("开始执行测试计划场景用例 " + planReportId); - Map scenarioReportMap = this.executeScenarioCase(planReportId, testPlanID, projectID, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap()); - //执行性能测试任务 - LoggerUtil.info("开始执行测试计划性能用例 " + planReportId); - Map loadCaseReportMap = this.executeLoadCaseTask(planReportId, runModeConfig, triggerMode, reportInfoDTO.getPerformanceIdMap()); - LoggerUtil.info("开始生成测试计划报告 " + planReportId); - testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiCaseReportMap, scenarioReportMap, loadCaseReportMap); return planReportId; } @@ -1852,7 +1864,7 @@ public class TestPlanService { String apiRunConfig = JSONObject.toJSONString(runModeConfig); updatePlan(testplanRunRequest, testPlanId); return this.run(testPlanId, testplanRunRequest.getProjectId(), - testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getPlanScheduleReportInfoDTO() != null ? testplanRunRequest.getPlanScheduleReportInfoDTO() : null, apiRunConfig); + testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getReportId(), apiRunConfig); } @@ -2052,10 +2064,10 @@ public class TestPlanService { return extTestPlanMapper.list(request); } - public List runBatch(TestplanRunRequest request) { + public void runBatch(TestplanRunRequest request) { List ids = request.getTestPlanIds(); if (CollectionUtils.isEmpty(ids) && !request.getIsAll()) { - return new LinkedList<>(); + return; } LoggerUtil.info("开始查询测试计划"); List planList = new ArrayList<>(); @@ -2070,25 +2082,31 @@ public class TestPlanService { } Map testPlanMap = planList.stream().collect(Collectors.toMap(TestPlan::getId, a -> a, (k1, k2) -> k1)); - Map executeQueue = new LinkedHashMap<>(); - List responseDTOS = new LinkedList<>(); - Map planScheduleReportInfoDTOMap = new LinkedHashMap<>(); - boolean startThread = true; + Map executeQueue = new LinkedHashMap<>(); + + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < planList.size(); i++) { + if (StringUtils.isBlank(planList.get(i).getRunModeConfig())) { + StringBuilder append = stringBuilder.append("请保存[").append(planList.get(i).getName()).append("]的运行配置"); + if (i <= planList.size() - 2) { + append.append("/"); + } + } + } + + if (StringUtils.isNotEmpty(stringBuilder)) { + MSException.throwException(stringBuilder.toString()); + } + for (String id : ids) { TestPlanWithBLOBs testPlan = testPlanMap.get(id); - if (StringUtils.isBlank(testPlan.getRunModeConfig())) { - startThread = false; - MSException.throwException("请保存[" + testPlan.getName() + "]的运行配置"); - } - //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 - TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(testPlan.getProjectId(), testPlan.getId(), request.getUserId(), request.getTriggerMode()); - + String planReportId = UUID.randomUUID().toString(); + //创建测试报告 + this.genTestPlanReport(planReportId, testPlan.getId(), request.getUserId(), request.getTriggerMode()); //测试计划准备执行,取消测试计划的实际结束时间 extTestPlanMapper.updateActualEndTimeIsNullById(testPlan.getId()); + executeQueue.put(testPlan.getId(), planReportId); - executeQueue.put(testPlan.getId(), reportInfoDTO.getTestPlanReport()); - responseDTOS.add(new MsExecResponseDTO(testPlan.getId(), reportInfoDTO.getTestPlanReport().getId(), request.getTriggerMode())); - planScheduleReportInfoDTOMap.put(testPlan.getId(), reportInfoDTO); } LoggerUtil.info("开始生成测试计划队列"); @@ -2096,29 +2114,34 @@ public class TestPlanService { List planExecutionQueues = getTestPlanExecutionQueues(request, executeQueue); if (CollectionUtils.isNotEmpty(planExecutionQueues)) { - extTestPlanExecutionQueueMapper.sqlInsert(planExecutionQueues); + testPlanExecutionQueueService.batchSave(planExecutionQueues); } // 开始选择执行模式 - runByMode(startThread, request, testPlanMap, planScheduleReportInfoDTOMap, planExecutionQueues); + runByMode(request, testPlanMap, planExecutionQueues); - return responseDTOS; } - private List getTestPlanExecutionQueues(TestplanRunRequest request, Map executeQueue) { - List planExecutionQueues = new ArrayList<>(); - executeQueue.forEach((k, v) -> { + + private List getTestPlanExecutionQueues(TestplanRunRequest request, Map executeQueue) { + ListplanExecutionQueues = new ArrayList<>(); + String resourceId = UUID.randomUUID().toString(); + final int[] nextNum = {testPlanExecutionQueueService.getNextNum(resourceId)}; + executeQueue.forEach((k, v)->{ TestPlanExecutionQueue executionQueue = new TestPlanExecutionQueue(); executionQueue.setId(UUID.randomUUID().toString()); executionQueue.setCreateTime(System.currentTimeMillis()); - executionQueue.setReportId(v.getId()); + executionQueue.setReportId(v); executionQueue.setTestPlanId(k); executionQueue.setRunMode(request.getMode()); + executionQueue.setResourceId(resourceId); + executionQueue.setNum(nextNum[0]); + nextNum[0]++; planExecutionQueues.add(executionQueue); }); return planExecutionQueues; } - private void runByMode(boolean startThread, TestplanRunRequest request, Map testPlanMap, Map planScheduleReportInfoDTOMap, List planExecutionQueues) { + private void runByMode(TestplanRunRequest request, Map testPlanMap, List planExecutionQueues) { if (CollectionUtils.isNotEmpty(planExecutionQueues)) { Thread thread = new Thread(new Runnable() { @Override @@ -2128,23 +2151,21 @@ public class TestPlanService { TestPlanExecutionQueue planExecutionQueue = planExecutionQueues.get(0); TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); JSONObject jsonObject = JSONObject.parseObject(testPlan.getRunModeConfig()); - TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject, TestplanRunRequest.class); - runRequest.setPlanScheduleReportInfoDTO(planScheduleReportInfoDTOMap.get(planExecutionQueue.getTestPlanId())); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); + runRequest.setReportId(planExecutionQueue.getReportId()); runPlan(runRequest); - } else { + }else { for (TestPlanExecutionQueue planExecutionQueue : planExecutionQueues) { TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); JSONObject jsonObject = JSONObject.parseObject(testPlan.getRunModeConfig()); - TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject, TestplanRunRequest.class); - runRequest.setPlanScheduleReportInfoDTO(planScheduleReportInfoDTOMap.get(planExecutionQueue.getTestPlanId())); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); + runRequest.setReportId(planExecutionQueue.getReportId()); runPlan(runRequest); } } } }); - if (startThread) { - thread.start(); - } + thread.start(); } } diff --git a/backend/src/main/resources/db/migration/V115__1.20__release.sql b/backend/src/main/resources/db/migration/V115__1.20__release.sql index 62c81e7c71..f997f274c7 100644 --- a/backend/src/main/resources/db/migration/V115__1.20__release.sql +++ b/backend/src/main/resources/db/migration/V115__1.20__release.sql @@ -181,16 +181,18 @@ CREATE TABLE IF NOT EXISTS `test_plan_execution_queue` `run_mode` varchar(100) COMMENT '执行模式/scenario/api/test_paln_api/test_pan_scenario', create_time bigint(13) NULL COMMENT '创建时间', `test_plan_id` varchar(100) COMMENT 'testPlanId', + `resource_id` varchar(100) COMMENT 'resourceId/批次id', + `num` int null comment 'order', PRIMARY KEY (`id`), - KEY `report_id_idx` (`report_id`) + KEY `report_id_idx` (`report_id`), + KEY `resource_id_index` (`resource_id`), + KEY `num_index` (`num`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; -- 场景步骤结果增加简要信息 ALTER TABLE api_scenario_report_result ADD `base_info` LONGTEXT NULL; - - -- quota -- 处理移除组织时遗留的脏数据 delete diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index 544a85d454..87fe69879f 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -86,7 +86,7 @@ - +