diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 2ea71b9635..13ee36a210 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -48,6 +48,7 @@ import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.ListedHashTree; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -594,7 +595,6 @@ public class ApiAutomationService { report.setProjectId(projectId); report.setScenarioName(scenarioName); report.setScenarioId(scenarioId); - apiScenarioReportMapper.insert(report); return report; } @@ -696,7 +696,7 @@ public class ApiAutomationService { * @param request * @return */ - public String abandonedRun(RunScenarioRequest request) { + public String parallelRun(RunScenarioRequest request) { ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query)); @@ -823,6 +823,7 @@ public class ApiAutomationService { // 创建场景报告 if (reportIds != null) { //如果是测试计划页面触发的执行方式,生成报告时createScenarioReport第二个参数需要特殊处理 + APIScenarioReportResult report = null; if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) { String testPlanScenarioId = item.getId(); if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) { @@ -834,12 +835,13 @@ public class ApiAutomationService { scenario.setEnvironmentMap(JSON.parseObject(environment, Map.class)); } } - createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), + report = createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig()); } else { - createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), + report = createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig()); } + apiScenarioReportMapper.insert(report); reportIds.add(group.getName()); } group.setHashTree(scenarios); @@ -909,7 +911,7 @@ public class ApiAutomationService { * @param request * @return */ - public String run(RunScenarioRequest request) { + public String serialRun(RunScenarioRequest request) { ServiceUtils.getSelectAllIds(request, request.getCondition(), (query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query)); List ids = request.getIds(); @@ -953,6 +955,25 @@ public class ApiAutomationService { return request.getId(); } + @Value("${run.concurrency}") + private String concurrency; + + public String run(RunScenarioRequest request) { + if (request.getConfig() != null && request.getConfig().getMode().equals("serial")) { + return this.serialRun(request); + } else { + // 校验并发数量 + int count = 50; + if (StringUtils.isNotEmpty(concurrency)) { + count = Integer.parseInt(concurrency); + } + if (request.getIds().size() > count) { + MSException.throwException("并发数量过大,请重新选择!"); + } + return this.parallelRun(request); + } + } + public void checkScenarioIsRunning(List ids) { List lastReportStatusByIds = apiReportService.selectLastReportByIds(ids); for (ApiScenarioReport report : lastReportStatusByIds) { @@ -1013,8 +1034,9 @@ public class ApiAutomationService { MSException.throwException(e.getMessage()); } // 调用执行方法 - createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), + APIScenarioReportResult report = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId(), null); + apiScenarioReportMapper.insert(report); // 调用执行方法 // jMeterService.runTest(request.getId(), hashTree, ApiRunMode.SCENARIO.name(), true, null); // 调用执行方法 @@ -1037,11 +1059,6 @@ public class ApiAutomationService { if (CollectionUtils.isEmpty(request.getPlanIds())) { MSException.throwException(Translator.get("plan id is null ")); } -// List scenarioIds = request.getScenarioIds(); -// if (request.isSelectAllDate()) { -// scenarioIds = this.getAllScenarioIdsByFontedSelect( -// request.getModuleIds(), request.getName(), request.getProjectId(), request.getFilters(), request.getUnSelectIds()); -// } Map> mapping = request.getMapping(); Map envMap = request.getEnvMap(); Set set = mapping.keySet(); @@ -1158,7 +1175,6 @@ public class ApiAutomationService { testCaseReviewScenario.setUpdateTime(System.currentTimeMillis()); testCaseReviewScenario.setEnvironment(JSON.toJSONString(newEnvMap)); testCaseReviewScenarioMapper.insert(testCaseReviewScenario); - }); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index d3a18661e8..071a0cea02 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -43,6 +43,7 @@ import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.jorphan.collections.HashTree; import org.aspectj.util.FileUtil; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -293,7 +294,8 @@ public class ApiDefinitionService { test.setTags(request.getTags()); } else { test.setTags(null); - } this.setModule(test); + } + this.setModule(test); apiDefinitionMapper.updateByPrimaryKeySelective(test); return test; } @@ -526,6 +528,9 @@ public class ApiDefinitionService { } } + @Value("${run.concurrency}") + private String concurrency; + /** * 测试执行 * @@ -534,6 +539,13 @@ public class ApiDefinitionService { * @return */ public String run(RunDefinitionRequest request, List bodyFiles) { + int count = 100; + if (StringUtils.isNotEmpty(concurrency)) { + count = Integer.parseInt(concurrency); + } + if (request.getTestElement() != null && request.getTestElement().getHashTree().size() == 1 && request.getTestElement().getHashTree().get(0).getHashTree().size() > count) { + MSException.throwException("并发数量过大,请重新选择!"); + } List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); FileUtils.createBodyFiles(bodyUploadIds, bodyFiles); diff --git a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue index 2a4fe8c2fe..af541e03b4 100644 --- a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiCaseList.vue @@ -605,6 +605,7 @@ export default { let reqObj = {id: getUUID().substring(0, 8), testElement: testPlan, type: 'API_PLAN', reportId: "run", projectId: projectId}; let bodyFiles = getBodyUploadFiles(reqObj, this.runData); this.$fileUpload("/api/definition/run", null, bodyFiles, reqObj, response => { + this.$message('任务执行中,请稍后刷新查看结果'); }); } else { testPlan.serializeThreadgroups = false; @@ -617,10 +618,10 @@ export default { let reqObj = {id: getUUID().substring(0, 8), testElement: testPlan, type: 'API_PLAN', reportId: "run", projectId: projectId}; let bodyFiles = getBodyUploadFiles(reqObj, this.runData); this.$fileUpload("/api/definition/run", null, bodyFiles, reqObj, response => { + this.$message('任务执行中,请稍后刷新查看结果'); }); } this.search(); - this.$message('任务执行中,请稍后刷新查看结果'); }, autoCheckStatus() { // 检查执行结果,自动更新计划状态 if (!this.planId) { diff --git a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue index e79e24c68c..4e420cd68d 100644 --- a/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue @@ -324,7 +324,9 @@ export default { this.selectRows.forEach(row => { this.buildExecuteParam(param,row); }); - this.$post("/test/case/review/scenario/case/run", param, response => {}); + this.$post("/test/case/review/scenario/case/run", param, response => { + this.$message('任务执行中,请稍后刷新查看结果'); + }); } if (this.planId) { let selectParam = buildBatchParam(this); @@ -334,9 +336,9 @@ export default { }); param.condition = selectParam.condition; this.$post("/test/plan/scenario/case/run", param, response => { + this.$message('任务执行中,请稍后刷新查看结果'); }); } - this.$message('任务执行中,请稍后刷新查看结果'); this.search(); }, execute(row) {