refactor(接口测试): 资源池执行结果优化

Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
fit2-zhao 2023-05-10 14:00:03 +08:00 committed by fit2-zhao
parent dd4cec4085
commit b74d048f94
7 changed files with 57 additions and 46 deletions

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto.definition.request.controller; package io.metersphere.api.dto.definition.request.controller;
import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.constants.ElementConstants; import io.metersphere.commons.constants.ElementConstants;
import io.metersphere.plugin.core.MsParameter; import io.metersphere.plugin.core.MsParameter;
import io.metersphere.plugin.core.MsTestElement; import io.metersphere.plugin.core.MsTestElement;
@ -52,7 +53,7 @@ public class MsTransactionController extends MsTestElement {
if (StringUtils.isEmpty(this.getName())) { if (StringUtils.isEmpty(this.getName())) {
this.setName(getLabelName()); this.setName(getLabelName());
} }
transactionController.setName("Transaction=" + this.getName()); transactionController.setName(CommonConstants.PRE_TRANSACTION + this.getName());
transactionController.setProperty(TestElement.TEST_CLASS, TransactionController.class.getName()); transactionController.setProperty(TestElement.TEST_CLASS, TransactionController.class.getName());
transactionController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TransactionControllerGui")); transactionController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TransactionControllerGui"));
transactionController.setGenerateParentSample(generateParentSample); transactionController.setGenerateParentSample(generateParentSample);

View File

@ -1,7 +1,6 @@
package io.metersphere.api.jmeter; package io.metersphere.api.jmeter;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
@ -49,23 +48,15 @@ public class KafkaListenerTask implements Runnable {
@Override @Override
public void run() { public void run() {
try { try {
// 分三类存储
Map<String, List<ResultDTO>> assortMap = new LinkedHashMap<>();
List<ResultDTO> resultDTOS = new LinkedList<>();
LoggerUtil.info("KAFKA解析结果任务开始解析结果", String.valueOf(record.key()));
ResultDTO dto = this.formatResult(); ResultDTO dto = this.formatResult();
if (dto == null) { if (dto == null) {
LoggerUtil.info("未获取到执行结果", String.valueOf(record.key())); LoggerUtil.info("KAFKA监听未获取到执行结果", String.valueOf(record.key()));
return; return;
} }
LoggerUtil.info("KAFKA监听解任务开始处理结果"
if (BooleanUtils.isTrue(dto.getHasEnded())) { + dto.getRequestResults().size() + "", String.valueOf(record.key()));
redisTemplateService.delFilePath(dto.getReportId()); // 分三类存储
resultDTOS.add(dto); Map<String, List<ResultDTO>> assortMap = new LinkedHashMap<>();
// 全局并发队列
PoolExecBlockingQueueUtil.offer(dto.getReportId());
LoggerUtil.info("KAFKA消费结束", record.key());
}
// 携带结果 // 携带结果
if (CollectionUtils.isNotEmpty(dto.getRequestResults())) { if (CollectionUtils.isNotEmpty(dto.getRequestResults())) {
String key = RUN_MODE_MAP.get(dto.getRunMode()); String key = RUN_MODE_MAP.get(dto.getRunMode());
@ -77,25 +68,25 @@ public class KafkaListenerTask implements Runnable {
}}); }});
} }
} }
if (MapUtils.isNotEmpty(assortMap)) { if (MapUtils.isNotEmpty(assortMap)) {
LoggerUtil.info("KAFKA消费执行内容存储开始", String.valueOf(record.key()));
testResultService.batchSaveResults(assortMap); testResultService.batchSaveResults(assortMap);
LoggerUtil.info("KAFKA消费执行内容存储结束", String.valueOf(record.key()));
} }
// 更新执行结果 // 更新执行结果
if (CollectionUtils.isNotEmpty(resultDTOS)) { if (BooleanUtils.isTrue(dto.getHasEnded())) {
resultDTOS.forEach(testResult -> { redisTemplateService.delFilePath(dto.getReportId());
LoggerUtil.info("资源 " + testResult.getTestId() + " 整体执行完成", testResult.getReportId()); LoggerUtil.info("KAFKA监听开始处理报告状态", dto.getReportId());
testResultService.testEnded(testResult); testResultService.testEnded(dto);
LoggerUtil.info("执行队列处理:" + testResult.getQueueId(), testResult.getReportId()); LoggerUtil.info("KAFKA监听开始处理执行队列", dto.getReportId());
apiExecutionQueueService.queueNext(testResult); apiExecutionQueueService.queueNext(dto);
// 更新测试计划报告 // 更新测试计划报告
LoggerUtil.info("Check Processing Test Plan report status" + testResult.getQueueId() + "" + testResult.getTestId(), testResult.getReportId()); LoggerUtil.info("Check Processing Test Plan report status", dto.getReportId());
apiExecutionQueueService.checkTestPlanCaseTestEnd(testResult.getTestId(), testResult.getRunMode(), testResult.getTestPlanReportId()); apiExecutionQueueService.checkTestPlanCaseTestEnd(dto.getTestId(), dto.getRunMode(), dto.getTestPlanReportId());
}); LoggerUtil.info("KAFKA监听整体资源处理结束", dto.getReportId());
} }
} catch (Exception e) { } catch (Exception e) {
LoggerUtil.error("KAFKA消费失败", String.valueOf(record.key()), e); LoggerUtil.error("KAFKA监听消费失败", String.valueOf(record.key()), e);
} }
} }

