From 19bb132115c590c1b74a2e23ce0e6db5b1c84742 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Mon, 8 Nov 2021 15:58:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=A7=E8=A1=8C=E8=BF=87=E7=A8=8B=E4=B8=AD?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E6=83=85=E5=86=B5=EF=BC=8C=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BatchRunDefinitionRequest.java | 2 + .../metersphere/api/jmeter/JMeterService.java | 31 +--- .../api/service/ApiAutomationService.java | 39 +++-- .../api/service/ApiJmeterFileService.java | 2 +- .../api/service/ApiScenarioReportService.java | 133 ++++++++++++++- .../api/service/RemakeReportService.java | 152 ++++++++++++++++++ .../commons/constants/ReportTriggerMode.java | 1 + .../track/service/TestPlanApiCaseService.java | 29 +++- 8 files changed, 345 insertions(+), 44 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/service/RemakeReportService.java diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java index 8045ff6905..c04e176b57 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java @@ -13,6 +13,8 @@ public class BatchRunDefinitionRequest { private List planIds; + private String triggerMode; + private RunModeConfig config; } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java index 1f60311b82..caf1edbd97 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java @@ -7,9 +7,10 @@ import io.metersphere.api.dto.automation.ExecuteType; import io.metersphere.api.dto.automation.RunModeConfig; import io.metersphere.api.service.ApiScenarioReportService; import io.metersphere.api.service.NodeKafkaService; +import io.metersphere.api.service.RemakeReportService; import io.metersphere.base.domain.TestResource; import io.metersphere.base.domain.TestResourcePool; -import io.metersphere.base.mapper.TestResourcePoolMapper; +import io.metersphere.base.mapper.*; import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ResourcePoolTypeEnum; import io.metersphere.commons.constants.TriggerMode; @@ -175,16 +176,7 @@ public class JMeterService { MSException.throwException(e.getMessage()); } } else { - try { - this.send(runRequest, config, reportId); - } catch (Exception e) { - e.printStackTrace(); - if (MessageCache.cache.get(config.getAmassReport()) != null - && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { - MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(reportId); - } - MessageCache.batchTestCases.remove(reportId); - } + this.send(runRequest, config, reportId); } } @@ -200,21 +192,12 @@ public class JMeterService { String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port); ResponseEntity result = restTemplate.postForEntity(uri, runRequest, String.class); if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) { - // 清理零时报告 - ApiScenarioReportService apiScenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class); - apiScenarioReportService.delete(reportId); - MSException.throwException("执行失败:" + result); - if (MessageCache.cache.get(config.getAmassReport()) != null - && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { - MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(reportId); - } + ApiScenarioReportService remakeReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class); + remakeReportService.remake(runRequest, config, reportId); } } catch (Exception e) { - if (MessageCache.cache.get(config.getAmassReport()) != null - && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { - MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(reportId); - } - MessageCache.batchTestCases.remove(reportId); + RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); + remakeReportService.remake(runRequest, config, reportId); } } } 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 c3852116d8..a9e6eb6085 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -139,7 +139,7 @@ public class ApiAutomationService { @Resource private ResourcePoolCalculation resourcePoolCalculation; @Resource - private NodeKafkaService nodeKafkaService; + private RemakeReportService remakeReportService; @Resource private ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper; @Resource @@ -1187,14 +1187,29 @@ public class ApiAutomationService { executeQueue.put(report.getId(), runModeDataDTO); } else { // 生成报告和HashTree - HashTree hashTree = generateHashTree(item, reportId, planEnvMap); - executeQueue.put(report.getId(), new RunModeDataDTO(hashTree, report)); + try { + HashTree hashTree = generateHashTree(item, reportId, planEnvMap); + executeQueue.put(report.getId(), new RunModeDataDTO(hashTree, report)); + } catch (Exception ex) { + if (StringUtils.equalsAny(request.getTriggerMode(), TriggerMode.BATCH.name(), TriggerMode.SCHEDULE.name())) { + String testPlanScenarioId; + if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) { + testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId()); + } else { + testPlanScenarioId = request.getPlanScenarioId(); + } + remakeReportService.remakeScenario(request.getRunMode(), testPlanScenarioId, request.getConfig(), item, report); + } else { + MSException.throwException(ex); + } + } } scenarioIds.add(item.getId()); scenarioNames.append(item.getName()).append(","); // 重置报告ID reportId = UUID.randomUUID().toString(); } catch (Exception ex) { + ex.printStackTrace(); MSException.throwException("解析运行步骤失败!场景名称:" + item.getName()); } } @@ -1343,12 +1358,18 @@ public class ApiAutomationService { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class); // 开始并发执行 - for (String reportId : executeQueue.keySet()) { - //存储报告 - APIScenarioReportResult report = executeQueue.get(reportId).getReport(); - batchMapper.insert(report); - } - sqlSession.commit(); + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + for (String reportId : executeQueue.keySet()) { + //存储报告 + APIScenarioReportResult report = executeQueue.get(reportId).getReport(); + batchMapper.insert(report); + } + sqlSession.flushStatements(); + } + }); + thread.start(); for (String reportId : executeQueue.keySet()) { if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) { 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 b819a8ea57..3cbe813a2c 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java @@ -62,7 +62,7 @@ public class ApiJmeterFileService { planEnvMap = JSON.parseObject(environment, Map.class); } } - HashTree hashTree = null; + HashTree hashTree; if (ApiRunMode.DEFINITION.name().equals(runMode) || ApiRunMode.API_PLAN.name().equals(runMode)) { hashTree = testPlanApiCaseService.generateHashTree(testId); } else { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 1592c1864d..b9538ec282 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -7,12 +7,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.cache.TestPlanReportExecuteCatch; -import io.metersphere.api.dto.APIReportBatchRequest; -import io.metersphere.api.dto.DeleteAPIReportRequest; -import io.metersphere.api.dto.JvmInfoDTO; -import io.metersphere.api.dto.QueryAPIReportRequest; +import io.metersphere.api.dto.*; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.ExecuteType; +import io.metersphere.api.dto.automation.RunModeConfig; import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.api.jmeter.MessageCache; @@ -84,6 +82,12 @@ public class ApiScenarioReportService { private UserService userService; @Resource private ProjectMapper projectMapper; + @Resource + private ApiDefinitionExecResultMapper execResultMapper; + @Resource + private TestPlanApiCaseMapper testPlanApiCaseMapper; + @Resource + private TestCaseReviewApiCaseMapper testCaseReviewApiCaseMapper; public ApiScenarioReport complete(TestResult result, String runMode) { // 更新场景 @@ -866,4 +870,125 @@ public class ApiScenarioReportService { } return count; } + + + public void remake(RunRequest runRequest, RunModeConfig config, String reportId) { + if (MessageCache.cache.get(config.getAmassReport()) != null + && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { + MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(reportId); + } + // 重置报告状态 + if (StringUtils.isNotEmpty(reportId)) { + // 清理零时报告 + if (StringUtils.equalsAnyIgnoreCase(runRequest.getRunMode(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) { + ApiDefinitionExecResult result = execResultMapper.selectByPrimaryKey(reportId); + if (result != null) { + result.setStatus("error"); + result.setEndTime(System.currentTimeMillis()); + execResultMapper.updateByPrimaryKeySelective(result); + + TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(runRequest.getTestId()); + if (testPlanApiCase != null) { + testPlanApiCase.setStatus("error"); + testPlanApiCase.setUpdateTime(System.currentTimeMillis()); + testPlanApiCaseMapper.updateByPrimaryKeySelective(testPlanApiCase); + } + TestCaseReviewApiCase testCaseReviewApiCase = testCaseReviewApiCaseMapper.selectByPrimaryKey(runRequest.getTestId()); + if (testCaseReviewApiCase != null) { + testCaseReviewApiCase.setStatus("error"); + testCaseReviewApiCase.setUpdateTime(System.currentTimeMillis()); + testCaseReviewApiCaseMapper.updateByPrimaryKeySelective(testCaseReviewApiCase); + } + } + } else if (StringUtils.equals(runRequest.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setEndTime(System.currentTimeMillis()); + report.setStatus(APITestStatus.Error.name()); + + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); + if (testPlanApiScenario != null) { + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + + report.setTestPlanScenarioId(testPlanApiScenario.getId()); + } + apiScenarioReportMapper.updateByPrimaryKey(report); + } + } else if (StringUtils.equalsAny(runRequest.getRunMode(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setEndTime(System.currentTimeMillis()); + report.setStatus(APITestStatus.Error.name()); + String planScenarioId = report.getScenarioId(); + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(planScenarioId); + if (testPlanApiScenario != null) { + report.setScenarioId(testPlanApiScenario.getApiScenarioId()); + report.setTestPlanScenarioId(planScenarioId); + report.setEndTime(System.currentTimeMillis()); + + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + } + apiScenarioReportMapper.updateByPrimaryKeySelective(report); + } + } else { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setStatus(APITestStatus.Error.name()); + apiScenarioReportMapper.updateByPrimaryKey(report); + } + if (StringUtils.isNotEmpty(runRequest.getTestId())) { + ApiScenarioWithBLOBs scenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(runRequest.getTestId()); + if (scenarioWithBLOBs != null) { + scenarioWithBLOBs.setLastResult("Fail"); + scenarioWithBLOBs.setPassRate("0%"); + scenarioWithBLOBs.setReportId(report.getId()); + scenarioWithBLOBs.setExecuteTimes(1); + apiScenarioMapper.updateByPrimaryKey(scenarioWithBLOBs); + } + } + } + MessageCache.batchTestCases.remove(reportId); + MessageCache.executionQueue.remove(reportId); + } + } + + public void remakeScenario(String runMode, String testId, RunModeConfig config, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiScenarioReport report) { + if (MessageCache.cache.get(config.getAmassReport()) != null + && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { + MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(report.getId()); + } + // 生成失败报告 + if (StringUtils.equalsAny(runMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCENARIO_PLAN.name())) { + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testId); + if (testPlanApiScenario != null) { + report.setScenarioId(scenarioWithBLOBs.getId()); + report.setTestPlanScenarioId(testId); + report.setEndTime(System.currentTimeMillis()); + + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + } + } else { + scenarioWithBLOBs.setLastResult("Fail"); + scenarioWithBLOBs.setPassRate("0%"); + scenarioWithBLOBs.setReportId(report.getId()); + scenarioWithBLOBs.setExecuteTimes(1); + apiScenarioMapper.updateByPrimaryKey(scenarioWithBLOBs); + } + report.setStatus(APITestStatus.Error.name()); + apiScenarioReportMapper.insert(report); + MessageCache.batchTestCases.remove(report.getId()); + MessageCache.executionQueue.remove(report.getId()); + } } diff --git a/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java b/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java new file mode 100644 index 0000000000..9779b67790 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java @@ -0,0 +1,152 @@ +package io.metersphere.api.service; + +import io.metersphere.api.dto.RunRequest; +import io.metersphere.api.dto.automation.RunModeConfig; +import io.metersphere.api.dto.automation.ScenarioStatus; +import io.metersphere.api.jmeter.MessageCache; +import io.metersphere.base.domain.*; +import io.metersphere.base.mapper.*; +import io.metersphere.commons.constants.APITestStatus; +import io.metersphere.commons.constants.ApiRunMode; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; + +@Service +@Transactional(rollbackFor = Exception.class) +public class RemakeReportService { + @Resource + private ApiScenarioReportMapper apiScenarioReportMapper; + @Resource + private ApiScenarioMapper apiScenarioMapper; + @Resource + private ApiDefinitionExecResultMapper execResultMapper; + @Resource + private TestPlanApiCaseMapper testPlanApiCaseMapper; + @Resource + private TestCaseReviewApiCaseMapper testCaseReviewApiCaseMapper; + @Resource + private TestPlanApiScenarioMapper testPlanApiScenarioMapper; + + public void remake(RunRequest runRequest, RunModeConfig config, String reportId) { + if (MessageCache.cache.get(config.getAmassReport()) != null + && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { + MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(reportId); + } + // 重置报告状态 + if (StringUtils.isNotEmpty(reportId)) { + // 清理零时报告 + if (StringUtils.equalsAnyIgnoreCase(runRequest.getRunMode(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) { + ApiDefinitionExecResult result = execResultMapper.selectByPrimaryKey(reportId); + if (result != null) { + result.setStatus("error"); + result.setEndTime(System.currentTimeMillis()); + execResultMapper.updateByPrimaryKeySelective(result); + + TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(runRequest.getTestId()); + if (testPlanApiCase != null) { + testPlanApiCase.setStatus("error"); + testPlanApiCase.setUpdateTime(System.currentTimeMillis()); + testPlanApiCaseMapper.updateByPrimaryKeySelective(testPlanApiCase); + } + TestCaseReviewApiCase testCaseReviewApiCase = testCaseReviewApiCaseMapper.selectByPrimaryKey(runRequest.getTestId()); + if (testCaseReviewApiCase != null) { + testCaseReviewApiCase.setStatus("error"); + testCaseReviewApiCase.setUpdateTime(System.currentTimeMillis()); + testCaseReviewApiCaseMapper.updateByPrimaryKeySelective(testCaseReviewApiCase); + } + } + } else if (StringUtils.equals(runRequest.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setEndTime(System.currentTimeMillis()); + report.setStatus(APITestStatus.Error.name()); + + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); + if (testPlanApiScenario != null) { + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + + report.setTestPlanScenarioId(testPlanApiScenario.getId()); + } + apiScenarioReportMapper.updateByPrimaryKey(report); + } + } else if (StringUtils.equalsAny(runRequest.getRunMode(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setEndTime(System.currentTimeMillis()); + report.setStatus(APITestStatus.Error.name()); + String planScenarioId = report.getScenarioId(); + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(planScenarioId); + if (testPlanApiScenario != null) { + report.setScenarioId(testPlanApiScenario.getApiScenarioId()); + report.setTestPlanScenarioId(planScenarioId); + report.setEndTime(System.currentTimeMillis()); + + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + } + apiScenarioReportMapper.updateByPrimaryKeySelective(report); + } + } else { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId); + if (report != null) { + report.setStatus(APITestStatus.Error.name()); + apiScenarioReportMapper.updateByPrimaryKey(report); + } + if (StringUtils.isNotEmpty(runRequest.getTestId())) { + ApiScenarioWithBLOBs scenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(runRequest.getTestId()); + if (scenarioWithBLOBs != null) { + scenarioWithBLOBs.setLastResult("Fail"); + scenarioWithBLOBs.setPassRate("0%"); + scenarioWithBLOBs.setReportId(report.getId()); + scenarioWithBLOBs.setExecuteTimes(1); + apiScenarioMapper.updateByPrimaryKey(scenarioWithBLOBs); + } + } + } + MessageCache.batchTestCases.remove(reportId); + MessageCache.executionQueue.remove(reportId); + } + } + + public void remakeScenario(String runMode, String testId, RunModeConfig config, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiScenarioReport report) { + if (MessageCache.cache.get(config.getAmassReport()) != null + && MessageCache.cache.get(config.getAmassReport()).getReportIds() != null) { + MessageCache.cache.get(config.getAmassReport()).getReportIds().remove(report.getId()); + } + // 生成失败报告 + if (StringUtils.equalsAny(runMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCENARIO_PLAN.name())) { + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testId); + if (testPlanApiScenario != null) { + report.setScenarioId(scenarioWithBLOBs.getId()); + report.setTestPlanScenarioId(testId); + report.setEndTime(System.currentTimeMillis()); + + testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); + testPlanApiScenario.setPassRate("0%"); + testPlanApiScenario.setReportId(report.getId()); + testPlanApiScenario.setUpdateTime(report.getCreateTime()); + testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + } + } else { + scenarioWithBLOBs.setLastResult("Fail"); + scenarioWithBLOBs.setPassRate("0%"); + scenarioWithBLOBs.setReportId(report.getId()); + scenarioWithBLOBs.setExecuteTimes(1); + apiScenarioMapper.updateByPrimaryKey(scenarioWithBLOBs); + } + report.setStatus(APITestStatus.Error.name()); + apiScenarioReportMapper.insert(report); + MessageCache.batchTestCases.remove(report.getId()); + MessageCache.executionQueue.remove(report.getId()); + } +} diff --git a/backend/src/main/java/io/metersphere/commons/constants/ReportTriggerMode.java b/backend/src/main/java/io/metersphere/commons/constants/ReportTriggerMode.java index d417e4a393..2f393233d6 100644 --- a/backend/src/main/java/io/metersphere/commons/constants/ReportTriggerMode.java +++ b/backend/src/main/java/io/metersphere/commons/constants/ReportTriggerMode.java @@ -10,4 +10,5 @@ public enum ReportTriggerMode { CASE, TEST_PLAN_SCHEDULE, TEST_PLAN_API, + API_PLAN } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java index 769131c848..7b11181844 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java @@ -9,6 +9,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.api.dto.JvmInfoDTO; import io.metersphere.api.dto.RunModeDataDTO; +import io.metersphere.api.dto.RunRequest; import io.metersphere.api.dto.automation.TestPlanFailureApiDTO; import io.metersphere.api.dto.definition.ApiTestCaseDTO; import io.metersphere.api.dto.definition.ApiTestCaseRequest; @@ -27,6 +28,7 @@ import io.metersphere.api.jmeter.MessageCache; import io.metersphere.api.jmeter.ResourcePoolCalculation; import io.metersphere.api.service.ApiDefinitionExecResultService; import io.metersphere.api.service.ApiTestCaseService; +import io.metersphere.api.service.RemakeReportService; import io.metersphere.api.service.task.NamedThreadFactory; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; @@ -94,6 +96,8 @@ public class TestPlanApiCaseService { private TestPlanService testPlanService; @Resource private TestResourcePoolMapper testResourcePoolMapper; + @Resource + private RemakeReportService remakeReportService; public TestPlanApiCase getInfo(String caseId, String testPlanId) { TestPlanApiCaseExample example = new TestPlanApiCaseExample(); @@ -397,6 +401,9 @@ public class TestPlanApiCaseService { List planApiCases = testPlanApiCaseMapper.selectByExample(example); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class); + if (StringUtils.isEmpty(request.getTriggerMode())) { + request.setTriggerMode(ApiRunMode.API_PLAN.name()); + } // 资源池 if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) { TestResourcePool pool = testResourcePoolMapper.selectByPrimaryKey(request.getConfig().getResourcePoolId()); @@ -432,18 +439,27 @@ public class TestPlanApiCaseService { ApiDefinitionExecResult execResult = executeQueue.get(testPlanApiCase); execResult.setId(executeQueue.get(testPlanApiCase).getId()); execResult.setStatus(APITestStatus.Running.name()); - mapper.updateByPrimaryKey(execResult); reportIds.add(execResult.getId()); RunModeDataDTO modeDataDTO; if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) { modeDataDTO = new RunModeDataDTO(testPlanApiCase.getId(), UUID.randomUUID().toString()); } else { // 生成报告和HashTree - HashTree hashTree = generateHashTree(testPlanApiCase.getId()); - modeDataDTO = new RunModeDataDTO(hashTree, UUID.randomUUID().toString()); + try { + HashTree hashTree = generateHashTree(testPlanApiCase.getId()); + modeDataDTO = new RunModeDataDTO(hashTree, UUID.randomUUID().toString()); + } catch (Exception e) { + RunRequest runRequest = new RunRequest(); + runRequest.setTestId(testPlanApiCase.getId()); + runRequest.setRunMode(request.getTriggerMode()); + remakeReportService.remake(runRequest, request.getConfig(), execResult.getId()); + reportIds.remove(executeQueue.get(testPlanApiCase).getId()); + continue; + } } + mapper.updateByPrimaryKey(execResult); modeDataDTO.setApiCaseId(execResult.getId()); - Future future = executorService.submit(new SerialApiExecTask(jMeterService, mapper, modeDataDTO, request.getConfig(), ApiRunMode.API_PLAN.name())); + Future future = executorService.submit(new SerialApiExecTask(jMeterService, mapper, modeDataDTO, request.getConfig(), request.getTriggerMode())); ApiDefinitionExecResult report = future.get(); // 如果开启失败结束执行,则判断返回结果状态 if (request.getConfig().isOnSampleError()) { @@ -463,6 +479,7 @@ public class TestPlanApiCaseService { List removeList = executeQueue.entrySet().stream() .filter(map -> !reportIds.contains(map.getValue().getId())) .map(map -> map.getValue().getId()).collect(Collectors.toList()); + ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample(); example.createCriteria().andIdIn(removeList); mapper.deleteByExample(example); @@ -487,10 +504,10 @@ public class TestPlanApiCaseService { // 开始并发执行 for (String reportId : executeQueue.keySet()) { if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) { - jMeterService.runTest(executeQueue.get(reportId).getId(), reportId, ApiRunMode.API_PLAN.name(), null, request.getConfig()); + jMeterService.runTest(executeQueue.get(reportId).getId(), reportId, request.getTriggerMode(), null, request.getConfig()); } else { HashTree hashTree = generateHashTree(executeQueue.get(reportId).getId()); - jMeterService.runLocal(reportId, hashTree, TriggerMode.BATCH.name(), ApiRunMode.API_PLAN.name()); + jMeterService.runLocal(reportId, hashTree, TriggerMode.BATCH.name(), request.getTriggerMode()); } } }