fix(接口定义): 修复并发执行事务锁失效问题;修复并发执行集成报告问题。

This commit is contained in:
fit2-zhao 2021-11-09 12:28:35 +08:00 committed by fit2-zhao
parent a8c5505a0d
commit 5187bdf4a3
19 changed files with 101 additions and 197 deletions

View File

@ -326,7 +326,7 @@ public class ApiAutomationController {
@GetMapping(value = "/stop/{reportId}") @GetMapping(value = "/stop/{reportId}")
public void stop(@PathVariable String reportId) { public void stop(@PathVariable String reportId) {
if (StringUtils.isNotEmpty(reportId)) { if (StringUtils.isNotEmpty(reportId)) {
MessageCache.batchTestCases.remove(reportId); MessageCache.caseExecResourceLock.remove(reportId);
new LocalRunner().stop(reportId); new LocalRunner().stop(reportId);
} }
} }

View File

@ -17,9 +17,10 @@ import java.util.List;
public class APIBackendListenerClient extends AbstractBackendListenerClient implements Serializable { public class APIBackendListenerClient extends AbstractBackendListenerClient implements Serializable {
public final static String TEST_ID = "ms.test.id"; 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(); public String runMode = ApiRunMode.RUN.name();
private String amassReport;
private final List<SampleResult> queue = new ArrayList<>(); private final List<SampleResult> queue = new ArrayList<>();
// 测试ID // 测试ID
@ -42,7 +43,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
public void teardownTest(BackendListenerContext context) throws Exception { public void teardownTest(BackendListenerContext context) throws Exception {
APIBackendListenerHandler apiBackendListenerHandler = APIBackendListenerHandler apiBackendListenerHandler =
CommonBeanFactory.getBean(APIBackendListenerHandler.class); 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); super.teardownTest(context);
} }
@ -50,6 +51,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
this.testId = context.getParameter(APIBackendListenerClient.TEST_ID); this.testId = context.getParameter(APIBackendListenerClient.TEST_ID);
this.runMode = context.getParameter("runMode"); this.runMode = context.getParameter("runMode");
this.debugReportId = context.getParameter("debugReportId"); this.debugReportId = context.getParameter("debugReportId");
this.amassReport = context.getParameter(AMASS_REPORT);
if (StringUtils.isBlank(this.runMode)) { if (StringUtils.isBlank(this.runMode)) {
this.runMode = ApiRunMode.RUN.name(); this.runMode = ApiRunMode.RUN.name();
} }

View File

@ -2,13 +2,10 @@ package io.metersphere.api.jmeter;
import io.metersphere.api.dto.RunningParamKeys; import io.metersphere.api.dto.RunningParamKeys;
import io.metersphere.api.service.ApiEnvironmentRunningParamService;
import io.metersphere.api.service.MsResultService; import io.metersphere.api.service.MsResultService;
import io.metersphere.api.service.TestResultService; import io.metersphere.api.service.TestResultService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.samplers.SampleResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -26,15 +23,12 @@ public class APIBackendListenerHandler {
@Resource @Resource
private TestResultService testResultService; private TestResultService testResultService;
@Resource @Resource
private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService;
@Resource
private MsResultService resultService; private MsResultService resultService;
Logger testPlanLog = LoggerFactory.getLogger("testPlanExecuteLog"); public void handleTeardownTest(List<SampleResult> queue, String runMode, String testId, String debugReportId, String amassReport) throws Exception {
public void handleTeardownTest(List<SampleResult> queue, String runMode, String testId, String debugReportId) throws Exception {
TestResult testResult = new TestResult(); TestResult testResult = new TestResult();
testResult.setTestId(testId); testResult.setTestId(testId);
testResult.setSetReportId(amassReport);
MessageCache.runningEngine.remove(testId); MessageCache.runningEngine.remove(testId);
testResult.setTotal(0); testResult.setTotal(0);
List<String> enviromentList = new ArrayList<>(); List<String> enviromentList = new ArrayList<>();
@ -60,7 +54,7 @@ public class APIBackendListenerHandler {
if (!MessageCache.reportCache.containsKey(testId) && resultService.getProcessCache().containsKey(testId)) { if (!MessageCache.reportCache.containsKey(testId) && resultService.getProcessCache().containsKey(testId)) {
resultService.getProcessCache().remove(testId); resultService.getProcessCache().remove(testId);
} }
if(StringUtils.isNotEmpty(testId)) { if (StringUtils.isNotEmpty(testId)) {
MessageCache.executionQueue.remove(testId); MessageCache.executionQueue.remove(testId);
} }
} }

View File

@ -18,6 +18,12 @@ public class FixedTask {
@Scheduled(cron = "*/6 * * * * ?") @Scheduled(cron = "*/6 * * * * ?")
public void execute() { public void execute() {
if (MessageCache.caseExecResourceLock.size() > 10000) {
MessageCache.caseExecResourceLock.clear();
}
if (MessageCache.scenarioExecResourceLock.size() > 5000) {
MessageCache.scenarioExecResourceLock.clear();
}
if (scenarioReportService == null) { if (scenarioReportService == null) {
scenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class); scenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
} }
@ -26,7 +32,7 @@ public class FixedTask {
ReportCounter counter = MessageCache.cache.get(key); ReportCounter counter = MessageCache.cache.get(key);
LogUtil.info("集成报告:【" + key + "】总执行场景:【" + counter.getReportIds().size() + "】已经执行完成场景:【" + counter.getNumber() + ""); 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()); scenarioReportService.margeReport(key, counter.getReportIds());
guardTask.remove(key); guardTask.remove(key);
MessageCache.cache.remove(key); MessageCache.cache.remove(key);
@ -34,7 +40,7 @@ public class FixedTask {
try { try {
if (guardTask.containsKey(key)) { if (guardTask.containsKey(key)) {
int number = guardTask.get(key); int number = guardTask.get(key);
number +=1; number += 1;
guardTask.put(key, number); guardTask.put(key, number);
} else { } else {
guardTask.put(key, 0); guardTask.put(key, 0);

View File

@ -73,7 +73,7 @@ public class JMeterService {
HashTree testPlan = getHashTree(scriptWrapper); HashTree testPlan = getHashTree(scriptWrapper);
JMeterVars.addJSR223PostProcessor(testPlan); JMeterVars.addJSR223PostProcessor(testPlan);
String runMode = StringUtils.isBlank(debugReportId) ? ApiRunMode.RUN.name() : ApiRunMode.DEBUG.name(); 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); LocalRunner runner = new LocalRunner(testPlan);
runner.run(testId); runner.run(testId);
} catch (Exception e) { } catch (Exception e) {
@ -102,11 +102,14 @@ public class JMeterService {
return (HashTree) field.get(scriptWrapper); 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 backendListener = new BackendListener();
backendListener.setName(testId); backendListener.setName(testId);
Arguments arguments = new Arguments(); Arguments arguments = new Arguments();
arguments.addArgument(APIBackendListenerClient.TEST_ID, testId); arguments.addArgument(APIBackendListenerClient.TEST_ID, testId);
if (StringUtils.isNotEmpty(amassReport)) {
arguments.addArgument(APIBackendListenerClient.AMASS_REPORT, amassReport);
}
if (StringUtils.isNotBlank(runMode)) { if (StringUtils.isNotBlank(runMode)) {
arguments.addArgument("runMode", 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(); init();
FixedTask.tasks.put(testId, System.currentTimeMillis()); 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))) { if (ExecuteType.Debug.name().equals(debugReportId) || (ApiRunMode.SCENARIO.name().equals(runMode) && !TriggerMode.BATCH.name().equals(debugReportId))) {
addResultCollector(testId, testPlan); addResultCollector(testId, testPlan);
} }
@ -192,7 +195,7 @@ public class JMeterService {
String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port); String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port);
ResponseEntity<String> result = restTemplate.postForEntity(uri, runRequest, String.class); ResponseEntity<String> result = restTemplate.postForEntity(uri, runRequest, String.class);
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) { 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); remakeReportService.remake(runRequest, config, reportId);
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -1,5 +1,6 @@
package io.metersphere.api.jmeter; package io.metersphere.api.jmeter;
import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiDefinitionExecResult;
import org.apache.jmeter.engine.StandardJMeterEngine; import org.apache.jmeter.engine.StandardJMeterEngine;
@ -17,10 +18,13 @@ public class MessageCache {
public static ConcurrentHashMap<String, StandardJMeterEngine> runningEngine = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, StandardJMeterEngine> runningEngine = new ConcurrentHashMap<>();
public static ConcurrentLinkedDeque<String> terminationOrderDeque = new ConcurrentLinkedDeque<>(); public static ConcurrentLinkedDeque<String> terminationOrderDeque = new ConcurrentLinkedDeque<>();
// 用例并发锁
public static ConcurrentHashMap<String, ApiDefinitionExecResult> batchTestCases = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, ApiDefinitionExecResult> caseExecResourceLock = new ConcurrentHashMap<>();
// 场景并发锁
public static ConcurrentHashMap<String, APIScenarioReportResult> scenarioExecResourceLock = new ConcurrentHashMap<>();
// 串行执行队列 KEY=报告ID VALUE=开始时间 // 串行执行队列 KEY=报告ID VALUE=开始时间
public static Map<String, Long> executionQueue = new HashMap<>(); public static Map<String, Long> executionQueue = new HashMap<>();
} }

View File

@ -14,6 +14,8 @@ public class TestResult {
private String testId; private String testId;
private String setReportId;
private int scenarioTotal; private int scenarioTotal;
private int scenarioSuccess; private int scenarioSuccess;

View File

@ -1304,6 +1304,9 @@ public class ApiAutomationService {
hashTreeUtil.setEnvParamsMapToHashTree(hashTree, executeEnvParams); hashTreeUtil.setEnvParamsMapToHashTree(hashTree, executeEnvParams);
executeQueue.get(key).setHashTree(hashTree); executeQueue.get(key).setHashTree(hashTree);
} }
if (request.getConfig() != null && StringUtils.isNotEmpty(serialReportId)) {
request.getConfig().setAmassReport(serialReportId);
}
Future<ApiScenarioReport> future = executorService.submit(new SerialScenarioExecTask(jMeterService, apiScenarioReportMapper, executeQueue.get(key), request)); Future<ApiScenarioReport> future = executorService.submit(new SerialScenarioExecTask(jMeterService, apiScenarioReportMapper, executeQueue.get(key), request));
future.get(); future.get();
// 如果开启失败结束执行则判断返回结果状态 // 如果开启失败结束执行则判断返回结果状态
@ -1365,8 +1368,11 @@ public class ApiAutomationService {
//存储报告 //存储报告
APIScenarioReportResult report = executeQueue.get(reportId).getReport(); APIScenarioReportResult report = executeQueue.get(reportId).getReport();
batchMapper.insert(report); batchMapper.insert(report);
// 增加一个本地锁防止并发找不到资源
MessageCache.scenarioExecResourceLock.put(reportId,report);
} }
sqlSession.flushStatements(); sqlSession.flushStatements();
sqlSession.commit();
} }
}); });
thread.start(); thread.start();
@ -1381,7 +1387,7 @@ public class ApiAutomationService {
} }
jMeterService.runTest(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig()); jMeterService.runTest(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig());
} else { } 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()); TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode());
} }
} }
@ -1590,7 +1596,7 @@ public class ApiAutomationService {
List<String> reportIds = new LinkedList<>(); List<String> reportIds = new LinkedList<>();
try { try {
HashTree hashTree = generateHashTree(apiScenarios, request, reportIds); 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<String, String> scenarioReportIdMap = new HashMap<>(); Map<String, String> scenarioReportIdMap = new HashMap<>();
for (String id : ids) { for (String id : ids) {
@ -1666,7 +1672,7 @@ public class ApiAutomationService {
FileUtils.createBodyFiles(request.getScenarioFileIds(), scenarioFiles); 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(); return request.getId();
} }

View File

@ -71,7 +71,7 @@ public class ApiDefinitionExecResultService {
if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) { if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) {
scenarioResult.getRequestResults().forEach(item -> { scenarioResult.getRequestResults().forEach(item -> {
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) { 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) { if (saveResult == null) {
saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(result.getTestId()); saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(result.getTestId());
} }
@ -125,7 +125,7 @@ public class ApiDefinitionExecResultService {
} }
apiDefinitionService.removeCache(result.getTestId()); apiDefinitionService.removeCache(result.getTestId());
if (StringUtils.isNotEmpty(result.getTestId())) { if (StringUtils.isNotEmpty(result.getTestId())) {
MessageCache.batchTestCases.remove(result.getTestId()); MessageCache.caseExecResourceLock.remove(result.getTestId());
} }
// 发送通知 // 发送通知
sendNotice(saveResult); sendNotice(saveResult);

View File

@ -901,7 +901,7 @@ public class ApiDefinitionService {
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) { if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
jMeterService.runTest(request.getId(), request.getId(), runMode, null, request.getConfig()); jMeterService.runTest(request.getId(), request.getId(), runMode, null, request.getConfig());
} else { } else {
jMeterService.runLocal(request.getId(), hashTree, request.getReportId(), runMode); jMeterService.runLocal(request.getId(),request.getConfig(), hashTree, request.getReportId(), runMode);
} }
return request.getId(); return request.getId();
} }

View File

@ -7,10 +7,12 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.cache.TestPlanReportExecuteCatch; 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.APIScenarioReportResult;
import io.metersphere.api.dto.automation.ExecuteType; 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.automation.ScenarioStatus;
import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.jmeter.MessageCache; import io.metersphere.api.jmeter.MessageCache;
@ -82,12 +84,6 @@ public class ApiScenarioReportService {
private UserService userService; private UserService userService;
@Resource @Resource
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Resource
private ApiDefinitionExecResultMapper execResultMapper;
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper;
@Resource
private TestCaseReviewApiCaseMapper testCaseReviewApiCaseMapper;
public ApiScenarioReport complete(TestResult result, String runMode) { public ApiScenarioReport complete(TestResult result, String runMode) {
// 更新场景 // 更新场景
@ -160,8 +156,10 @@ public class ApiScenarioReportService {
public ApiScenarioReport editReport(ScenarioResult test, long startTime) { public ApiScenarioReport editReport(ScenarioResult test, long startTime) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(test.getName()); ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(test.getName());
if (report == null) {
report = MessageCache.scenarioExecResourceLock.get(test.getName());
}
if (report != null) { if (report != null) {
report.setId(report.getId());
report.setName(report.getScenarioName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); report.setName(report.getScenarioName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis()));
report.setEndTime(System.currentTimeMillis()); report.setEndTime(System.currentTimeMillis());
report.setUpdateTime(startTime); report.setUpdateTime(startTime);
@ -170,6 +168,7 @@ public class ApiScenarioReportService {
if (StringUtils.isNotEmpty(report.getTriggerMode()) && report.getTriggerMode().equals("CASE")) { if (StringUtils.isNotEmpty(report.getTriggerMode()) && report.getTriggerMode().equals("CASE")) {
report.setTriggerMode(TriggerMode.MANUAL.name()); report.setTriggerMode(TriggerMode.MANUAL.name());
} }
MessageCache.scenarioExecResourceLock.remove(report.getId());
apiScenarioReportMapper.updateByPrimaryKeySelective(report); apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} }
return report; return report;
@ -534,25 +533,30 @@ public class ApiScenarioReportService {
} }
private void counter(TestResult result) { private void counter(TestResult result) {
if (CollectionUtils.isEmpty(result.getScenarios())) { if (CollectionUtils.isEmpty(result.getScenarios()) && StringUtils.isNotEmpty(result.getTestId())) {
if (StringUtils.isNotEmpty(result.getTestId())) {
List<String> list = new LinkedList<>(); List<String> list = new LinkedList<>();
try { try {
list = JSON.parseObject(result.getTestId(), List.class); list = JSON.parseObject(result.getTestId(), List.class);
} catch (Exception e) { } catch (Exception e) {
list.add(result.getTestId()); list.add(result.getTestId());
} }
if (StringUtils.isNotEmpty(result.getSetReportId())) {
list.add(result.getSetReportId());
}
ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample(); ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample();
scenarioReportExample.createCriteria().andIdIn(list); scenarioReportExample.createCriteria().andScenarioIdIn(list);
List<ApiScenarioReport> reportList = apiScenarioReportMapper.selectByExample(scenarioReportExample); List<ApiScenarioReport> reportList = apiScenarioReportMapper.selectByExample(scenarioReportExample);
for (ApiScenarioReport report : reportList) { for (ApiScenarioReport report : reportList) {
if (report.getExecuteType().equals(ExecuteType.Marge.name())) { report.setStatus("Error");
Object obj = MessageCache.cache.get(report.getScenarioId()); 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) { if (obj != null) {
ReportCounter counter = (ReportCounter) obj; ReportCounter counter = (ReportCounter) obj;
counter.setNumber(counter.getNumber() + 1); counter.setNumber(counter.getNumber() + 1);
MessageCache.cache.put(report.getScenarioId(), counter); MessageCache.cache.put(result.getSetReportId(), counter);
}
} }
} }
} }
@ -560,8 +564,6 @@ public class ApiScenarioReportService {
} }
public ApiScenarioReport updateScenario(TestResult result) { public ApiScenarioReport updateScenario(TestResult result) {
// 针对未正常返回结果的报告计数
counter(result);
ApiScenarioReport lastReport = null; ApiScenarioReport lastReport = null;
for (ScenarioResult item : result.getScenarios()) { for (ScenarioResult item : result.getScenarios()) {
// 更新报告状态 // 更新报告状态
@ -570,6 +572,7 @@ public class ApiScenarioReportService {
startTime = item.getRequestResults().get(0).getStartTime(); startTime = item.getRequestResults().get(0).getStartTime();
} }
ApiScenarioReport report = editReport(item, startTime); ApiScenarioReport report = editReport(item, startTime);
if (report != null) { if (report != null) {
// 合并并行报告 // 合并并行报告
TestResult newResult = createTestResult(result.getTestId(), item); TestResult newResult = createTestResult(result.getTestId(), item);
@ -606,15 +609,17 @@ public class ApiScenarioReportService {
lastReport = report; lastReport = report;
MessageCache.executionQueue.remove(report.getId()); MessageCache.executionQueue.remove(report.getId());
if (report.getExecuteType().equals(ExecuteType.Marge.name())) { if (report.getExecuteType().equals(ExecuteType.Marge.name())) {
Object obj = MessageCache.cache.get(report.getScenarioId()); Object obj = MessageCache.cache.get(result.getSetReportId());
if (obj != null) { if (obj != null) {
ReportCounter counter = (ReportCounter) obj; ReportCounter counter = (ReportCounter) obj;
counter.setNumber(counter.getNumber() + 1); counter.setNumber(counter.getNumber() + 1);
MessageCache.cache.put(report.getScenarioId(), counter); MessageCache.cache.put(result.getSetReportId(), counter);
} }
} }
} }
} }
// 针对未正常返回结果的报告计数
counter(result);
return lastReport; return lastReport;
} }
@ -871,124 +876,4 @@ public class ApiScenarioReportService {
return count; 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());
}
} }

View File

@ -795,7 +795,7 @@ public class ApiTestCaseService {
sqlSession.commit(); sqlSession.commit();
for (RunCaseRequest runCaseRequest : executeQueue) { for (RunCaseRequest runCaseRequest : executeQueue) {
MessageCache.batchTestCases.put(runCaseRequest.getReportId(), runCaseRequest.getReport()); MessageCache.caseExecResourceLock.put(runCaseRequest.getReportId(), runCaseRequest.getReport());
run(runCaseRequest); run(runCaseRequest);
} }
} }
@ -816,16 +816,16 @@ public class ApiTestCaseService {
try { try {
HashTree jmeterHashTree = this.generateHashTree(request, testCaseWithBLOBs); 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) { } catch (Exception ex) {
ApiDefinitionExecResult result = MessageCache.batchTestCases.get(request.getReportId()); ApiDefinitionExecResult result = MessageCache.caseExecResourceLock.get(request.getReportId());
result.setStatus("error"); result.setStatus("error");
apiDefinitionExecResultMapper.updateByPrimaryKey(result); apiDefinitionExecResultMapper.updateByPrimaryKey(result);
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId()); ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId());
caseWithBLOBs.setStatus("error"); caseWithBLOBs.setStatus("error");
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs); apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
MessageCache.batchTestCases.remove(request.getReportId()); MessageCache.caseExecResourceLock.remove(request.getReportId());
LogUtil.error(ex.getMessage(), ex); LogUtil.error(ex.getMessage(), ex);
} }
} }
@ -842,7 +842,7 @@ public class ApiTestCaseService {
request.setTestPlanId(testPlanID); request.setTestPlanId(testPlanID);
HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs); HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs);
// 调用执行方法 // 调用执行方法
jMeterService.runLocal(id, jmeterHashTree, debugReportId, runMode); jMeterService.runLocal(id,null, jmeterHashTree, debugReportId, runMode);
} catch (Exception ex) { } catch (Exception ex) {
LogUtil.error(ex); LogUtil.error(ex);
} }

