fix(接口测试): 支持分布式执行,执行队列入库

This commit is contained in:
fit2-zhao 2021-12-20 19:44:13 +08:00 committed by fit2-zhao
parent 75c6378c6c
commit 17a4ababeb
40 changed files with 2540 additions and 588 deletions

View File

@ -148,7 +148,7 @@
<dependency>
<groupId>io.metersphere</groupId>
<artifactId>ms-jmeter-core</artifactId>
<version>1.0.1</version>
<version>1.0.2</version>
</dependency>
<!-- 排除jmeter中的 xstream 解决bug -->

View File

@ -2,7 +2,6 @@ package io.metersphere.api.cache;
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.jmeter.JmeterThreadUtils;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.domain.ApiScenarioReportExample;
@ -192,10 +191,6 @@ public class TestPlanExecuteInfo {
JmeterThreadUtils.stop(apiCaseExecuteThreadMap.get(resourceId));
}
}
if (apiCaseExecuteThreadMap.containsKey(resourceId)) {
SerialBlockingQueueUtil.remove(apiCaseExecuteThreadMap.get(resourceId));
}
}
List<String> updateScenarioReportList = new ArrayList<>();
@ -209,10 +204,6 @@ public class TestPlanExecuteInfo {
JmeterThreadUtils.stop(apiScenarioThreadMap.get(resourceId));
}
}
if (apiScenarioThreadMap.containsKey(resourceId)) {
SerialBlockingQueueUtil.remove(apiScenarioThreadMap.get(resourceId));
}
}
if (CollectionUtils.isNotEmpty(updateScenarioReportList)) {
ApiScenarioReportMapper apiScenarioReportMapper = CommonBeanFactory.getBean(ApiScenarioReportMapper.class);
@ -232,10 +223,6 @@ public class TestPlanExecuteInfo {
}
loadCaseExecInfo.put(resourceId, TestPlanApiExecuteStatus.FAILD.name());
}
if (loadCaseReportIdMap.containsKey(resourceId)) {
SerialBlockingQueueUtil.remove(loadCaseReportIdMap.get(resourceId));
}
}
this.countUnFinishedNum();

View File

@ -27,8 +27,7 @@ public class RunModeDataDTO {
}
public RunModeDataDTO(HashTree hashTree, APIScenarioReportResult report, String testId) {
this.hashTree = hashTree;
public RunModeDataDTO(APIScenarioReportResult report, String testId) {
this.report = report;
this.testId = testId;
}

View File

@ -213,7 +213,6 @@ public class ApiExecuteService {
CollectionUtils.isNotEmpty(request.getTestElement().getHashTree().get(0).getHashTree()) ?
request.getTestElement().getHashTree().get(0).getHashTree().get(0).getName() : request.getId();
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, request.getId(), runMode, hashTree);
runRequest.setConfig(request.getConfig());
runRequest.setDebug(request.isDebug());
// 开始执行
jMeterService.run(runRequest);

View File

@ -1,39 +1,26 @@
package io.metersphere.api.exec.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.definition.BatchRunDefinitionRequest;
import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.MsTestPlan;
import io.metersphere.api.dto.definition.request.MsThreadGroup;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.api.service.RemakeReportService;
import io.metersphere.base.domain.*;
import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiExecutionQueue;
import io.metersphere.base.domain.TestPlanApiCase;
import io.metersphere.base.domain.TestPlanApiCaseExample;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
@ -52,18 +39,19 @@ public class TestPlanApiExecuteService {
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
@Resource
private JMeterService jMeterService;
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private RemakeReportService remakeReportService;
private ApiScenarioSerialService apiScenarioSerialService;
@Resource
private ApiExecutionQueueService apiExecutionQueueService;
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
List<String> ids = request.getPlanIds();
if (CollectionUtils.isEmpty(ids)) {
return new LinkedList<>();
}
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
example.createCriteria().andIdIn(ids);
example.setOrderByClause("`order` DESC");
@ -75,8 +63,6 @@ public class TestPlanApiExecuteService {
}
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
// 资源池
GenerateHashTreeUtil.setPoolResource(request.getConfig());
// 开始选择执行模式
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
Map<TestPlanApiCase, ApiDefinitionExecResult> executeQueue = new LinkedHashMap<>();
@ -101,7 +87,13 @@ public class TestPlanApiExecuteService {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
// 开始串行执行
serial(executeQueue, request);
String runMode = request.getTriggerMode();
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig() != null ? request.getConfig().getResourcePoolId() : null, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), null, runMode);
if (executionQueue != null) {
if (executionQueue.getQueue() != null) {
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
}
}
} else {
Map<String, TestPlanApiCase> executeQueue = new HashMap<>();
//记录案例线程结果以及执行失败的案例ID
@ -130,169 +122,31 @@ public class TestPlanApiExecuteService {
return responseDTOS;
}
private void serial(Map<TestPlanApiCase, ApiDefinitionExecResult> executeQueue, BatchRunDefinitionRequest request) {
// 开始串行执行
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().setName("TestPlanCase串行执行线程");
List<String> executeErrorList = new ArrayList<>();
for (TestPlanApiCase testPlanApiCase : executeQueue.keySet()) {
try {
ApiDefinitionExecResult execResult = executeQueue.get(testPlanApiCase);
execResult.setStatus(APITestStatus.Running.name());
apiDefinitionExecResultMapper.updateByPrimaryKey(execResult);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testPlanApiCase.getId(), execResult.getId(), request.getTriggerMode(), null);
runRequest.setConfig(request.getConfig());
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig()));
runRequest.setTestPlanReportId(request.getPlanReportId());
try {
if (!GenerateHashTreeUtil.isResourcePool(request.getConfig()).isPool()) {
runRequest.setHashTree(generateHashTree(testPlanApiCase.getId()));
}
} catch (Exception e) {
remakeReportService.remake(runRequest);
continue;
}
LoggerUtil.info("TestPlan Serial run 【 " + runRequest.getReportId() + "】start");
// 开始执行
jMeterService.run(runRequest);
Object reportObj = SerialBlockingQueueUtil.take(runRequest.getReportId());
if (reportObj == null) {
LoggerUtil.info("TestPlan Serial run-进入超时补偿处理:【 " + runRequest.getReportId() + "");
ApiDefinitionExecResult apiDefinitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(runRequest.getReportId());
if (apiDefinitionExecResult != null) {
apiDefinitionExecResult.setStatus("timeout");
apiDefinitionExecResultMapper.updateByPrimaryKey(apiDefinitionExecResult);
}
}
LoggerUtil.info("TestPlan Serial run 【 " + runRequest.getReportId() + "】end");
// 如果开启失败结束执行则判断返回结果状态
if (request.getConfig().isOnSampleError()) {
if (reportObj != null && reportObj instanceof ApiDefinitionExecResult) {
ApiDefinitionExecResult result = (ApiDefinitionExecResult) reportObj;
if (result == null || !result.getStatus().equals("Success")) {
break;
}
}
}
} catch (Exception e) {
executeErrorList.add(testPlanApiCase.getId());
LogUtil.error("执行终止:" + e.getMessage());
break;
}
}
//如果是测试计划生成报告的执行则更新执行信息执行线程信息
TestPlanReportExecuteCatch.set(request.getPlanReportId(), executeErrorList);
} catch (Exception e) {
LogUtil.error(e);
}
}
});
thread.start();
}
private void parallel(Map<String, TestPlanApiCase> executeQueue, BatchRunDefinitionRequest request) {
List<String> executeErrorList = new ArrayList<>();
for (String reportId : executeQueue.keySet()) {
TestPlanApiCase testPlanApiCase = executeQueue.get(reportId);
try {
HashTree hashTree = null;
if (!GenerateHashTreeUtil.isResourcePool(request.getConfig()).isPool()) {
hashTree = generateHashTree(testPlanApiCase.getId());
}
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testPlanApiCase.getId(), reportId, request.getTriggerMode(), hashTree);
runRequest.setConfig(request.getConfig());
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig()));
runRequest.setTestPlanReportId(request.getPlanReportId());
jMeterService.run(runRequest);
} catch (Exception e) {
executeErrorList.add(testPlanApiCase.getId());
}
}
//如果是测试计划生成报告的执行则更新执行信息执行线程信息
TestPlanReportExecuteCatch.set(request.getPlanReportId(), executeErrorList);
}
public HashTree generateHashTree(String testId) {
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
if (apiCase != null) {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
HashTree jmeterHashTree = new HashTree();
MsTestPlan testPlan = new MsTestPlan();
testPlan.setHashTree(new LinkedList<>());
if (caseWithBLOBs != null) {
String poolId = request.getConfig() != null ? request.getConfig().getResourcePoolId() : null;
String mode = request.getConfig() != null ? request.getConfig().getMode() : null;
ApiExecutionQueue executionQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), mode, request.getTriggerMode());
if (executionQueue != null) {
for (String reportId : executeQueue.keySet()) {
TestPlanApiCase testPlanApiCase = executeQueue.get(reportId);
try {
MsThreadGroup group = new MsThreadGroup();
group.setLabel(caseWithBLOBs.getName());
group.setName(caseWithBLOBs.getName());
MsTestElement testElement = parse(caseWithBLOBs, testId);
group.setHashTree(new LinkedList<>());
group.getHashTree().add(testElement);
testPlan.getHashTree().add(group);
} catch (Exception ex) {
MSException.throwException(ex.getMessage());
HashTree hashTree = null;
if (request.getConfig() == null || !GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testPlanApiCase.getId());
}
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testPlanApiCase.getId(), reportId, request.getTriggerMode(), hashTree);
if (request.getConfig() != null) {
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
}
runRequest.setTestPlanReportId(request.getPlanReportId());
jMeterService.run(runRequest);
} catch (Exception e) {
executeErrorList.add(testPlanApiCase.getId());
}
}
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
return jmeterHashTree;
//如果是测试计划生成报告的执行则更新执行信息执行线程信息
TestPlanReportExecuteCatch.set(request.getPlanReportId(), executeErrorList);
}
return null;
}
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
String api = caseWithBLOBs.getRequest();
JSONObject element = JSON.parseObject(api);
ElementUtil.dataFormatting(element);
LinkedList<MsTestElement> list = new LinkedList<>();
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
list.addAll(elements);
}
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(planId);
if (element.getString("type").equals("HTTPSamplerProxy")) {
MsHTTPSamplerProxy httpSamplerProxy = JSON.parseObject(api, MsHTTPSamplerProxy.class);
httpSamplerProxy.setHashTree(list);
httpSamplerProxy.setName(planId);
httpSamplerProxy.setUseEnvironment(apiCase.getEnvironmentId());
return httpSamplerProxy;
}
if (element.getString("type").equals("TCPSampler")) {
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class);
msTCPSampler.setUseEnvironment(apiCase.getEnvironmentId());
msTCPSampler.setHashTree(list);
msTCPSampler.setName(planId);
return msTCPSampler;
}
if (element.getString("type").equals("DubboSampler")) {
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class);
dubboSampler.setUseEnvironment(apiCase.getEnvironmentId());
dubboSampler.setHashTree(list);
dubboSampler.setName(planId);
return dubboSampler;
}
if (element.getString("type").equals("JDBCSampler")) {
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
jDBCSampler.setUseEnvironment(apiCase.getEnvironmentId());
jDBCSampler.setHashTree(list);
jDBCSampler.setName(planId);
return jDBCSampler;
}
} catch (Exception e) {
LogUtil.error(e);
}
return null;
}
}

View File

@ -0,0 +1,10 @@
package io.metersphere.api.exec.queue;
import io.metersphere.base.domain.ApiExecutionQueue;
import io.metersphere.base.domain.ApiExecutionQueueDetail;
import lombok.Data;
@Data
public class DBTestQueue extends ApiExecutionQueue {
private ApiExecutionQueueDetail queue;
}

View File

@ -21,9 +21,11 @@ public class ExecTask implements Runnable {
LoggerUtil.info("开始执行报告ID" + request.getReportId() + " 】,资源ID【 " + request.getTestId() + "");
JMeterService jMeterService = CommonBeanFactory.getBean(JMeterService.class);
jMeterService.addQueue(request);
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
if (res == null) {
LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时");
if (request.getPool() == null || !request.getPool().isPool()) {
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
if (res == null) {
LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时");
}
}
LoggerUtil.info("任务:【 " + request.getReportId() + " 】执行完成");
}

View File

@ -1,6 +1,7 @@
package io.metersphere.api.exec.queue;
import io.metersphere.api.exec.utils.NamedThreadFactory;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils;
@ -103,6 +104,7 @@ public class ExecThreadPoolExecutor {
public void setCorePoolSize(int corePoolSize) {
try {
MessageCache.corePoolSize = corePoolSize;
threadPool.setCorePoolSize(corePoolSize);
threadPool.setMaximumPoolSize(corePoolSize);
threadPool.allowCoreThreadTimeOut(true);

View File

@ -1,53 +0,0 @@
package io.metersphere.api.exec.queue;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.ResultDTO;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class SerialBlockingQueueUtil {
// 只作用与串行任务
public static Map<String, BlockingQueue<Object>> queue = new ConcurrentHashMap<>();
public static final String END_SIGN = "RUN-END";
private static final int QUEUE_SIZE = 1;
public static void offer(ResultDTO dto, Object report) {
String key = dto != null && StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString()) ? dto.getReportId() + "_" + dto.getTestId() : dto.getReportId();
if (StringUtils.isNotEmpty(key) && queue.containsKey(key)) {
try {
queue.get(key).offer(report);
} catch (Exception e) {
LogUtil.error(e);
} finally {
queue.remove(key);
}
}
}
public static Object take(String key) {
try {
if (StringUtils.isNotEmpty(key) && !queue.containsKey(key)) {
BlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE);
queue.put(key, blockingQueue);
return blockingQueue.poll(3, TimeUnit.MINUTES);
}
} catch (Exception e) {
LogUtil.error("获取队列失败:" + e.getMessage());
}
return null;
}
public static void remove(String key) {
if (StringUtils.isNotEmpty(key) && queue.containsKey(key)) {
queue.get(key).offer(END_SIGN);
queue.remove(key);
}
}
}

View File

@ -9,14 +9,10 @@ import io.metersphere.api.dto.automation.ExecuteType;
import io.metersphere.api.dto.automation.RunScenarioRequest;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.api.jmeter.ReportCounter;
import io.metersphere.api.service.ApiScenarioReportService;
import io.metersphere.api.service.ApiScenarioReportStructureService;
import io.metersphere.api.service.RemakeReportService;
import io.metersphere.api.service.TcpApiParamService;
import io.metersphere.api.service.*;
import io.metersphere.base.domain.ApiScenarioExample;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.TestPlanApiScenario;
@ -24,6 +20,7 @@ import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.constants.TriggerMode;
@ -44,7 +41,11 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.comparators.FixedOrderComparator;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.jorphan.collections.HashTree;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@ -61,6 +62,8 @@ public class ApiScenarioExecuteService {
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiExecutionQueueService apiExecutionQueueService;
@Resource
private ExtApiScenarioMapper extApiScenarioMapper;
@Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@ -85,6 +88,8 @@ public class ApiScenarioExecuteService {
private TcpApiParamService tcpApiParamService;
@Resource
private JMeterService jMeterService;
@Resource
private SqlSessionFactory sqlSessionFactory;
public List<MsExecResponseDTO> run(RunScenarioRequest request) {
if (LoggerUtil.getLogger().isDebugEnabled()) {
@ -101,9 +106,6 @@ public class ApiScenarioExecuteService {
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
MSException.throwException((apiScenarios.get(0).getName() + "" + Translator.get("automation_exec_info")));
}
// 资源池
LoggerUtil.info("Scenario run-执行脚本装载-开始检查是否需要加载资源池");
GenerateHashTreeUtil.setPoolResource(request.getConfig());
// 环境检查
LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查");
apiScenarioEnvService.checkEnv(request, apiScenarios);
@ -145,33 +147,41 @@ public class ApiScenarioExecuteService {
report.setId(serialReportId);
request.getConfig().setAmassReport(serialReportId);
apiScenarioReportMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
// 增加并行集合报告
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.PARALLEL.toString())) {
List<String> testIds = executeQueue.entrySet().stream().map(reports -> reports.getValue().getTestId()).collect(Collectors.toList());
ReportCounter counter = new ReportCounter();
counter.setCompletedIds(new LinkedList<>());
if (CollectionUtils.isNotEmpty(request.getConfig().getTestResources())) {
counter.setPoolUrls(request.getConfig().getTestResources());
}
counter.setTestIds(testIds);
MessageCache.concurrencyCounter.put(serialReportId, counter);
LoggerUtil.debug("Scenario run-执行脚本装载-初始化并行集成报告队列:" + JSON.toJSONString(counter));
apiScenarioReportStructureService.save(apiScenarios, serialReportId);
}
}
// 开始执行
if (executeQueue != null && executeQueue.size() > 0) {
String reportType = request.getConfig().getReportType();
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), serialReportId, reportType, request.getRunMode());
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
if (StringUtils.isNotEmpty(serialReportId)) {
apiScenarioReportStructureService.save(apiScenarios, serialReportId);
}
apiScenarioSerialService.serial(executeQueue, request, serialReportId, responseDTOS);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
// 非集合报告先生成执行队列
if (StringUtils.isEmpty(serialReportId)) {
for (String reportId : executeQueue.keySet()) {
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
report.setStatus(APITestStatus.Waiting.name());
batchMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode()));
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
if (executionQueue.getQueue() != null) {
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
}
} else {
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS);
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS, executionQueue.getId());
}
}
return responseDTOS;
@ -254,9 +264,12 @@ public class ApiScenarioExecuteService {
executeQueue.put(report.getId(), runModeDataDTO);
} else {
try {
// 生成报告和HashTree
HashTree hashTree = GenerateHashTreeUtil.generateHashTree(scenario, reportId, planEnvMap);
executeQueue.put(report.getId(), new RunModeDataDTO(hashTree, report, testPlanScenarioId));
// 生成并行报告和HashTree
RunModeDataDTO runModeDataDTO = new RunModeDataDTO(report, testPlanScenarioId);
if (request.getConfig() != null && !request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
runModeDataDTO.setHashTree(GenerateHashTreeUtil.generateHashTree(scenario, reportId, planEnvMap));
}
executeQueue.put(report.getId(), runModeDataDTO);
} catch (Exception ex) {
scenarioIds.remove(scenario.getId());
if (StringUtils.equalsAny(request.getTriggerMode(), TriggerMode.BATCH.name(), TriggerMode.SCHEDULE.name())) {
@ -302,8 +315,12 @@ public class ApiScenarioExecuteService {
} else {
// 生成报告和HashTree
try {
HashTree hashTree = GenerateHashTreeUtil.generateHashTree(item, StringUtils.isNotEmpty(serialReportId) ? serialReportId + "-" + i : reportId, new HashMap<>());
executeQueue.put(report.getId(), new RunModeDataDTO(hashTree, report, item.getId()));
RunModeDataDTO runModeDataDTO = new RunModeDataDTO(report, item.getId());
if (request.getConfig() != null && !request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
HashTree hashTree = GenerateHashTreeUtil.generateHashTree(item, StringUtils.isNotEmpty(serialReportId) ? serialReportId + "-" + i : reportId, new HashMap<>());
runModeDataDTO.setHashTree(hashTree);
}
executeQueue.put(report.getId(), runModeDataDTO);
} catch (Exception ex) {
scenarioIds.remove(item.getId());
if (StringUtils.equalsAny(request.getTriggerMode(), TriggerMode.BATCH.name(), TriggerMode.SCHEDULE.name())) {
@ -360,9 +377,7 @@ public class ApiScenarioExecuteService {
// 调用执行方法
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), ApiRunMode.SCENARIO.name(), hashTree);
runRequest.setConfig(request.getConfig());
runRequest.setDebug(true);
jMeterService.run(runRequest);
return request.getId();
}

View File

@ -30,7 +30,7 @@ public class ApiScenarioParallelService {
@Resource
private JMeterService jMeterService;
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS) {
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS, String queueId) {
if (StringUtils.isEmpty(serialReportId)) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
@ -46,14 +46,16 @@ public class ApiScenarioParallelService {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
for (String reportId : executeQueue.keySet()) {
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(executeQueue.get(reportId).getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), executeQueue.get(reportId).getHashTree());
runRequest.setConfig(request.getConfig());
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig()));
runRequest.setQueueId(queueId);
if (request.getConfig() != null) {
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
runRequest.setPoolId(request.getConfig().getResourcePoolId());
}
runRequest.setTestPlanReportId(request.getTestPlanReportId());
runRequest.setHashTree(executeQueue.get(reportId).getHashTree());
if (LoggerUtil.getLogger().isDebugEnabled()) {
LoggerUtil.debug("Scenario run-开始并发执行:" + JSON.toJSONString(request));
}

View File

@ -1,142 +1,196 @@
package io.metersphere.api.exec.scenario;
import io.metersphere.api.dto.RunModeDataDTO;
import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.api.dto.automation.RunScenarioRequest;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.request.ElementUtil;
import io.metersphere.api.dto.definition.request.MsTestPlan;
import io.metersphere.api.dto.definition.request.MsThreadGroup;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.service.ApiScenarioReportService;
import io.metersphere.api.service.ApiTestEnvironmentService;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.HashTreeUtil;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.jorphan.collections.HashTree;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
@Service
public class ApiScenarioSerialService {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private JMeterService jMeterService;
@Resource
private ApiScenarioReportService apiScenarioReportService;
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
public void serial(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS) {
public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) {
LoggerUtil.debug("Scenario run-执行脚本装载-进入串行准备");
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
// 非集合报告先生成执行队列
if (StringUtils.isEmpty(serialReportId)) {
for (String reportId : executeQueue.keySet()) {
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
report.setStatus(APITestStatus.Waiting.name());
batchMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode()));
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
if (!StringUtils.equals(executionQueue.getReportType(), RunModeConstants.SET_REPORT.toString())) {
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
report.setStatus(APITestStatus.Running.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
apiScenarioReportMapper.updateByPrimaryKey(report);
} else {
ApiDefinitionExecResult execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
execResult.setStatus(APITestStatus.Running.name());
apiDefinitionExecResultMapper.updateByPrimaryKey(execResult);
}
}
// 开始串行执行
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Scenario串行执行线程");
try {
//记录串行执行中的环境参数供下一个场景执行时使用 <envId,<key,data>>
Map<String, Map<String, String>> executeEnvParams = new LinkedHashMap<>();
ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
HashTreeUtil hashTreeUtil = new HashTreeUtil();
for (String key : executeQueue.keySet()) {
APIScenarioReportResult report = executeQueue.get(key).getReport();
if (StringUtils.isEmpty(serialReportId)) {
report.setStatus(APITestStatus.Running.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
apiScenarioReportMapper.updateByPrimaryKey(report);
}
String queueReportId = StringUtils.isNotEmpty(serialReportId) ? serialReportId + "_" + executeQueue.get(key).getTestId() : key;
LoggerUtil.info("Scenario run-开始执行队列ID" + queueReportId + "");
try {
if (!executeEnvParams.isEmpty()) {
HashTree hashTree = executeQueue.get(key).getHashTree();
hashTreeUtil.setEnvParamsMapToHashTree(hashTree, executeEnvParams);
executeQueue.get(key).setHashTree(hashTree);
}
String reportId = StringUtils.isNotEmpty(serialReportId) ? serialReportId : key;
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(executeQueue.get(key).getTestId(), reportId, request.getRunMode(), executeQueue.get(key).getHashTree());
if (request.getConfig() != null) {
runRequest.setConfig(request.getConfig());
}
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig()));
runRequest.setTestPlanReportId(request.getTestPlanReportId());
// 开始执行
jMeterService.run(runRequest);
Object reportObj = SerialBlockingQueueUtil.take(queueReportId);
if (reportObj == null) {
LoggerUtil.info("Scenario run-进入超时补偿处理:【 " + queueReportId + "");
ApiScenarioReport scenarioReport = apiScenarioReportMapper.selectByPrimaryKey(reportId);
if (scenarioReport != null) {
scenarioReport.setStatus("Timeout");
apiScenarioReportMapper.updateByPrimaryKey(scenarioReport);
}
}
LoggerUtil.info("Scenario run-执行完成:【 " + queueReportId + "");
// 如果开启失败结束执行则判断返回结果状态
if (request.getConfig().isOnSampleError()) {
if (reportObj != null && reportObj instanceof ApiScenarioReport) {
ApiScenarioReport scenarioReport = (ApiScenarioReport) reportObj;
if (!scenarioReport.getStatus().equals("Success")) {
break;
}
}
}
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(executeQueue.get(key).getHashTree(), apiTestEnvironmentService);
executeEnvParams = hashTreeUtil.mergeParamDataMap(executeEnvParams, envParamsMap);
} catch (Exception e) {
SerialBlockingQueueUtil.remove(queueReportId);
LogUtil.error("执行终止:" + e.getMessage());
break;
}
LoggerUtil.info("Scenario run-开始执行队列ID" + executionQueue.getReportId() + "");
try {
HashTree hashTree = null;
if (StringUtils.isEmpty(executionQueue.getPoolId())) {
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(queue.getTestId());
Map<String, String> planEnvMap = new LinkedHashMap<>();
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
planEnvMap = JSON.parseObject(queue.getEvnMap(), Map.class);
}
// 更新集成报告
if (StringUtils.isNotEmpty(serialReportId)) {
apiScenarioReportService.margeReport(serialReportId);
}
} catch (Exception e) {
LogUtil.error(e);
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, queue.getReportId(), planEnvMap);
} else {
hashTree = generateHashTree(queue.getTestId());
}
// 更新环境变量
this.initEnv(hashTree);
}
String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(queue.getTestId(), reportId, executionQueue.getRunMode(), hashTree);
runRequest.setReportType(executionQueue.getReportType());
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(executionQueue.getPoolId()));
runRequest.setTestPlanReportId(executionQueue.getReportId());
runRequest.setRunType(RunModeConstants.SERIAL.toString());
runRequest.setQueueId(executionQueue.getId());
runRequest.setPoolId(executionQueue.getPoolId());
// 开始执行
jMeterService.run(runRequest);
} catch (Exception e) {
LogUtil.error("执行终止:" + e.getMessage());
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
report.setStatus(APITestStatus.Error.name());
apiScenarioReportMapper.updateByPrimaryKey(report);
} else {
ApiDefinitionExecResult apiDefinitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
if (apiDefinitionExecResult != null) {
apiDefinitionExecResult.setStatus("timeout");
apiDefinitionExecResultMapper.updateByPrimaryKey(apiDefinitionExecResult);
}
}
});
thread.start();
}
}
private void initEnv(HashTree hashTree) {
ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
HashTreeUtil hashTreeUtil = new HashTreeUtil();
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService);
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
}
public HashTree generateHashTree(String testId) {
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
if (apiCase != null) {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
HashTree jmeterHashTree = new HashTree();
MsTestPlan testPlan = new MsTestPlan();
testPlan.setHashTree(new LinkedList<>());
if (caseWithBLOBs != null) {
try {
MsThreadGroup group = new MsThreadGroup();
group.setLabel(caseWithBLOBs.getName());
group.setName(caseWithBLOBs.getName());
MsTestElement testElement = parse(caseWithBLOBs, testId);
group.setHashTree(new LinkedList<>());
group.getHashTree().add(testElement);
testPlan.getHashTree().add(group);
} catch (Exception ex) {
MSException.throwException(ex.getMessage());
}
}
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
return jmeterHashTree;
}
return null;
}
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
String api = caseWithBLOBs.getRequest();
JSONObject element = JSON.parseObject(api);
ElementUtil.dataFormatting(element);
LinkedList<MsTestElement> list = new LinkedList<>();
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
list.addAll(elements);
}
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(planId);
if (element.getString("type").equals("HTTPSamplerProxy")) {
MsHTTPSamplerProxy httpSamplerProxy = JSON.parseObject(api, MsHTTPSamplerProxy.class);
httpSamplerProxy.setHashTree(list);
httpSamplerProxy.setName(planId);
httpSamplerProxy.setUseEnvironment(apiCase.getEnvironmentId());
return httpSamplerProxy;
}
if (element.getString("type").equals("TCPSampler")) {
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class);
msTCPSampler.setUseEnvironment(apiCase.getEnvironmentId());
msTCPSampler.setHashTree(list);
msTCPSampler.setName(planId);
return msTCPSampler;
}
if (element.getString("type").equals("DubboSampler")) {
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class);
dubboSampler.setUseEnvironment(apiCase.getEnvironmentId());
dubboSampler.setHashTree(list);
dubboSampler.setName(planId);
return dubboSampler;
}
if (element.getString("type").equals("JDBCSampler")) {
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
jDBCSampler.setUseEnvironment(apiCase.getEnvironmentId());
jDBCSampler.setHashTree(list);
jDBCSampler.setName(planId);
return jDBCSampler;
}
} catch (Exception e) {
LogUtil.error(e);
}
return null;
}
}