View File

@ -22,6 +22,7 @@ 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.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.dto.MsRegexDTO; import io.metersphere.dto.MsRegexDTO;
import io.metersphere.dto.RequestResult; import io.metersphere.dto.RequestResult;
@ -176,7 +177,8 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
dto.setRunMode(runMode); dto.setRunMode(runMode);
String console = FixedCapacityUtil.getJmeterLogger(this.getName(), false); String console = FixedCapacityUtil.getJmeterLogger(this.getName(), false);
if (StringUtils.isNotEmpty(requestResult.getName()) && requestResult.getName().startsWith("Transaction=")) { if (StringUtils.isNotEmpty(requestResult.getName())
&& requestResult.getName().startsWith(CommonConstants.PRE_TRANSACTION)) {
requestResult.getSubRequestResults().forEach(transactionResult -> { requestResult.getSubRequestResults().forEach(transactionResult -> {
this.sendResult(transactionResult, console, dto); this.sendResult(transactionResult, console, dto);
}); });
@ -201,7 +203,8 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
} }
private void setVars(SampleResult result) { private void setVars(SampleResult result) {
if (StringUtils.isNotEmpty(result.getSampleLabel()) && result.getSampleLabel().startsWith("Transaction=")) { if (StringUtils.isNotEmpty(result.getSampleLabel())
&& result.getSampleLabel().startsWith(CommonConstants.PRE_TRANSACTION)) {
for (int i = 0; i < result.getSubResults().length; i++) { for (int i = 0; i < result.getSubResults().length; i++) {
SampleResult subResult = result.getSubResults()[i]; SampleResult subResult = result.getSubResults()[i];
this.setVars(subResult); this.setVars(subResult);

View File

@ -13,5 +13,5 @@ public class CommonConstants {
public static final String CASE = "CASE"; public static final String CASE = "CASE";
public static final String USER = "user"; public static final String USER = "user";
public static final String USER_NAME = "userName"; public static final String USER_NAME = "userName";
public static final String PRE_TRANSACTION = "Transaction=";
} }

View File

@ -2,7 +2,6 @@ package io.metersphere.service;
import io.metersphere.api.dto.automation.ApiTestReportVariable; import io.metersphere.api.dto.automation.ApiTestReportVariable;
import io.metersphere.api.exec.scenario.ApiEnvironmentRunningParamService; import io.metersphere.api.exec.scenario.ApiEnvironmentRunningParamService;
import io.metersphere.utils.ReportStatusUtil;
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.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioMapper;
@ -13,7 +12,6 @@ import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.DateUtils; import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
import io.metersphere.vo.ResultVO;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.BaseSystemConfigDTO; import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.RequestResult; import io.metersphere.dto.RequestResult;
@ -27,6 +25,8 @@ import io.metersphere.service.scenario.ApiScenarioExecutionInfoService;
import io.metersphere.service.scenario.ApiScenarioReportService; import io.metersphere.service.scenario.ApiScenarioReportService;
import io.metersphere.service.scenario.ApiScenarioReportStructureService; import io.metersphere.service.scenario.ApiScenarioReportStructureService;
import io.metersphere.service.scenario.ApiScenarioService; import io.metersphere.service.scenario.ApiScenarioService;
import io.metersphere.utils.ReportStatusUtil;
import io.metersphere.vo.ResultVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;

View File

@ -131,6 +131,7 @@ public class ApiDefinitionExecResultService {
for (ResultDTO dto : resultDTOS) { for (ResultDTO dto : resultDTOS) {
this.mergeRetryResults(dto); this.mergeRetryResults(dto);
LoggerUtil.info("开始存储报告结果[ " + dto.getRequestResults().size() + " ]", dto.getReportId());
if (CollectionUtils.isNotEmpty(dto.getRequestResults())) { if (CollectionUtils.isNotEmpty(dto.getRequestResults())) {
for (RequestResult item : dto.getRequestResults()) { for (RequestResult item : dto.getRequestResults()) {
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) { if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {

View File

@ -1,11 +1,13 @@
package io.metersphere.service.scenario; package io.metersphere.service.scenario;
import io.metersphere.commons.utils.ResultConversionUtil;
import io.metersphere.base.domain.ApiScenarioReportResultWithBLOBs; import io.metersphere.base.domain.ApiScenarioReportResultWithBLOBs;
import io.metersphere.base.mapper.ApiScenarioReportResultMapper; import io.metersphere.base.mapper.ApiScenarioReportResultMapper;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.utils.ResultConversionUtil;
import io.metersphere.dto.RequestResult; import io.metersphere.dto.RequestResult;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.ExecutorType;
@ -15,7 +17,6 @@ import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.util.List; import java.util.List;
@Service @Service
@ -31,17 +32,22 @@ public class ApiScenarioReportResultService {
if (queue.size() == 1) { if (queue.size() == 1) {
queue.forEach(item -> { queue.forEach(item -> {
// 事物控制器出来的结果特殊处理 // 事物控制器出来的结果特殊处理
if (StringUtils.isNotEmpty(item.getName()) && item.getName().startsWith("Transaction=") && CollectionUtils.isEmpty(item.getSubRequestResults())) { if (StringUtils.isNotEmpty(item.getName())
&& item.getName().startsWith(CommonConstants.PRE_TRANSACTION)
&& CollectionUtils.isEmpty(item.getSubRequestResults())) {
LoggerUtil.debug("合并事物请求暂不入库"); LoggerUtil.debug("合并事物请求暂不入库");
} else { } else {
apiScenarioReportResultMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(reportId, item)); apiScenarioReportResultMapper.insert(ResultConversionUtil
.getApiScenarioReportResultBLOBs(reportId, item));
} }
}); });
} else { } else {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioReportResultMapper batchMapper = sqlSession.getMapper(ApiScenarioReportResultMapper.class); ApiScenarioReportResultMapper batchMapper = sqlSession.getMapper(ApiScenarioReportResultMapper.class);
queue.forEach(item -> { queue.forEach(item -> {
if (StringUtils.isEmpty(item.getName()) || !item.getName().startsWith("Transaction=") || !CollectionUtils.isEmpty(item.getSubRequestResults())) { if (StringUtils.isEmpty(item.getName()) ||
!item.getName().startsWith(CommonConstants.PRE_TRANSACTION) ||
!CollectionUtils.isEmpty(item.getSubRequestResults())) {
batchMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(reportId, item)); batchMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(reportId, item));
} }
}); });
@ -53,21 +59,30 @@ public class ApiScenarioReportResultService {
} }
} }
public void batchSave(List<ResultDTO> dtos) { public void batchSave(List<ResultDTO> results) {
if (CollectionUtils.isNotEmpty(dtos)) { if (CollectionUtils.isNotEmpty(results)) {
if (dtos.size() == 1 && CollectionUtils.isNotEmpty(dtos.get(0).getRequestResults()) && dtos.get(0).getRequestResults().size() == 1) { if (results.size() == 1 &&
CollectionUtils.isNotEmpty(results.get(0).getRequestResults())
&& results.get(0).getRequestResults().size() == 1) {
// 单条储存 // 单条储存
RequestResult requestResult = dtos.get(0).getRequestResults().get(0); RequestResult requestResult = results.get(0).getRequestResults().get(0);
if (StringUtils.isEmpty(requestResult.getName()) || !requestResult.getName().startsWith("Transaction=") || !CollectionUtils.isEmpty(requestResult.getSubRequestResults())) { LoggerUtil.info("开始存储报告结果[ 1 ]", results.get(0).getReportId());
apiScenarioReportResultMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(dtos.get(0).getReportId(), requestResult)); if (StringUtils.isEmpty(requestResult.getName())
|| !requestResult.getName().startsWith(CommonConstants.PRE_TRANSACTION)
|| !CollectionUtils.isEmpty(requestResult.getSubRequestResults())) {
apiScenarioReportResultMapper.insert(ResultConversionUtil
.getApiScenarioReportResultBLOBs(results.get(0).getReportId(), requestResult));
} }
} else { } else {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiScenarioReportResultMapper batchMapper = sqlSession.getMapper(ApiScenarioReportResultMapper.class); ApiScenarioReportResultMapper batchMapper = sqlSession.getMapper(ApiScenarioReportResultMapper.class);
for (ResultDTO dto : dtos) { for (ResultDTO dto : results) {
LoggerUtil.info("开始存储报告结果[ " + dto.getRequestResults().size() + " ]", dto.getReportId());
if (CollectionUtils.isNotEmpty(dto.getRequestResults())) { if (CollectionUtils.isNotEmpty(dto.getRequestResults())) {
dto.getRequestResults().forEach(item -> { dto.getRequestResults().forEach(item -> {
if (StringUtils.isEmpty(item.getName()) || !item.getName().startsWith("Transaction=") || !CollectionUtils.isEmpty(item.getSubRequestResults())) { if (StringUtils.isEmpty(item.getName()) ||
!item.getName().startsWith(CommonConstants.PRE_TRANSACTION) ||
!CollectionUtils.isEmpty(item.getSubRequestResults())) {
batchMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(dto.getReportId(), item)); batchMapper.insert(ResultConversionUtil.getApiScenarioReportResultBLOBs(dto.getReportId(), item));
} }
}); });