fix(接口测试): 修复同步接收报告结果有时间差问题

--bug=1027294 --user=赵勇 【接口测试】场景-生成报告-步骤显示返回结果未执行 https://www.tapd.cn/55049933/s/1386310

Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
fit2-zhao 2023-06-26 16:04:14 +08:00 committed by fit2-zhao
parent c67ae4ddce
commit 06a3a274af
5 changed files with 79 additions and 73 deletions

View File

@ -10,17 +10,13 @@ import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.NewDriverManager; import io.metersphere.api.jmeter.NewDriverManager;
import io.metersphere.api.jmeter.utils.ApiFakeErrorUtil; import io.metersphere.api.jmeter.utils.ApiFakeErrorUtil;
import io.metersphere.api.jmeter.utils.SmoothWeighted; import io.metersphere.api.jmeter.utils.SmoothWeighted;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.base.domain.ApiExecutionQueueDetail; import io.metersphere.base.domain.ApiExecutionQueueDetail;
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.base.mapper.plan.TestPlanApiCaseMapper; import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.constants.PropertyConstant; import io.metersphere.commons.constants.PropertyConstant;
import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
@ -31,13 +27,11 @@ import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.service.RemakeReportService; import io.metersphere.service.RemakeReportService;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
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 java.util.*; import java.util.*;
@ -50,8 +44,6 @@ public class ApiCaseSerialService {
@Resource @Resource
private JMeterService jMeterService; private JMeterService jMeterService;
@Resource @Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper; private ApiTestCaseMapper apiTestCaseMapper;
@Resource @Resource
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
@ -91,29 +83,11 @@ public class ApiCaseSerialService {
// 判断触发资源对象是用例 // 判断触发资源对象是用例
if (!GenerateHashTreeUtil.isSetReport(executionQueue.getReportType()) if (!GenerateHashTreeUtil.isSetReport(executionQueue.getReportType())
|| StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) { || StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) {
updateDefinitionExecResultToRunning(queue, runRequest); remakeReportService.updateApiReport(queue, runRequest);
} }
jMeterService.run(runRequest); jMeterService.run(runRequest);
} }
@Transactional(propagation = Propagation.NOT_SUPPORTED)
protected void updateDefinitionExecResultToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
if (execResult != null) {
if (MapUtils.isNotEmpty(runRequest.getExtendedParameters())) {
runRequest.getExtendedParameters().put(CommonConstants.USER_ID, execResult.getUserId());
} else {
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
this.put(CommonConstants.USER_ID, execResult.getUserId());
}});
}
execResult.setStartTime(System.currentTimeMillis());
execResult.setStatus(ApiReportStatus.RUNNING.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ]", execResult.getId());
}
}
private void initEnv(HashTree hashTree) { private void initEnv(HashTree hashTree) {
BaseEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(BaseEnvironmentService.class); BaseEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(BaseEnvironmentService.class);
HashTreeUtil hashTreeUtil = new HashTreeUtil(); HashTreeUtil hashTreeUtil = new HashTreeUtil();

View File

@ -6,15 +6,11 @@ import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.utils.ApiFakeErrorUtil; import io.metersphere.api.jmeter.utils.ApiFakeErrorUtil;
import io.metersphere.api.jmeter.utils.SmoothWeighted; import io.metersphere.api.jmeter.utils.SmoothWeighted;
import io.metersphere.base.domain.ApiExecutionQueueDetail; import io.metersphere.base.domain.ApiExecutionQueueDetail;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.domain.ApiScenarioWithBLOBs; import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.TestPlanApiScenario; import io.metersphere.base.domain.TestPlanApiScenario;
import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper; import io.metersphere.base.mapper.plan.TestPlanApiScenarioMapper;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.utils.GenerateHashTreeUtil; import io.metersphere.commons.utils.GenerateHashTreeUtil;
import io.metersphere.commons.utils.HashTreeUtil; import io.metersphere.commons.utils.HashTreeUtil;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
@ -33,15 +29,12 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class ApiScenarioSerialService { public class ApiScenarioSerialService {
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource @Resource
private JMeterService jMeterService; private JMeterService jMeterService;
@Resource @Resource
@ -108,44 +101,10 @@ public class ApiScenarioSerialService {
return; return;
} }
// 更新报告状态 // 更新报告状态
updateReportToRunning(queue, runRequest); remakeReportService.updateScenarioReport(queue, runRequest);
jMeterService.run(runRequest); jMeterService.run(runRequest);
} }
/**
* 更新报告状态
*
* @param queue
* @param runRequest
*/
public void updateReportToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
if (!GenerateHashTreeUtil.isSetReport(runRequest.getReportType()) &&
StringUtils.equalsAny(runRequest.getRunMode(),
ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(),
ApiRunMode.JENKINS_SCENARIO_PLAN.name(),
ApiRunMode.UI_SCENARIO.name(),
ApiRunMode.UI_SCENARIO_PLAN.name(),
ApiRunMode.UI_JENKINS_SCENARIO_PLAN.name(),
ApiRunMode.UI_SCHEDULE_SCENARIO.name(),
ApiRunMode.UI_SCHEDULE_SCENARIO_PLAN.name())
) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
if (report != null) {
report.setStatus(ApiReportStatus.RUNNING.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
runRequest.setExtendedParameters(new HashMap<>() {{
this.put(CommonConstants.USER_ID, report.getCreateUser());
}});
apiScenarioReportMapper.updateByPrimaryKey(report);
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ]", report.getId());
}
}
}
private void initEnv(HashTree hashTree) { private void initEnv(HashTree hashTree) {
HashTreeUtil hashTreeUtil = new HashTreeUtil(); HashTreeUtil hashTreeUtil = new HashTreeUtil();
Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService); Map<String, Map<String, String>> envParamsMap = hashTreeUtil.getEnvParamsDataByHashTree(hashTree, apiTestEnvironmentService);

View File

@ -2,15 +2,29 @@ package io.metersphere.service;
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil; import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.jmeter.ApiLocalRunner; import io.metersphere.api.jmeter.ApiLocalRunner;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.base.domain.ApiExecutionQueueDetail;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.FixedCapacityUtil; import io.metersphere.commons.utils.FixedCapacityUtil;
import io.metersphere.commons.utils.GenerateHashTreeUtil;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
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 jakarta.annotation.Resource;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
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.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
@Service @Service
public class RemakeReportService { public class RemakeReportService {
@ -20,6 +34,10 @@ public class RemakeReportService {
@Resource @Resource
@Lazy @Lazy
private TestResultService testResultService; private TestResultService testResultService;
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
public void queueNext(JmeterRunRequestDTO request, String errorMsg) { public void queueNext(JmeterRunRequestDTO request, String errorMsg) {
try { try {
@ -41,7 +59,7 @@ public class RemakeReportService {
queueService.checkTestPlanCaseTestEnd(dto.getTestId(), dto.getRunMode(), dto.getTestPlanReportId()); queueService.checkTestPlanCaseTestEnd(dto.getTestId(), dto.getRunMode(), dto.getTestPlanReportId());
} catch (Exception e) { } catch (Exception e) {
LoggerUtil.error("回退报告异常", request.getReportId(), e); LoggerUtil.error("回退报告异常", request.getReportId(), e);
}finally { } finally {
ApiLocalRunner.clearCache(request.getReportId()); ApiLocalRunner.clearCache(request.getReportId());
} }
} }
@ -61,4 +79,58 @@ public class RemakeReportService {
updateReport(request, errorMsg); updateReport(request, errorMsg);
queueNext(request, errorMsg); queueNext(request, errorMsg);
} }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateApiReport(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
if (execResult != null) {
if (MapUtils.isNotEmpty(runRequest.getExtendedParameters())) {
runRequest.getExtendedParameters().put(CommonConstants.USER_ID, execResult.getUserId());
} else {
runRequest.setExtendedParameters(new HashMap<>() {{
this.put(CommonConstants.USER_ID, execResult.getUserId());
}});
}
execResult.setStartTime(System.currentTimeMillis());
execResult.setStatus(ApiReportStatus.RUNNING.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ]", execResult.getId());
}
}
/**
* 更新报告状态
*
* @param queue
* @param runRequest
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateScenarioReport(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
if (!GenerateHashTreeUtil.isSetReport(runRequest.getReportType()) &&
StringUtils.equalsAny(runRequest.getRunMode(),
ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(),
ApiRunMode.JENKINS_SCENARIO_PLAN.name(),
ApiRunMode.UI_SCENARIO.name(),
ApiRunMode.UI_SCENARIO_PLAN.name(),
ApiRunMode.UI_JENKINS_SCENARIO_PLAN.name(),
ApiRunMode.UI_SCHEDULE_SCENARIO.name(),
ApiRunMode.UI_SCHEDULE_SCENARIO_PLAN.name())
) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
if (report != null) {
report.setStatus(ApiReportStatus.RUNNING.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
runRequest.setExtendedParameters(new HashMap<>() {{
this.put(CommonConstants.USER_ID, report.getCreateUser());
}});
apiScenarioReportMapper.updateByPrimaryKey(report);
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ]", report.getId());
}
}
}
} }

View File

@ -348,7 +348,7 @@ export default {
this.report = response.data || {}; this.report = response.data || {};
if (response.data) { if (response.data) {
if (response.data.status === 'RUNNING') { if (response.data.status === 'RUNNING') {
setTimeout(this.getReport, 2000); setTimeout(this.getReport, 5000);
} else { } else {
this.content = JSON.parse(response.data.content); this.content = JSON.parse(response.data.content);
if (!this.content) { if (!this.content) {

View File

@ -1171,7 +1171,8 @@ export default {
}, },
margeTransaction(item, console, arr) { margeTransaction(item, console, arr) {
arr.forEach((sub) => { arr.forEach((sub) => {
if (item.data && item.data.id + '_' + item.data.parentIndex === sub.resourceId) { if (item.data && item.data.id + '_' + item.data.parentIndex === sub.resourceId
&& item.data.requestResult.length === 0) {
sub.responseResult.console = console; sub.responseResult.console = console;
item.data.requestResult.push(sub); item.data.requestResult.push(sub);
// //
@ -1179,7 +1180,7 @@ export default {
item.data.testing = false; item.data.testing = false;
item.data.debug = true; item.data.debug = true;
} }
if (sub.subRequestResults && sub.subRequestResults.length > 0) { if (sub.method === 'Request' && sub.subRequestResults && sub.subRequestResults.length > 0) {
this.margeTransaction(item, console, sub.subRequestResults); this.margeTransaction(item, console, sub.subRequestResults);
} }
}); });