View File

@ -54,7 +54,7 @@ public class ApiDefinitionExecResultUtil {
apiResult.setTriggerMode(TriggerMode.BATCH.name());
}
apiResult.setActuator("LOCAL");
if (GenerateHashTreeUtil.isResourcePool(request.getConfig()).isPool()) {
if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) {
apiResult.setActuator(request.getConfig().getResourcePoolId());
}
if (StringUtils.isEmpty(request.getUserId())) {

View File

@ -77,26 +77,26 @@ public class GenerateHashTreeUtil {
return new LinkedList<>();
}
public static BooleanPool isResourcePool(RunModeConfigDTO config) {
public static BooleanPool isResourcePool(String id) {
BooleanPool pool = new BooleanPool();
pool.setPool(config != null && StringUtils.isNotEmpty(config.getResourcePoolId()));
pool.setPool(StringUtils.isNotEmpty(id));
if (pool.isPool()) {
TestResourcePool resourcePool = CommonBeanFactory.getBean(TestResourcePoolMapper.class).selectByPrimaryKey(config.getResourcePoolId());
TestResourcePool resourcePool = CommonBeanFactory.getBean(TestResourcePoolMapper.class).selectByPrimaryKey(id);
pool.setK8s(resourcePool != null && resourcePool.getApi() && resourcePool.getType().equals(ResourcePoolTypeEnum.K8S.name()));
}
return pool;
}
public static void setPoolResource(RunModeConfigDTO config) {
if (GenerateHashTreeUtil.isResourcePool(config).isPool()) {
if (GenerateHashTreeUtil.isResourcePool(config).isK8s()) {
public static List<JvmInfoDTO> setPoolResource(String id) {
if (GenerateHashTreeUtil.isResourcePool(id).isPool()) {
if (GenerateHashTreeUtil.isResourcePool(id).isK8s()) {
LogUtil.info("K8S 暂时不做校验 ");
} else {
ResourcePoolCalculation resourcePoolCalculation = CommonBeanFactory.getBean(ResourcePoolCalculation.class);
List<JvmInfoDTO> testResources = resourcePoolCalculation.getPools(config.getResourcePoolId());
config.setTestResources(testResources);
return resourcePoolCalculation.getPools(id);
}
}
return null;
}
public static HashTree generateHashTree(ApiScenarioWithBLOBs item, String reportId, Map<String, String> planEnvMap) {
@ -109,7 +109,7 @@ public class GenerateHashTreeUtil {
group.setName(reportId);
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
group.setOnSampleError(scenario.getOnSampleError());
if (planEnvMap.size() > 0) {
if (planEnvMap != null && planEnvMap.size() > 0) {
scenario.setEnvironmentMap(planEnvMap);
}
GenerateHashTreeUtil.parse(item.getScenarioDefinition(), scenario);

View File

@ -1,33 +0,0 @@
package io.metersphere.api.jmeter;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.service.MsResultService;
import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
public class APIBackendListenerHandler {
public void handleTeardownTest(ResultDTO dto, Map<String, Object> kafkaConfig) {
LoggerUtil.info("开始处理执行结果报告【" + dto.getReportId() + " 】,资源【 " + dto.getTestId() + "");
TestResultService testResultService = CommonBeanFactory.getBean(TestResultService.class);
MsResultService resultService = CommonBeanFactory.getBean(MsResultService.class);
// 无结果返回直接结束队列
if (dto == null || CollectionUtils.isEmpty(dto.getRequestResults())) {
SerialBlockingQueueUtil.offer(dto, SerialBlockingQueueUtil.END_SIGN);
}
dto.setConsole(resultService.getJmeterLogger(dto.getReportId()));
// 存储结果
testResultService.saveResults(dto);
if (StringUtils.isNotEmpty(dto.getReportId())) {
SerialBlockingQueueUtil.remove(dto.getReportId());
}
}
}

View File

@ -2,6 +2,7 @@ package io.metersphere.api.jmeter;
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.MsResultService;
import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.utils.CommonBeanFactory;
@ -23,11 +24,14 @@ public class APISingleResultListener extends MsExecListener {
public void testEnded(ResultDTO dto, Map<String, Object> kafkaConfig) {
try {
LoggerUtil.info("进入TEST-END处理报告【" + dto.getReportId() + " 】整体执行完成;" + dto.getRunMode());
// 全局并发队列
PoolExecBlockingQueueUtil.offer(dto.getReportId());
dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId()));
// 整体执行结束更新资源状态
CommonBeanFactory.getBean(TestResultService.class).testEnded(dto);
LoggerUtil.info("执行队列处理:" + dto.getQueueId());
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
} catch (Exception e) {
LoggerUtil.error(e);
}

View File

@ -1,67 +1,24 @@
package io.metersphere.api.jmeter;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.service.ApiScenarioReportService;
import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class FixedTask {
public static Map<String, Integer> guardTask = new HashMap<>();
private ApiScenarioReportService scenarioReportService;
private ApiExecutionQueueService queueService;
@Scheduled(cron = "*/6 * * * * ?")
@Scheduled(cron = "0 */5 * * * ?")
public void execute() {
if (MessageCache.caseExecResourceLock.size() > 10000) {
MessageCache.caseExecResourceLock.clear();
}
if (scenarioReportService == null) {
scenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
}
if (MessageCache.concurrencyCounter != null && MessageCache.concurrencyCounter.size() > 0) {
for (String key : MessageCache.concurrencyCounter.keySet()) {
ReportCounter counter = MessageCache.concurrencyCounter.get(key);
LoggerUtil.info("集成报告:【" + key + "】总执行场景:【" + counter.getTestIds().size() + "】已经执行完成场景:【" + counter.getCompletedIds().size() + "");
List<String> filterList = counter.getTestIds().stream().filter(t -> !counter.getCompletedIds().contains(t)).collect(Collectors.toList());
LoggerUtil.debug("剩余要执行的报告" + JSON.toJSONString(filterList));
// 合并
if (counter.getCompletedIds().size() >= counter.getTestIds().size()) {
scenarioReportService.margeReport(key);
guardTask.remove(key);
MessageCache.concurrencyCounter.remove(key);
} else {
try {
if (guardTask.containsKey(key)) {
int number = guardTask.get(key);
number += 1;
guardTask.put(key, number);
} else {
guardTask.put(key, 0);
}
if (CollectionUtils.isNotEmpty(counter.getPoolUrls()) && counter.getCompletedIds().size() > 0 && guardTask.get(key) > 200) {
// 资源池中已经没有执行的请求了
int runningCount = scenarioReportService.get(key, counter);
if (runningCount == 0) {
LoggerUtil.error("发生未知异常,进行资源合并,请检查资源池是否正常运行");
scenarioReportService.margeReport(key);
guardTask.remove(key);
MessageCache.concurrencyCounter.remove(key);
}
}
} catch (Exception ex) {
LoggerUtil.error(ex.getMessage());
}
}
}
if (queueService == null) {
queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class);
}
LoggerUtil.info("进入超时处理");
queueService.timeOut();
}
}

View File

@ -3,6 +3,7 @@ package io.metersphere.api.jmeter;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.RunRequest;
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.service.ApiScenarioReportService;
import io.metersphere.api.service.RemakeReportService;
import io.metersphere.commons.constants.ApiRunMode;
@ -31,6 +32,7 @@ import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
@ -83,14 +85,14 @@ public class JMeterService {
LoggerUtil.debug("监听MessageCache.tasks当前容量" + MessageCache.jmeterLogTask.size());
if (request.isDebug() && !StringUtils.equalsAny(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
JMeterBase.addSyncListener(request, APISingleResultListener.class.getCanonicalName());
JMeterBase.addSyncListener(request, request.getHashTree(), APISingleResultListener.class.getCanonicalName());
}
if (request.isDebug()) {
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加Debug Listener");
addDebugListener(request.getReportId(), request.getHashTree());
} else {
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
JMeterBase.addSyncListener(request, APISingleResultListener.class.getCanonicalName());
JMeterBase.addSyncListener(request, request.getHashTree(), APISingleResultListener.class.getCanonicalName());
}
LocalRunner runner = new LocalRunner(request.getHashTree());
@ -99,45 +101,41 @@ public class JMeterService {
private void runNode(JmeterRunRequestDTO request) {
// 获取可以执行的资源池
if (request.getConfig() != null) {
BaseSystemConfigDTO baseInfo = request.getConfig().getBaseInfo();
if (baseInfo == null) {
baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
}
// 占位符
String platformUrl = "http://localhost:8081";
if (baseInfo != null) {
platformUrl = baseInfo.getUrl();
}
platformUrl += "/api/jmeter/download?testId=" + request.getTestId() + "&reportId=" + request.getReportId() + "&runMode=" + request.getRunMode();
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
// 占位符
String platformUrl = "http://localhost:8081";
if (baseInfo != null) {
platformUrl = baseInfo.getUrl();
}
platformUrl += "/api/jmeter/download?testId=" + request.getTestId() + "&reportId=" + request.getReportId() + "&runMode=" + request.getRunMode();
request.setPlatformUrl(platformUrl);
request.setKafkaConfig(KafkaConfig.getKafka());
// 如果是K8S调用
if (request.getPool().isK8s()) {
try {
LoggerUtil.error("开始发送请求[ " + request.getTestId() + " ] 到K8S节点执行");
final Engine engine = EngineFactory.createApiEngine(request);
engine.start();
} catch (Exception e) {
LoggerUtil.error("调用K8S执行请求[ " + request.getTestId() + " ] 失败:" + e.getMessage());
ApiScenarioReportService apiScenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
apiScenarioReportService.delete(request.getReportId());
MSException.throwException(e.getMessage());
}
} else {
this.send(request);
request.setPlatformUrl(platformUrl);
request.setKafkaConfig(KafkaConfig.getKafka());
// 如果是K8S调用
if (request.getPool().isK8s()) {
try {
LoggerUtil.error("开始发送请求[ " + request.getTestId() + " ] 到K8S节点执行");
final Engine engine = EngineFactory.createApiEngine(request);
engine.start();
} catch (Exception e) {
LoggerUtil.error("调用K8S执行请求[ " + request.getTestId() + " ] 失败:" + e.getMessage());
ApiScenarioReportService apiScenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
apiScenarioReportService.delete(request.getReportId());
MSException.throwException(e.getMessage());
}
} else {
this.send(request);
}
}
private synchronized void send(JmeterRunRequestDTO request) {
try {
int index = (int) (Math.random() * request.getConfig().getTestResources().size());
JvmInfoDTO jvmInfoDTO = request.getConfig().getTestResources().get(index);
List<JvmInfoDTO> resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId());
int index = (int) (Math.random() * resources.size());
JvmInfoDTO jvmInfoDTO = resources.get(index);
TestResourceDTO testResource = jvmInfoDTO.getTestResource();
String configuration = testResource.getConfiguration();
request.setCorePoolSize(MessageCache.corePoolSize);
NodeDTO node = JSON.parseObject(configuration, NodeDTO.class);
String nodeIp = node.getIp();
Integer port = node.getPort();

View File

@ -1,6 +1,5 @@
package io.metersphere.api.jmeter;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
@ -17,10 +16,6 @@ public class JmeterThreadUtils {
StringBuilder threadNames = new StringBuilder();
for (int i = 0; i < noThreads; i++) {
if (StringUtils.isNotEmpty(lstThreads[i].getName()) && lstThreads[i].getName().startsWith(name)) {
String threadName = StringUtils.substringBeforeLast(lstThreads[i].getName(), THREAD_SPLIT);
if (StringUtils.isNotEmpty(threadName)) {
SerialBlockingQueueUtil.remove(threadName);
}
System.out.println("异常强制处理线程编号:" + i + " = " + lstThreads[i].getName());
LogUtil.error("异常强制处理线程编号:" + i + " = " + lstThreads[i].getName());
threadNames.append(lstThreads[i].getName()).append("");

View File

@ -10,8 +10,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MessageCache {
public final static Map<String, ReportCounter> concurrencyCounter = new HashMap<>();
public final static ConcurrentHashMap<String, Session> reportCache = new ConcurrentHashMap<>();
// 用例并发锁
public final static ConcurrentHashMap<String, ApiDefinitionExecResult> caseExecResourceLock = new ConcurrentHashMap<>();
@ -20,4 +18,6 @@ public class MessageCache {
// 定时任务报告
public final static List<String> jobReportCache = new LinkedList<>();
public static int corePoolSize = 10;
}

View File

@ -19,7 +19,6 @@ package io.metersphere.api.jmeter;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.RunningParamKeys;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.service.MsResultService;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
@ -105,7 +104,6 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
result.setResponseCode(TEST_END);
ResultDTO dto = new ResultDTO();
dto.setReportId(this.getName());
SerialBlockingQueueUtil.offer(dto, SerialBlockingQueueUtil.END_SIGN);
try {
if (client != null) {
client.close();

View File

@ -4,9 +4,10 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.service.ApiEnvironmentRunningParamService;
import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.config.KafkaConfig;
import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil;
@ -28,8 +29,8 @@ public class MsKafkaListener {
if (testResult != null && testResult.getArbitraryData() != null && testResult.getArbitraryData().containsKey("TEST_END") && (Boolean) testResult.getArbitraryData().get("TEST_END")) {
LoggerUtil.info("报告 【 " + testResult.getReportId() + " 】资源 " + testResult.getTestId() + " 整体执行完成");
testResultService.testEnded(testResult);
// 串行队列
SerialBlockingQueueUtil.offer(testResult, SerialBlockingQueueUtil.END_SIGN);
LoggerUtil.info("执行队列处理:" + testResult.getQueueId());
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(testResult);
// 全局并发队列
PoolExecBlockingQueueUtil.offer(testResult.getReportId());
} else {

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
@ -82,8 +81,6 @@ public class ApiDefinitionExecResultService {
}
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
ApiDefinitionExecResult result = this.save(item, dto.getReportId(), dto.getConsole(), count, dto.getRunMode(), dto.getTestId(), isFirst);
// 串行队列
SerialBlockingQueueUtil.offer(dto, result != null ? result : SerialBlockingQueueUtil.END_SIGN);
if (result != null) {
// 发送通知
sendNotice(result);
@ -224,8 +221,6 @@ public class ApiDefinitionExecResultService {
//更新报告ID
caseReportMap.put(dto.getTestId(), saveResult.getId());
isFirst = false;
// 串行队列
SerialBlockingQueueUtil.offer(dto, SerialBlockingQueueUtil.END_SIGN);
}
}
}

View File

@ -0,0 +1,222 @@
package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.RunModeDataDTO;
import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
import io.metersphere.base.mapper.ApiExecutionQueueMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.ext.ExtApiExecutionQueueMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
public class ApiExecutionQueueService {
@Resource
private ApiExecutionQueueMapper queueMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private ApiExecutionQueueDetailMapper executionQueueDetailMapper;
@Resource
private ApiScenarioSerialService apiScenarioSerialService;
@Resource
private ApiScenarioReportService apiScenarioReportService;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode) {
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
executionQueue.setId(UUID.randomUUID().toString());
executionQueue.setCreateTime(System.currentTimeMillis());
executionQueue.setPoolId(poolId);
executionQueue.setReportId(reportId);
executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString());
executionQueue.setRunMode(runMode);
queueMapper.insert(executionQueue);
DBTestQueue resQueue = new DBTestQueue();
BeanUtils.copyBean(resQueue, executionQueue);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiExecutionQueueDetailMapper batchMapper = sqlSession.getMapper(ApiExecutionQueueDetailMapper.class);
if (StringUtils.equals(type, ApiRunMode.API_PLAN.name())) {
final int[] sort = {0};
if (StringUtils.equals(reportType, RunModeConstants.PARALLEL.toString())) {
Map<String, TestPlanApiCase> runMap = (Map<String, TestPlanApiCase>) runObj;
runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(k, v.getId(), type, sort[0], executionQueue.getId(), null);
if (sort[0] == 0) {
resQueue.setQueue(queue);
}
sort[0]++;
batchMapper.insert(queue);
});
} else {
Map<TestPlanApiCase, ApiDefinitionExecResult> runMap = (Map<TestPlanApiCase, ApiDefinitionExecResult>) runObj;
runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(v.getId(), k.getId(), type, sort[0], executionQueue.getId(), null);
if (sort[0] == 0) {
resQueue.setQueue(queue);
}
sort[0]++;
batchMapper.insert(queue);
});
}
} else {
Map<String, RunModeDataDTO> runMap = (Map<String, RunModeDataDTO>) runObj;
final int[] sort = {0};
runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), type, sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap()));
queue.setSort(sort[0]);
if (sort[0] == 0) {
resQueue.setQueue(queue);
}
sort[0]++;
batchMapper.insert(queue);
});
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
return resQueue;
}
private ApiExecutionQueueDetail detail(String reportId, String testId, String type, int sort, String queueId, String envMap) {
ApiExecutionQueueDetail queue = new ApiExecutionQueueDetail();
queue.setCreateTime(System.currentTimeMillis());
queue.setId(UUID.randomUUID().toString());
queue.setEvnMap(envMap);
queue.setReportId(reportId);
queue.setTestId(testId);
queue.setType(type);
queue.setSort(sort);
queue.setQueueId(queueId);
return queue;
}
public DBTestQueue edit(String id, String testId) {
ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(id);
if (executionQueue != null) {
DBTestQueue queue = new DBTestQueue();
BeanUtils.copyBean(queue, executionQueue);
if (executionQueue != null) {
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.setOrderByClause("sort asc");
example.createCriteria().andQueueIdEqualTo(id);
List<ApiExecutionQueueDetail> queues = executionQueueDetailMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(queues)) {
List<ApiExecutionQueueDetail> list = queues.stream().filter(item -> StringUtils.equals(item.getTestId(), testId)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(list)) {
executionQueueDetailMapper.deleteByPrimaryKey(list.get(0).getId());
queues.remove(list.get(0));
BeanUtils.copyBean(queue, executionQueue);
if (CollectionUtils.isNotEmpty(queues)) {
queue.setQueue(queues.get(0));
}
}
if (CollectionUtils.isEmpty(queues)) {
queueMapper.deleteByPrimaryKey(id);
}
} else {
queueMapper.deleteByPrimaryKey(id);
}
}
return queue;
}
return null;
}
public void queueNext(ResultDTO dto) {
DBTestQueue executionQueue = this.edit(dto.getQueueId(), dto.getTestId());
if (executionQueue != null) {
LoggerUtil.info("开始处理执行队列:" + executionQueue.getId());
if (executionQueue.getQueue() != null && StringUtils.isNotEmpty(executionQueue.getQueue().getTestId())) {
if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) {
LoggerUtil.info("当前执行队列是:" + JSON.toJSONString(executionQueue.getQueue()));
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
}
} else {
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
apiScenarioReportService.margeReport(dto.getReportId());
}
queueMapper.deleteByPrimaryKey(executionQueue.getId());
LoggerUtil.info("队列:" + dto.getQueueId() + " 执行结束");
}
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andQueueIdEqualTo(dto.getQueueId()).andTestIdEqualTo(dto.getTestId());
executionQueueDetailMapper.deleteByExample(example);
}
}
public void timeOut() {
final int SECOND_MILLIS = 1000;
final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
long now = System.currentTimeMillis();
// 五分钟前的数据
now = now - 5 * MINUTE_MILLIS;
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andCreateTimeLessThan(now);
List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(queueDetails)) {
queueDetails.forEach(item -> {
if (StringUtils.equalsAny(item.getType(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null) {
report.setStatus("timeout");
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
if (result != null) {
result.setStatus("timeout");
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
}
}
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
});
}
ApiExecutionQueueExample queueDetailExample = new ApiExecutionQueueExample();
queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(now);
List<ApiExecutionQueue> executionQueues = queueMapper.selectByExample(queueDetailExample);
if (CollectionUtils.isNotEmpty(executionQueues)) {
executionQueues.forEach(item -> {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null) {
report.setStatus("timeout");
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
}
});
}
// 清除异常队列/一般是服务突然停止产生
extApiExecutionQueueMapper.delete();
}
}

View File

@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.definition.request.MsTestPlan;
import io.metersphere.api.dto.scenario.request.BodyFile;
import io.metersphere.api.exec.api.TestPlanApiExecuteService;
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.JarConfig;
@ -38,7 +38,7 @@ import java.util.zip.ZipOutputStream;
public class ApiJmeterFileService {
@Resource
private TestPlanApiExecuteService testPlanApiExecuteService;
private ApiScenarioSerialService apiScenarioSerialService;
@Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
@ -78,7 +78,7 @@ public class ApiJmeterFileService {
}
HashTree hashTree;
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
hashTree = testPlanApiExecuteService.generateHashTree(remoteTestId);
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId);
} else {
if (scenario == null) {
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);

View File

@ -12,8 +12,6 @@ import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.api.dto.automation.ExecuteType;
import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.api.jmeter.ReportCounter;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
@ -90,16 +88,7 @@ public class ApiScenarioReportService {
}
public ApiScenarioReport testEnded(ResultDTO dto) {
// 并发集成报告计数
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
LoggerUtil.info("接收到集合报告【" + dto.getReportId() + "】部分结果【" + dto.getTestId() + "");
Object obj = MessageCache.concurrencyCounter.get(dto.getReportId());
if (obj != null) {
ReportCounter counter = (ReportCounter) obj;
counter.getCompletedIds().add(dto.getTestId());
MessageCache.concurrencyCounter.put(dto.getReportId(), counter);
}
} else {
if (!StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
// 更新控制台信息
apiScenarioReportStructureService.update(dto.getReportId(), dto.getConsole());
}
@ -116,7 +105,6 @@ public class ApiScenarioReportService {
scenarioReport = updateScenario(requestResults, dto);
}
// 串行队列
SerialBlockingQueueUtil.offer(dto, scenarioReport != null ? scenarioReport : SerialBlockingQueueUtil.END_SIGN);
return scenarioReport;
}
@ -268,7 +256,12 @@ public class ApiScenarioReportService {
apiScenarioMapper.updateByPrimaryKey(scenario);
}
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success", dto.getRunMode());
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success";
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
return report;
}
@ -278,9 +271,14 @@ public class ApiScenarioReportService {
Map<String, String> scenarioAndErrorMap = new HashMap<>();
Map<String, String> planScenarioReportMap = new HashMap<>();
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Error")).count();
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success", dto.getRunMode());
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success";
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
if (report != null) {
if (StringUtils.isNotEmpty(dto.getTestPlanReportId()) && !testPlanReportIdList.contains(dto.getTestPlanReportId())) {
testPlanReportIdList.add(dto.getTestPlanReportId());
@ -338,10 +336,7 @@ public class ApiScenarioReportService {
public void margeReport(String reportId) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId);
// 要合并的报告已经被删除
if (report == null) {
MessageCache.concurrencyCounter.remove(reportId);
} else {
if (report != null) {
// 更新场景状态
ApiScenarioReportResultExample example = new ApiScenarioReportResultExample();
example.createCriteria().andReportIdEqualTo(reportId).andStatusEqualTo("Error");
@ -358,7 +353,12 @@ public class ApiScenarioReportService {
public ApiScenarioReport updateScenario(List<ApiScenarioReportResult> requestResults, ResultDTO dto) {
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Error")).count();
// 更新报告状态
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success", dto.getRunMode());
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success";
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
// 更新场景状态
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(dto.getTestId());
if (scenario == null) {
@ -478,7 +478,6 @@ public class ApiScenarioReportService {
apiScenarioReportDetailMapper.deleteByPrimaryKey(request.getId());
// 补充逻辑如果是集成报告则把零时报告全部删除
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getId());
MessageCache.concurrencyCounter.remove(request.getId());
if (report != null && StringUtils.isNotEmpty(report.getScenarioId())) {
List<String> list = getReportIds(report.getScenarioId());
if (CollectionUtils.isNotEmpty(list)) {
@ -506,9 +505,6 @@ public class ApiScenarioReportService {
public void deleteAPIReportBatch(APIReportBatchRequest reportRequest) {
List<String> ids = reportRequest.getIds();
ids.forEach(item -> {
MessageCache.concurrencyCounter.remove(item);
});
if (reportRequest.isSelectAllDate()) {
ids = this.idList(reportRequest);
if (reportRequest.getUnSelectIds() != null) {

View File

@ -1,13 +1,12 @@
package io.metersphere.api.service;
import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.api.jmeter.ReportCounter;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
@ -36,12 +35,11 @@ public class RemakeReportService {
public void remake(JmeterRunRequestDTO request) {
try {
if (StringUtils.equals(request.getReportType(), RunModeConstants.SET_REPORT.toString())) {
Object obj = MessageCache.concurrencyCounter.get(request.getReportId());
if (obj != null) {
ReportCounter counter = (ReportCounter) obj;
counter.getCompletedIds().add(request.getTestId());
MessageCache.concurrencyCounter.put(request.getReportId(), counter);
}
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andQueueIdEqualTo(request.getQueueId()).andTestIdEqualTo(request.getTestId());
CommonBeanFactory.getBean(ApiExecutionQueueDetailMapper.class).deleteByExample(example);
CommonBeanFactory.getBean(ApiExecutionQueueService.class).edit(request.getQueueId(), request.getTestId());
}
// 清理零时报告
if (StringUtils.equalsAnyIgnoreCase(request.getRunMode(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
@ -117,7 +115,6 @@ public class RemakeReportService {
}
}
MessageCache.caseExecResourceLock.remove(request.getReportId());
SerialBlockingQueueUtil.remove(request.getReportId());
} catch (Exception e) {
LogUtil.error(e);
}
@ -147,6 +144,5 @@ public class RemakeReportService {
report.setStatus(APITestStatus.Error.name());
apiScenarioReportMapper.insert(report);
MessageCache.caseExecResourceLock.remove(report.getId());
SerialBlockingQueueUtil.remove(report.getId());
}
}

View File

@ -1,7 +1,6 @@
package io.metersphere.api.service;
import io.metersphere.api.dto.automation.ApiTestReportVariable;
import io.metersphere.api.exec.queue.SerialBlockingQueueUtil;
import io.metersphere.api.jmeter.ExecutedHandleSingleton;
import io.metersphere.base.domain.*;
import io.metersphere.commons.constants.ApiRunMode;
@ -97,7 +96,6 @@ public class TestResultService {
reportTask.setPrincipal(principal);
reportTask.setExecutionTime(DateUtils.getTimeString(scenarioReport.getUpdateTime()));
reportTask.setEnvironment(environment);
dto.setTestId(scenarioReport.getScenarioId());
updateScenarioTestCaseStates(dto.getTestId(), dto.getRunMode());
if (reportTask != null) {
@ -107,11 +105,6 @@ public class TestResultService {
}
}
}
} else {
// 串行队列
if (dto != null && org.apache.commons.collections.CollectionUtils.isEmpty(dto.getRequestResults())) {
SerialBlockingQueueUtil.offer(dto, SerialBlockingQueueUtil.END_SIGN);
}
}
}

View File

@ -0,0 +1,21 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
@Data
public class ApiExecutionQueue implements Serializable {
private String id;
private String reportId;
private String reportType;
private String runMode;
private String poolId;
private Long createTime;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,25 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
@Data
public class ApiExecutionQueueDetail implements Serializable {
private String id;
private String queueId;
private Integer sort;
private String reportId;
private String testId;
private String type;
private Long createTime;
private String evnMap;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,670 @@
package io.metersphere.base.domain;
import java.util.ArrayList;
import java.util.List;
public class ApiExecutionQueueDetailExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public ApiExecutionQueueDetailExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(String value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(String value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(String value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(String value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(String value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(String value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdLike(String value) {
addCriterion("id like", value, "id");
return (Criteria) this;
}
public Criteria andIdNotLike(String value) {
addCriterion("id not like", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<String> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<String> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(String value1, String value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(String value1, String value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andQueueIdIsNull() {
addCriterion("queue_id is null");
return (Criteria) this;
}
public Criteria andQueueIdIsNotNull() {
addCriterion("queue_id is not null");
return (Criteria) this;
}
public Criteria andQueueIdEqualTo(String value) {
addCriterion("queue_id =", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdNotEqualTo(String value) {
addCriterion("queue_id <>", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdGreaterThan(String value) {
addCriterion("queue_id >", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdGreaterThanOrEqualTo(String value) {
addCriterion("queue_id >=", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdLessThan(String value) {
addCriterion("queue_id <", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdLessThanOrEqualTo(String value) {
addCriterion("queue_id <=", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdLike(String value) {
addCriterion("queue_id like", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdNotLike(String value) {
addCriterion("queue_id not like", value, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdIn(List<String> values) {
addCriterion("queue_id in", values, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdNotIn(List<String> values) {
addCriterion("queue_id not in", values, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdBetween(String value1, String value2) {
addCriterion("queue_id between", value1, value2, "queueId");
return (Criteria) this;
}
public Criteria andQueueIdNotBetween(String value1, String value2) {
addCriterion("queue_id not between", value1, value2, "queueId");
return (Criteria) this;
}
public Criteria andSortIsNull() {
addCriterion("sort is null");
return (Criteria) this;
}
public Criteria andSortIsNotNull() {
addCriterion("sort is not null");
return (Criteria) this;
}
public Criteria andSortEqualTo(Integer value) {
addCriterion("sort =", value, "sort");
return (Criteria) this;
}
public Criteria andSortNotEqualTo(Integer value) {
addCriterion("sort <>", value, "sort");
return (Criteria) this;
}
public Criteria andSortGreaterThan(Integer value) {
addCriterion("sort >", value, "sort");
return (Criteria) this;
}
public Criteria andSortGreaterThanOrEqualTo(Integer value) {
addCriterion("sort >=", value, "sort");
return (Criteria) this;
}
public Criteria andSortLessThan(Integer value) {
addCriterion("sort <", value, "sort");
return (Criteria) this;
}
public Criteria andSortLessThanOrEqualTo(Integer value) {
addCriterion("sort <=", value, "sort");
return (Criteria) this;
}
public Criteria andSortIn(List<Integer> values) {
addCriterion("sort in", values, "sort");
return (Criteria) this;
}
public Criteria andSortNotIn(List<Integer> values) {
addCriterion("sort not in", values, "sort");
return (Criteria) this;
}
public Criteria andSortBetween(Integer value1, Integer value2) {
addCriterion("sort between", value1, value2, "sort");
return (Criteria) this;
}
public Criteria andSortNotBetween(Integer value1, Integer value2) {
addCriterion("sort not between", value1, value2, "sort");
return (Criteria) this;
}
public Criteria andReportIdIsNull() {
addCriterion("report_id is null");
return (Criteria) this;
}
public Criteria andReportIdIsNotNull() {
addCriterion("report_id is not null");
return (Criteria) this;
}
public Criteria andReportIdEqualTo(String value) {
addCriterion("report_id =", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotEqualTo(String value) {
addCriterion("report_id <>", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThan(String value) {
addCriterion("report_id >", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThanOrEqualTo(String value) {
addCriterion("report_id >=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThan(String value) {
addCriterion("report_id <", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThanOrEqualTo(String value) {
addCriterion("report_id <=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLike(String value) {
addCriterion("report_id like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotLike(String value) {
addCriterion("report_id not like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdIn(List<String> values) {
addCriterion("report_id in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotIn(List<String> values) {
addCriterion("report_id not in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdBetween(String value1, String value2) {
addCriterion("report_id between", value1, value2, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotBetween(String value1, String value2) {
addCriterion("report_id not between", value1, value2, "reportId");
return (Criteria) this;
}
public Criteria andTestIdIsNull() {
addCriterion("test_id is null");
return (Criteria) this;
}
public Criteria andTestIdIsNotNull() {
addCriterion("test_id is not null");
return (Criteria) this;
}
public Criteria andTestIdEqualTo(String value) {
addCriterion("test_id =", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdNotEqualTo(String value) {
addCriterion("test_id <>", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdGreaterThan(String value) {
addCriterion("test_id >", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdGreaterThanOrEqualTo(String value) {
addCriterion("test_id >=", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdLessThan(String value) {
addCriterion("test_id <", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdLessThanOrEqualTo(String value) {
addCriterion("test_id <=", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdLike(String value) {
addCriterion("test_id like", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdNotLike(String value) {
addCriterion("test_id not like", value, "testId");
return (Criteria) this;
}
public Criteria andTestIdIn(List<String> values) {
addCriterion("test_id in", values, "testId");
return (Criteria) this;
}
public Criteria andTestIdNotIn(List<String> values) {
addCriterion("test_id not in", values, "testId");
return (Criteria) this;
}
public Criteria andTestIdBetween(String value1, String value2) {
addCriterion("test_id between", value1, value2, "testId");
return (Criteria) this;
}
public Criteria andTestIdNotBetween(String value1, String value2) {
addCriterion("test_id not between", value1, value2, "testId");
return (Criteria) this;
}
public Criteria andTypeIsNull() {
addCriterion("`type` is null");
return (Criteria) this;
}
public Criteria andTypeIsNotNull() {
addCriterion("`type` is not null");
return (Criteria) this;
}
public Criteria andTypeEqualTo(String value) {
addCriterion("`type` =", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotEqualTo(String value) {
addCriterion("`type` <>", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThan(String value) {
addCriterion("`type` >", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThanOrEqualTo(String value) {
addCriterion("`type` >=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThan(String value) {
addCriterion("`type` <", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThanOrEqualTo(String value) {
addCriterion("`type` <=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLike(String value) {
addCriterion("`type` like", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotLike(String value) {
addCriterion("`type` not like", value, "type");
return (Criteria) this;
}
public Criteria andTypeIn(List<String> values) {
addCriterion("`type` in", values, "type");
return (Criteria) this;
}
public Criteria andTypeNotIn(List<String> values) {
addCriterion("`type` not in", values, "type");
return (Criteria) this;
}
public Criteria andTypeBetween(String value1, String value2) {
addCriterion("`type` between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andTypeNotBetween(String value1, String value2) {
addCriterion("`type` not between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andCreateTimeIsNull() {
addCriterion("create_time is null");
return (Criteria) this;
}
public Criteria andCreateTimeIsNotNull() {
addCriterion("create_time is not null");
return (Criteria) this;
}
public Criteria andCreateTimeEqualTo(Long value) {
addCriterion("create_time =", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotEqualTo(Long value) {
addCriterion("create_time <>", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThan(Long value) {
addCriterion("create_time >", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
addCriterion("create_time >=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThan(Long value) {
addCriterion("create_time <", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
addCriterion("create_time <=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeIn(List<Long> values) {
addCriterion("create_time in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotIn(List<Long> values) {
addCriterion("create_time not in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeBetween(Long value1, Long value2) {
addCriterion("create_time between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@ -0,0 +1,610 @@
package io.metersphere.base.domain;
import java.util.ArrayList;
import java.util.List;
public class ApiExecutionQueueExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public ApiExecutionQueueExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(String value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(String value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(String value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(String value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(String value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(String value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdLike(String value) {
addCriterion("id like", value, "id");
return (Criteria) this;
}
public Criteria andIdNotLike(String value) {
addCriterion("id not like", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<String> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<String> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(String value1, String value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(String value1, String value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andReportIdIsNull() {
addCriterion("report_id is null");
return (Criteria) this;
}
public Criteria andReportIdIsNotNull() {
addCriterion("report_id is not null");
return (Criteria) this;
}
public Criteria andReportIdEqualTo(String value) {
addCriterion("report_id =", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotEqualTo(String value) {
addCriterion("report_id <>", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThan(String value) {
addCriterion("report_id >", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThanOrEqualTo(String value) {
addCriterion("report_id >=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThan(String value) {
addCriterion("report_id <", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThanOrEqualTo(String value) {
addCriterion("report_id <=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLike(String value) {
addCriterion("report_id like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotLike(String value) {
addCriterion("report_id not like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdIn(List<String> values) {
addCriterion("report_id in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotIn(List<String> values) {
addCriterion("report_id not in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdBetween(String value1, String value2) {
addCriterion("report_id between", value1, value2, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotBetween(String value1, String value2) {
addCriterion("report_id not between", value1, value2, "reportId");
return (Criteria) this;
}
public Criteria andReportTypeIsNull() {
addCriterion("report_type is null");
return (Criteria) this;
}
public Criteria andReportTypeIsNotNull() {
addCriterion("report_type is not null");
return (Criteria) this;
}
public Criteria andReportTypeEqualTo(String value) {
addCriterion("report_type =", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeNotEqualTo(String value) {
addCriterion("report_type <>", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeGreaterThan(String value) {
addCriterion("report_type >", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeGreaterThanOrEqualTo(String value) {
addCriterion("report_type >=", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeLessThan(String value) {
addCriterion("report_type <", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeLessThanOrEqualTo(String value) {
addCriterion("report_type <=", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeLike(String value) {
addCriterion("report_type like", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeNotLike(String value) {
addCriterion("report_type not like", value, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeIn(List<String> values) {
addCriterion("report_type in", values, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeNotIn(List<String> values) {
addCriterion("report_type not in", values, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeBetween(String value1, String value2) {
addCriterion("report_type between", value1, value2, "reportType");
return (Criteria) this;
}
public Criteria andReportTypeNotBetween(String value1, String value2) {
addCriterion("report_type not between", value1, value2, "reportType");
return (Criteria) this;
}
public Criteria andRunModeIsNull() {
addCriterion("run_mode is null");
return (Criteria) this;
}
public Criteria andRunModeIsNotNull() {
addCriterion("run_mode is not null");
return (Criteria) this;
}
public Criteria andRunModeEqualTo(String value) {
addCriterion("run_mode =", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeNotEqualTo(String value) {
addCriterion("run_mode <>", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeGreaterThan(String value) {
addCriterion("run_mode >", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeGreaterThanOrEqualTo(String value) {
addCriterion("run_mode >=", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeLessThan(String value) {
addCriterion("run_mode <", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeLessThanOrEqualTo(String value) {
addCriterion("run_mode <=", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeLike(String value) {
addCriterion("run_mode like", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeNotLike(String value) {
addCriterion("run_mode not like", value, "runMode");
return (Criteria) this;
}
public Criteria andRunModeIn(List<String> values) {
addCriterion("run_mode in", values, "runMode");
return (Criteria) this;
}
public Criteria andRunModeNotIn(List<String> values) {
addCriterion("run_mode not in", values, "runMode");
return (Criteria) this;
}
public Criteria andRunModeBetween(String value1, String value2) {
addCriterion("run_mode between", value1, value2, "runMode");
return (Criteria) this;
}
public Criteria andRunModeNotBetween(String value1, String value2) {
addCriterion("run_mode not between", value1, value2, "runMode");
return (Criteria) this;
}
public Criteria andPoolIdIsNull() {
addCriterion("pool_id is null");
return (Criteria) this;
}
public Criteria andPoolIdIsNotNull() {
addCriterion("pool_id is not null");
return (Criteria) this;
}
public Criteria andPoolIdEqualTo(String value) {
addCriterion("pool_id =", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdNotEqualTo(String value) {
addCriterion("pool_id <>", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdGreaterThan(String value) {
addCriterion("pool_id >", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdGreaterThanOrEqualTo(String value) {
addCriterion("pool_id >=", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdLessThan(String value) {
addCriterion("pool_id <", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdLessThanOrEqualTo(String value) {
addCriterion("pool_id <=", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdLike(String value) {
addCriterion("pool_id like", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdNotLike(String value) {
addCriterion("pool_id not like", value, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdIn(List<String> values) {
addCriterion("pool_id in", values, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdNotIn(List<String> values) {
addCriterion("pool_id not in", values, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdBetween(String value1, String value2) {
addCriterion("pool_id between", value1, value2, "poolId");
return (Criteria) this;
}
public Criteria andPoolIdNotBetween(String value1, String value2) {
addCriterion("pool_id not between", value1, value2, "poolId");
return (Criteria) this;
}
public Criteria andCreateTimeIsNull() {
addCriterion("create_time is null");
return (Criteria) this;
}
public Criteria andCreateTimeIsNotNull() {
addCriterion("create_time is not null");
return (Criteria) this;
}
public Criteria andCreateTimeEqualTo(Long value) {
addCriterion("create_time =", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotEqualTo(Long value) {
addCriterion("create_time <>", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThan(Long value) {
addCriterion("create_time >", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
addCriterion("create_time >=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThan(Long value) {
addCriterion("create_time <", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
addCriterion("create_time <=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeIn(List<Long> values) {
addCriterion("create_time in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotIn(List<Long> values) {
addCriterion("create_time not in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeBetween(Long value1, Long value2) {
addCriterion("create_time between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@ -0,0 +1,36 @@
package io.metersphere.base.mapper;
import io.metersphere.base.domain.ApiExecutionQueueDetail;
import io.metersphere.base.domain.ApiExecutionQueueDetailExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface ApiExecutionQueueDetailMapper {
long countByExample(ApiExecutionQueueDetailExample example);
int deleteByExample(ApiExecutionQueueDetailExample example);
int deleteByPrimaryKey(String id);
int insert(ApiExecutionQueueDetail record);
int insertSelective(ApiExecutionQueueDetail record);
List<ApiExecutionQueueDetail> selectByExampleWithBLOBs(ApiExecutionQueueDetailExample example);
List<ApiExecutionQueueDetail> selectByExample(ApiExecutionQueueDetailExample example);
ApiExecutionQueueDetail selectByPrimaryKey(String id);
int updateByExampleSelective(@Param("record") ApiExecutionQueueDetail record, @Param("example") ApiExecutionQueueDetailExample example);
int updateByExampleWithBLOBs(@Param("record") ApiExecutionQueueDetail record, @Param("example") ApiExecutionQueueDetailExample example);
int updateByExample(@Param("record") ApiExecutionQueueDetail record, @Param("example") ApiExecutionQueueDetailExample example);
int updateByPrimaryKeySelective(ApiExecutionQueueDetail record);
int updateByPrimaryKeyWithBLOBs(ApiExecutionQueueDetail record);
int updateByPrimaryKey(ApiExecutionQueueDetail record);
}

View File

@ -0,0 +1,304 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ApiExecutionQueueDetailMapper">
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.ApiExecutionQueueDetail">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="queue_id" jdbcType="VARCHAR" property="queueId" />
<result column="sort" jdbcType="INTEGER" property="sort" />
<result column="report_id" jdbcType="VARCHAR" property="reportId" />
<result column="test_id" jdbcType="VARCHAR" property="testId" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiExecutionQueueDetail">
<result column="evn_map" jdbcType="LONGVARCHAR" property="evnMap" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, queue_id, sort, report_id, test_id, `type`, create_time
</sql>
<sql id="Blob_Column_List">
evn_map
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetailExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from api_execution_queue_detail
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetailExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from api_execution_queue_detail
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from api_execution_queue_detail
where id = #{id,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from api_execution_queue_detail
where id = #{id,jdbcType=VARCHAR}
</delete>
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetailExample">
delete from api_execution_queue_detail
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetail">
insert into api_execution_queue_detail (id, queue_id, sort,
report_id, test_id, `type`,
create_time, evn_map)
values (#{id,jdbcType=VARCHAR}, #{queueId,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER},
#{reportId,jdbcType=VARCHAR}, #{testId,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{evnMap,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetail">
insert into api_execution_queue_detail
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="queueId != null">
queue_id,
</if>
<if test="sort != null">
sort,
</if>
<if test="reportId != null">
report_id,
</if>
<if test="testId != null">
test_id,
</if>
<if test="type != null">
`type`,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="evnMap != null">
evn_map,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=VARCHAR},
</if>
<if test="queueId != null">
#{queueId,jdbcType=VARCHAR},
</if>
<if test="sort != null">
#{sort,jdbcType=INTEGER},
</if>
<if test="reportId != null">
#{reportId,jdbcType=VARCHAR},
</if>
<if test="testId != null">
#{testId,jdbcType=VARCHAR},
</if>
<if test="type != null">
#{type,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
<if test="evnMap != null">
#{evnMap,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetailExample" resultType="java.lang.Long">
select count(*) from api_execution_queue_detail
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update api_execution_queue_detail
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=VARCHAR},
</if>
<if test="record.queueId != null">
queue_id = #{record.queueId,jdbcType=VARCHAR},
</if>
<if test="record.sort != null">
sort = #{record.sort,jdbcType=INTEGER},
</if>
<if test="record.reportId != null">
report_id = #{record.reportId,jdbcType=VARCHAR},
</if>
<if test="record.testId != null">
test_id = #{record.testId,jdbcType=VARCHAR},
</if>
<if test="record.type != null">
`type` = #{record.type,jdbcType=VARCHAR},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
<if test="record.evnMap != null">
evn_map = #{record.evnMap,jdbcType=LONGVARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExampleWithBLOBs" parameterType="map">
update api_execution_queue_detail
set id = #{record.id,jdbcType=VARCHAR},
queue_id = #{record.queueId,jdbcType=VARCHAR},
sort = #{record.sort,jdbcType=INTEGER},
report_id = #{record.reportId,jdbcType=VARCHAR},
test_id = #{record.testId,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
evn_map = #{record.evnMap,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update api_execution_queue_detail
set id = #{record.id,jdbcType=VARCHAR},
queue_id = #{record.queueId,jdbcType=VARCHAR},
sort = #{record.sort,jdbcType=INTEGER},
report_id = #{record.reportId,jdbcType=VARCHAR},
test_id = #{record.testId,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetail">
update api_execution_queue_detail
<set>
<if test="queueId != null">
queue_id = #{queueId,jdbcType=VARCHAR},
</if>
<if test="sort != null">
sort = #{sort,jdbcType=INTEGER},
</if>
<if test="reportId != null">
report_id = #{reportId,jdbcType=VARCHAR},
</if>
<if test="testId != null">
test_id = #{testId,jdbcType=VARCHAR},
</if>
<if test="type != null">
`type` = #{type,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
<if test="evnMap != null">
evn_map = #{evnMap,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetail">
update api_execution_queue_detail
set queue_id = #{queueId,jdbcType=VARCHAR},
sort = #{sort,jdbcType=INTEGER},
report_id = #{reportId,jdbcType=VARCHAR},
test_id = #{testId,jdbcType=VARCHAR},
`type` = #{type,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
evn_map = #{evnMap,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.ApiExecutionQueueDetail">
update api_execution_queue_detail
set queue_id = #{queueId,jdbcType=VARCHAR},
sort = #{sort,jdbcType=INTEGER},
report_id = #{reportId,jdbcType=VARCHAR},
test_id = #{testId,jdbcType=VARCHAR},
`type` = #{type,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -0,0 +1,30 @@
package io.metersphere.base.mapper;
import io.metersphere.base.domain.ApiExecutionQueue;
import io.metersphere.base.domain.ApiExecutionQueueExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface ApiExecutionQueueMapper {
long countByExample(ApiExecutionQueueExample example);
int deleteByExample(ApiExecutionQueueExample example);
int deleteByPrimaryKey(String id);
int insert(ApiExecutionQueue record);
int insertSelective(ApiExecutionQueue record);
List<ApiExecutionQueue> selectByExample(ApiExecutionQueueExample example);
ApiExecutionQueue selectByPrimaryKey(String id);
int updateByExampleSelective(@Param("record") ApiExecutionQueue record, @Param("example") ApiExecutionQueueExample example);
int updateByExample(@Param("record") ApiExecutionQueue record, @Param("example") ApiExecutionQueueExample example);
int updateByPrimaryKeySelective(ApiExecutionQueue record);
int updateByPrimaryKey(ApiExecutionQueue record);
}

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ApiExecutionQueueMapper">
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.ApiExecutionQueue">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="report_id" jdbcType="VARCHAR" property="reportId" />
<result column="report_type" jdbcType="VARCHAR" property="reportType" />
<result column="run_mode" jdbcType="VARCHAR" property="runMode" />
<result column="pool_id" jdbcType="VARCHAR" property="poolId" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, report_id, report_type, run_mode, pool_id, create_time
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from api_execution_queue
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from api_execution_queue
where id = #{id,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from api_execution_queue
where id = #{id,jdbcType=VARCHAR}
</delete>
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueExample">
delete from api_execution_queue
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
insert into api_execution_queue (id, report_id, report_type,
run_mode, pool_id, create_time
)
values (#{id,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR}, #{reportType,jdbcType=VARCHAR},
#{runMode,jdbcType=VARCHAR}, #{poolId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
insert into api_execution_queue
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="reportId != null">
report_id,
</if>
<if test="reportType != null">
report_type,
</if>
<if test="runMode != null">
run_mode,
</if>
<if test="poolId != null">
pool_id,
</if>
<if test="createTime != null">
create_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=VARCHAR},
</if>
<if test="reportId != null">
#{reportId,jdbcType=VARCHAR},
</if>
<if test="reportType != null">
#{reportType,jdbcType=VARCHAR},
</if>
<if test="runMode != null">
#{runMode,jdbcType=VARCHAR},
</if>
<if test="poolId != null">
#{poolId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueExample" resultType="java.lang.Long">
select count(*) from api_execution_queue
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update api_execution_queue
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=VARCHAR},
</if>
<if test="record.reportId != null">
report_id = #{record.reportId,jdbcType=VARCHAR},
</if>
<if test="record.reportType != null">
report_type = #{record.reportType,jdbcType=VARCHAR},
</if>
<if test="record.runMode != null">
run_mode = #{record.runMode,jdbcType=VARCHAR},
</if>
<if test="record.poolId != null">
pool_id = #{record.poolId,jdbcType=VARCHAR},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update api_execution_queue
set id = #{record.id,jdbcType=VARCHAR},
report_id = #{record.reportId,jdbcType=VARCHAR},
report_type = #{record.reportType,jdbcType=VARCHAR},
run_mode = #{record.runMode,jdbcType=VARCHAR},
pool_id = #{record.poolId,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
update api_execution_queue
<set>
<if test="reportId != null">
report_id = #{reportId,jdbcType=VARCHAR},
</if>
<if test="reportType != null">
report_type = #{reportType,jdbcType=VARCHAR},
</if>
<if test="runMode != null">
run_mode = #{runMode,jdbcType=VARCHAR},
</if>
<if test="poolId != null">
pool_id = #{poolId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
update api_execution_queue
set report_id = #{reportId,jdbcType=VARCHAR},
report_type = #{reportType,jdbcType=VARCHAR},
run_mode = #{runMode,jdbcType=VARCHAR},
pool_id = #{poolId,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -0,0 +1,5 @@
package io.metersphere.base.mapper.ext;
public interface ExtApiExecutionQueueMapper {
void delete();
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiExecutionQueueMapper">
<delete id="delete">
DELETE from api_execution_queue where id not IN (SELECT t1.queue_id from api_execution_queue_detail t1);
</delete>
</mapper>

View File

@ -192,6 +192,5 @@ public class TaskService {
} else {
new LocalRunner().stop(request.getReportId());
}
MessageCache.concurrencyCounter.remove(request.getReportId());
}
}

View File

@ -70,5 +70,29 @@ CREATE TABLE IF NOT EXISTS `api_scenario_report_structure`
INSERT INTO user_group_permission (id, group_id, permission_id, module_id)
VALUES (UUID(), 'project_app_manager', 'PROJECT_APP_MANAGER:READ+EDIT', 'PROJECT_APP_MANAGER');
CREATE TABLE IF NOT EXISTS `api_execution_queue`
(
`id` varchar(50) NOT NULL COMMENT 'ID',
`test_queue` LONGTEXT COMMENT '执行资源Id队列fifo',
`report_id` varchar(100) COMMENT '集合报告/测试计划报告',
`report_type` varchar(100) COMMENT '报告类型/计划报告/单独报告',
`run_mode` varchar(100) COMMENT '执行模式/scenario/api/test_paln_api/test_pan_scenario',
`pool_id` varchar(100) DEFAULT NULL COMMENT '执行资源池',
create_time bigint(13) NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `api_execution_queue_detail`
(
`id` varchar(50) NOT NULL COMMENT 'ID',
`queue_id` LONGTEXT COMMENT '队列id',
`report_id` varchar(100) COMMENT '报告id',
`test_id` varchar(100) COMMENT '资源id',
`evn_map` varchar(100) COMMENT '环境',
`type` varchar(100) DEFAULT NULL COMMENT '资源类型',
create_time bigint(13) NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
ALTER TABLE load_test
MODIFY name VARCHAR(255) NOT NULL COMMENT 'Test name';