refactor(接口测试): 大批量执行效率优化修复多节点执行阻塞时间长问题

This commit is contained in:
fit2-zhao 2022-01-29 17:46:58 +08:00 committed by fit2-zhao
parent f97917b581
commit e119cdf628
30 changed files with 687 additions and 689 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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,16 +25,11 @@ 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.sleep(5000);
Thread.currentThread().setName("API-CASE-THREAD"); Thread.currentThread().setName("API-CASE-THREAD");
for (String testId : executeQueue.keySet()) { for (String testId : executeQueue.keySet()) {
ApiDefinitionExecResult result = executeQueue.get(testId); ApiDefinitionExecResult result = executeQueue.get(testId);
String reportId = result.getId(); String reportId = result.getId();
HashTree hashTree = null; HashTree hashTree = null;
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testId, result.getId(), runMode, config.getEnvMap());
}
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId())); runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
runRequest.setTestPlanReportId(executionQueue.getReportId()); runRequest.setTestPlanReportId(executionQueue.getReportId());
@ -46,10 +40,11 @@ public class ApiCaseParallelExecuteService {
if (executionQueue.getQueue() != null) { if (executionQueue.getQueue() != null) {
runRequest.setPlatformUrl(executionQueue.getQueue().getId()); runRequest.setPlatformUrl(executionQueue.getQueue().getId());
} }
jMeterService.run(runRequest); if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest);
runRequest.setHashTree(hashTree);
} }
} catch (Exception e) { jMeterService.run(runRequest);
LoggerUtil.error("并发执行用例失败:" + e.getMessage());
} }
} }
}); });

View File

@ -22,12 +22,10 @@ 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() + " 】执行完成");
} }
} }

View File

@ -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);

View File

@ -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())); responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
// 增加并行集合报告 reportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType());
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 reportType = request.getConfig().getReportType();
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId; String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
// 生成执行队列
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId() DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId()
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig()); , ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { // 预生成报告
if (StringUtils.isNotEmpty(serialReportId)) { apiScenarioReportService.batchSave(executeQueue, serialReportId, request.getRunMode(), responseDTOS);
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig() != null ? request.getConfig().getReportType() : null);
} // 开始执行
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); if (StringUtils.equals(request.getConfig().getMode(), RunModeConstants.SERIAL.toString())) {
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class); serialService.serial(executionQueue, executionQueue.getQueue());
// 非集合报告先生成执行队列
if (StringUtils.isEmpty(serialReportId)) {
for (String reportId : executeQueue.keySet()) {
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
report.setStatus(APITestStatus.Waiting.name());
batchMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(executeQueue.get(reportId).getTestId(), reportId, request.getRunMode()));
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
if (executionQueue.getQueue() != null) {
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
}
} else { } else {
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS, executionQueue); parallelService.parallel(executeQueue, request, serialReportId, 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,11 +270,11 @@ 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<>());
@ -320,28 +284,11 @@ public class ApiScenarioExecuteService {
runModeDataDTO.setReport(report); runModeDataDTO.setReport(report);
runModeDataDTO.setReportId(report.getId()); runModeDataDTO.setReportId(report.getId());
executeQueue.put(report.getId(), runModeDataDTO); executeQueue.put(report.getId(), runModeDataDTO);
} else { runModeDataDTO.setScenario(item);
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); 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);
}
}
}
// 生成报告结构 // 生成报告结构
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);
} }
} }
} }

View File

@ -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()) { for (String reportId : executeQueue.keySet()) {
//存储报告 RunModeDataDTO dataDTO = executeQueue.get(reportId);
APIScenarioReportResult report = executeQueue.get(reportId).getReport(); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null);
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()) {
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(executeQueue.get(reportId).getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), executeQueue.get(reportId).getHashTree());
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);
} }
} }

View File

@ -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() + "");
try { String reportId = StringUtils.isNotEmpty(executionQueue.getReportId()) ? executionQueue.getReportId() : queue.getReportId();
if (!StringUtils.equals(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name())) {
reportId = queue.getReportId();
}
HashTree hashTree = null; 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 {
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,7 +142,8 @@ 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) {
try {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId); ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
String envId = null; String envId = null;
if (caseWithBLOBs == null) { if (caseWithBLOBs == null) {
@ -173,7 +160,7 @@ public class ApiScenarioSerialService {
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) { } catch (Exception ex) {
ApiDefinitionExecResult apiDefinitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId); RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
remakeReportService.remake(runRequest);
if (apiDefinitionExecResult != null) { ResultDTO dto = new ResultDTO();
apiDefinitionExecResult.setStatus("Error"); BeanUtils.copyBean(dto, runRequest);
apiDefinitionExecResultMapper.updateByPrimaryKey(apiDefinitionExecResult); CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
CommonBeanFactory.getBean(ApiDefinitionExecResultService.class)
.editStatus(apiDefinitionExecResult, runMode, "error"
, System.currentTimeMillis(), apiDefinitionExecResult.getId(), testId);
}
MSException.throwException(ex.getMessage());
}
} }
return null; return null;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);

View File

@ -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 "";
}
}
} }

View File

@ -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();
} }
} }

View File

@ -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 {
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
}
}
public void addQueue(JmeterRunRequestDTO request) {
this.runLocal(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;
}
} }
} }

View File

@ -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];

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
} }
} }

View File

@ -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<>();
try {
String scenarioDefinition = scenario.getScenarioDefinition(); String scenarioDefinition = scenario.getScenarioDefinition();
JSONObject scenarioObj = JSONObject.parseObject(scenarioDefinition); JSONObject scenarioObj = JSONObject.parseObject(scenarioDefinition);
List<ApiMethodUrlDTO> stepUrlList = this.getMethodUrlDTOByHashTreeJsonObj(scenarioObj); List<ApiMethodUrlDTO> stepUrlList = hashTreeService.getMethodUrlDTOByHashTreeJsonObj(scenarioObj);
if (CollectionUtils.isNotEmpty(stepUrlList)) { if (CollectionUtils.isNotEmpty(stepUrlList)) {
Collection unionList = CollectionUtils.union(urlList, stepUrlList); Collection unionList = CollectionUtils.union(urlList, stepUrlList);
urlList = new ArrayList<>(unionList); 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());

View File

@ -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);
}
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);
} }

View File

@ -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) {
// 报告详情内容 // 报告详情内容
@ -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);
} }
@ -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);
@ -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);
}
}
}
} }

View File

@ -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);
}
}
}

View File

@ -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 "";
}
}
}

View File

@ -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());

View File

@ -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) {

View File

@ -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());
} }
} }
} }