View File

@ -113,7 +113,8 @@ public class RemakeReportService {
} }
} }
} }
MessageCache.batchTestCases.remove(reportId); MessageCache.caseExecResourceLock.remove(reportId);
MessageCache.scenarioExecResourceLock.remove(reportId);
MessageCache.executionQueue.remove(reportId); MessageCache.executionQueue.remove(reportId);
} }
} }
@ -146,7 +147,8 @@ public class RemakeReportService {
} }
report.setStatus(APITestStatus.Error.name()); report.setStatus(APITestStatus.Error.name());
apiScenarioReportMapper.insert(report); apiScenarioReportMapper.insert(report);
MessageCache.batchTestCases.remove(report.getId()); MessageCache.caseExecResourceLock.remove(report.getId());
MessageCache.scenarioExecResourceLock.remove(report.getId());
MessageCache.executionQueue.remove(report.getId()); MessageCache.executionQueue.remove(report.getId());
} }
} }

View File

@ -53,7 +53,7 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
jMeterService.runTest(runModeDataDTO.getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig()); jMeterService.runTest(runModeDataDTO.getTestId(), reportId, request.getRunMode(), testPlanScenarioId, request.getConfig());
} else { } else {
reportId = runModeDataDTO.getReport().getId(); 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)) { while (MessageCache.executionQueue.containsKey(reportId)) {
long time = MessageCache.executionQueue.get(runModeDataDTO.getReport().getId()); long time = MessageCache.executionQueue.get(runModeDataDTO.getReport().getId());
@ -68,8 +68,8 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
} }
break; break;
} }
if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) { if (MessageCache.terminationOrderDeque.contains(reportId)) {
MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId()); MessageCache.terminationOrderDeque.remove(reportId);
break; break;
} }
Thread.sleep(1000); Thread.sleep(1000);

