refactor(接口测试): 大批量执行效率优化修复多节点执行阻塞时间长问题
This commit is contained in:
parent
f97917b581
commit
e119cdf628
|
@ -1,9 +1,9 @@
|
||||||
package io.metersphere.api.dto;
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
||||||
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import java.util.Map;
|
||||||
@Setter
|
@Setter
|
||||||
public class RunModeDataDTO {
|
public class RunModeDataDTO {
|
||||||
// 执行HashTree
|
// 执行HashTree
|
||||||
private HashTree hashTree;
|
private ApiScenarioWithBLOBs scenario;
|
||||||
// 测试场景/测试用例
|
// 测试场景/测试用例
|
||||||
private String testId;
|
private String testId;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||||
import io.metersphere.api.dto.mockconfig.MockConfigStaticData;
|
import io.metersphere.api.dto.mockconfig.MockConfigStaticData;
|
||||||
import io.metersphere.api.dto.scenario.KeyValue;
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||||
import io.metersphere.api.service.ApiAutomationService;
|
|
||||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||||
|
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||||
import io.metersphere.commons.constants.MsTestElementConstants;
|
import io.metersphere.commons.constants.MsTestElementConstants;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
|
@ -96,10 +96,10 @@ public class MsScenario extends MsTestElement {
|
||||||
return;
|
return;
|
||||||
} else if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
} else if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||||
try {
|
try {
|
||||||
ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class);
|
ApiScenarioMapper apiAutomationService = CommonBeanFactory.getBean(ApiScenarioMapper.class);
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId());
|
ApiScenarioWithBLOBs scenario = apiAutomationService.selectByPrimaryKey(this.getId());
|
||||||
if (scenario != null && StringUtils.isNotEmpty(scenario.getScenarioDefinition())) {
|
if (scenario != null && StringUtils.isNotEmpty(scenario.getScenarioDefinition())) {
|
||||||
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
|
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
|
||||||
// 历史数据处理
|
// 历史数据处理
|
||||||
|
@ -179,9 +179,9 @@ public class MsScenario extends MsTestElement {
|
||||||
}
|
}
|
||||||
ParameterConfig newConfig = new ParameterConfig();
|
ParameterConfig newConfig = new ParameterConfig();
|
||||||
if (this.isEnvironmentEnable()) {
|
if (this.isEnvironmentEnable()) {
|
||||||
ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class);
|
ApiScenarioMapper apiScenarioMapper = CommonBeanFactory.getBean(ApiScenarioMapper.class);
|
||||||
EnvironmentGroupProjectService environmentGroupProjectService = CommonBeanFactory.getBean(EnvironmentGroupProjectService.class);
|
EnvironmentGroupProjectService environmentGroupProjectService = CommonBeanFactory.getBean(EnvironmentGroupProjectService.class);
|
||||||
ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId());
|
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(this.getId());
|
||||||
String environmentType = scenario.getEnvironmentType();
|
String environmentType = scenario.getEnvironmentType();
|
||||||
String environmentJson = scenario.getEnvironmentJson();
|
String environmentJson = scenario.getEnvironmentJson();
|
||||||
String environmentGroupId = scenario.getEnvironmentGroupId();
|
String environmentGroupId = scenario.getEnvironmentGroupId();
|
||||||
|
|
|
@ -7,9 +7,9 @@ import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||||
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
||||||
|
import io.metersphere.api.service.ApiCaseResultService;
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
|
||||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||||
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
|
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||||
|
@ -26,24 +26,16 @@ import org.apache.commons.beanutils.BeanComparator;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections4.comparators.FixedOrderComparator;
|
import org.apache.commons.collections4.comparators.FixedOrderComparator;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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 org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class ApiCaseExecuteService {
|
public class ApiCaseExecuteService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private SqlSessionFactory sqlSessionFactory;
|
|
||||||
@Resource
|
|
||||||
private ApiScenarioSerialService apiScenarioSerialService;
|
private ApiScenarioSerialService apiScenarioSerialService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiExecutionQueueService apiExecutionQueueService;
|
private ApiExecutionQueueService apiExecutionQueueService;
|
||||||
|
@ -55,6 +47,8 @@ public class ApiCaseExecuteService {
|
||||||
private ApiTestCaseMapper apiTestCaseMapper;
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private EnvironmentGroupProjectService environmentGroupProjectService;
|
private EnvironmentGroupProjectService environmentGroupProjectService;
|
||||||
|
@Resource
|
||||||
|
private ApiCaseResultService apiCaseResultService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试计划case执行
|
* 测试计划case执行
|
||||||
|
@ -79,8 +73,6 @@ public class ApiCaseExecuteService {
|
||||||
example.createCriteria().andIdIn(ids);
|
example.createCriteria().andIdIn(ids);
|
||||||
example.setOrderByClause("`order` DESC");
|
example.setOrderByClause("`order` DESC");
|
||||||
List<TestPlanApiCase> planApiCases = testPlanApiCaseMapper.selectByExample(example);
|
List<TestPlanApiCase> planApiCases = testPlanApiCaseMapper.selectByExample(example);
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
|
||||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
|
||||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||||
request.setTriggerMode(ApiRunMode.API_PLAN.name());
|
request.setTriggerMode(ApiRunMode.API_PLAN.name());
|
||||||
}
|
}
|
||||||
|
@ -89,14 +81,12 @@ public class ApiCaseExecuteService {
|
||||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||||
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
||||||
planApiCases.forEach(testPlanApiCase -> {
|
planApiCases.forEach(testPlanApiCase -> {
|
||||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, batchMapper);
|
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status);
|
||||||
executeQueue.put(testPlanApiCase.getId(), report);
|
executeQueue.put(testPlanApiCase.getId(), report);
|
||||||
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
|
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
|
||||||
});
|
});
|
||||||
sqlSession.flushStatements();
|
|
||||||
if (sqlSession != null && sqlSessionFactory != null) {
|
apiCaseResultService.batchSave(executeQueue);
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoggerUtil.debug("开始生成测试计划队列");
|
LoggerUtil.debug("开始生成测试计划队列");
|
||||||
String reportType = request.getConfig().getReportType();
|
String reportType = request.getConfig().getReportType();
|
||||||
|
@ -155,8 +145,6 @@ public class ApiCaseExecuteService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
|
||||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
|
||||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||||
request.setTriggerMode(ApiRunMode.DEFINITION.name());
|
request.setTriggerMode(ApiRunMode.DEFINITION.name());
|
||||||
}
|
}
|
||||||
|
@ -168,14 +156,12 @@ public class ApiCaseExecuteService {
|
||||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null, request.getConfig());
|
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null, request.getConfig());
|
||||||
report.setStatus(status);
|
report.setStatus(status);
|
||||||
report.setName(caseWithBLOBs.getName());
|
report.setName(caseWithBLOBs.getName());
|
||||||
batchMapper.insert(report);
|
report.setVersionId(caseWithBLOBs.getVersionId());
|
||||||
executeQueue.put(caseWithBLOBs.getId(), report);
|
executeQueue.put(caseWithBLOBs.getId(), report);
|
||||||
responseDTOS.add(new MsExecResponseDTO(caseWithBLOBs.getId(), report.getId(), request.getTriggerMode()));
|
responseDTOS.add(new MsExecResponseDTO(caseWithBLOBs.getId(), report.getId(), request.getTriggerMode()));
|
||||||
});
|
});
|
||||||
sqlSession.flushStatements();
|
|
||||||
if (sqlSession != null && sqlSessionFactory != null) {
|
apiCaseResultService.batchSave(executeQueue);
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
String reportType = request.getConfig().getReportType();
|
String reportType = request.getConfig().getReportType();
|
||||||
String poolId = request.getConfig().getResourcePoolId();
|
String poolId = request.getConfig().getResourcePoolId();
|
||||||
|
|
|
@ -8,7 +8,6 @@ import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||||
import io.metersphere.constants.RunModeConstants;
|
import io.metersphere.constants.RunModeConstants;
|
||||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.dto.RunModeConfigDTO;
|
import io.metersphere.dto.RunModeConfigDTO;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -26,30 +25,26 @@ public class ApiCaseParallelExecuteService {
|
||||||
Thread thread = new Thread(new Runnable() {
|
Thread thread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
Thread.currentThread().setName("API-CASE-THREAD");
|
||||||
Thread.sleep(5000);
|
for (String testId : executeQueue.keySet()) {
|
||||||
Thread.currentThread().setName("API-CASE-THREAD");
|
ApiDefinitionExecResult result = executeQueue.get(testId);
|
||||||
for (String testId : executeQueue.keySet()) {
|
String reportId = result.getId();
|
||||||
ApiDefinitionExecResult result = executeQueue.get(testId);
|
HashTree hashTree = null;
|
||||||
String reportId = result.getId();
|
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
|
||||||
HashTree hashTree = null;
|
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
|
||||||
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
|
runRequest.setTestPlanReportId(executionQueue.getReportId());
|
||||||
hashTree = apiScenarioSerialService.generateHashTree(testId, result.getId(), runMode, config.getEnvMap());
|
runRequest.setPoolId(config.getResourcePoolId());
|
||||||
}
|
runRequest.setReportType(executionQueue.getReportType());
|
||||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
|
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
||||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
|
runRequest.setQueueId(executionQueue.getId());
|
||||||
runRequest.setTestPlanReportId(executionQueue.getReportId());
|
if (executionQueue.getQueue() != null) {
|
||||||
runRequest.setPoolId(config.getResourcePoolId());
|
runRequest.setPlatformUrl(executionQueue.getQueue().getId());
|
||||||
runRequest.setReportType(executionQueue.getReportType());
|
|
||||||
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
|
||||||
runRequest.setQueueId(executionQueue.getId());
|
|
||||||
if (executionQueue.getQueue() != null) {
|
|
||||||
runRequest.setPlatformUrl(executionQueue.getQueue().getId());
|
|
||||||
}
|
|
||||||
jMeterService.run(runRequest);
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
|
||||||
LoggerUtil.error("并发执行用例失败:" + e.getMessage());
|
hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
|
||||||
|
runRequest.setHashTree(hashTree);
|
||||||
|
}
|
||||||
|
jMeterService.run(runRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,11 +22,9 @@ public class ExecTask implements Runnable {
|
||||||
LoggerUtil.info("开始执行报告ID:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】");
|
LoggerUtil.info("开始执行报告ID:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】");
|
||||||
JMeterService jMeterService = CommonBeanFactory.getBean(JMeterService.class);
|
JMeterService jMeterService = CommonBeanFactory.getBean(JMeterService.class);
|
||||||
jMeterService.addQueue(request);
|
jMeterService.addQueue(request);
|
||||||
if (request.getPool() == null || !request.getPool().isPool()) {
|
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
|
||||||
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
|
if (res == null && !JmeterThreadUtils.isRunning(request.getReportId(), request.getTestId())) {
|
||||||
if (res == null && !JmeterThreadUtils.isRunning(request.getReportId(), request.getTestId())) {
|
LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时");
|
||||||
LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LoggerUtil.info("任务:【 " + request.getReportId() + " 】执行完成");
|
LoggerUtil.info("任务:【 " + request.getReportId() + " 】执行完成");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package io.metersphere.api.exec.queue;
|
package io.metersphere.api.exec.queue;
|
||||||
|
|
||||||
import io.metersphere.api.exec.utils.NamedThreadFactory;
|
import io.metersphere.api.exec.utils.NamedThreadFactory;
|
||||||
import io.metersphere.api.jmeter.MessageCache;
|
|
||||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
@ -93,6 +92,7 @@ public class ExecThreadPoolExecutor {
|
||||||
buffer.append(" 队列大小:" + (queue.size() + queue.remainingCapacity())).append("\n");
|
buffer.append(" 队列大小:" + (queue.size() + queue.remainingCapacity())).append("\n");
|
||||||
buffer.append(" 当前排队线程数:" + (msRejectedExecutionHandler.getBufferQueue().size() + queue.size())).append("\n");
|
buffer.append(" 当前排队线程数:" + (msRejectedExecutionHandler.getBufferQueue().size() + queue.size())).append("\n");
|
||||||
buffer.append(" 队列剩余大小:" + queue.remainingCapacity()).append("\n");
|
buffer.append(" 队列剩余大小:" + queue.remainingCapacity()).append("\n");
|
||||||
|
buffer.append(" 阻塞队列大小:" + PoolExecBlockingQueueUtil.queue.size()).append("\n");
|
||||||
buffer.append(" 队列使用度:" + divide(queue.size(), queue.size() + queue.remainingCapacity()));
|
buffer.append(" 队列使用度:" + divide(queue.size(), queue.size() + queue.remainingCapacity()));
|
||||||
|
|
||||||
LoggerUtil.info(buffer.toString());
|
LoggerUtil.info(buffer.toString());
|
||||||
|
@ -104,7 +104,6 @@ public class ExecThreadPoolExecutor {
|
||||||
|
|
||||||
public void setCorePoolSize(int corePoolSize) {
|
public void setCorePoolSize(int corePoolSize) {
|
||||||
try {
|
try {
|
||||||
MessageCache.corePoolSize = corePoolSize;
|
|
||||||
threadPool.setCorePoolSize(corePoolSize);
|
threadPool.setCorePoolSize(corePoolSize);
|
||||||
threadPool.setMaximumPoolSize(corePoolSize);
|
threadPool.setMaximumPoolSize(corePoolSize);
|
||||||
threadPool.allowCoreThreadTimeOut(true);
|
threadPool.allowCoreThreadTimeOut(true);
|
||||||
|
|
|
@ -11,7 +11,10 @@ import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.service.*;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
|
import io.metersphere.api.service.ApiScenarioReportService;
|
||||||
|
import io.metersphere.api.service.ApiScenarioReportStructureService;
|
||||||
|
import io.metersphere.api.service.TcpApiParamService;
|
||||||
import io.metersphere.base.domain.ApiScenarioExample;
|
import io.metersphere.base.domain.ApiScenarioExample;
|
||||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||||
|
@ -22,7 +25,6 @@ import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||||
import io.metersphere.commons.constants.TriggerMode;
|
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -42,11 +44,7 @@ import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.collections4.comparators.FixedOrderComparator;
|
import org.apache.commons.collections4.comparators.FixedOrderComparator;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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.apache.jorphan.collections.HashTree;
|
||||||
import org.mybatis.spring.SqlSessionUtils;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
@ -76,21 +74,17 @@ public class ApiScenarioExecuteService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioReportService apiScenarioReportService;
|
private ApiScenarioReportService apiScenarioReportService;
|
||||||
@Resource
|
@Resource
|
||||||
private RemakeReportService remakeReportService;
|
|
||||||
@Resource
|
|
||||||
private EnvironmentGroupProjectService environmentGroupProjectService;
|
private EnvironmentGroupProjectService environmentGroupProjectService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioReportStructureService apiScenarioReportStructureService;
|
private ApiScenarioReportStructureService reportStructureService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioSerialService apiScenarioSerialService;
|
private ApiScenarioSerialService serialService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioParallelService apiScenarioParallelService;
|
private ApiScenarioParallelService parallelService;
|
||||||
@Resource
|
@Resource
|
||||||
private TcpApiParamService tcpApiParamService;
|
private TcpApiParamService tcpApiParamService;
|
||||||
@Resource
|
@Resource
|
||||||
private JMeterService jMeterService;
|
private JMeterService jMeterService;
|
||||||
@Resource
|
|
||||||
private SqlSessionFactory sqlSessionFactory;
|
|
||||||
|
|
||||||
public List<MsExecResponseDTO> run(RunScenarioRequest request) {
|
public List<MsExecResponseDTO> run(RunScenarioRequest request) {
|
||||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||||
|
@ -119,7 +113,7 @@ public class ApiScenarioExecuteService {
|
||||||
LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查");
|
LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查");
|
||||||
apiScenarioEnvService.checkEnv(request, apiScenarios);
|
apiScenarioEnvService.checkEnv(request, apiScenarios);
|
||||||
// 集合报告设置
|
// 集合报告设置
|
||||||
if (request.getConfig() != null && StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())
|
if (StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())
|
||||||
&& StringUtils.isNotEmpty(request.getConfig().getReportName())) {
|
&& StringUtils.isNotEmpty(request.getConfig().getReportName())) {
|
||||||
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||||
request.setExecuteType(ExecuteType.Completed.name());
|
request.setExecuteType(ExecuteType.Completed.name());
|
||||||
|
@ -128,14 +122,14 @@ public class ApiScenarioExecuteService {
|
||||||
}
|
}
|
||||||
serialReportId = UUID.randomUUID().toString();
|
serialReportId = UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
|
||||||
|
|
||||||
Map<String, RunModeDataDTO> executeQueue = new LinkedHashMap<>();
|
Map<String, RunModeDataDTO> executeQueue = new LinkedHashMap<>();
|
||||||
List<String> scenarioIds = new ArrayList<>();
|
List<String> scenarioIds = new ArrayList<>();
|
||||||
StringBuilder scenarioNames = new StringBuilder();
|
StringBuilder scenarioNames = new StringBuilder();
|
||||||
|
|
||||||
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列");
|
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列");
|
||||||
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(),
|
||||||
|
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
//测试计划执行
|
//测试计划执行
|
||||||
assemblyPlanScenario(apiScenarios, request, executeQueue, scenarioIds, scenarioNames);
|
assemblyPlanScenario(apiScenarios, request, executeQueue, scenarioIds, scenarioNames);
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,58 +138,43 @@ public class ApiScenarioExecuteService {
|
||||||
}
|
}
|
||||||
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列完成:" + executeQueue.size());
|
LoggerUtil.info("Scenario run-执行脚本装载-初始化执行队列完成:" + executeQueue.size());
|
||||||
|
|
||||||
|
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||||
|
if (executeQueue.isEmpty()) {
|
||||||
|
return responseDTOS;
|
||||||
|
}
|
||||||
if (GenerateHashTreeUtil.isSetReport(request.getConfig())) {
|
if (GenerateHashTreeUtil.isSetReport(request.getConfig())) {
|
||||||
LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId);
|
LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId);
|
||||||
request.getConfig().setReportId(UUID.randomUUID().toString());
|
request.getConfig().setReportId(UUID.randomUUID().toString());
|
||||||
|
|
||||||
APIScenarioReportResult report = apiScenarioReportService.init(request.getConfig().getReportId(),
|
String reportScenarioIds = JSON.toJSONString(CollectionUtils.isNotEmpty(scenarioIds) && scenarioIds.size() > 50 ? scenarioIds.subList(0, 50) : scenarioIds);
|
||||||
JSON.toJSONString(CollectionUtils.isNotEmpty(scenarioIds) && scenarioIds.size() > 50 ? scenarioIds.subList(0, 50) : scenarioIds),
|
APIScenarioReportResult report = apiScenarioReportService.init(request.getConfig().getReportId(), reportScenarioIds,
|
||||||
scenarioNames.length() >= 3000 ? scenarioNames.substring(0, 2000) : scenarioNames.deleteCharAt(scenarioNames.length() - 1).toString(),
|
scenarioNames.toString(), ReportTriggerMode.MANUAL.name(), ExecuteType.Saved.name(), request.getProjectId(),
|
||||||
ReportTriggerMode.MANUAL.name(), ExecuteType.Saved.name(), request.getProjectId(), request.getReportUserID(), request.getConfig(), JSON.toJSONString(scenarioIds));
|
request.getReportUserID(), request.getConfig());
|
||||||
|
|
||||||
report.setVersionId(apiScenarios.get(0).getVersionId());
|
report.setVersionId(apiScenarios.get(0).getVersionId());
|
||||||
report.setName(request.getConfig().getReportName());
|
report.setName(request.getConfig().getReportName());
|
||||||
report.setId(serialReportId);
|
report.setId(serialReportId);
|
||||||
request.getConfig().setAmassReport(serialReportId);
|
request.getConfig().setAmassReport(serialReportId);
|
||||||
|
report.setStatus(APITestStatus.Running.name());
|
||||||
apiScenarioReportMapper.insert(report);
|
apiScenarioReportMapper.insert(report);
|
||||||
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
|
|
||||||
// 增加并行集合报告
|
|
||||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.PARALLEL.toString())) {
|
|
||||||
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig() != null
|
|
||||||
? request.getConfig().getReportType() : null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 开始执行
|
|
||||||
if (executeQueue != null && executeQueue.size() > 0) {
|
|
||||||
String reportType = request.getConfig().getReportType();
|
|
||||||
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
|
|
||||||
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId()
|
|
||||||
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
|
|
||||||
|
|
||||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
|
||||||
if (StringUtils.isNotEmpty(serialReportId)) {
|
reportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType());
|
||||||
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig() != null ? request.getConfig().getReportType() : null);
|
}
|
||||||
}
|
String reportType = request.getConfig().getReportType();
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
|
||||||
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
|
// 生成执行队列
|
||||||
// 非集合报告,先生成执行队列
|
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId()
|
||||||
if (StringUtils.isEmpty(serialReportId)) {
|
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
|
||||||
for (String reportId : executeQueue.keySet()) {
|
|
||||||
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
|
// 预生成报告
|
||||||
report.setStatus(APITestStatus.Waiting.name());
|
apiScenarioReportService.batchSave(executeQueue, serialReportId, request.getRunMode(), responseDTOS);
|
||||||
batchMapper.insert(report);
|
|
||||||
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode()));
|
// 开始执行
|
||||||
}
|
if (StringUtils.equals(request.getConfig().getMode(), RunModeConstants.SERIAL.toString())) {
|
||||||
sqlSession.flushStatements();
|
serialService.serial(executionQueue, executionQueue.getQueue());
|
||||||
if (sqlSession != null && sqlSessionFactory != null) {
|
} else {
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
parallelService.parallel(executeQueue, request, serialReportId, executionQueue);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (executionQueue.getQueue() != null) {
|
|
||||||
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS, executionQueue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return responseDTOS;
|
return responseDTOS;
|
||||||
}
|
}
|
||||||
|
@ -239,11 +218,9 @@ public class ApiScenarioExecuteService {
|
||||||
if (scenario.getStepTotal() == null || scenario.getStepTotal() == 0) {
|
if (scenario.getStepTotal() == null || scenario.getStepTotal() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
APIScenarioReportResult report;
|
|
||||||
Map<String, String> planEnvMap = new HashMap<>();
|
|
||||||
|
|
||||||
//测试计划页面触发的执行方式,生成报告时createScenarioReport第二个参数需要特殊处理
|
|
||||||
// 获取场景用例单独的执行环境
|
// 获取场景用例单独的执行环境
|
||||||
|
Map<String, String> planEnvMap = new HashMap<>();
|
||||||
TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId);
|
TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId);
|
||||||
String envJson = planApiScenario.getEnvironment();
|
String envJson = planApiScenario.getEnvironment();
|
||||||
String envType = planApiScenario.getEnvironmentType();
|
String envType = planApiScenario.getEnvironmentType();
|
||||||
|
@ -259,36 +236,23 @@ public class ApiScenarioExecuteService {
|
||||||
if (StringUtils.isEmpty(projectId)) {
|
if (StringUtils.isEmpty(projectId)) {
|
||||||
projectId = scenario.getProjectId();
|
projectId = scenario.getProjectId();
|
||||||
}
|
}
|
||||||
report = apiScenarioReportService.init(reportId, testPlanScenarioId, scenario.getName(), request.getTriggerMode(),
|
|
||||||
request.getExecuteType(), projectId, request.getReportUserID(), request.getConfig(), scenario.getId());
|
APIScenarioReportResult report = apiScenarioReportService.init(reportId, testPlanScenarioId, scenario.getName(), request.getTriggerMode(),
|
||||||
|
request.getExecuteType(), projectId, request.getReportUserID(), request.getConfig());
|
||||||
|
|
||||||
report.setVersionId(scenario.getVersionId());
|
report.setVersionId(scenario.getVersionId());
|
||||||
scenarioIds.add(scenario.getId());
|
scenarioIds.add(scenario.getId());
|
||||||
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
|
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
|
||||||
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
|
runModeDataDTO.setTestId(testPlanScenarioId);
|
||||||
runModeDataDTO.setTestId(testPlanScenarioId);
|
runModeDataDTO.setPlanEnvMap(planEnvMap);
|
||||||
runModeDataDTO.setPlanEnvMap(planEnvMap);
|
runModeDataDTO.setReport(report);
|
||||||
runModeDataDTO.setReport(report);
|
runModeDataDTO.setReportId(report.getId());
|
||||||
runModeDataDTO.setReportId(report.getId());
|
runModeDataDTO.setScenario(scenario);
|
||||||
executeQueue.put(report.getId(), runModeDataDTO);
|
executeQueue.put(report.getId(), runModeDataDTO);
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
// 生成并行报告和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, request.getConfig().getReportType()));
|
|
||||||
}
|
|
||||||
executeQueue.put(report.getId(), runModeDataDTO);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
scenarioIds.remove(scenario.getId());
|
|
||||||
executeQueue.remove(report.getId());
|
|
||||||
remakeReportService.remakeScenario(request.getRunMode(), testPlanScenarioId, scenario, report);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scenarioNames.append(scenario.getName()).append(",");
|
scenarioNames.append(scenario.getName()).append(",");
|
||||||
// 生成文档结构
|
// 生成文档结构
|
||||||
if (request.getConfig() == null || !StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||||
apiScenarioReportStructureService.save(scenario, report.getId(), request.getConfig() != null ? request.getConfig().getReportType() : null);
|
reportStructureService.save(scenario, report.getId(), request.getConfig() != null ? request.getConfig().getReportType() : null);
|
||||||
}
|
}
|
||||||
// 重置报告ID
|
// 重置报告ID
|
||||||
reportId = UUID.randomUUID().toString();
|
reportId = UUID.randomUUID().toString();
|
||||||
|
@ -306,42 +270,25 @@ public class ApiScenarioExecuteService {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
APIScenarioReportResult report = apiScenarioReportService.init(reportId, item.getId(), item.getName(), request.getTriggerMode(),
|
APIScenarioReportResult report = apiScenarioReportService.init(reportId, item.getId(), item.getName(), request.getTriggerMode(),
|
||||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig(), item.getId());
|
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());
|
||||||
scenarioIds.add(item.getId());
|
scenarioIds.add(item.getId());
|
||||||
report.setVersionId(item.getVersionId());
|
report.setVersionId(item.getVersionId());
|
||||||
scenarioNames.append(item.getName()).append(",");
|
scenarioNames.append(item.getName()).append(",");
|
||||||
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
|
|
||||||
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
|
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
|
||||||
runModeDataDTO.setTestId(item.getId());
|
runModeDataDTO.setTestId(item.getId());
|
||||||
runModeDataDTO.setPlanEnvMap(new HashMap<>());
|
runModeDataDTO.setPlanEnvMap(new HashMap<>());
|
||||||
if (request.getConfig().getEnvMap() != null) {
|
if (request.getConfig().getEnvMap() != null) {
|
||||||
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
|
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
|
||||||
}
|
|
||||||
runModeDataDTO.setReport(report);
|
|
||||||
runModeDataDTO.setReportId(report.getId());
|
|
||||||
executeQueue.put(report.getId(), runModeDataDTO);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
// 生成报告和HashTree
|
|
||||||
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, request.getConfig().getEnvMap(), request.getConfig().getReportType());
|
|
||||||
runModeDataDTO.setHashTree(hashTree);
|
|
||||||
}
|
|
||||||
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
|
|
||||||
executeQueue.put(report.getId(), runModeDataDTO);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
scenarioIds.remove(item.getId());
|
|
||||||
if (StringUtils.equalsAny(request.getTriggerMode(), TriggerMode.BATCH.name(), TriggerMode.SCHEDULE.name())) {
|
|
||||||
remakeReportService.remakeScenario(request.getRunMode(), null, item, report);
|
|
||||||
} else {
|
|
||||||
MSException.throwException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
runModeDataDTO.setReport(report);
|
||||||
|
runModeDataDTO.setReportId(report.getId());
|
||||||
|
executeQueue.put(report.getId(), runModeDataDTO);
|
||||||
|
runModeDataDTO.setScenario(item);
|
||||||
|
executeQueue.put(report.getId(), runModeDataDTO);
|
||||||
// 生成报告结构
|
// 生成报告结构
|
||||||
if (request.getConfig() == null || !StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||||
apiScenarioReportStructureService.save(item, report.getId(), request.getConfig() != null ? request.getConfig().getReportType() : null);
|
reportStructureService.save(item, report.getId(), request.getConfig().getReportType());
|
||||||
}
|
}
|
||||||
// 重置报告ID
|
// 重置报告ID
|
||||||
reportId = UUID.randomUUID().toString();
|
reportId = UUID.randomUUID().toString();
|
||||||
|
@ -381,13 +328,12 @@ public class ApiScenarioExecuteService {
|
||||||
request.getExecuteType(),
|
request.getExecuteType(),
|
||||||
request.getProjectId(),
|
request.getProjectId(),
|
||||||
SessionUtils.getUserId(),
|
SessionUtils.getUserId(),
|
||||||
request.getConfig(),
|
request.getConfig());
|
||||||
request.getId());
|
|
||||||
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(request.getScenarioId());
|
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(request.getScenarioId());
|
||||||
String reportType = request.getConfig() != null ? request.getConfig().getReportType() : null;
|
String reportType = request.getConfig() != null ? request.getConfig().getReportType() : null;
|
||||||
if (scenario != null) {
|
if (scenario != null) {
|
||||||
report.setVersionId(scenario.getVersionId());
|
report.setVersionId(scenario.getVersionId());
|
||||||
apiScenarioReportStructureService.save(scenario, report.getId(), reportType);
|
reportStructureService.save(scenario, report.getId(), reportType);
|
||||||
} else {
|
} else {
|
||||||
if (request.getTestElement() != null && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree())) {
|
if (request.getTestElement() != null && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree())) {
|
||||||
ApiScenarioWithBLOBs apiScenario = new ApiScenarioWithBLOBs();
|
ApiScenarioWithBLOBs apiScenario = new ApiScenarioWithBLOBs();
|
||||||
|
@ -396,7 +342,7 @@ public class ApiScenarioExecuteService {
|
||||||
if (testElement != null) {
|
if (testElement != null) {
|
||||||
apiScenario.setName(testElement.getName());
|
apiScenario.setName(testElement.getName());
|
||||||
apiScenario.setScenarioDefinition(JSON.toJSONString(testElement));
|
apiScenario.setScenarioDefinition(JSON.toJSONString(testElement));
|
||||||
apiScenarioReportStructureService.save(apiScenario, report.getId(), reportType);
|
reportStructureService.save(apiScenario, report.getId(), reportType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,53 +2,28 @@ package io.metersphere.api.exec.scenario;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import io.metersphere.api.dto.RunModeDataDTO;
|
import io.metersphere.api.dto.RunModeDataDTO;
|
||||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
|
||||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
|
||||||
import io.metersphere.constants.RunModeConstants;
|
import io.metersphere.constants.RunModeConstants;
|
||||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.dto.MsExecResponseDTO;
|
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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 org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ApiScenarioParallelService {
|
public class ApiScenarioParallelService {
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SqlSessionFactory sqlSessionFactory;
|
|
||||||
@Resource
|
@Resource
|
||||||
private JMeterService jMeterService;
|
private JMeterService jMeterService;
|
||||||
|
|
||||||
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS, DBTestQueue executionQueue) {
|
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) {
|
||||||
if (StringUtils.isEmpty(serialReportId)) {
|
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
|
||||||
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
|
|
||||||
// 开始并发执行
|
|
||||||
for (String reportId : executeQueue.keySet()) {
|
|
||||||
//存储报告
|
|
||||||
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
|
|
||||||
batchMapper.insert(report);
|
|
||||||
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode()));
|
|
||||||
}
|
|
||||||
sqlSession.flushStatements();
|
|
||||||
if (sqlSession != null && sqlSessionFactory != null) {
|
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String reportId : executeQueue.keySet()) {
|
for (String reportId : executeQueue.keySet()) {
|
||||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(executeQueue.get(reportId).getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), executeQueue.get(reportId).getHashTree());
|
RunModeDataDTO dataDTO = executeQueue.get(reportId);
|
||||||
|
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null);
|
||||||
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
|
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
|
||||||
runRequest.setQueueId(executionQueue.getId());
|
runRequest.setQueueId(executionQueue.getId());
|
||||||
if (request.getConfig() != null) {
|
if (request.getConfig() != null) {
|
||||||
|
@ -56,12 +31,15 @@ public class ApiScenarioParallelService {
|
||||||
runRequest.setPoolId(request.getConfig().getResourcePoolId());
|
runRequest.setPoolId(request.getConfig().getResourcePoolId());
|
||||||
}
|
}
|
||||||
runRequest.setTestPlanReportId(request.getTestPlanReportId());
|
runRequest.setTestPlanReportId(request.getTestPlanReportId());
|
||||||
runRequest.setHashTree(executeQueue.get(reportId).getHashTree());
|
|
||||||
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId));
|
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId));
|
||||||
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
||||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||||
LoggerUtil.debug("Scenario run-开始并发执行:" + JSON.toJSONString(request));
|
LoggerUtil.debug("Scenario run-开始并发执行:" + JSON.toJSONString(request));
|
||||||
}
|
}
|
||||||
|
// 本地执行生成hashTree
|
||||||
|
if (request.getConfig() != null && !runRequest.getPool().isPool()) {
|
||||||
|
runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest));
|
||||||
|
}
|
||||||
jMeterService.run(runRequest);
|
jMeterService.run(runRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,13 @@ import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
|
||||||
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
||||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.service.ApiDefinitionExecResultService;
|
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||||
import io.metersphere.api.service.TestResultService;
|
import io.metersphere.api.service.RemakeReportService;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.exception.MSException;
|
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.HashTreeUtil;
|
import io.metersphere.commons.utils.HashTreeUtil;
|
||||||
|
@ -80,8 +78,19 @@ public class ApiScenarioSerialService {
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggerUtil.info("Scenario run-开始执行,队列ID:【 " + executionQueue.getReportId() + " 】");
|
LoggerUtil.info("Scenario run-开始执行,队列ID:【 " + executionQueue.getReportId() + " 】");
|
||||||
|
String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
|
||||||
|
if (!StringUtils.equals(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
||||||
|
reportId = queue.getReportId();
|
||||||
|
}
|
||||||
|
HashTree hashTree = null;
|
||||||
|
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());
|
||||||
try {
|
try {
|
||||||
HashTree hashTree = null;
|
|
||||||
if (StringUtils.isEmpty(executionQueue.getPoolId())) {
|
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())) {
|
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 = null;
|
ApiScenarioWithBLOBs scenario = null;
|
||||||
|
@ -99,53 +108,30 @@ public class ApiScenarioSerialService {
|
||||||
if ((planEnvMap == null || planEnvMap.isEmpty()) && StringUtils.isNotEmpty(queue.getEvnMap())) {
|
if ((planEnvMap == null || planEnvMap.isEmpty()) && StringUtils.isNotEmpty(queue.getEvnMap())) {
|
||||||
planEnvMap = JSON.parseObject(queue.getEvnMap(), Map.class);
|
planEnvMap = JSON.parseObject(queue.getEvnMap(), Map.class);
|
||||||
}
|
}
|
||||||
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, queue.getReportId(), planEnvMap, executionQueue.getReportType());
|
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, planEnvMap, runRequest);
|
||||||
} else {
|
} else {
|
||||||
Map<String, String> map = new LinkedHashMap<>();
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
|
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
|
||||||
map = JSON.parseObject(queue.getEvnMap(), Map.class);
|
map = JSON.parseObject(queue.getEvnMap(), Map.class);
|
||||||
}
|
}
|
||||||
hashTree = generateHashTree(queue.getTestId(), queue.getReportId(), executionQueue.getRunMode(), map);
|
hashTree = generateHashTree(queue.getTestId(), map, runRequest);
|
||||||
}
|
}
|
||||||
// 更新环境变量
|
// 更新环境变量
|
||||||
this.initEnv(hashTree);
|
this.initEnv(hashTree);
|
||||||
}
|
}
|
||||||
String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
|
runRequest.setHashTree(hashTree);
|
||||||
if (!StringUtils.equals(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
|
||||||
reportId = 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());
|
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
runRequest.setPlatformUrl(queue.getId());
|
runRequest.setPlatformUrl(queue.getId());
|
||||||
}
|
}
|
||||||
// 开始执行
|
// 开始执行
|
||||||
jMeterService.run(runRequest);
|
jMeterService.run(runRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LoggerUtil.error("执行终止:" + e.getMessage());
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
remakeReportService.remake(runRequest);
|
||||||
ResultDTO dto = new ResultDTO();
|
ResultDTO dto = new ResultDTO();
|
||||||
BeanUtils.copyBean(dto, queue);
|
BeanUtils.copyBean(dto, runRequest);
|
||||||
dto.setRunType(RunModeConstants.SERIAL.toString());
|
|
||||||
dto.setReportType(executionQueue.getReportType());
|
|
||||||
dto.setRunMode(executionQueue.getRunMode());
|
|
||||||
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())) {
|
|
||||||
CommonBeanFactory.getBean(TestResultService.class).testEnded(dto);
|
|
||||||
} else {
|
|
||||||
ApiDefinitionExecResult apiDefinitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
|
|
||||||
if (apiDefinitionExecResult != null) {
|
|
||||||
apiDefinitionExecResult.setStatus("Error");
|
|
||||||
apiDefinitionExecResultMapper.updateByPrimaryKey(apiDefinitionExecResult);
|
|
||||||
CommonBeanFactory.getBean(ApiDefinitionExecResultService.class)
|
|
||||||
.editStatus(apiDefinitionExecResult, executionQueue.getRunMode(), "Error"
|
|
||||||
, System.currentTimeMillis(), apiDefinitionExecResult.getId(), queue.getTestId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||||
|
LoggerUtil.error("执行终止:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,24 +142,25 @@ public class ApiScenarioSerialService {
|
||||||
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashTree generateHashTree(String testId, String reportId, String runMode, Map<String, String> envMap) {
|
public HashTree generateHashTree(String testId, Map<String, String> envMap, JmeterRunRequestDTO runRequest) {
|
||||||
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
try {
|
||||||
String envId = null;
|
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
||||||
if (caseWithBLOBs == null) {
|
String envId = null;
|
||||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
if (caseWithBLOBs == null) {
|
||||||
if (apiCase != null) {
|
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
if (apiCase != null) {
|
||||||
envId = apiCase.getEnvironmentId();
|
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
||||||
|
envId = apiCase.getEnvironmentId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (envMap != null && envMap.containsKey(caseWithBLOBs.getProjectId())) {
|
||||||
if (envMap != null && envMap.containsKey(caseWithBLOBs.getProjectId())) {
|
envId = envMap.get(caseWithBLOBs.getProjectId());
|
||||||
envId = envMap.get(caseWithBLOBs.getProjectId());
|
}
|
||||||
}
|
if (caseWithBLOBs != null) {
|
||||||
if (caseWithBLOBs != null) {
|
HashTree jmeterHashTree = new HashTree();
|
||||||
HashTree jmeterHashTree = new HashTree();
|
MsTestPlan testPlan = new MsTestPlan();
|
||||||
MsTestPlan testPlan = new MsTestPlan();
|
testPlan.setHashTree(new LinkedList<>());
|
||||||
testPlan.setHashTree(new LinkedList<>());
|
|
||||||
try {
|
|
||||||
MsThreadGroup group = new MsThreadGroup();
|
MsThreadGroup group = new MsThreadGroup();
|
||||||
group.setLabel(caseWithBLOBs.getName());
|
group.setLabel(caseWithBLOBs.getName());
|
||||||
group.setName(caseWithBLOBs.getName());
|
group.setName(caseWithBLOBs.getName());
|
||||||
|
@ -185,18 +172,13 @@ public class ApiScenarioSerialService {
|
||||||
testPlan.getHashTree().add(group);
|
testPlan.getHashTree().add(group);
|
||||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||||
return jmeterHashTree;
|
return jmeterHashTree;
|
||||||
} catch (Exception ex) {
|
|
||||||
ApiDefinitionExecResult apiDefinitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId);
|
|
||||||
|
|
||||||
if (apiDefinitionExecResult != null) {
|
|
||||||
apiDefinitionExecResult.setStatus("Error");
|
|
||||||
apiDefinitionExecResultMapper.updateByPrimaryKey(apiDefinitionExecResult);
|
|
||||||
CommonBeanFactory.getBean(ApiDefinitionExecResultService.class)
|
|
||||||
.editStatus(apiDefinitionExecResult, runMode, "error"
|
|
||||||
, System.currentTimeMillis(), apiDefinitionExecResult.getId(), testId);
|
|
||||||
}
|
|
||||||
MSException.throwException(ex.getMessage());
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
remakeReportService.remake(runRequest);
|
||||||
|
ResultDTO dto = new ResultDTO();
|
||||||
|
BeanUtils.copyBean(dto, runRequest);
|
||||||
|
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
import io.metersphere.base.domain.TestPlanApiCase;
|
import io.metersphere.base.domain.TestPlanApiCase;
|
||||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
|
||||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.TriggerMode;
|
import io.metersphere.commons.constants.TriggerMode;
|
||||||
|
@ -40,7 +39,7 @@ public class ApiDefinitionExecResultUtil {
|
||||||
return apiResult;
|
return apiResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status, ApiDefinitionExecResultMapper batchMapper) {
|
public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status) {
|
||||||
ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult();
|
ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult();
|
||||||
apiResult.setId(UUID.randomUUID().toString());
|
apiResult.setId(UUID.randomUUID().toString());
|
||||||
apiResult.setCreateTime(System.currentTimeMillis());
|
apiResult.setCreateTime(System.currentTimeMillis());
|
||||||
|
@ -68,7 +67,6 @@ public class ApiDefinitionExecResultUtil {
|
||||||
apiResult.setType(ApiRunMode.API_PLAN.name());
|
apiResult.setType(ApiRunMode.API_PLAN.name());
|
||||||
apiResult.setStatus(status);
|
apiResult.setStatus(status);
|
||||||
apiResult.setContent(request.getPlanReportId());
|
apiResult.setContent(request.getPlanReportId());
|
||||||
batchMapper.insert(apiResult);
|
|
||||||
return apiResult;
|
return apiResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,19 @@ import io.metersphere.api.dto.EnvironmentType;
|
||||||
import io.metersphere.api.dto.definition.request.*;
|
import io.metersphere.api.dto.definition.request.*;
|
||||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||||
import io.metersphere.api.jmeter.ResourcePoolCalculation;
|
import io.metersphere.api.jmeter.ResourcePoolCalculation;
|
||||||
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
|
import io.metersphere.api.service.RemakeReportService;
|
||||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
import io.metersphere.base.domain.TestResourcePool;
|
import io.metersphere.base.domain.TestResourcePool;
|
||||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||||
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.constants.RunModeConstants;
|
import io.metersphere.constants.RunModeConstants;
|
||||||
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.dto.JvmInfoDTO;
|
import io.metersphere.dto.JvmInfoDTO;
|
||||||
|
import io.metersphere.dto.ResultDTO;
|
||||||
import io.metersphere.dto.RunModeConfigDTO;
|
import io.metersphere.dto.RunModeConfigDTO;
|
||||||
import io.metersphere.plugin.core.MsTestElement;
|
import io.metersphere.plugin.core.MsTestElement;
|
||||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||||
|
@ -120,14 +124,14 @@ public class GenerateHashTreeUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashTree generateHashTree(ApiScenarioWithBLOBs item, String reportId, Map<String, String> planEnvMap, String reportType) {
|
public static HashTree generateHashTree(ApiScenarioWithBLOBs item, Map<String, String> planEnvMap, JmeterRunRequestDTO runRequest) {
|
||||||
HashTree jmeterHashTree = new HashTree();
|
HashTree jmeterHashTree = new HashTree();
|
||||||
MsTestPlan testPlan = new MsTestPlan();
|
MsTestPlan testPlan = new MsTestPlan();
|
||||||
testPlan.setHashTree(new LinkedList<>());
|
testPlan.setHashTree(new LinkedList<>());
|
||||||
try {
|
try {
|
||||||
MsThreadGroup group = new MsThreadGroup();
|
MsThreadGroup group = new MsThreadGroup();
|
||||||
group.setLabel(item.getName());
|
group.setLabel(item.getName());
|
||||||
group.setName(reportId);
|
group.setName(runRequest.getReportId());
|
||||||
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
|
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
|
||||||
group.setOnSampleError(scenario.getOnSampleError());
|
group.setOnSampleError(scenario.getOnSampleError());
|
||||||
if (planEnvMap != null && planEnvMap.size() > 0) {
|
if (planEnvMap != null && planEnvMap.size() > 0) {
|
||||||
|
@ -144,11 +148,15 @@ public class GenerateHashTreeUtil {
|
||||||
group.setHashTree(scenarios);
|
group.setHashTree(scenarios);
|
||||||
testPlan.getHashTree().add(group);
|
testPlan.getHashTree().add(group);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
MSException.throwException(ex.getMessage());
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
remakeReportService.remake(runRequest);
|
||||||
|
ResultDTO dto = new ResultDTO();
|
||||||
|
BeanUtils.copyBean(dto, runRequest);
|
||||||
|
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
|
||||||
}
|
}
|
||||||
ParameterConfig config = new ParameterConfig();
|
ParameterConfig config = new ParameterConfig();
|
||||||
config.setScenarioId(item.getId());
|
config.setScenarioId(item.getId());
|
||||||
config.setReportType(reportType);
|
config.setReportType(runRequest.getReportType());
|
||||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
||||||
return jmeterHashTree;
|
return jmeterHashTree;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package io.metersphere.api.jmeter;
|
||||||
|
|
||||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
import io.metersphere.api.service.MsResultService;
|
|
||||||
import io.metersphere.api.service.TestResultService;
|
import io.metersphere.api.service.TestResultService;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
@ -21,7 +20,7 @@ public class APISingleResultListener extends MsExecListener {
|
||||||
@Override
|
@Override
|
||||||
public void handleTeardownTest(ResultDTO dto, Map<String, Object> kafkaConfig) {
|
public void handleTeardownTest(ResultDTO dto, Map<String, Object> kafkaConfig) {
|
||||||
LoggerUtil.info("处理单条执行结果报告【" + dto.getReportId() + " 】,资源【 " + dto.getTestId() + " 】");
|
LoggerUtil.info("处理单条执行结果报告【" + dto.getReportId() + " 】,资源【 " + dto.getTestId() + " 】");
|
||||||
dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId()));
|
dto.setConsole(FixedCapacityUtils.getJmeterLogger(dto.getReportId()));
|
||||||
CommonBeanFactory.getBean(TestResultService.class).saveResults(dto);
|
CommonBeanFactory.getBean(TestResultService.class).saveResults(dto);
|
||||||
|
|
||||||
// 更新报告最后接收到请求的时间
|
// 更新报告最后接收到请求的时间
|
||||||
|
@ -38,7 +37,7 @@ public class APISingleResultListener extends MsExecListener {
|
||||||
LoggerUtil.info("进入TEST-END处理报告【" + dto.getReportId() + " 】整体执行完成;" + dto.getRunMode());
|
LoggerUtil.info("进入TEST-END处理报告【" + dto.getReportId() + " 】整体执行完成;" + dto.getRunMode());
|
||||||
// 全局并发队列
|
// 全局并发队列
|
||||||
PoolExecBlockingQueueUtil.offer(dto.getReportId());
|
PoolExecBlockingQueueUtil.offer(dto.getReportId());
|
||||||
dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId()));
|
dto.setConsole(FixedCapacityUtils.getJmeterLogger(dto.getReportId()));
|
||||||
// 整体执行结束更新资源状态
|
// 整体执行结束更新资源状态
|
||||||
CommonBeanFactory.getBean(TestResultService.class).testEnded(dto);
|
CommonBeanFactory.getBean(TestResultService.class).testEnded(dto);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package io.metersphere.api.jmeter;
|
package io.metersphere.api.jmeter;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class FixedCapacityUtils {
|
public class FixedCapacityUtils {
|
||||||
public static Map<Long, StringBuffer> fixedCapacityCache = Collections.synchronizedMap(new LRUHashMap<>());
|
public static Map<Long, StringBuffer> fixedCapacityCache = Collections.synchronizedMap(new LRUHashMap<>());
|
||||||
|
public final static Map<String, Long> jmeterLogTask = new HashMap<>();
|
||||||
|
|
||||||
public static StringBuffer get(Long key) {
|
public static StringBuffer get(Long key) {
|
||||||
return fixedCapacityCache.get(key);
|
return fixedCapacityCache.get(key);
|
||||||
|
@ -28,4 +31,25 @@ public class FixedCapacityUtils {
|
||||||
return size() > capacity;
|
return size() > capacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getJmeterLogger(String testId) {
|
||||||
|
try {
|
||||||
|
Long startTime = FixedCapacityUtils.jmeterLogTask.get(testId);
|
||||||
|
if (startTime == null) {
|
||||||
|
startTime = FixedCapacityUtils.jmeterLogTask.get("[" + testId + "]");
|
||||||
|
}
|
||||||
|
if (startTime == null) {
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
Long endTime = System.currentTimeMillis();
|
||||||
|
Long finalStartTime = startTime;
|
||||||
|
String logMessage = FixedCapacityUtils.fixedCapacityCache.entrySet().stream()
|
||||||
|
.filter(map -> map.getKey() > finalStartTime && map.getKey() < endTime)
|
||||||
|
.map(map -> map.getValue()).collect(Collectors.joining());
|
||||||
|
return logMessage;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package io.metersphere.api.jmeter;
|
||||||
|
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -15,7 +14,6 @@ public class FixedTask {
|
||||||
if (queueService == null) {
|
if (queueService == null) {
|
||||||
queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class);
|
queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class);
|
||||||
}
|
}
|
||||||
LoggerUtil.info("进入超时处理");
|
|
||||||
queueService.timeOut();
|
queueService.timeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import io.metersphere.performance.engine.Engine;
|
||||||
import io.metersphere.performance.engine.EngineFactory;
|
import io.metersphere.performance.engine.EngineFactory;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.jmeter.save.SaveService;
|
import org.apache.jmeter.save.SaveService;
|
||||||
import org.apache.jmeter.testelement.TestElement;
|
import org.apache.jmeter.testelement.TestElement;
|
||||||
|
@ -25,7 +26,6 @@ import org.apache.jorphan.collections.HashTree;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
@ -34,7 +34,6 @@ import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class JMeterService {
|
public class JMeterService {
|
||||||
public static final String BASE_URL = "http://%s:%d";
|
public static final String BASE_URL = "http://%s:%d";
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -77,11 +76,11 @@ public class JMeterService {
|
||||||
|
|
||||||
private void runLocal(JmeterRunRequestDTO request) {
|
private void runLocal(JmeterRunRequestDTO request) {
|
||||||
init();
|
init();
|
||||||
if (!MessageCache.jmeterLogTask.containsKey(request.getReportId())) {
|
if (!FixedCapacityUtils.jmeterLogTask.containsKey(request.getReportId())) {
|
||||||
MessageCache.jmeterLogTask.put(request.getReportId(), System.currentTimeMillis());
|
FixedCapacityUtils.jmeterLogTask.put(request.getReportId(), System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggerUtil.debug("监听MessageCache.tasks当前容量:" + MessageCache.jmeterLogTask.size());
|
LoggerUtil.debug("监听MessageCache.tasks当前容量:" + FixedCapacityUtils.jmeterLogTask.size());
|
||||||
if (request.isDebug() && !StringUtils.equalsAny(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
if (request.isDebug() && !StringUtils.equalsAny(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
|
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
|
||||||
JMeterBase.addSyncListener(request, request.getHashTree(), APISingleResultListener.class.getCanonicalName());
|
JMeterBase.addSyncListener(request, request.getHashTree(), APISingleResultListener.class.getCanonicalName());
|
||||||
|
@ -135,9 +134,16 @@ public class JMeterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send(JmeterRunRequestDTO request) {
|
private synchronized void send(JmeterRunRequestDTO request) {
|
||||||
try {
|
try {
|
||||||
List<JvmInfoDTO> resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId());
|
List<JvmInfoDTO> resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId());
|
||||||
|
if (CollectionUtils.isEmpty(resources)) {
|
||||||
|
LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】");
|
||||||
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
remakeReportService.remake(request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int index = (int) (Math.random() * resources.size());
|
int index = (int) (Math.random() * resources.size());
|
||||||
JvmInfoDTO jvmInfoDTO = resources.get(index);
|
JvmInfoDTO jvmInfoDTO = resources.get(index);
|
||||||
TestResourceDTO testResource = jvmInfoDTO.getTestResource();
|
TestResourceDTO testResource = jvmInfoDTO.getTestResource();
|
||||||
|
@ -150,7 +156,6 @@ public class JMeterService {
|
||||||
String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port);
|
String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port);
|
||||||
|
|
||||||
LoggerUtil.info("开始发送请求【 " + request.getReportId() + " 】,资源【 " + request.getTestId() + " 】" + uri + " 节点执行");
|
LoggerUtil.info("开始发送请求【 " + request.getReportId() + " 】,资源【 " + request.getTestId() + " 】" + uri + " 节点执行");
|
||||||
|
|
||||||
ResponseEntity<String> result = restTemplate.postForEntity(uri, request, String.class);
|
ResponseEntity<String> result = restTemplate.postForEntity(uri, request, String.class);
|
||||||
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) {
|
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) {
|
||||||
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
|
||||||
|
@ -168,14 +173,40 @@ public class JMeterService {
|
||||||
|
|
||||||
|
|
||||||
public void run(JmeterRunRequestDTO request) {
|
public void run(JmeterRunRequestDTO request) {
|
||||||
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addQueue(JmeterRunRequestDTO request) {
|
|
||||||
if (request.getPool().isPool()) {
|
if (request.getPool().isPool()) {
|
||||||
this.runNode(request);
|
this.runNode(request);
|
||||||
} else {
|
} else {
|
||||||
this.runLocal(request);
|
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQueue(JmeterRunRequestDTO request) {
|
||||||
|
this.runLocal(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getRunningQueue(String poolId, String reportId) {
|
||||||
|
try {
|
||||||
|
List<JvmInfoDTO> resources = GenerateHashTreeUtil.setPoolResource(poolId);
|
||||||
|
if (CollectionUtils.isEmpty(resources)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean isRunning = false;
|
||||||
|
for (JvmInfoDTO jvmInfoDTO : resources) {
|
||||||
|
TestResourceDTO testResource = jvmInfoDTO.getTestResource();
|
||||||
|
String configuration = testResource.getConfiguration();
|
||||||
|
NodeDTO node = JSON.parseObject(configuration, NodeDTO.class);
|
||||||
|
String nodeIp = node.getIp();
|
||||||
|
Integer port = node.getPort();
|
||||||
|
String uri = String.format(BASE_URL + "/jmeter/get/running/queue/" + reportId, nodeIp, port);
|
||||||
|
ResponseEntity<Boolean> result = restTemplate.getForEntity(uri, Boolean.class);
|
||||||
|
if (result != null && result.getBody()) {
|
||||||
|
isRunning = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isRunning;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package io.metersphere.api.jmeter;
|
package io.metersphere.api.jmeter;
|
||||||
|
|
||||||
|
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
|
||||||
|
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public class JmeterThreadUtils {
|
public class JmeterThreadUtils {
|
||||||
private final static String THREAD_SPLIT = " ";
|
|
||||||
|
|
||||||
public static String stop(String name) {
|
public static String stop(String name) {
|
||||||
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
|
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
|
||||||
|
@ -24,6 +26,15 @@ public class JmeterThreadUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isRunning(String reportId, String testId) {
|
public static boolean isRunning(String reportId, String testId) {
|
||||||
|
if (StringUtils.isEmpty(reportId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (PoolExecBlockingQueueUtil.queue.containsKey(reportId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).check(reportId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
|
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
|
||||||
int noThreads = currentGroup.activeCount();
|
int noThreads = currentGroup.activeCount();
|
||||||
Thread[] lstThreads = new Thread[noThreads];
|
Thread[] lstThreads = new Thread[noThreads];
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package io.metersphere.api.jmeter;
|
|
||||||
|
|
||||||
import javax.websocket.Session;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class MessageCache {
|
|
||||||
public final static ConcurrentHashMap<String, Session> reportCache = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public final static Map<String, Long> jmeterLogTask = new HashMap<>();
|
|
||||||
|
|
||||||
// 定时任务报告
|
|
||||||
public final static List<String> jobReportCache = new LinkedList<>();
|
|
||||||
|
|
||||||
public static int corePoolSize = 10;
|
|
||||||
}
|
|
|
@ -23,7 +23,6 @@ import io.metersphere.api.dto.RequestResultExpandDTO;
|
||||||
import io.metersphere.api.dto.RunningParamKeys;
|
import io.metersphere.api.dto.RunningParamKeys;
|
||||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||||
import io.metersphere.api.exec.utils.ResultParseUtil;
|
import io.metersphere.api.exec.utils.ResultParseUtil;
|
||||||
import io.metersphere.api.service.MsResultService;
|
|
||||||
import io.metersphere.commons.utils.*;
|
import io.metersphere.commons.utils.*;
|
||||||
import io.metersphere.dto.RequestResult;
|
import io.metersphere.dto.RequestResult;
|
||||||
import io.metersphere.jmeter.JMeterBase;
|
import io.metersphere.jmeter.JMeterBase;
|
||||||
|
@ -156,7 +155,7 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
||||||
dto.setReportId("send." + this.getName());
|
dto.setReportId("send." + this.getName());
|
||||||
dto.setToReport(this.getName());
|
dto.setToReport(this.getName());
|
||||||
|
|
||||||
String console = CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(this.getName());
|
String console = FixedCapacityUtils.getJmeterLogger(this.getName());
|
||||||
if (StringUtils.isNotEmpty(requestResult.getName()) && requestResult.getName().startsWith("Transaction=")) {
|
if (StringUtils.isNotEmpty(requestResult.getName()) && requestResult.getName().startsWith("Transaction=")) {
|
||||||
requestResult.getSubRequestResults().forEach(transactionResult -> {
|
requestResult.getSubRequestResults().forEach(transactionResult -> {
|
||||||
transactionResult.getResponseResult().setConsole(console);
|
transactionResult.getResponseResult().setConsole(console);
|
||||||
|
|
|
@ -7,7 +7,6 @@ import io.metersphere.base.domain.TestResourcePool;
|
||||||
import io.metersphere.base.domain.TestResourcePoolExample;
|
import io.metersphere.base.domain.TestResourcePoolExample;
|
||||||
import io.metersphere.base.mapper.TestResourceMapper;
|
import io.metersphere.base.mapper.TestResourceMapper;
|
||||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||||
import io.metersphere.commons.exception.MSException;
|
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.dto.JvmInfoDTO;
|
import io.metersphere.dto.JvmInfoDTO;
|
||||||
import io.metersphere.dto.NodeDTO;
|
import io.metersphere.dto.NodeDTO;
|
||||||
|
@ -71,9 +70,6 @@ public class ResourcePoolCalculation {
|
||||||
availableNodes.add(nodeJvm);
|
availableNodes.add(nodeJvm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isEmpty(availableNodes)) {
|
|
||||||
MSException.throwException("未获取到资源池,请检查配置【系统设置-系统-测试资源池】");
|
|
||||||
}
|
|
||||||
return availableNodes;
|
return availableNodes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ import io.metersphere.api.dto.automation.parse.ScenarioImport;
|
||||||
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
|
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
|
||||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||||
import io.metersphere.api.dto.datacount.ApiMethodUrlDTO;
|
import io.metersphere.api.dto.datacount.ApiMethodUrlDTO;
|
||||||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
|
||||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||||
import io.metersphere.api.dto.definition.request.*;
|
import io.metersphere.api.dto.definition.request.*;
|
||||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||||
|
@ -106,10 +104,6 @@ public class ApiAutomationService {
|
||||||
@Resource
|
@Resource
|
||||||
private EsbApiParamService esbApiParamService;
|
private EsbApiParamService esbApiParamService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestCaseService apiTestCaseService;
|
|
||||||
@Resource
|
|
||||||
private ApiDefinitionService apiDefinitionService;
|
|
||||||
@Resource
|
|
||||||
private ApiTestEnvironmentMapper apiTestEnvironmentMapper;
|
private ApiTestEnvironmentMapper apiTestEnvironmentMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
|
@ -137,7 +131,8 @@ public class ApiAutomationService {
|
||||||
private ApiScenarioExecuteService apiScenarioExecuteService;
|
private ApiScenarioExecuteService apiScenarioExecuteService;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtProjectVersionMapper extProjectVersionMapper;
|
private ExtProjectVersionMapper extProjectVersionMapper;
|
||||||
|
@Resource
|
||||||
|
private MsHashTreeService hashTreeService;
|
||||||
|
|
||||||
private ThreadLocal<Long> currentScenarioOrder = new ThreadLocal<>();
|
private ThreadLocal<Long> currentScenarioOrder = new ThreadLocal<>();
|
||||||
|
|
||||||
|
@ -680,126 +675,16 @@ public class ApiAutomationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiScenarioDTO getApiScenario(String id) {
|
|
||||||
return extApiScenarioMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApiScenarioDTO getNewApiScenario(String id) {
|
public ApiScenarioDTO getNewApiScenario(String id) {
|
||||||
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(id);
|
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(id);
|
||||||
if (scenarioWithBLOBs != null && StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
if (scenarioWithBLOBs != null && StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
||||||
JSONObject element = JSON.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
JSONObject element = JSON.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||||
this.dataFormatting(element);
|
hashTreeService.dataFormatting(element);
|
||||||
scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(element));
|
scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(element));
|
||||||
}
|
}
|
||||||
return scenarioWithBLOBs;
|
return scenarioWithBLOBs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static List<String> requests = new ArrayList<String>() {{
|
|
||||||
this.add("HTTPSamplerProxy");
|
|
||||||
this.add("DubboSampler");
|
|
||||||
this.add("JDBCSampler");
|
|
||||||
this.add("TCPSampler");
|
|
||||||
}};
|
|
||||||
|
|
||||||
private void setElement(JSONObject element, Integer num, Boolean enable, String versionName, Boolean versionEnable) {
|
|
||||||
element.put("num", num);
|
|
||||||
element.put("enable", enable == null ? false : enable);
|
|
||||||
element.put("versionName", versionName);
|
|
||||||
element.put("versionEnable", versionEnable == null ? false : versionEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject setRequest(JSONObject element) {
|
|
||||||
boolean enable = element.getBoolean("enable");
|
|
||||||
boolean isExist = false;
|
|
||||||
if (StringUtils.equalsIgnoreCase(element.getString("refType"), "CASE")) {
|
|
||||||
ApiTestCaseInfo apiTestCase = apiTestCaseService.get(element.getString("id"));
|
|
||||||
if (apiTestCase != null) {
|
|
||||||
if (StringUtils.equalsIgnoreCase(element.getString("referenced"), "REF")) {
|
|
||||||
JSONObject refElement = JSON.parseObject(apiTestCase.getRequest());
|
|
||||||
ElementUtil.dataFormatting(refElement);
|
|
||||||
JSONArray array = refElement.getJSONArray("hashTree");
|
|
||||||
BeanUtils.copyBean(element, refElement);
|
|
||||||
if (array != null) {
|
|
||||||
ElementUtil.mergeHashTree(element, refElement.getJSONArray("hashTree"));
|
|
||||||
}
|
|
||||||
element.put("referenced", "REF");
|
|
||||||
element.put("disabled", true);
|
|
||||||
element.put("name", apiTestCase.getName());
|
|
||||||
}
|
|
||||||
element.put("id", apiTestCase.getId());
|
|
||||||
isExist = true;
|
|
||||||
this.setElement(element, apiTestCase.getNum(), enable, apiTestCase.getVersionName(), apiTestCase.getVersionEnable());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ApiDefinitionResult definitionWithBLOBs = apiDefinitionService.getById(element.getString("id"));
|
|
||||||
if (definitionWithBLOBs != null) {
|
|
||||||
element.put("id", definitionWithBLOBs.getId());
|
|
||||||
this.setElement(element, definitionWithBLOBs.getNum(), enable, definitionWithBLOBs.getVersionName(), definitionWithBLOBs.getVersionEnable());
|
|
||||||
isExist = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isExist) {
|
|
||||||
if (StringUtils.equalsIgnoreCase(element.getString("referenced"), "REF")) {
|
|
||||||
element.put("enable", false);
|
|
||||||
}
|
|
||||||
element.put("num", "");
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject setRefScenario(JSONObject element) {
|
|
||||||
boolean enable = element.containsKey("enable") ? element.getBoolean("enable") : true;
|
|
||||||
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(element.getString("id"));
|
|
||||||
if (scenarioWithBLOBs != null && StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
|
||||||
boolean environmentEnable = element.containsKey("environmentEnable")
|
|
||||||
? element.getBoolean("environmentEnable") : false;
|
|
||||||
|
|
||||||
if (StringUtils.equalsIgnoreCase(element.getString("referenced"), "REF")) {
|
|
||||||
element = JSON.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
|
||||||
element.put("referenced", "REF");
|
|
||||||
element.put("name", scenarioWithBLOBs.getName());
|
|
||||||
}
|
|
||||||
element.put("id", scenarioWithBLOBs.getId());
|
|
||||||
element.put("environmentEnable", environmentEnable);
|
|
||||||
this.setElement(element, scenarioWithBLOBs.getNum(), enable, scenarioWithBLOBs.getVersionName(), scenarioWithBLOBs.getVersionEnable());
|
|
||||||
} else {
|
|
||||||
if (StringUtils.equalsIgnoreCase(element.getString("referenced"), "REF")) {
|
|
||||||
element.put("enable", false);
|
|
||||||
}
|
|
||||||
element.put("num", "");
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dataFormatting(JSONArray hashTree) {
|
|
||||||
for (int i = 0; i < hashTree.size(); i++) {
|
|
||||||
JSONObject element = hashTree.getJSONObject(i);
|
|
||||||
if (element != null && StringUtils.equalsIgnoreCase(element.getString("type"), "scenario")) {
|
|
||||||
element = this.setRefScenario(element);
|
|
||||||
hashTree.set(i, element);
|
|
||||||
} else if (element != null && requests.contains(element.getString("type"))) {
|
|
||||||
element = this.setRequest(element);
|
|
||||||
hashTree.set(i, element);
|
|
||||||
}
|
|
||||||
if (element.containsKey("hashTree")) {
|
|
||||||
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
|
||||||
dataFormatting(elementJSONArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dataFormatting(JSONObject element) {
|
|
||||||
if (element != null && StringUtils.equalsIgnoreCase(element.getString("type"), "scenario")) {
|
|
||||||
element = this.setRefScenario(element);
|
|
||||||
} else if (element != null && requests.contains(element.getString("type"))) {
|
|
||||||
element = this.setRequest(element);
|
|
||||||
}
|
|
||||||
if (element != null && element.containsKey("hashTree")) {
|
|
||||||
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
|
||||||
dataFormatting(elementJSONArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String setDomain(ApiScenarioEnvRequest request) {
|
public String setDomain(ApiScenarioEnvRequest request) {
|
||||||
Boolean enable = request.getEnvironmentEnable();
|
Boolean enable = request.getEnvironmentEnable();
|
||||||
String scenarioDefinition = request.getDefinition();
|
String scenarioDefinition = request.getDefinition();
|
||||||
|
@ -1179,7 +1064,6 @@ public class ApiAutomationService {
|
||||||
apiScenarioMapper.updateByExampleSelective(
|
apiScenarioMapper.updateByExampleSelective(
|
||||||
apiScenarioWithBLOBs,
|
apiScenarioWithBLOBs,
|
||||||
apiScenarioExample);
|
apiScenarioExample);
|
||||||
// apiScenarioReferenceIdService.saveByApiScenario(apiScenarioWithBLOBs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bathEditEnv(ApiScenarioBatchRequest request) {
|
public void bathEditEnv(ApiScenarioBatchRequest request) {
|
||||||
|
@ -1440,45 +1324,6 @@ public class ApiAutomationService {
|
||||||
return apiImport;
|
return apiImport;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHashTree(JSONArray hashTree) {
|
|
||||||
// 将引用转成复制
|
|
||||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
|
||||||
for (int i = 0; i < hashTree.size(); i++) {
|
|
||||||
JSONObject object = (JSONObject) hashTree.get(i);
|
|
||||||
String referenced = object.getString("referenced");
|
|
||||||
if (StringUtils.isNotBlank(referenced) && StringUtils.equals(referenced, "REF")) {
|
|
||||||
// 检测引用对象是否存在,若果不存在则改成复制对象
|
|
||||||
String refType = object.getString("refType");
|
|
||||||
if (StringUtils.isNotEmpty(refType)) {
|
|
||||||
if (refType.equals("CASE")) {
|
|
||||||
ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(object.getString("id"));
|
|
||||||
if (bloBs != null) {
|
|
||||||
object = JSON.parseObject(bloBs.getRequest());
|
|
||||||
object.put("id", bloBs.getId());
|
|
||||||
object.put("name", bloBs.getName());
|
|
||||||
hashTree.set(i, object);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString("id"));
|
|
||||||
if (bloBs != null) {
|
|
||||||
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
|
||||||
hashTree.set(i, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ("scenario".equals(object.getString("type"))) {
|
|
||||||
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString("id"));
|
|
||||||
if (bloBs != null) {
|
|
||||||
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
|
||||||
hashTree.set(i, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (object != null && CollectionUtils.isNotEmpty(object.getJSONArray("hashTree"))) {
|
|
||||||
setHashTree(object.getJSONArray("hashTree"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ApiScenarioWithBLOBs> getExportResult(ApiScenarioBatchRequest request) {
|
private List<ApiScenarioWithBLOBs> getExportResult(ApiScenarioBatchRequest request) {
|
||||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||||
|
@ -1493,7 +1338,7 @@ public class ApiAutomationService {
|
||||||
JSONObject scenario = JSONObject.parseObject(item.getScenarioDefinition());
|
JSONObject scenario = JSONObject.parseObject(item.getScenarioDefinition());
|
||||||
JSONArray hashTree = scenario.getJSONArray("hashTree");
|
JSONArray hashTree = scenario.getJSONArray("hashTree");
|
||||||
if (hashTree != null) {
|
if (hashTree != null) {
|
||||||
setHashTree(hashTree);
|
hashTreeService.setHashTree(hashTree);
|
||||||
scenario.put("hashTree", hashTree);
|
scenario.put("hashTree", hashTree);
|
||||||
}
|
}
|
||||||
item.setScenarioDefinition(JSON.toJSONString(scenario));
|
item.setScenarioDefinition(JSON.toJSONString(scenario));
|
||||||
|
@ -1717,78 +1562,16 @@ public class ApiAutomationService {
|
||||||
|
|
||||||
public List<ApiMethodUrlDTO> parseUrl(ApiScenarioWithBLOBs scenario) {
|
public List<ApiMethodUrlDTO> parseUrl(ApiScenarioWithBLOBs scenario) {
|
||||||
List<ApiMethodUrlDTO> urlList = new ArrayList<>();
|
List<ApiMethodUrlDTO> urlList = new ArrayList<>();
|
||||||
|
String scenarioDefinition = scenario.getScenarioDefinition();
|
||||||
try {
|
JSONObject scenarioObj = JSONObject.parseObject(scenarioDefinition);
|
||||||
String scenarioDefinition = scenario.getScenarioDefinition();
|
List<ApiMethodUrlDTO> stepUrlList = hashTreeService.getMethodUrlDTOByHashTreeJsonObj(scenarioObj);
|
||||||
JSONObject scenarioObj = JSONObject.parseObject(scenarioDefinition);
|
if (CollectionUtils.isNotEmpty(stepUrlList)) {
|
||||||
List<ApiMethodUrlDTO> stepUrlList = this.getMethodUrlDTOByHashTreeJsonObj(scenarioObj);
|
Collection unionList = CollectionUtils.union(urlList, stepUrlList);
|
||||||
if (CollectionUtils.isNotEmpty(stepUrlList)) {
|
urlList = new ArrayList<>(unionList);
|
||||||
Collection unionList = CollectionUtils.union(urlList, stepUrlList);
|
|
||||||
urlList = new ArrayList<>(unionList);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
}
|
}
|
||||||
return urlList;
|
return urlList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ApiMethodUrlDTO> getMethodUrlDTOByHashTreeJsonObj(JSONObject obj) {
|
|
||||||
List<ApiMethodUrlDTO> returnList = new ArrayList<>();
|
|
||||||
if (obj != null && obj.containsKey("hashTree")) {
|
|
||||||
JSONArray hashArr = obj.getJSONArray("hashTree");
|
|
||||||
for (int i = 0; i < hashArr.size(); i++) {
|
|
||||||
JSONObject elementObj = hashArr.getJSONObject(i);
|
|
||||||
if (elementObj == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elementObj.containsKey("url") && elementObj.containsKey("method")) {
|
|
||||||
String url = elementObj.getString("url");
|
|
||||||
String method = elementObj.getString("method");
|
|
||||||
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(url, method);
|
|
||||||
if (!returnList.contains(dto)) {
|
|
||||||
returnList.add(dto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (elementObj.containsKey("path") && elementObj.containsKey("method")) {
|
|
||||||
String path = elementObj.getString("path");
|
|
||||||
String method = elementObj.getString("method");
|
|
||||||
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(path, method);
|
|
||||||
if (!returnList.contains(dto)) {
|
|
||||||
returnList.add(dto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elementObj.containsKey("id") && elementObj.containsKey("refType")) {
|
|
||||||
String refType = elementObj.getString("refType");
|
|
||||||
String id = elementObj.getString("id");
|
|
||||||
if (StringUtils.equals("CASE", refType)) {
|
|
||||||
ApiDefinition apiDefinition = apiTestCaseService.findApiUrlAndMethodById(id);
|
|
||||||
if (apiDefinition != null) {
|
|
||||||
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(apiDefinition.getPath(), apiDefinition.getMethod());
|
|
||||||
if (!returnList.contains(dto)) {
|
|
||||||
returnList.add(dto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (StringUtils.equals("API", refType)) {
|
|
||||||
ApiDefinition apiDefinition = apiDefinitionService.selectUrlAndMethodById(id);
|
|
||||||
if (apiDefinition != null) {
|
|
||||||
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(apiDefinition.getPath(), apiDefinition.getMethod());
|
|
||||||
if (!returnList.contains(dto)) {
|
|
||||||
returnList.add(dto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ApiMethodUrlDTO> stepUrlList = this.getMethodUrlDTOByHashTreeJsonObj(elementObj);
|
|
||||||
if (CollectionUtils.isNotEmpty(stepUrlList)) {
|
|
||||||
Collection unionList = CollectionUtils.union(returnList, stepUrlList);
|
|
||||||
returnList = new ArrayList<>(unionList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScenarioEnv getApiScenarioProjectId(String id) {
|
public ScenarioEnv getApiScenarioProjectId(String id) {
|
||||||
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(id);
|
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
|
@ -1926,7 +1709,6 @@ public class ApiAutomationService {
|
||||||
return returnList;
|
return returnList;
|
||||||
} else {
|
} else {
|
||||||
apiScenarioList.forEach(item -> {
|
apiScenarioList.forEach(item -> {
|
||||||
String testName = item.getName();
|
|
||||||
MsTestPlan testPlan = new MsTestPlan();
|
MsTestPlan testPlan = new MsTestPlan();
|
||||||
testPlan.setHashTree(new LinkedList<>());
|
testPlan.setHashTree(new LinkedList<>());
|
||||||
JmxInfoDTO dto = apiTestService.updateJmxString(generateJmx(item), item.getProjectId());
|
JmxInfoDTO dto = apiTestService.updateJmxString(generateJmx(item), item.getProjectId());
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||||
|
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||||
|
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 org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApiCaseResultService {
|
||||||
|
@Resource
|
||||||
|
private SqlSessionFactory sqlSessionFactory;
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||||
|
public void batchSave(Map<String, ApiDefinitionExecResult> executeQueue) {
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||||
|
for (String testId : executeQueue.keySet()) {
|
||||||
|
ApiDefinitionExecResult report = executeQueue.get(testId);
|
||||||
|
batchMapper.insert(report);
|
||||||
|
}
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
if (sqlSession != null && sqlSessionFactory != null) {
|
||||||
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
|
||||||
import io.metersphere.commons.constants.*;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.utils.DateUtils;
|
import io.metersphere.commons.utils.DateUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -21,35 +22,29 @@ import io.metersphere.track.dto.TestPlanDTO;
|
||||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||||
import io.metersphere.track.request.testcase.TrackCount;
|
import io.metersphere.track.request.testcase.TrackCount;
|
||||||
import io.metersphere.track.service.TestCaseReviewApiCaseService;
|
import io.metersphere.track.service.TestCaseReviewApiCaseService;
|
||||||
import io.metersphere.track.service.TestPlanApiCaseService;
|
|
||||||
import io.metersphere.track.service.TestPlanService;
|
|
||||||
import io.metersphere.track.service.TestPlanTestCaseService;
|
import io.metersphere.track.service.TestPlanTestCaseService;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
import org.apache.commons.beanutils.BeanMap;
|
import org.apache.commons.beanutils.BeanMap;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class ApiDefinitionExecResultService {
|
public class ApiDefinitionExecResultService {
|
||||||
Logger testPlanLog = LoggerFactory.getLogger("testPlanExecuteLog");
|
|
||||||
@Resource
|
@Resource
|
||||||
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiCaseService testPlanApiCaseService;
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanService testPlanService;
|
private ExtTestPlanMapper extTestPlanMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestCaseMapper apiTestCaseMapper;
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -68,11 +63,6 @@ public class ApiDefinitionExecResultService {
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
|
|
||||||
public void saveApiResult(List<RequestResult> requestResults, ResultDTO dto) {
|
public void saveApiResult(List<RequestResult> requestResults, ResultDTO dto) {
|
||||||
boolean isFirst = true;
|
|
||||||
int count = requestResults.stream()
|
|
||||||
.filter(item -> !StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_"))
|
|
||||||
.collect(Collectors.toList()).size();
|
|
||||||
|
|
||||||
LoggerUtil.info("接收到API/CASE执行结果【 " + requestResults.size() + " 】");
|
LoggerUtil.info("接收到API/CASE执行结果【 " + requestResults.size() + " 】");
|
||||||
|
|
||||||
for (RequestResult item : requestResults) {
|
for (RequestResult item : requestResults) {
|
||||||
|
@ -81,12 +71,11 @@ public class ApiDefinitionExecResultService {
|
||||||
item.getResponseResult().setResponseTime((item.getEndTime() - item.getStartTime()));
|
item.getResponseResult().setResponseTime((item.getEndTime() - item.getStartTime()));
|
||||||
}
|
}
|
||||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
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);
|
ApiDefinitionExecResult result = this.save(item, dto.getReportId(), dto.getConsole(), dto.getRunMode(), dto.getTestId());
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
// 发送通知
|
// 发送通知
|
||||||
sendNotice(result);
|
sendNotice(result);
|
||||||
}
|
}
|
||||||
isFirst = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,18 +125,26 @@ public class ApiDefinitionExecResultService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setExecResult(String id, String status, Long time) {
|
||||||
|
TestPlanApiCase apiCase = new TestPlanApiCase();
|
||||||
|
apiCase.setId(id);
|
||||||
|
apiCase.setStatus(status);
|
||||||
|
apiCase.setUpdateTime(time);
|
||||||
|
testPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||||
|
}
|
||||||
|
|
||||||
public void editStatus(ApiDefinitionExecResult saveResult, String type, String status, Long time, String reportId, String testId) {
|
public void editStatus(ApiDefinitionExecResult saveResult, String type, String status, Long time, String reportId, String testId) {
|
||||||
String name = testId;
|
String name = testId;
|
||||||
String version = "";
|
String version = "";
|
||||||
if (StringUtils.equalsAnyIgnoreCase(type, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
if (StringUtils.equalsAnyIgnoreCase(type, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
||||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseService.getById(testId);
|
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||||
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
||||||
if (testPlanApiCase != null) {
|
if (testPlanApiCase != null) {
|
||||||
testPlanApiCaseService.setExecResult(testId, status, time);
|
this.setExecResult(testId, status, time);
|
||||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
||||||
testPlanApiCase.setStatus(status);
|
testPlanApiCase.setStatus(status);
|
||||||
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
||||||
testPlanApiCaseService.updateByPrimaryKeySelective(testPlanApiCase);
|
testPlanApiCaseMapper.updateByPrimaryKeySelective(testPlanApiCase);
|
||||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||||
LoggerUtil.debug("更新测试计划用例【 " + testPlanApiCase.getId() + " 】");
|
LoggerUtil.debug("更新测试计划用例【 " + testPlanApiCase.getId() + " 】");
|
||||||
}
|
}
|
||||||
|
@ -198,22 +195,14 @@ public class ApiDefinitionExecResultService {
|
||||||
* 定时任务时,userID要改为定时任务中的用户
|
* 定时任务时,userID要改为定时任务中的用户
|
||||||
*/
|
*/
|
||||||
public void saveApiResultByScheduleTask(List<RequestResult> requestResults, ResultDTO dto) {
|
public void saveApiResultByScheduleTask(List<RequestResult> requestResults, ResultDTO dto) {
|
||||||
boolean isFirst = true;
|
|
||||||
int countExpectProcessResultCount = 0;
|
|
||||||
if (CollectionUtils.isNotEmpty(requestResults)) {
|
if (CollectionUtils.isNotEmpty(requestResults)) {
|
||||||
for (RequestResult resultItem : requestResults) {
|
|
||||||
if (!StringUtils.startsWithAny(resultItem.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
|
||||||
countExpectProcessResultCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LoggerUtil.info("接收到定时任务执行结果【 " + requestResults.size() + " 】");
|
LoggerUtil.info("接收到定时任务执行结果【 " + requestResults.size() + " 】");
|
||||||
|
|
||||||
for (RequestResult item : requestResults) {
|
for (RequestResult item : requestResults) {
|
||||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||||
//对响应内容进行进一步解析。如果有附加信息(比如误报库信息),则根据附加信息内的数据进行其他判读
|
//对响应内容进行进一步解析。如果有附加信息(比如误报库信息),则根据附加信息内的数据进行其他判读
|
||||||
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(item);
|
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(item);
|
||||||
|
|
||||||
ApiDefinitionExecResult reportResult = this.save(item, dto.getReportId(), dto.getConsole(), countExpectProcessResultCount, dto.getRunMode(), dto.getTestId(), isFirst);
|
ApiDefinitionExecResult reportResult = this.save(item, dto.getReportId(), dto.getConsole(), dto.getRunMode(), dto.getTestId());
|
||||||
String status = item.isSuccess() ? "success" : "error";
|
String status = item.isSuccess() ? "success" : "error";
|
||||||
if (reportResult != null) {
|
if (reportResult != null) {
|
||||||
status = reportResult.getStatus();
|
status = reportResult.getStatus();
|
||||||
|
@ -222,17 +211,16 @@ public class ApiDefinitionExecResultService {
|
||||||
status = expandDTO.getStatus();
|
status = expandDTO.getStatus();
|
||||||
}
|
}
|
||||||
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||||
TestPlanApiCase apiCase = testPlanApiCaseService.getById(dto.getTestId());
|
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(dto.getTestId());
|
||||||
if (apiCase != null) {
|
if (apiCase != null) {
|
||||||
apiCase.setStatus(status);
|
apiCase.setStatus(status);
|
||||||
apiCase.setUpdateTime(System.currentTimeMillis());
|
apiCase.setUpdateTime(System.currentTimeMillis());
|
||||||
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
|
testPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
testPlanApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime());
|
this.setExecResult(dto.getTestId(), status, item.getStartTime());
|
||||||
testCaseReviewApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime());
|
testCaseReviewApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime());
|
||||||
}
|
}
|
||||||
isFirst = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +231,7 @@ public class ApiDefinitionExecResultService {
|
||||||
if (StringUtils.isNotEmpty(dto.getReportId())) {
|
if (StringUtils.isNotEmpty(dto.getReportId())) {
|
||||||
apiIdResultMap.put(dto.getReportId(), status);
|
apiIdResultMap.put(dto.getReportId(), status);
|
||||||
}
|
}
|
||||||
testPlanLog.info("TestPlanReportId[" + dto.getTestPlanReportId() + "] APICASE OVER. API CASE STATUS:" + JSONObject.toJSONString(apiIdResultMap));
|
LoggerUtil.info("TestPlanReportId[" + dto.getTestPlanReportId() + "] APICASE OVER. API CASE STATUS:" + JSONObject.toJSONString(apiIdResultMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,7 +239,7 @@ public class ApiDefinitionExecResultService {
|
||||||
*/
|
*/
|
||||||
public void updateTestCaseStates(String testPlanApiCaseId) {
|
public void updateTestCaseStates(String testPlanApiCaseId) {
|
||||||
try {
|
try {
|
||||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseService.getById(testPlanApiCaseId);
|
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(testPlanApiCaseId);
|
||||||
if (testPlanApiCase == null) return;
|
if (testPlanApiCase == null) return;
|
||||||
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseService.get(testPlanApiCase.getApiCaseId());
|
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseService.get(testPlanApiCase.getApiCaseId());
|
||||||
testPlanTestCaseService.updateTestCaseStates(apiTestCase.getId(), apiTestCase.getName(), testPlanApiCase.getTestPlanId(), TrackCount.TESTCASE);
|
testPlanTestCaseService.updateTestCaseStates(apiTestCase.getId(), apiTestCase.getName(), testPlanApiCase.getTestPlanId(), TrackCount.TESTCASE);
|
||||||
|
@ -322,7 +310,7 @@ public class ApiDefinitionExecResultService {
|
||||||
} else if ("load".equals(item.getCaseType())) {
|
} else if ("load".equals(item.getCaseType())) {
|
||||||
planRequest.setLoadId(item.getTestCaseID());
|
planRequest.setLoadId(item.getTestCaseID());
|
||||||
}
|
}
|
||||||
List<TestPlanDTO> dtoList = testPlanService.selectTestPlanByRelevancy(planRequest);
|
List<TestPlanDTO> dtoList = extTestPlanMapper.selectTestPlanByRelevancy(planRequest);
|
||||||
item.setTestPlanDTOList(dtoList);
|
item.setTestPlanDTOList(dtoList);
|
||||||
returnList.add(item);
|
returnList.add(item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -334,7 +322,7 @@ public class ApiDefinitionExecResultService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiDefinitionExecResult save(RequestResult item, String reportId, String console, int expectProcessResultCount, String type, String testId, boolean isFirst) {
|
private ApiDefinitionExecResult save(RequestResult item, String reportId, String console, String type, String testId) {
|
||||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||||
ApiDefinitionExecResult saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId);
|
ApiDefinitionExecResult saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId);
|
||||||
if (saveResult == null) {
|
if (saveResult == null) {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import io.metersphere.api.dto.RunModeDataDTO;
|
||||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||||
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
|
import io.metersphere.api.jmeter.JmeterThreadUtils;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||||
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
||||||
|
@ -13,6 +15,7 @@ import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiExecutionQueueMapper;
|
import io.metersphere.base.mapper.ext.ExtApiExecutionQueueMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
||||||
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.TestPlanReportStatus;
|
import io.metersphere.commons.constants.TestPlanReportStatus;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
@ -23,12 +26,15 @@ import io.metersphere.dto.RunModeConfigDTO;
|
||||||
import io.metersphere.track.service.TestPlanReportService;
|
import io.metersphere.track.service.TestPlanReportService;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionUtils;
|
import org.mybatis.spring.SqlSessionUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -54,10 +60,12 @@ public class ApiExecutionQueueService {
|
||||||
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
|
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
|
||||||
|
@Resource
|
||||||
|
private JMeterService jMeterService;
|
||||||
@Resource
|
@Resource
|
||||||
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
|
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
|
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
|
||||||
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
|
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
|
||||||
executionQueue.setId(UUID.randomUUID().toString());
|
executionQueue.setId(UUID.randomUUID().toString());
|
||||||
|
@ -237,13 +245,16 @@ public class ApiExecutionQueueService {
|
||||||
long count = executionQueueDetailMapper.countByExample(queueDetailExample);
|
long count = executionQueueDetailMapper.countByExample(queueDetailExample);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
queueMapper.deleteByPrimaryKey(dto.getQueueId());
|
queueMapper.deleteByPrimaryKey(dto.getQueueId());
|
||||||
|
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||||
|
apiScenarioReportService.margeReport(dto.getReportId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBTestQueue executionQueue = this.handleQueue(dto.getQueueId(), dto.getTestId());
|
DBTestQueue executionQueue = this.handleQueue(dto.getQueueId(), dto.getTestId());
|
||||||
if (executionQueue != null) {
|
if (executionQueue != null) {
|
||||||
// 串行失败停止
|
// 串行失败停止
|
||||||
if (executionQueue.getFailure() && StringUtils.isNotEmpty(executionQueue.getCompletedReportId())) {
|
if (BooleanUtils.isTrue(executionQueue.getFailure()) && StringUtils.isNotEmpty(executionQueue.getCompletedReportId())) {
|
||||||
boolean isNext = failure(executionQueue, dto);
|
boolean isNext = failure(executionQueue, dto);
|
||||||
if (!isNext) {
|
if (!isNext) {
|
||||||
return;
|
return;
|
||||||
|
@ -273,21 +284,34 @@ public class ApiExecutionQueueService {
|
||||||
final int SECOND_MILLIS = 1000;
|
final int SECOND_MILLIS = 1000;
|
||||||
final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
|
final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
|
||||||
// 计算二十分钟前的超时报告
|
// 计算二十分钟前的超时报告
|
||||||
final long twentyMinutesAgo = System.currentTimeMillis() - (20 * MINUTE_MILLIS);
|
final long twentyMinutesAgo = System.currentTimeMillis() - (30 * MINUTE_MILLIS);
|
||||||
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
|
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
|
||||||
example.createCriteria().andCreateTimeLessThan(twentyMinutesAgo);
|
example.createCriteria().andCreateTimeLessThan(twentyMinutesAgo);
|
||||||
List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example);
|
List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example);
|
||||||
|
|
||||||
queueDetails.forEach(item -> {
|
for (ApiExecutionQueueDetail item : queueDetails) {
|
||||||
ApiExecutionQueue queue = queueMapper.selectByPrimaryKey(item.getQueueId());
|
ApiExecutionQueue queue = queueMapper.selectByPrimaryKey(item.getQueueId());
|
||||||
if (queue != null && StringUtils.equalsAnyIgnoreCase(queue.getRunMode(),
|
if (queue == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 在资源池中执行
|
||||||
|
if (StringUtils.isNotEmpty(queue.getPoolId())
|
||||||
|
&& jMeterService.getRunningQueue(queue.getPoolId(), item.getReportId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 检查执行报告是否还在等待队列中或执行线程中
|
||||||
|
if (JmeterThreadUtils.isRunning(item.getReportId(), item.getTestId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 检查是否已经超时
|
||||||
|
if (StringUtils.equalsAnyIgnoreCase(queue.getRunMode(),
|
||||||
ApiRunMode.SCENARIO.name(),
|
ApiRunMode.SCENARIO.name(),
|
||||||
ApiRunMode.SCENARIO_PLAN.name(),
|
ApiRunMode.SCENARIO_PLAN.name(),
|
||||||
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
|
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
|
||||||
ApiRunMode.SCHEDULE_SCENARIO.name(),
|
ApiRunMode.SCHEDULE_SCENARIO.name(),
|
||||||
ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
|
||||||
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name())
|
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name(), APITestStatus.Waiting.name())
|
||||||
&& report.getUpdateTime() < twentyMinutesAgo) {
|
&& report.getUpdateTime() < twentyMinutesAgo) {
|
||||||
report.setStatus(ScenarioStatus.Timeout.name());
|
report.setStatus(ScenarioStatus.Timeout.name());
|
||||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||||
|
@ -311,13 +335,13 @@ public class ApiExecutionQueueService {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
|
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
|
||||||
if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name())) {
|
if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name(), APITestStatus.Waiting.name())) {
|
||||||
result.setStatus(ScenarioStatus.Timeout.name());
|
result.setStatus(ScenarioStatus.Timeout.name());
|
||||||
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
|
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
|
||||||
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
|
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
ApiExecutionQueueExample queueDetailExample = new ApiExecutionQueueExample();
|
ApiExecutionQueueExample queueDetailExample = new ApiExecutionQueueExample();
|
||||||
queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(twentyMinutesAgo);
|
queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(twentyMinutesAgo);
|
||||||
|
@ -325,7 +349,7 @@ public class ApiExecutionQueueService {
|
||||||
if (CollectionUtils.isNotEmpty(executionQueues)) {
|
if (CollectionUtils.isNotEmpty(executionQueues)) {
|
||||||
executionQueues.forEach(item -> {
|
executionQueues.forEach(item -> {
|
||||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
|
||||||
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name())
|
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name(), APITestStatus.Waiting.name())
|
||||||
&& (report.getUpdateTime() < twentyMinutesAgo)) {
|
&& (report.getUpdateTime() < twentyMinutesAgo)) {
|
||||||
report.setStatus(ScenarioStatus.Timeout.name());
|
report.setStatus(ScenarioStatus.Timeout.name());
|
||||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||||
import io.metersphere.service.JarConfigService;
|
import io.metersphere.service.JarConfigService;
|
||||||
import io.metersphere.service.PluginService;
|
import io.metersphere.service.PluginService;
|
||||||
|
@ -48,6 +49,10 @@ public class ApiJmeterFileService {
|
||||||
|
|
||||||
public byte[] downloadJmeterFiles(String runMode, String remoteTestId, String reportId, String reportType, String queueId) {
|
public byte[] downloadJmeterFiles(String runMode, String remoteTestId, String reportId, String reportType, String queueId) {
|
||||||
Map<String, String> planEnvMap = new HashMap<>();
|
Map<String, String> planEnvMap = new HashMap<>();
|
||||||
|
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(remoteTestId, reportId, runMode, null);
|
||||||
|
runRequest.setReportType(reportType);
|
||||||
|
runRequest.setQueueId(queueId);
|
||||||
|
|
||||||
ApiScenarioWithBLOBs scenario = null;
|
ApiScenarioWithBLOBs scenario = null;
|
||||||
if (StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
if (StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
||||||
// 获取场景用例单独的执行环境
|
// 获取场景用例单独的执行环境
|
||||||
|
@ -71,7 +76,7 @@ public class ApiJmeterFileService {
|
||||||
}
|
}
|
||||||
HashTree hashTree = null;
|
HashTree hashTree = null;
|
||||||
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())) {
|
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
||||||
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, reportId, runMode, envMap);
|
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, envMap, runRequest);
|
||||||
} else {
|
} else {
|
||||||
if (scenario == null) {
|
if (scenario == null) {
|
||||||
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);
|
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);
|
||||||
|
@ -92,11 +97,7 @@ public class ApiJmeterFileService {
|
||||||
planEnvMap = environmentGroupProjectService.getEnvMap(envGroupId);
|
planEnvMap = environmentGroupProjectService.getEnvMap(envGroupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, planEnvMap, runRequest);
|
||||||
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, reportId, planEnvMap, reportType);
|
|
||||||
} catch (Exception e) {
|
|
||||||
executionQueueDetailMapper.deleteByPrimaryKey(queueId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return zipFilesToByteArray((reportId + "_" + remoteTestId), hashTree);
|
return zipFilesToByteArray((reportId + "_" + remoteTestId), hashTree);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,18 @@ package io.metersphere.api.service;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.api.dto.APIReportBatchRequest;
|
import io.metersphere.api.dto.*;
|
||||||
import io.metersphere.api.dto.DeleteAPIReportRequest;
|
|
||||||
import io.metersphere.api.dto.EnvironmentType;
|
|
||||||
import io.metersphere.api.dto.QueryAPIReportRequest;
|
|
||||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
||||||
import io.metersphere.api.dto.automation.ExecuteType;
|
import io.metersphere.api.dto.automation.ExecuteType;
|
||||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||||
import io.metersphere.api.jmeter.ReportCounter;
|
import io.metersphere.api.jmeter.FixedCapacityUtils;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
||||||
import io.metersphere.commons.constants.*;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.DateUtils;
|
import io.metersphere.commons.utils.DateUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
|
||||||
import io.metersphere.commons.utils.ServiceUtils;
|
import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.constants.RunModeConstants;
|
import io.metersphere.constants.RunModeConstants;
|
||||||
|
@ -36,12 +32,15 @@ import io.metersphere.utils.LoggerUtil;
|
||||||
import org.apache.commons.beanutils.BeanMap;
|
import org.apache.commons.beanutils.BeanMap;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -82,7 +81,7 @@ public class ApiScenarioReportService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioReportStructureMapper apiScenarioReportStructureMapper;
|
private ApiScenarioReportStructureMapper apiScenarioReportStructureMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private MsResultService resultService;
|
private SqlSessionFactory sqlSessionFactory;
|
||||||
|
|
||||||
public void saveResult(List<RequestResult> requestResults, ResultDTO dto) {
|
public void saveResult(List<RequestResult> requestResults, ResultDTO dto) {
|
||||||
// 报告详情内容
|
// 报告详情内容
|
||||||
|
@ -238,9 +237,9 @@ public class ApiScenarioReportService {
|
||||||
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
|
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
|
||||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId());
|
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId());
|
||||||
if (testPlanApiScenario != null) {
|
if (testPlanApiScenario != null) {
|
||||||
if(report != null){
|
if (report != null) {
|
||||||
testPlanApiScenario.setLastResult(report.getStatus());
|
testPlanApiScenario.setLastResult(report.getStatus());
|
||||||
}else {
|
} else {
|
||||||
if (errorSize > 0) {
|
if (errorSize > 0) {
|
||||||
testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name());
|
testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name());
|
||||||
} else {
|
} else {
|
||||||
|
@ -333,7 +332,7 @@ public class ApiScenarioReportService {
|
||||||
report.setStatus(size > 0 ? ScenarioStatus.Error.name() : ScenarioStatus.Success.name());
|
report.setStatus(size > 0 ? ScenarioStatus.Error.name() : ScenarioStatus.Success.name());
|
||||||
report.setEndTime(System.currentTimeMillis());
|
report.setEndTime(System.currentTimeMillis());
|
||||||
// 更新控制台信息
|
// 更新控制台信息
|
||||||
apiScenarioReportStructureService.update(reportId, resultService.getJmeterLogger(reportId));
|
apiScenarioReportStructureService.update(reportId, FixedCapacityUtils.getJmeterLogger(reportId));
|
||||||
// 更新报告
|
// 更新报告
|
||||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||||
}
|
}
|
||||||
|
@ -351,9 +350,9 @@ public class ApiScenarioReportService {
|
||||||
scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
|
scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
|
||||||
}
|
}
|
||||||
if (scenario != null) {
|
if (scenario != null) {
|
||||||
if(StringUtils.equalsAnyIgnoreCase(status,ExecuteResult.errorReportResult.name())){
|
if (StringUtils.equalsAnyIgnoreCase(status, ExecuteResult.errorReportResult.name())) {
|
||||||
scenario.setLastResult(status);
|
scenario.setLastResult(status);
|
||||||
}else {
|
} else {
|
||||||
scenario.setLastResult(errorSize > 0 ? "Fail" : ScenarioStatus.Success.name());
|
scenario.setLastResult(errorSize > 0 ? "Fail" : ScenarioStatus.Success.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,32 +649,6 @@ public class ApiScenarioReportService {
|
||||||
return extApiScenarioReportMapper.countByApiScenarioId();
|
return extApiScenarioReportMapper.countByApiScenarioId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RestTemplate restTemplate;
|
|
||||||
private static final String BASE_URL = "http://%s:%d";
|
|
||||||
|
|
||||||
public Integer get(String reportId, ReportCounter counter) {
|
|
||||||
int count = 0;
|
|
||||||
try {
|
|
||||||
for (JvmInfoDTO item : counter.getPoolUrls()) {
|
|
||||||
TestResourceDTO testResource = item.getTestResource();
|
|
||||||
String configuration = testResource.getConfiguration();
|
|
||||||
NodeDTO node = JSON.parseObject(configuration, NodeDTO.class);
|
|
||||||
String nodeIp = node.getIp();
|
|
||||||
Integer port = node.getPort();
|
|
||||||
|
|
||||||
String uri = String.format(BASE_URL + "/jmeter/getRunning/" + reportId, nodeIp, port);
|
|
||||||
ResponseEntity<Integer> result = restTemplate.getForEntity(uri, Integer.class);
|
|
||||||
if (result == null) {
|
|
||||||
count += result.getBody();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e.getMessage());
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getReportStatusByReportIds(Collection<String> values) {
|
public Map<String, String> getReportStatusByReportIds(Collection<String> values) {
|
||||||
if (CollectionUtils.isEmpty(values)) {
|
if (CollectionUtils.isEmpty(values)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
|
@ -688,7 +661,7 @@ public class ApiScenarioReportService {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public APIScenarioReportResult init(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID, RunModeConfigDTO config, String desc) {
|
public APIScenarioReportResult init(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID, RunModeConfigDTO config) {
|
||||||
APIScenarioReportResult report = new APIScenarioReportResult();
|
APIScenarioReportResult report = new APIScenarioReportResult();
|
||||||
if (triggerMode.equals(ApiRunMode.SCENARIO.name()) || triggerMode.equals(ApiRunMode.DEFINITION.name())) {
|
if (triggerMode.equals(ApiRunMode.SCENARIO.name()) || triggerMode.equals(ApiRunMode.DEFINITION.name())) {
|
||||||
triggerMode = ReportTriggerMode.MANUAL.name();
|
triggerMode = ReportTriggerMode.MANUAL.name();
|
||||||
|
@ -696,6 +669,7 @@ public class ApiScenarioReportService {
|
||||||
report.setId(id);
|
report.setId(id);
|
||||||
report.setTestId(id);
|
report.setTestId(id);
|
||||||
if (StringUtils.isNotEmpty(scenarioName)) {
|
if (StringUtils.isNotEmpty(scenarioName)) {
|
||||||
|
scenarioName = scenarioName.length() >= 3000 ? scenarioName.substring(0, 2000) : scenarioName;
|
||||||
report.setName(scenarioName);
|
report.setName(scenarioName);
|
||||||
} else {
|
} else {
|
||||||
report.setName("场景调试");
|
report.setName("场景调试");
|
||||||
|
@ -703,7 +677,9 @@ public class ApiScenarioReportService {
|
||||||
report.setUpdateTime(System.currentTimeMillis());
|
report.setUpdateTime(System.currentTimeMillis());
|
||||||
report.setCreateTime(System.currentTimeMillis());
|
report.setCreateTime(System.currentTimeMillis());
|
||||||
|
|
||||||
report.setStatus(APITestStatus.Running.name());
|
String status = config != null && StringUtils.equals(config.getMode(), RunModeConstants.SERIAL.toString())
|
||||||
|
? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
||||||
|
report.setStatus(status);
|
||||||
if (StringUtils.isNotEmpty(userID)) {
|
if (StringUtils.isNotEmpty(userID)) {
|
||||||
report.setUserId(userID);
|
report.setUserId(userID);
|
||||||
report.setCreateUser(userID);
|
report.setCreateUser(userID);
|
||||||
|
@ -736,11 +712,11 @@ public class ApiScenarioReportService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String status;//增加误报状态判断
|
String status;//增加误报状态判断
|
||||||
if(errorSize > 0){
|
if (errorSize > 0) {
|
||||||
status = ScenarioStatus.Error.name();
|
status = ScenarioStatus.Error.name();
|
||||||
}else if(errorReportResultSize > 0){
|
} else if (errorReportResultSize > 0) {
|
||||||
status = ExecuteResult.errorReportResult.name();
|
status = ExecuteResult.errorReportResult.name();
|
||||||
}else {
|
} else {
|
||||||
status = ScenarioStatus.Success.name();
|
status = ScenarioStatus.Success.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,4 +740,22 @@ public class ApiScenarioReportService {
|
||||||
deleteByIds(ids);
|
deleteByIds(ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public void batchSave(Map<String, RunModeDataDTO> executeQueue, String serialReportId, String runMode, List<MsExecResponseDTO> 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();
|
||||||
|
batchMapper.insert(report);
|
||||||
|
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, runMode));
|
||||||
|
}
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
if (sqlSession != null && sqlSessionFactory != null) {
|
||||||
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,260 @@
|
||||||
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
|
import io.metersphere.api.dto.datacount.ApiMethodUrlDTO;
|
||||||
|
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||||
|
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
||||||
|
import io.metersphere.api.dto.definition.request.ElementUtil;
|
||||||
|
import io.metersphere.base.domain.ApiDefinition;
|
||||||
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
|
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||||
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MsHashTreeService {
|
||||||
|
@Resource
|
||||||
|
private ApiTestCaseService apiTestCaseService;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiDefinitionService apiDefinitionService;
|
||||||
|
@Resource
|
||||||
|
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||||
|
|
||||||
|
private static final String CASE = "CASE";
|
||||||
|
private static final String REFERENCED = "referenced";
|
||||||
|
private static final String REF = "REF";
|
||||||
|
private static final String REF_TYPE = "refType";
|
||||||
|
private static final String ID = "id";
|
||||||
|
private static final String NAME = "name";
|
||||||
|
private static final String SCENARIO = "scenario";
|
||||||
|
private static final String TYPE = "type";
|
||||||
|
private static final String HASH_TREE = "hashTree";
|
||||||
|
private static final String PATH = "path";
|
||||||
|
private static final String METHOD = "method";
|
||||||
|
private static final String ENABLE = "enable";
|
||||||
|
private static final String NUM = "num";
|
||||||
|
private static final String ENV_ENABLE = "environmentEnable";
|
||||||
|
private static final String DISABLED = "disabled";
|
||||||
|
private static final String VERSION_NAME = "versionName";
|
||||||
|
private static final String VERSION_ENABLE = "versionEnable";
|
||||||
|
private static final String URL = "url";
|
||||||
|
|
||||||
|
public void setHashTree(JSONArray hashTree) {
|
||||||
|
// 将引用转成复制
|
||||||
|
if (CollectionUtils.isEmpty(hashTree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < hashTree.size(); i++) {
|
||||||
|
JSONObject object = (JSONObject) hashTree.get(i);
|
||||||
|
String referenced = object.getString(REFERENCED);
|
||||||
|
if (StringUtils.isNotBlank(referenced) && StringUtils.equals(referenced, REF)) {
|
||||||
|
// 检测引用对象是否存在,若果不存在则改成复制对象
|
||||||
|
String refType = object.getString(REF_TYPE);
|
||||||
|
if (StringUtils.isNotEmpty(refType)) {
|
||||||
|
if (refType.equals(CASE)) {
|
||||||
|
ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(object.getString(ID));
|
||||||
|
if (bloBs != null) {
|
||||||
|
object = JSON.parseObject(bloBs.getRequest());
|
||||||
|
object.put(ID, bloBs.getId());
|
||||||
|
object.put(NAME, bloBs.getName());
|
||||||
|
hashTree.set(i, object);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString(ID));
|
||||||
|
if (bloBs != null) {
|
||||||
|
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
||||||
|
hashTree.set(i, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (SCENARIO.equals(object.getString(TYPE))) {
|
||||||
|
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString(ID));
|
||||||
|
if (bloBs != null) {
|
||||||
|
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
||||||
|
hashTree.set(i, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (object != null && CollectionUtils.isNotEmpty(object.getJSONArray(HASH_TREE))) {
|
||||||
|
setHashTree(object.getJSONArray(HASH_TREE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApiMethodUrlDTO> getMethodUrlDTOByHashTreeJsonObj(JSONObject obj) {
|
||||||
|
List<ApiMethodUrlDTO> returnList = new ArrayList<>();
|
||||||
|
if (obj != null && obj.containsKey(HASH_TREE)) {
|
||||||
|
JSONArray hashArr = obj.getJSONArray(HASH_TREE);
|
||||||
|
for (int i = 0; i < hashArr.size(); i++) {
|
||||||
|
JSONObject elementObj = hashArr.getJSONObject(i);
|
||||||
|
if (elementObj == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elementObj.containsKey(URL) && elementObj.containsKey(METHOD)) {
|
||||||
|
String url = elementObj.getString(URL);
|
||||||
|
String method = elementObj.getString(METHOD);
|
||||||
|
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(url, method);
|
||||||
|
if (!returnList.contains(dto)) {
|
||||||
|
returnList.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elementObj.containsKey(PATH) && elementObj.containsKey(METHOD)) {
|
||||||
|
String path = elementObj.getString(PATH);
|
||||||
|
String method = elementObj.getString(METHOD);
|
||||||
|
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(path, method);
|
||||||
|
if (!returnList.contains(dto)) {
|
||||||
|
returnList.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementObj.containsKey(ID) && elementObj.containsKey(REF_TYPE)) {
|
||||||
|
String refType = elementObj.getString(REF_TYPE);
|
||||||
|
String id = elementObj.getString(ID);
|
||||||
|
if (StringUtils.equals(CASE, refType)) {
|
||||||
|
ApiDefinition apiDefinition = apiTestCaseService.findApiUrlAndMethodById(id);
|
||||||
|
if (apiDefinition != null) {
|
||||||
|
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(apiDefinition.getPath(), apiDefinition.getMethod());
|
||||||
|
if (!returnList.contains(dto)) {
|
||||||
|
returnList.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (StringUtils.equals("API", refType)) {
|
||||||
|
ApiDefinition apiDefinition = apiDefinitionService.selectUrlAndMethodById(id);
|
||||||
|
if (apiDefinition != null) {
|
||||||
|
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(apiDefinition.getPath(), apiDefinition.getMethod());
|
||||||
|
if (!returnList.contains(dto)) {
|
||||||
|
returnList.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApiMethodUrlDTO> stepUrlList = this.getMethodUrlDTOByHashTreeJsonObj(elementObj);
|
||||||
|
if (CollectionUtils.isNotEmpty(stepUrlList)) {
|
||||||
|
Collection unionList = CollectionUtils.union(returnList, stepUrlList);
|
||||||
|
returnList = new ArrayList<>(unionList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static List<String> requests = new ArrayList<String>() {{
|
||||||
|
this.add("HTTPSamplerProxy");
|
||||||
|
this.add("DubboSampler");
|
||||||
|
this.add("JDBCSampler");
|
||||||
|
this.add("TCPSampler");
|
||||||
|
}};
|
||||||
|
|
||||||
|
private void setElement(JSONObject element, Integer num, Boolean enable, String versionName, Boolean versionEnable) {
|
||||||
|
element.put(NUM, num);
|
||||||
|
element.put(ENABLE, enable == null ? false : enable);
|
||||||
|
element.put(VERSION_NAME, versionName);
|
||||||
|
element.put(VERSION_ENABLE, versionEnable == null ? false : versionEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject setRequest(JSONObject element) {
|
||||||
|
boolean enable = element.getBoolean(ENABLE);
|
||||||
|
boolean isExist = false;
|
||||||
|
if (StringUtils.equalsIgnoreCase(element.getString(REF_TYPE), CASE)) {
|
||||||
|
ApiTestCaseInfo apiTestCase = apiTestCaseService.get(element.getString(ID));
|
||||||
|
if (apiTestCase != null) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(element.getString(REFERENCED), REF)) {
|
||||||
|
JSONObject refElement = JSON.parseObject(apiTestCase.getRequest());
|
||||||
|
ElementUtil.dataFormatting(refElement);
|
||||||
|
JSONArray array = refElement.getJSONArray(HASH_TREE);
|
||||||
|
BeanUtils.copyBean(element, refElement);
|
||||||
|
if (array != null) {
|
||||||
|
ElementUtil.mergeHashTree(element, refElement.getJSONArray(HASH_TREE));
|
||||||
|
}
|
||||||
|
element.put(REFERENCED, REF);
|
||||||
|
element.put(DISABLED, true);
|
||||||
|
element.put(NAME, apiTestCase.getName());
|
||||||
|
}
|
||||||
|
element.put(ID, apiTestCase.getId());
|
||||||
|
isExist = true;
|
||||||
|
this.setElement(element, apiTestCase.getNum(), enable, apiTestCase.getVersionName(), apiTestCase.getVersionEnable());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ApiDefinitionResult definitionWithBLOBs = apiDefinitionService.getById(element.getString(ID));
|
||||||
|
if (definitionWithBLOBs != null) {
|
||||||
|
element.put(ID, definitionWithBLOBs.getId());
|
||||||
|
this.setElement(element, definitionWithBLOBs.getNum(), enable, definitionWithBLOBs.getVersionName(), definitionWithBLOBs.getVersionEnable());
|
||||||
|
isExist = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isExist) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(element.getString(REFERENCED), REF)) {
|
||||||
|
element.put(ENABLE, false);
|
||||||
|
}
|
||||||
|
element.put(NUM, "");
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject setRefScenario(JSONObject element) {
|
||||||
|
boolean enable = element.containsKey(ENABLE) ? element.getBoolean(ENABLE) : true;
|
||||||
|
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(element.getString(ID));
|
||||||
|
if (scenarioWithBLOBs != null && StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
||||||
|
boolean environmentEnable = element.containsKey(ENV_ENABLE)
|
||||||
|
? element.getBoolean(ENV_ENABLE) : false;
|
||||||
|
|
||||||
|
if (StringUtils.equalsIgnoreCase(element.getString(REFERENCED), REF)) {
|
||||||
|
element = JSON.parseObject(scenarioWithBLOBs.getScenarioDefinition());
|
||||||
|
element.put(REFERENCED, REF);
|
||||||
|
element.put(NAME, scenarioWithBLOBs.getName());
|
||||||
|
}
|
||||||
|
element.put(ID, scenarioWithBLOBs.getId());
|
||||||
|
element.put(ENV_ENABLE, environmentEnable);
|
||||||
|
this.setElement(element, scenarioWithBLOBs.getNum(), enable, scenarioWithBLOBs.getVersionName(), scenarioWithBLOBs.getVersionEnable());
|
||||||
|
} else {
|
||||||
|
if (StringUtils.equalsIgnoreCase(element.getString(REFERENCED), REF)) {
|
||||||
|
element.put(ENABLE, false);
|
||||||
|
}
|
||||||
|
element.put(NUM, "");
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dataFormatting(JSONArray hashTree) {
|
||||||
|
for (int i = 0; i < hashTree.size(); i++) {
|
||||||
|
JSONObject element = hashTree.getJSONObject(i);
|
||||||
|
if (element != null && StringUtils.equalsIgnoreCase(element.getString(TYPE), SCENARIO)) {
|
||||||
|
element = this.setRefScenario(element);
|
||||||
|
hashTree.set(i, element);
|
||||||
|
} else if (element != null && requests.contains(element.getString(TYPE))) {
|
||||||
|
element = this.setRequest(element);
|
||||||
|
hashTree.set(i, element);
|
||||||
|
}
|
||||||
|
if (element.containsKey(HASH_TREE)) {
|
||||||
|
JSONArray elementJSONArray = element.getJSONArray(HASH_TREE);
|
||||||
|
dataFormatting(elementJSONArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dataFormatting(JSONObject element) {
|
||||||
|
if (element != null && StringUtils.equalsIgnoreCase(element.getString(TYPE), SCENARIO)) {
|
||||||
|
element = this.setRefScenario(element);
|
||||||
|
} else if (element != null && requests.contains(element.getString(TYPE))) {
|
||||||
|
element = this.setRequest(element);
|
||||||
|
}
|
||||||
|
if (element != null && element.containsKey(HASH_TREE)) {
|
||||||
|
JSONArray elementJSONArray = element.getJSONArray(HASH_TREE);
|
||||||
|
dataFormatting(elementJSONArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
package io.metersphere.api.service;
|
|
||||||
|
|
||||||
import io.metersphere.api.jmeter.FixedCapacityUtils;
|
|
||||||
import io.metersphere.api.jmeter.MessageCache;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class MsResultService {
|
|
||||||
public String getJmeterLogger(String testId) {
|
|
||||||
try {
|
|
||||||
Long startTime = MessageCache.jmeterLogTask.get(testId);
|
|
||||||
if (startTime == null) {
|
|
||||||
startTime = MessageCache.jmeterLogTask.get("[" + testId + "]");
|
|
||||||
}
|
|
||||||
if (startTime == null) {
|
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
Long endTime = System.currentTimeMillis();
|
|
||||||
Long finalStartTime = startTime;
|
|
||||||
String logMessage = FixedCapacityUtils.fixedCapacityCache.entrySet().stream()
|
|
||||||
.filter(map -> map.getKey() > finalStartTime && map.getKey() < endTime)
|
|
||||||
.map(map -> map.getValue()).collect(Collectors.joining());
|
|
||||||
return logMessage;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,18 +12,18 @@ import io.metersphere.dto.JmeterRunRequestDTO;
|
||||||
import io.metersphere.dto.ResultDTO;
|
import io.metersphere.dto.ResultDTO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class RemakeReportService {
|
public class RemakeReportService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioReportMapper apiScenarioReportMapper;
|
private ApiScenarioReportMapper apiScenarioReportMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioMapper apiScenarioMapper;
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
|
@Resource
|
||||||
private ApiDefinitionExecResultMapper execResultMapper;
|
private ApiDefinitionExecResultMapper execResultMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
|
@ -55,6 +55,19 @@ public class RemakeReportService {
|
||||||
testCaseReviewApiCaseMapper.updateByPrimaryKeySelective(testCaseReviewApiCase);
|
testCaseReviewApiCaseMapper.updateByPrimaryKeySelective(testCaseReviewApiCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||||
|
ApiDefinitionExecResult result = execResultMapper.selectByPrimaryKey(request.getReportId());
|
||||||
|
if (result != null) {
|
||||||
|
result.setStatus("error");
|
||||||
|
result.setEndTime(System.currentTimeMillis());
|
||||||
|
execResultMapper.updateByPrimaryKeySelective(result);
|
||||||
|
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseMapper.selectByPrimaryKey(request.getTestId());
|
||||||
|
if (apiTestCase != null) {
|
||||||
|
apiTestCase.setStatus("error");
|
||||||
|
apiTestCase.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
} else if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
||||||
if (report != null) {
|
if (report != null) {
|
||||||
|
@ -94,7 +107,7 @@ public class RemakeReportService {
|
||||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
|
||||||
if (report != null) {
|
if (report != null) {
|
||||||
report.setStatus(APITestStatus.Error.name());
|
report.setStatus(APITestStatus.Error.name());
|
||||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(request.getTestId())) {
|
if (StringUtils.isNotEmpty(request.getTestId())) {
|
||||||
ApiScenarioWithBLOBs scenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(request.getTestId());
|
ApiScenarioWithBLOBs scenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(request.getTestId());
|
||||||
|
@ -103,14 +116,11 @@ public class RemakeReportService {
|
||||||
scenarioWithBLOBs.setPassRate("0%");
|
scenarioWithBLOBs.setPassRate("0%");
|
||||||
scenarioWithBLOBs.setReportId(report.getId());
|
scenarioWithBLOBs.setReportId(report.getId());
|
||||||
scenarioWithBLOBs.setExecuteTimes(1);
|
scenarioWithBLOBs.setExecuteTimes(1);
|
||||||
apiScenarioMapper.updateByPrimaryKey(scenarioWithBLOBs);
|
apiScenarioMapper.updateByPrimaryKeySelective(scenarioWithBLOBs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理队列
|
// 处理队列
|
||||||
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
|
|
||||||
example.createCriteria().andQueueIdEqualTo(request.getQueueId()).andTestIdEqualTo(request.getTestId());
|
|
||||||
CommonBeanFactory.getBean(ApiExecutionQueueDetailMapper.class).deleteByExample(example);
|
|
||||||
ResultDTO dto = new ResultDTO();
|
ResultDTO dto = new ResultDTO();
|
||||||
BeanUtils.copyBean(dto, request);
|
BeanUtils.copyBean(dto, request);
|
||||||
dto.setQueueId(request.getQueueId());
|
dto.setQueueId(request.getQueueId());
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.service;
|
||||||
import io.metersphere.api.dto.automation.ApiTestReportVariable;
|
import io.metersphere.api.dto.automation.ApiTestReportVariable;
|
||||||
import io.metersphere.api.jmeter.ExecutedHandleSingleton;
|
import io.metersphere.api.jmeter.ExecutedHandleSingleton;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.constants.NoticeConstants;
|
import io.metersphere.commons.constants.NoticeConstants;
|
||||||
|
@ -43,6 +44,8 @@ public class TestResultService {
|
||||||
@Resource
|
@Resource
|
||||||
private ApiAutomationService apiAutomationService;
|
private ApiAutomationService apiAutomationService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
|
@Resource
|
||||||
private TestPlanApiCaseService testPlanApiCaseService;
|
private TestPlanApiCaseService testPlanApiCaseService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanTestCaseService testPlanTestCaseService;
|
private TestPlanTestCaseService testPlanTestCaseService;
|
||||||
|
@ -85,7 +88,7 @@ public class TestResultService {
|
||||||
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
ApiScenarioReport scenarioReport = apiScenarioReportService.testEnded(dto);
|
ApiScenarioReport scenarioReport = apiScenarioReportService.testEnded(dto);
|
||||||
if (scenarioReport != null) {
|
if (scenarioReport != null) {
|
||||||
ApiScenarioWithBLOBs apiScenario = apiAutomationService.getApiScenario(scenarioReport.getScenarioId());
|
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||||
String environment = "";
|
String environment = "";
|
||||||
//执行人
|
//执行人
|
||||||
String userName = "";
|
String userName = "";
|
||||||
|
@ -128,7 +131,7 @@ public class TestResultService {
|
||||||
if (StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
if (StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
|
||||||
TestPlanScenarioCaseService testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
|
TestPlanScenarioCaseService testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
|
||||||
TestPlanApiScenario testPlanApiScenario = testPlanScenarioCaseService.get(testPlanScenarioId);
|
TestPlanApiScenario testPlanApiScenario = testPlanScenarioCaseService.get(testPlanScenarioId);
|
||||||
ApiScenarioWithBLOBs apiScenario = CommonBeanFactory.getBean(ApiAutomationService.class).getApiScenario(testPlanApiScenario.getApiScenarioId());
|
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||||
testPlanTestCaseService.updateTestCaseStates(apiScenario.getId(), apiScenario.getName(), testPlanApiScenario.getTestPlanId(), TrackCount.AUTOMATION);
|
testPlanTestCaseService.updateTestCaseStates(apiScenario.getId(), apiScenario.getName(), testPlanApiScenario.getTestPlanId(), TrackCount.AUTOMATION);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.task.service;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import io.metersphere.api.dto.automation.TaskRequest;
|
import io.metersphere.api.dto.automation.TaskRequest;
|
||||||
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
|
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
|
||||||
|
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
|
@ -120,6 +121,7 @@ public class TaskService {
|
||||||
// 从队列移除
|
// 从队列移除
|
||||||
execThreadPoolExecutor.removeQueue(request.getReportId());
|
execThreadPoolExecutor.removeQueue(request.getReportId());
|
||||||
apiExecutionQueueService.stop(request.getReportId());
|
apiExecutionQueueService.stop(request.getReportId());
|
||||||
|
PoolExecBlockingQueueUtil.offer(request.getReportId());
|
||||||
if (StringUtils.equals(request.getType(), "API")) {
|
if (StringUtils.equals(request.getType(), "API")) {
|
||||||
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId());
|
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId());
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -151,6 +153,7 @@ public class TaskService {
|
||||||
// 从队列移除
|
// 从队列移除
|
||||||
execThreadPoolExecutor.removeQueue(item.getId());
|
execThreadPoolExecutor.removeQueue(item.getId());
|
||||||
apiExecutionQueueService.stop(item.getId());
|
apiExecutionQueueService.stop(item.getId());
|
||||||
|
PoolExecBlockingQueueUtil.offer(item.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (StringUtils.equals(request.getType(), "SCENARIO")) {
|
} else if (StringUtils.equals(request.getType(), "SCENARIO")) {
|
||||||
|
@ -165,6 +168,7 @@ public class TaskService {
|
||||||
// 从队列移除
|
// 从队列移除
|
||||||
execThreadPoolExecutor.removeQueue(report.getId());
|
execThreadPoolExecutor.removeQueue(report.getId());
|
||||||
apiExecutionQueueService.stop(report.getId());
|
apiExecutionQueueService.stop(report.getId());
|
||||||
|
PoolExecBlockingQueueUtil.offer(report.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (StringUtils.equals(request.getType(), "PERFORMANCE")) {
|
} else if (StringUtils.equals(request.getType(), "PERFORMANCE")) {
|
||||||
|
@ -177,6 +181,7 @@ public class TaskService {
|
||||||
// 从队列移除
|
// 从队列移除
|
||||||
execThreadPoolExecutor.removeQueue(loadTestReport.getId());
|
execThreadPoolExecutor.removeQueue(loadTestReport.getId());
|
||||||
apiExecutionQueueService.stop(loadTestReport.getId());
|
apiExecutionQueueService.stop(loadTestReport.getId());
|
||||||
|
PoolExecBlockingQueueUtil.offer(loadTestReport.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue