diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index b68ef841ed..6d4d1bdd37 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -326,7 +326,7 @@ public class ApiAutomationController { @GetMapping(value = "/stop/{reportId}") public void stop(@PathVariable String reportId) { if (StringUtils.isNotEmpty(reportId)) { - MessageCache.batchTestCases.remove(reportId); + MessageCache.caseExecResourceLock.remove(reportId); new LocalRunner().stop(reportId); } } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 837953783f..614e94478d 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -17,9 +17,10 @@ import java.util.List; public class APIBackendListenerClient extends AbstractBackendListenerClient implements Serializable { public final static String TEST_ID = "ms.test.id"; + public final static String AMASS_REPORT = "ms.test.amass.report.id"; public String runMode = ApiRunMode.RUN.name(); - + private String amassReport; private final List queue = new ArrayList<>(); // 测试ID @@ -42,7 +43,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl public void teardownTest(BackendListenerContext context) throws Exception { APIBackendListenerHandler apiBackendListenerHandler = CommonBeanFactory.getBean(APIBackendListenerHandler.class); - apiBackendListenerHandler.handleTeardownTest(queue, this.runMode, this.testId, this.debugReportId); + apiBackendListenerHandler.handleTeardownTest(queue, this.runMode, this.testId, this.debugReportId, this.amassReport); super.teardownTest(context); } @@ -50,6 +51,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl this.testId = context.getParameter(APIBackendListenerClient.TEST_ID); this.runMode = context.getParameter("runMode"); this.debugReportId = context.getParameter("debugReportId"); + this.amassReport = context.getParameter(AMASS_REPORT); if (StringUtils.isBlank(this.runMode)) { this.runMode = ApiRunMode.RUN.name(); } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerHandler.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerHandler.java index ef8279d382..50af871e8f 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerHandler.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerHandler.java @@ -2,13 +2,10 @@ package io.metersphere.api.jmeter; import io.metersphere.api.dto.RunningParamKeys; -import io.metersphere.api.service.ApiEnvironmentRunningParamService; import io.metersphere.api.service.MsResultService; import io.metersphere.api.service.TestResultService; import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.samplers.SampleResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,15 +23,12 @@ public class APIBackendListenerHandler { @Resource private TestResultService testResultService; @Resource - private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService; - @Resource private MsResultService resultService; - Logger testPlanLog = LoggerFactory.getLogger("testPlanExecuteLog"); - - public void handleTeardownTest(List queue, String runMode, String testId, String debugReportId) throws Exception { + public void handleTeardownTest(List queue, String runMode, String testId, String debugReportId, String amassReport) throws Exception { TestResult testResult = new TestResult(); testResult.setTestId(testId); + testResult.setSetReportId(amassReport); MessageCache.runningEngine.remove(testId); testResult.setTotal(0); List enviromentList = new ArrayList<>(); @@ -60,7 +54,7 @@ public class APIBackendListenerHandler { if (!MessageCache.reportCache.containsKey(testId) && resultService.getProcessCache().containsKey(testId)) { resultService.getProcessCache().remove(testId); } - if(StringUtils.isNotEmpty(testId)) { + if (StringUtils.isNotEmpty(testId)) { MessageCache.executionQueue.remove(testId); } } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java b/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java index b29b807434..f673db05ce 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java @@ -18,6 +18,12 @@ public class FixedTask { @Scheduled(cron = "*/6 * * * * ?") public void execute() { + if (MessageCache.caseExecResourceLock.size() > 10000) { + MessageCache.caseExecResourceLock.clear(); + } + if (MessageCache.scenarioExecResourceLock.size() > 5000) { + MessageCache.scenarioExecResourceLock.clear(); + } if (scenarioReportService == null) { scenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class); } @@ -26,7 +32,7 @@ public class FixedTask { ReportCounter counter = MessageCache.cache.get(key); LogUtil.info("集成报告:【" + key + "】总执行场景:【" + counter.getReportIds().size() + "】已经执行完成场景:【" + counter.getNumber() + "】"); // 合并 - if (counter.getNumber() == counter.getReportIds().size()) { + if (counter.getNumber() >= counter.getReportIds().size()) { scenarioReportService.margeReport(key, counter.getReportIds()); guardTask.remove(key); MessageCache.cache.remove(key); @@ -34,7 +40,7 @@ public class FixedTask { try { if (guardTask.containsKey(key)) { int number = guardTask.get(key); - number +=1; + number += 1; guardTask.put(key, number); } else { guardTask.put(key, 0); 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 caf1edbd97..b37469156f 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java @@ -73,7 +73,7 @@ public class JMeterService { HashTree testPlan = getHashTree(scriptWrapper); JMeterVars.addJSR223PostProcessor(testPlan); String runMode = StringUtils.isBlank(debugReportId) ? ApiRunMode.RUN.name() : ApiRunMode.DEBUG.name(); - addBackendListener(testId, debugReportId, runMode, testPlan); + addBackendListener(testId, null, debugReportId, runMode, testPlan); LocalRunner runner = new LocalRunner(testPlan); runner.run(testId); } catch (Exception e) { @@ -102,11 +102,14 @@ public class JMeterService { return (HashTree) field.get(scriptWrapper); } - private void addBackendListener(String testId, String debugReportId, String runMode, HashTree testPlan) { + private void addBackendListener(String testId, String amassReport, String debugReportId, String runMode, HashTree testPlan) { BackendListener backendListener = new BackendListener(); backendListener.setName(testId); Arguments arguments = new Arguments(); arguments.addArgument(APIBackendListenerClient.TEST_ID, testId); + if (StringUtils.isNotEmpty(amassReport)) { + arguments.addArgument(APIBackendListenerClient.AMASS_REPORT, amassReport); + } if (StringUtils.isNotBlank(runMode)) { arguments.addArgument("runMode", runMode); } @@ -128,10 +131,10 @@ public class JMeterService { } - public void runLocal(String testId, HashTree testPlan, String debugReportId, String runMode) { + public void runLocal(String testId, RunModeConfig config, HashTree testPlan, String debugReportId, String runMode) { init(); FixedTask.tasks.put(testId, System.currentTimeMillis()); - addBackendListener(testId, debugReportId, runMode, testPlan); + addBackendListener(testId, config != null ? config.getAmassReport() : "", debugReportId, runMode, testPlan); if (ExecuteType.Debug.name().equals(debugReportId) || (ApiRunMode.SCENARIO.name().equals(runMode) && !TriggerMode.BATCH.name().equals(debugReportId))) { addResultCollector(testId, testPlan); } @@ -192,7 +195,7 @@ 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 remakeReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class); + RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); remakeReportService.remake(runRequest, config, reportId); } } catch (Exception e) { diff --git a/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java b/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java index 47bd821598..ccaa206a6b 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java @@ -1,5 +1,6 @@ package io.metersphere.api.jmeter; +import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.base.domain.ApiDefinitionExecResult; import org.apache.jmeter.engine.StandardJMeterEngine; @@ -17,10 +18,13 @@ public class MessageCache { public static ConcurrentHashMap runningEngine = new ConcurrentHashMap<>(); public static ConcurrentLinkedDeque terminationOrderDeque = new ConcurrentLinkedDeque<>(); - - public static ConcurrentHashMap batchTestCases = new ConcurrentHashMap<>(); + // 用例并发锁 + public static ConcurrentHashMap caseExecResourceLock = new ConcurrentHashMap<>(); + // 场景并发锁 + public static ConcurrentHashMap scenarioExecResourceLock = new ConcurrentHashMap<>(); // 串行执行队列 KEY=报告ID VALUE=开始时间 public static Map executionQueue = new HashMap<>(); + } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java index 96e9c8ea76..6b5a75fd95 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -14,6 +14,8 @@ public class TestResult { private String testId; + private String setReportId; + private int scenarioTotal; private int scenarioSuccess; 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 a9e6eb6085..5af3e359e3 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -1304,6 +1304,9 @@ public class ApiAutomationService { hashTreeUtil.setEnvParamsMapToHashTree(hashTree, executeEnvParams); executeQueue.get(key).setHashTree(hashTree); } + if (request.getConfig() != null && StringUtils.isNotEmpty(serialReportId)) { + request.getConfig().setAmassReport(serialReportId); + } Future future = executorService.submit(new SerialScenarioExecTask(jMeterService, apiScenarioReportMapper, executeQueue.get(key), request)); future.get(); // 如果开启失败结束执行,则判断返回结果状态 @@ -1365,8 +1368,11 @@ public class ApiAutomationService { //存储报告 APIScenarioReportResult report = executeQueue.get(reportId).getReport(); batchMapper.insert(report); + // 增加一个本地锁,防止并发找不到资源 + MessageCache.scenarioExecResourceLock.put(reportId,report); } sqlSession.flushStatements(); + sqlSession.commit(); } }); thread.start(); @@ -1381,7 +1387,7 @@ public class ApiAutomationService { } jMeterService.runTest(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig()); } else { - jMeterService.runLocal(reportId, executeQueue.get(reportId).getHashTree(), + jMeterService.runLocal(reportId, request.getConfig(), executeQueue.get(reportId).getHashTree(), TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode()); } } @@ -1590,7 +1596,7 @@ public class ApiAutomationService { List reportIds = new LinkedList<>(); try { HashTree hashTree = generateHashTree(apiScenarios, request, reportIds); - jMeterService.runLocal(reportIds.size() == 1 ? reportIds.get(0) : JSON.toJSONString(reportIds), hashTree, request.getReportId(), runMode); + jMeterService.runLocal(reportIds.size() == 1 ? reportIds.get(0) : JSON.toJSONString(reportIds), request.getConfig(), hashTree, request.getReportId(), runMode); Map scenarioReportIdMap = new HashMap<>(); for (String id : ids) { @@ -1666,7 +1672,7 @@ public class ApiAutomationService { FileUtils.createBodyFiles(request.getScenarioFileIds(), scenarioFiles); // 调用执行方法 - jMeterService.runLocal(request.getId(), hashTree, request.getExecuteType(), ApiRunMode.SCENARIO.name()); + jMeterService.runLocal(request.getId(), request.getConfig(), hashTree, request.getExecuteType(), ApiRunMode.SCENARIO.name()); return request.getId(); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java index 0aecdff590..72d655e79d 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java @@ -71,7 +71,7 @@ public class ApiDefinitionExecResultService { if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) { scenarioResult.getRequestResults().forEach(item -> { if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) { - ApiDefinitionExecResult saveResult = MessageCache.batchTestCases.get(result.getTestId()); + ApiDefinitionExecResult saveResult = MessageCache.caseExecResourceLock.get(result.getTestId()); if (saveResult == null) { saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(result.getTestId()); } @@ -125,7 +125,7 @@ public class ApiDefinitionExecResultService { } apiDefinitionService.removeCache(result.getTestId()); if (StringUtils.isNotEmpty(result.getTestId())) { - MessageCache.batchTestCases.remove(result.getTestId()); + MessageCache.caseExecResourceLock.remove(result.getTestId()); } // 发送通知 sendNotice(saveResult); 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 7fc86b6da6..75b96904f3 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -901,7 +901,7 @@ public class ApiDefinitionService { if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) { jMeterService.runTest(request.getId(), request.getId(), runMode, null, request.getConfig()); } else { - jMeterService.runLocal(request.getId(), hashTree, request.getReportId(), runMode); + jMeterService.runLocal(request.getId(),request.getConfig(), hashTree, request.getReportId(), runMode); } return request.getId(); } 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 b9538ec282..d9027c1884 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -7,10 +7,12 @@ 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.*; +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.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; @@ -82,12 +84,6 @@ 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) { // 更新场景 @@ -160,8 +156,10 @@ public class ApiScenarioReportService { public ApiScenarioReport editReport(ScenarioResult test, long startTime) { ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(test.getName()); + if (report == null) { + report = MessageCache.scenarioExecResourceLock.get(test.getName()); + } if (report != null) { - report.setId(report.getId()); report.setName(report.getScenarioName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); report.setEndTime(System.currentTimeMillis()); report.setUpdateTime(startTime); @@ -170,6 +168,7 @@ public class ApiScenarioReportService { if (StringUtils.isNotEmpty(report.getTriggerMode()) && report.getTriggerMode().equals("CASE")) { report.setTriggerMode(TriggerMode.MANUAL.name()); } + MessageCache.scenarioExecResourceLock.remove(report.getId()); apiScenarioReportMapper.updateByPrimaryKeySelective(report); } return report; @@ -534,25 +533,30 @@ public class ApiScenarioReportService { } private void counter(TestResult result) { - if (CollectionUtils.isEmpty(result.getScenarios())) { - if (StringUtils.isNotEmpty(result.getTestId())) { - List list = new LinkedList<>(); - try { - list = JSON.parseObject(result.getTestId(), List.class); - } catch (Exception e) { - list.add(result.getTestId()); - } - ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample(); - scenarioReportExample.createCriteria().andIdIn(list); - List reportList = apiScenarioReportMapper.selectByExample(scenarioReportExample); - for (ApiScenarioReport report : reportList) { - if (report.getExecuteType().equals(ExecuteType.Marge.name())) { - Object obj = MessageCache.cache.get(report.getScenarioId()); - if (obj != null) { - ReportCounter counter = (ReportCounter) obj; - counter.setNumber(counter.getNumber() + 1); - MessageCache.cache.put(report.getScenarioId(), counter); - } + if (CollectionUtils.isEmpty(result.getScenarios()) && StringUtils.isNotEmpty(result.getTestId())) { + List list = new LinkedList<>(); + try { + list = JSON.parseObject(result.getTestId(), List.class); + } catch (Exception e) { + list.add(result.getTestId()); + } + if (StringUtils.isNotEmpty(result.getSetReportId())) { + list.add(result.getSetReportId()); + } + ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample(); + scenarioReportExample.createCriteria().andScenarioIdIn(list); + List reportList = apiScenarioReportMapper.selectByExample(scenarioReportExample); + for (ApiScenarioReport report : reportList) { + report.setStatus("Error"); + apiScenarioReportMapper.updateByPrimaryKey(report); + MessageCache.scenarioExecResourceLock.remove(report.getId()); + MessageCache.executionQueue.remove(report.getId()); + if (StringUtils.equals(report.getExecuteType(), ExecuteType.Marge.name()) || StringUtils.equals(report.getScenarioId(), result.getSetReportId())) { + Object obj = MessageCache.cache.get(result.getSetReportId()); + if (obj != null) { + ReportCounter counter = (ReportCounter) obj; + counter.setNumber(counter.getNumber() + 1); + MessageCache.cache.put(result.getSetReportId(), counter); } } } @@ -560,8 +564,6 @@ public class ApiScenarioReportService { } public ApiScenarioReport updateScenario(TestResult result) { - // 针对未正常返回结果的报告计数 - counter(result); ApiScenarioReport lastReport = null; for (ScenarioResult item : result.getScenarios()) { // 更新报告状态 @@ -570,6 +572,7 @@ public class ApiScenarioReportService { startTime = item.getRequestResults().get(0).getStartTime(); } ApiScenarioReport report = editReport(item, startTime); + if (report != null) { // 合并并行报告 TestResult newResult = createTestResult(result.getTestId(), item); @@ -606,15 +609,17 @@ public class ApiScenarioReportService { lastReport = report; MessageCache.executionQueue.remove(report.getId()); if (report.getExecuteType().equals(ExecuteType.Marge.name())) { - Object obj = MessageCache.cache.get(report.getScenarioId()); + Object obj = MessageCache.cache.get(result.getSetReportId()); if (obj != null) { ReportCounter counter = (ReportCounter) obj; counter.setNumber(counter.getNumber() + 1); - MessageCache.cache.put(report.getScenarioId(), counter); + MessageCache.cache.put(result.getSetReportId(), counter); } } } } + // 针对未正常返回结果的报告计数 + counter(result); return lastReport; } @@ -871,124 +876,4 @@ 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/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index dd32f7589b..cc90571afd 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -795,7 +795,7 @@ public class ApiTestCaseService { sqlSession.commit(); for (RunCaseRequest runCaseRequest : executeQueue) { - MessageCache.batchTestCases.put(runCaseRequest.getReportId(), runCaseRequest.getReport()); + MessageCache.caseExecResourceLock.put(runCaseRequest.getReportId(), runCaseRequest.getReport()); run(runCaseRequest); } } @@ -816,16 +816,16 @@ public class ApiTestCaseService { try { HashTree jmeterHashTree = this.generateHashTree(request, testCaseWithBLOBs); // 调用执行方法 - jMeterService.runLocal(request.getReportId(), jmeterHashTree, null, request.getRunMode()); + jMeterService.runLocal(request.getReportId(),null, jmeterHashTree, null, request.getRunMode()); } catch (Exception ex) { - ApiDefinitionExecResult result = MessageCache.batchTestCases.get(request.getReportId()); + ApiDefinitionExecResult result = MessageCache.caseExecResourceLock.get(request.getReportId()); result.setStatus("error"); apiDefinitionExecResultMapper.updateByPrimaryKey(result); ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId()); caseWithBLOBs.setStatus("error"); apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs); - MessageCache.batchTestCases.remove(request.getReportId()); + MessageCache.caseExecResourceLock.remove(request.getReportId()); LogUtil.error(ex.getMessage(), ex); } } @@ -842,7 +842,7 @@ public class ApiTestCaseService { request.setTestPlanId(testPlanID); HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs); // 调用执行方法 - jMeterService.runLocal(id, jmeterHashTree, debugReportId, runMode); + jMeterService.runLocal(id,null, jmeterHashTree, debugReportId, runMode); } catch (Exception ex) { LogUtil.error(ex); } diff --git a/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java b/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java index 9779b67790..4291c5e2b6 100644 --- a/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/RemakeReportService.java @@ -113,7 +113,8 @@ public class RemakeReportService { } } } - MessageCache.batchTestCases.remove(reportId); + MessageCache.caseExecResourceLock.remove(reportId); + MessageCache.scenarioExecResourceLock.remove(reportId); MessageCache.executionQueue.remove(reportId); } } @@ -146,7 +147,8 @@ public class RemakeReportService { } report.setStatus(APITestStatus.Error.name()); apiScenarioReportMapper.insert(report); - MessageCache.batchTestCases.remove(report.getId()); + MessageCache.caseExecResourceLock.remove(report.getId()); + MessageCache.scenarioExecResourceLock.remove(report.getId()); MessageCache.executionQueue.remove(report.getId()); } } diff --git a/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java b/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java index 99c95ae55f..ada44c6a6f 100644 --- a/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java +++ b/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java @@ -53,7 +53,7 @@ public class SerialScenarioExecTask implements Callable { jMeterService.runTest(runModeDataDTO.getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig()); } else { reportId = runModeDataDTO.getReport().getId(); - jMeterService.runLocal(runModeDataDTO.getReport().getId(), runModeDataDTO.getHashTree(), TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode()); + jMeterService.runLocal(runModeDataDTO.getReport().getId(),request.getConfig(), runModeDataDTO.getHashTree(), TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode()); } while (MessageCache.executionQueue.containsKey(reportId)) { long time = MessageCache.executionQueue.get(runModeDataDTO.getReport().getId()); @@ -68,8 +68,8 @@ public class SerialScenarioExecTask implements Callable { } break; } - if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { - MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId()); + if (MessageCache.terminationOrderDeque.contains(reportId)) { + MessageCache.terminationOrderDeque.remove(reportId); break; } Thread.sleep(1000); diff --git a/backend/src/main/java/io/metersphere/service/CustomFunctionService.java b/backend/src/main/java/io/metersphere/service/CustomFunctionService.java index 1ad145e32d..200d442842 100644 --- a/backend/src/main/java/io/metersphere/service/CustomFunctionService.java +++ b/backend/src/main/java/io/metersphere/service/CustomFunctionService.java @@ -121,7 +121,7 @@ public class CustomFunctionService { config.setProjectId(request.getProjectId()); HashTree hashTree = request.getTestElement().generateHashTree(config); String runMode = ApiRunMode.DEFINITION.name(); - jMeterService.runLocal(request.getId(), hashTree, request.getReportId(), runMode); + jMeterService.runLocal(request.getId(),request.getConfig(), hashTree, request.getReportId(), runMode); return request.getId(); } } diff --git a/backend/src/main/java/io/metersphere/task/service/TaskService.java b/backend/src/main/java/io/metersphere/task/service/TaskService.java index bbe9fe2bb8..21ad736d0f 100644 --- a/backend/src/main/java/io/metersphere/task/service/TaskService.java +++ b/backend/src/main/java/io/metersphere/task/service/TaskService.java @@ -108,7 +108,7 @@ public class TaskService { result.setStatus("STOP"); apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result); actuator = result.getActuator(); - MessageCache.batchTestCases.remove(result.getId()); + MessageCache.caseExecResourceLock.remove(result.getId()); } } else if (StringUtils.equals(request.getType(), "SCENARIO")) { ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId()); 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 7b11181844..5ecf963e94 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java @@ -497,7 +497,7 @@ public class TestPlanApiCaseService { planApiCases.forEach(testPlanApiCase -> { ApiDefinitionExecResult report = addResult(request, testPlanApiCase, APITestStatus.Running.name(), batchMapper); executeQueue.put(report.getId(), testPlanApiCase); - MessageCache.batchTestCases.put(report.getId(), report); + MessageCache.caseExecResourceLock.put(report.getId(), report); }); sqlSession.commit(); @@ -507,7 +507,7 @@ public class TestPlanApiCaseService { 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(), request.getTriggerMode()); + jMeterService.runLocal(reportId,request.getConfig(), hashTree, TriggerMode.BATCH.name(), request.getTriggerMode()); } } } 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 b81369d17f..ed9c18a195 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -993,7 +993,7 @@ public class TestPlanService { testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig()); String runMode = ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(); // 调用执行方法 - jMeterService.runLocal(request.getId(), jmeterHashTree, request.getReportId(), runMode); + jMeterService.runLocal(request.getId(),request.getConfig(), jmeterHashTree, request.getReportId(), runMode); } return returnId; diff --git a/backend/src/main/java/io/metersphere/track/service/task/SerialApiExecTask.java b/backend/src/main/java/io/metersphere/track/service/task/SerialApiExecTask.java index f78bb3c1eb..2e4176c598 100644 --- a/backend/src/main/java/io/metersphere/track/service/task/SerialApiExecTask.java +++ b/backend/src/main/java/io/metersphere/track/service/task/SerialApiExecTask.java @@ -34,14 +34,14 @@ public class SerialApiExecTask implements Callable { @Override public T call() { try { - if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { + if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId()); return null; } if (config != null && StringUtils.isNotBlank(config.getResourcePoolId())) { jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getApiCaseId(), runMode, null, config); } else { - jMeterService.runLocal(runModeDataDTO.getApiCaseId(), runModeDataDTO.getHashTree(), runModeDataDTO.getReport() != null ? runModeDataDTO.getReport().getTriggerMode() : null, runMode); + jMeterService.runLocal(runModeDataDTO.getApiCaseId(), config, runModeDataDTO.getHashTree(), runModeDataDTO.getReport() != null ? runModeDataDTO.getReport().getTriggerMode() : null, runMode); } // 轮询查看报告状态,最多200次,防止死循环 ApiDefinitionExecResult report = null; @@ -53,7 +53,7 @@ public class SerialApiExecTask implements Callable { if (report != null && !report.getStatus().equals(APITestStatus.Running.name())) { break; } - if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { + if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId()); break; }