View File

@ -121,7 +121,7 @@ public class CustomFunctionService {
config.setProjectId(request.getProjectId()); config.setProjectId(request.getProjectId());
HashTree hashTree = request.getTestElement().generateHashTree(config); HashTree hashTree = request.getTestElement().generateHashTree(config);
String runMode = ApiRunMode.DEFINITION.name(); 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(); return request.getId();
} }
} }

View File

@ -108,7 +108,7 @@ public class TaskService {
result.setStatus("STOP"); result.setStatus("STOP");
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result); apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
actuator = result.getActuator(); actuator = result.getActuator();
MessageCache.batchTestCases.remove(result.getId()); MessageCache.caseExecResourceLock.remove(result.getId());
} }
} else if (StringUtils.equals(request.getType(), "SCENARIO")) { } else if (StringUtils.equals(request.getType(), "SCENARIO")) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId()); ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());

View File

@ -497,7 +497,7 @@ public class TestPlanApiCaseService {
planApiCases.forEach(testPlanApiCase -> { planApiCases.forEach(testPlanApiCase -> {
ApiDefinitionExecResult report = addResult(request, testPlanApiCase, APITestStatus.Running.name(), batchMapper); ApiDefinitionExecResult report = addResult(request, testPlanApiCase, APITestStatus.Running.name(), batchMapper);
executeQueue.put(report.getId(), testPlanApiCase); executeQueue.put(report.getId(), testPlanApiCase);
MessageCache.batchTestCases.put(report.getId(), report); MessageCache.caseExecResourceLock.put(report.getId(), report);
}); });
sqlSession.commit(); sqlSession.commit();
@ -507,7 +507,7 @@ public class TestPlanApiCaseService {
jMeterService.runTest(executeQueue.get(reportId).getId(), reportId, request.getTriggerMode(), null, request.getConfig()); jMeterService.runTest(executeQueue.get(reportId).getId(), reportId, request.getTriggerMode(), null, request.getConfig());
} else { } else {
HashTree hashTree = generateHashTree(executeQueue.get(reportId).getId()); 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());
} }
} }
} }

View File

@ -993,7 +993,7 @@ public class TestPlanService {
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig()); testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
String runMode = ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(); 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; return returnId;

View File

@ -34,14 +34,14 @@ public class SerialApiExecTask<T> implements Callable<T> {
@Override @Override
public T call() { public T call() {
try { 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()); MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
return null; return null;
} }
if (config != null && StringUtils.isNotBlank(config.getResourcePoolId())) { if (config != null && StringUtils.isNotBlank(config.getResourcePoolId())) {
jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getApiCaseId(), runMode, null, config); jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getApiCaseId(), runMode, null, config);
} else { } 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次防止死循环 // 轮询查看报告状态最多200次防止死循环
ApiDefinitionExecResult report = null; ApiDefinitionExecResult report = null;
@ -53,7 +53,7 @@ public class SerialApiExecTask<T> implements Callable<T> {
if (report != null && !report.getStatus().equals(APITestStatus.Running.name())) { if (report != null && !report.getStatus().equals(APITestStatus.Running.name())) {
break; 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()); MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
break; break;
} }