From 6e99229bfcb90e3d9d1da91eba29446426bc782c Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Fri, 14 Jan 2022 10:17:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/exec/api/ApiCaseExecuteService.java | 4 +- .../api/ApiCaseParallelExecuteService.java | 2 +- .../scenario/ApiScenarioExecuteService.java | 3 +- .../scenario/ApiScenarioSerialService.java | 10 +- .../api/service/ApiExecutionQueueService.java | 171 ++++++++++-------- .../api/service/ApiJmeterFileService.java | 2 +- 6 files changed, 101 insertions(+), 91 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java index fd756bd785..c5294b73f5 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java @@ -101,7 +101,7 @@ public class ApiCaseExecuteService { String reportType = request.getConfig().getReportType(); String poolId = request.getConfig().getResourcePoolId(); String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name(); - DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap(), request.getConfig().isOnSampleError()); + DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig()); // 开始选择执行模式 if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { @@ -178,7 +178,7 @@ public class ApiCaseExecuteService { String reportType = request.getConfig().getReportType(); String poolId = request.getConfig().getResourcePoolId(); - DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig().getEnvMap(), request.getConfig().isOnSampleError()); + DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig()); // 开始选择执行模式 if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { LoggerUtil.debug("开始串行执行"); diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java index 87a6332bd8..a7b2e4f482 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java @@ -34,7 +34,7 @@ public class ApiCaseParallelExecuteService { String reportId = result.getId(); HashTree hashTree = null; if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) { - hashTree = apiScenarioSerialService.generateHashTree(testId, executionQueue.getRunMode(), config.getEnvMap()); + hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap()); } JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree); runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId())); diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java index 65cbf7dfbc..6a54ce17a0 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java @@ -167,8 +167,7 @@ public class ApiScenarioExecuteService { String reportType = request.getConfig().getReportType(); String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId; DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId() - , ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig().getEnvMap() - , request.getConfig().isOnSampleError()); + , ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig()); if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { if (StringUtils.isNotEmpty(serialReportId)) { diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java index 5049de2592..cbb37e65f6 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java @@ -104,7 +104,7 @@ public class ApiScenarioSerialService { if (StringUtils.isNotEmpty(queue.getEvnMap())) { map = JSON.parseObject(queue.getEvnMap(), Map.class); } - hashTree = generateHashTree(queue.getTestId(), queue.getType(), map); + hashTree = generateHashTree(queue.getTestId(), map); } // 更新环境变量 this.initEnv(hashTree); @@ -152,12 +152,10 @@ public class ApiScenarioSerialService { hashTreeUtil.mergeParamDataMap(null, envParamsMap); } - public HashTree generateHashTree(String testId, String type, Map envMap) { - ApiTestCaseWithBLOBs caseWithBLOBs = null; + public HashTree generateHashTree(String testId, Map envMap) { + ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId); String envId = null; - if (StringUtils.equals(type, ApiRunMode.DEFINITION.name())) { - caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId); - } else { + if (caseWithBLOBs == null) { TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId); if (apiCase != null) { caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java index fba80ea0d6..fbf7f2d3ae 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java @@ -19,6 +19,7 @@ import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.ResultDTO; +import io.metersphere.dto.RunModeConfigDTO; import io.metersphere.track.service.TestPlanReportService; import io.metersphere.utils.LoggerUtil; import org.apache.commons.collections4.CollectionUtils; @@ -57,12 +58,12 @@ public class ApiExecutionQueueService { @Resource private ExtApiExecutionQueueMapper extApiExecutionQueueMapper; - public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, Map envMap, boolean failure) { + public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) { ApiExecutionQueue executionQueue = new ApiExecutionQueue(); executionQueue.setId(UUID.randomUUID().toString()); executionQueue.setCreateTime(System.currentTimeMillis()); executionQueue.setPoolId(poolId); - executionQueue.setFailure(failure); + executionQueue.setFailure(config.isOnSampleError()); executionQueue.setReportId(reportId); executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString()); executionQueue.setRunMode(runMode); @@ -76,12 +77,12 @@ public class ApiExecutionQueueService { if (StringUtils.equalsAnyIgnoreCase(type, ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) { final int[] sort = {0}; Map runMap = (Map) runObj; - if (envMap == null) { - envMap = new LinkedHashMap<>(); + if (config.getEnvMap() == null) { + config.setEnvMap(new LinkedHashMap<>()); } - String envStr = JSON.toJSONString(envMap); + String envStr = JSON.toJSONString(config.getEnvMap()); runMap.forEach((k, v) -> { - ApiExecutionQueueDetail queue = detail(v.getId(), k, type, sort[0], executionQueue.getId(), envStr); + ApiExecutionQueueDetail queue = detail(v.getId(), k, config.getMode(), sort[0], executionQueue.getId(), envStr); if (sort[0] == 0) { resQueue.setQueue(queue); } @@ -93,7 +94,7 @@ public class ApiExecutionQueueService { Map runMap = (Map) runObj; final int[] sort = {0}; runMap.forEach((k, v) -> { - ApiExecutionQueueDetail queue = detail(k, v.getTestId(), type, sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap())); + ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap())); queue.setSort(sort[0]); if (sort[0] == 0) { resQueue.setQueue(queue); @@ -124,10 +125,48 @@ public class ApiExecutionQueueService { return queue; } + private boolean failure(DBTestQueue executionQueue, ResultDTO dto) { + LoggerUtil.info("进入失败停止处理:" + executionQueue.getId()); + boolean isError = false; + if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO.name(), + ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), + ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(executionQueue.getNowReportId()); + if (report != null && StringUtils.equalsIgnoreCase(report.getStatus(), "Error")) { + isError = true; + } + } else { + ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(executionQueue.getNowReportId()); + if (result != null && StringUtils.equalsIgnoreCase(result.getStatus(), "Error")) { + isError = true; + } + } + if (isError) { + ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample(); + example.createCriteria().andQueueIdEqualTo(dto.getQueueId()); + + if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) { + CommonBeanFactory.getBean(TestPlanReportService.class).finishedTestPlanReport(dto.getTestPlanReportId(), "Stopped"); + } + // 更新未执行的报告状态 + List details = executionQueueDetailMapper.selectByExample(example); + List reportIds = details.stream().map(ApiExecutionQueueDetail::getReportId).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(reportIds)) { + extApiDefinitionExecResultMapper.update(reportIds); + extApiScenarioReportMapper.update(reportIds); + } + // 清除队列 + executionQueueDetailMapper.deleteByExample(example); + queueMapper.deleteByPrimaryKey(executionQueue.getId()); + return false; + } + return true; + } + public DBTestQueue edit(String id, String testId) { ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(id); + DBTestQueue queue = new DBTestQueue(); if (executionQueue != null) { - DBTestQueue queue = new DBTestQueue(); BeanUtils.copyBean(queue, executionQueue); if (executionQueue != null) { ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample(); @@ -152,50 +191,21 @@ public class ApiExecutionQueueService { queueMapper.deleteByPrimaryKey(id); } } - return queue; } - return null; + return queue; } public void queueNext(ResultDTO dto) { DBTestQueue executionQueue = this.edit(dto.getQueueId(), dto.getTestId()); if (executionQueue != null) { + // 串行失败停止 if (executionQueue.getFailure()) { - LoggerUtil.info("进入失败停止处理:" + executionQueue.getId()); - boolean isError = false; - if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO.name(), - ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), - ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { - ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(executionQueue.getNowReportId()); - if (report != null && StringUtils.equalsIgnoreCase(report.getStatus(), "Error")) { - isError = true; - } - } else { - ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(executionQueue.getNowReportId()); - if (result != null && StringUtils.equalsIgnoreCase(result.getStatus(), "Error")) { - isError = true; - } - } - if (isError) { - ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample(); - example.createCriteria().andQueueIdEqualTo(dto.getQueueId()); - - if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) { - CommonBeanFactory.getBean(TestPlanReportService.class).finishedTestPlanReport(dto.getTestPlanReportId(), "Stopped"); - } - // 更新未执行的报告状态 - List details = executionQueueDetailMapper.selectByExample(example); - List reportIds = details.stream().map(ApiExecutionQueueDetail::getReportId).collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(reportIds)) { - extApiDefinitionExecResultMapper.update(reportIds); - extApiScenarioReportMapper.update(reportIds); - } - // 清除队列 - executionQueueDetailMapper.deleteByExample(example); - queueMapper.deleteByPrimaryKey(executionQueue.getId()); + boolean isNext = failure(executionQueue, dto); + if (!isNext) { return; } } + LoggerUtil.info("开始处理执行队列:" + executionQueue.getId()); if (executionQueue.getQueue() != null && StringUtils.isNotEmpty(executionQueue.getQueue().getTestId())) { if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) { @@ -220,61 +230,64 @@ public class ApiExecutionQueueService { } } - public void timeOut() { final int SECOND_MILLIS = 1000; final int MINUTE_MILLIS = 60 * SECOND_MILLIS; // 计算二十分钟前的超时报告 - final long timeBeforeTimeOutStemp = System.currentTimeMillis() - (20 * MINUTE_MILLIS); + final long twentyMinutesAgo = System.currentTimeMillis() - (20 * MINUTE_MILLIS); ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample(); - example.createCriteria().andCreateTimeLessThan(timeBeforeTimeOutStemp); + example.createCriteria().andCreateTimeLessThan(twentyMinutesAgo); List queueDetails = executionQueueDetailMapper.selectByExample(example); - if (CollectionUtils.isNotEmpty(queueDetails)) { - queueDetails.forEach(item -> { - if (StringUtils.equalsAnyIgnoreCase(item.getType(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { - ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId()); - if (report != null - && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name()) - && report.getUpdateTime() < timeBeforeTimeOutStemp) { - //场景报告最后一次更新时间于当前时间相比超过了20分钟,也就是20分钟没有步骤执行完成。这种情况下做超时处理 - report.setStatus(ScenarioStatus.Timeout.name()); - apiScenarioReportMapper.updateByPrimaryKeySelective(report); + queueDetails.forEach(item -> { + ApiExecutionQueue queue = queueMapper.selectByPrimaryKey(item.getQueueId()); + if (queue != null && StringUtils.equalsAnyIgnoreCase(queue.getRunMode(), + ApiRunMode.SCENARIO.name(), + ApiRunMode.SCENARIO_PLAN.name(), + ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), + ApiRunMode.SCHEDULE_SCENARIO.name(), + ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId()); + if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name()) + && report.getUpdateTime() < twentyMinutesAgo) { + report.setStatus(ScenarioStatus.Timeout.name()); + apiScenarioReportMapper.updateByPrimaryKeySelective(report); - ResultDTO dto = new ResultDTO(); - dto.setQueueId(item.getQueueId()); - dto.setTestId(item.getTestId()); - ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(item.getQueueId()); - if (executionQueue != null) { - dto.setTestPlanReportId(executionQueue.getReportId()); - dto.setReportId(executionQueue.getReportId()); - dto.setRunMode(executionQueue.getRunMode()); - dto.setRunType(RunModeConstants.SERIAL.toString()); - dto.setReportType(executionQueue.getReportType()); - queueNext(dto); - }else { - executionQueueDetailMapper.deleteByPrimaryKey(item.getId()); - } - } - } else { - ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId()); - if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name())) { - result.setStatus(ScenarioStatus.Timeout.name()); - apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result); + LoggerUtil.info("超时处理报告:" + report.getId()); + ResultDTO dto = new ResultDTO(); + dto.setQueueId(item.getQueueId()); + dto.setTestId(item.getTestId()); + ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(item.getQueueId()); + if (executionQueue != null && StringUtils.equalsIgnoreCase(item.getType(), RunModeConstants.SERIAL.toString())) { + LoggerUtil.info("超时处理报告:【" + report.getId() + "】进入下一个执行"); + dto.setTestPlanReportId(executionQueue.getReportId()); + dto.setReportId(executionQueue.getReportId()); + dto.setRunMode(executionQueue.getRunMode()); + dto.setRunType(item.getType()); + dto.setReportType(executionQueue.getReportType()); + queueNext(dto); + } else { executionQueueDetailMapper.deleteByPrimaryKey(item.getId()); } } - }); - } + } else { + ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId()); + if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name())) { + result.setStatus(ScenarioStatus.Timeout.name()); + apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result); + executionQueueDetailMapper.deleteByPrimaryKey(item.getId()); + } + } + }); ApiExecutionQueueExample queueDetailExample = new ApiExecutionQueueExample(); - queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(timeBeforeTimeOutStemp); + queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(twentyMinutesAgo); List executionQueues = queueMapper.selectByExample(queueDetailExample); if (CollectionUtils.isNotEmpty(executionQueues)) { executionQueues.forEach(item -> { ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId()); if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name()) - && (report.getUpdateTime() < timeBeforeTimeOutStemp)) { + && (report.getUpdateTime() < twentyMinutesAgo)) { report.setStatus(ScenarioStatus.Timeout.name()); apiScenarioReportMapper.updateByPrimaryKeySelective(report); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java b/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java index 061eade52f..a57d95d789 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java @@ -72,7 +72,7 @@ public class ApiJmeterFileService { } HashTree hashTree; if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) { - hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, runMode, envMap); + hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, envMap); } else { if (scenario == null) { scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);