refactor(接口测试): 优化超时时间处理

This commit is contained in:
fit2-zhao 2022-01-14 10:17:59 +08:00 committed by fit2-zhao
parent f4be6257e4
commit 39cccc782b
6 changed files with 101 additions and 91 deletions

View File

@ -101,7 +101,7 @@ public class ApiCaseExecuteService {
String reportType = request.getConfig().getReportType();
String poolId = request.getConfig().getResourcePoolId();
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap(), request.getConfig().isOnSampleError());
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig());
// 开始选择执行模式
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
@ -178,7 +178,7 @@ public class ApiCaseExecuteService {
String reportType = request.getConfig().getReportType();
String poolId = request.getConfig().getResourcePoolId();
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig().getEnvMap(), request.getConfig().isOnSampleError());
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig());
// 开始选择执行模式
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
LoggerUtil.debug("开始串行执行");

View File

@ -34,7 +34,7 @@ public class ApiCaseParallelExecuteService {
String reportId = result.getId();
HashTree hashTree = null;
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
hashTree = apiScenarioSerialService.generateHashTree(testId, executionQueue.getRunMode(), config.getEnvMap());
hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap());
}
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));

View File

@ -167,8 +167,7 @@ public class ApiScenarioExecuteService {
String reportType = request.getConfig().getReportType();
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId()
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig().getEnvMap()
, request.getConfig().isOnSampleError());
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig());
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
if (StringUtils.isNotEmpty(serialReportId)) {

View File

@ -104,7 +104,7 @@ public class ApiScenarioSerialService {
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
map = JSON.parseObject(queue.getEvnMap(), Map.class);
}
hashTree = generateHashTree(queue.getTestId(), queue.getType(), map);
hashTree = generateHashTree(queue.getTestId(), map);
}
// 更新环境变量
this.initEnv(hashTree);
@ -152,12 +152,10 @@ public class ApiScenarioSerialService {
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
}
public HashTree generateHashTree(String testId, String type, Map<String, String> envMap) {
ApiTestCaseWithBLOBs caseWithBLOBs = null;
public HashTree generateHashTree(String testId, Map<String, String> envMap) {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
String envId = null;
if (StringUtils.equals(type, ApiRunMode.DEFINITION.name())) {
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
} else {
if (caseWithBLOBs == null) {
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
if (apiCase != null) {
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());

View File

@ -19,6 +19,7 @@ import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.ResultDTO;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections4.CollectionUtils;
@ -57,12 +58,12 @@ public class ApiExecutionQueueService {
@Resource
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, Map<String, String> envMap, boolean failure) {
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
executionQueue.setId(UUID.randomUUID().toString());
executionQueue.setCreateTime(System.currentTimeMillis());
executionQueue.setPoolId(poolId);
executionQueue.setFailure(failure);
executionQueue.setFailure(config.isOnSampleError());
executionQueue.setReportId(reportId);
executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString());
executionQueue.setRunMode(runMode);
@ -76,12 +77,12 @@ public class ApiExecutionQueueService {
if (StringUtils.equalsAnyIgnoreCase(type, ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) {
final int[] sort = {0};
Map<String, ApiDefinitionExecResult> runMap = (Map<String, ApiDefinitionExecResult>) runObj;
if (envMap == null) {
envMap = new LinkedHashMap<>();
if (config.getEnvMap() == null) {
config.setEnvMap(new LinkedHashMap<>());
}
String envStr = JSON.toJSONString(envMap);
String envStr = JSON.toJSONString(config.getEnvMap());
runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(v.getId(), k, type, sort[0], executionQueue.getId(), envStr);
ApiExecutionQueueDetail queue = detail(v.getId(), k, config.getMode(), sort[0], executionQueue.getId(), envStr);
if (sort[0] == 0) {
resQueue.setQueue(queue);
}
@ -93,7 +94,7 @@ public class ApiExecutionQueueService {
Map<String, RunModeDataDTO> runMap = (Map<String, RunModeDataDTO>) runObj;
final int[] sort = {0};
runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), type, sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap()));
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap()));
queue.setSort(sort[0]);
if (sort[0] == 0) {
resQueue.setQueue(queue);
@ -124,10 +125,48 @@ public class ApiExecutionQueueService {
return queue;
}
private boolean failure(DBTestQueue executionQueue, ResultDTO dto) {
LoggerUtil.info("进入失败停止处理:" + executionQueue.getId());
boolean isError = false;
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (report != null && StringUtils.equalsIgnoreCase(report.getStatus(), "Error")) {
isError = true;
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (result != null && StringUtils.equalsIgnoreCase(result.getStatus(), "Error")) {
isError = true;
}
}
if (isError) {
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andQueueIdEqualTo(dto.getQueueId());
if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) {
CommonBeanFactory.getBean(TestPlanReportService.class).finishedTestPlanReport(dto.getTestPlanReportId(), "Stopped");
}
// 更新未执行的报告状态
List<ApiExecutionQueueDetail> details = executionQueueDetailMapper.selectByExample(example);
List<String> reportIds = details.stream().map(ApiExecutionQueueDetail::getReportId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(reportIds)) {
extApiDefinitionExecResultMapper.update(reportIds);
extApiScenarioReportMapper.update(reportIds);
}
// 清除队列
executionQueueDetailMapper.deleteByExample(example);
queueMapper.deleteByPrimaryKey(executionQueue.getId());
return false;
}
return true;
}
public DBTestQueue edit(String id, String testId) {
ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(id);
DBTestQueue queue = new DBTestQueue();
if (executionQueue != null) {
DBTestQueue queue = new DBTestQueue();
BeanUtils.copyBean(queue, executionQueue);
if (executionQueue != null) {
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
@ -152,50 +191,21 @@ public class ApiExecutionQueueService {
queueMapper.deleteByPrimaryKey(id);
}
}
return queue;
}
return null;
return queue;
}
public void queueNext(ResultDTO dto) {
DBTestQueue executionQueue = this.edit(dto.getQueueId(), dto.getTestId());
if (executionQueue != null) {
// 串行失败停止
if (executionQueue.getFailure()) {
LoggerUtil.info("进入失败停止处理:" + executionQueue.getId());
boolean isError = false;
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (report != null && StringUtils.equalsIgnoreCase(report.getStatus(), "Error")) {
isError = true;
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (result != null && StringUtils.equalsIgnoreCase(result.getStatus(), "Error")) {
isError = true;
}
}
if (isError) {
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andQueueIdEqualTo(dto.getQueueId());
if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) {
CommonBeanFactory.getBean(TestPlanReportService.class).finishedTestPlanReport(dto.getTestPlanReportId(), "Stopped");
}
// 更新未执行的报告状态
List<ApiExecutionQueueDetail> details = executionQueueDetailMapper.selectByExample(example);
List<String> reportIds = details.stream().map(ApiExecutionQueueDetail::getReportId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(reportIds)) {
extApiDefinitionExecResultMapper.update(reportIds);
extApiScenarioReportMapper.update(reportIds);
}
// 清除队列
executionQueueDetailMapper.deleteByExample(example);
queueMapper.deleteByPrimaryKey(executionQueue.getId());
boolean isNext = failure(executionQueue, dto);
if (!isNext) {
return;
}
}
LoggerUtil.info("开始处理执行队列:" + executionQueue.getId());
if (executionQueue.getQueue() != null && StringUtils.isNotEmpty(executionQueue.getQueue().getTestId())) {
if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) {
@ -220,61 +230,64 @@ public class ApiExecutionQueueService {
}
}
public void timeOut() {
final int SECOND_MILLIS = 1000;
final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
// 计算二十分钟前的超时报告
final long timeBeforeTimeOutStemp = System.currentTimeMillis() - (20 * MINUTE_MILLIS);
final long twentyMinutesAgo = System.currentTimeMillis() - (20 * MINUTE_MILLIS);
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andCreateTimeLessThan(timeBeforeTimeOutStemp);
example.createCriteria().andCreateTimeLessThan(twentyMinutesAgo);
List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(queueDetails)) {
queueDetails.forEach(item -> {
if (StringUtils.equalsAnyIgnoreCase(item.getType(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null
&& StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name())
&& report.getUpdateTime() < timeBeforeTimeOutStemp) {
//场景报告最后一次更新时间于当前时间相比超过了20分钟也就是20分钟没有步骤执行完成这种情况下做超时处理
report.setStatus(ScenarioStatus.Timeout.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
queueDetails.forEach(item -> {
ApiExecutionQueue queue = queueMapper.selectByPrimaryKey(item.getQueueId());
if (queue != null && StringUtils.equalsAnyIgnoreCase(queue.getRunMode(),
ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(),
ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name())
&& report.getUpdateTime() < twentyMinutesAgo) {
report.setStatus(ScenarioStatus.Timeout.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
ResultDTO dto = new ResultDTO();
dto.setQueueId(item.getQueueId());
dto.setTestId(item.getTestId());
ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(item.getQueueId());
if (executionQueue != null) {
dto.setTestPlanReportId(executionQueue.getReportId());
dto.setReportId(executionQueue.getReportId());
dto.setRunMode(executionQueue.getRunMode());
dto.setRunType(RunModeConstants.SERIAL.toString());
dto.setReportType(executionQueue.getReportType());
queueNext(dto);
}else {
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
}
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name())) {
result.setStatus(ScenarioStatus.Timeout.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
LoggerUtil.info("超时处理报告:" + report.getId());
ResultDTO dto = new ResultDTO();
dto.setQueueId(item.getQueueId());
dto.setTestId(item.getTestId());
ApiExecutionQueue executionQueue = queueMapper.selectByPrimaryKey(item.getQueueId());
if (executionQueue != null && StringUtils.equalsIgnoreCase(item.getType(), RunModeConstants.SERIAL.toString())) {
LoggerUtil.info("超时处理报告:【" + report.getId() + "】进入下一个执行");
dto.setTestPlanReportId(executionQueue.getReportId());
dto.setReportId(executionQueue.getReportId());
dto.setRunMode(executionQueue.getRunMode());
dto.setRunType(item.getType());
dto.setReportType(executionQueue.getReportType());
queueNext(dto);
} else {
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
}
}
});
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
if (result != null && StringUtils.equalsAnyIgnoreCase(result.getStatus(), TestPlanReportStatus.RUNNING.name())) {
result.setStatus(ScenarioStatus.Timeout.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
executionQueueDetailMapper.deleteByPrimaryKey(item.getId());
}
}
});
ApiExecutionQueueExample queueDetailExample = new ApiExecutionQueueExample();
queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(timeBeforeTimeOutStemp);
queueDetailExample.createCriteria().andReportTypeEqualTo(RunModeConstants.SET_REPORT.toString()).andCreateTimeLessThan(twentyMinutesAgo);
List<ApiExecutionQueue> executionQueues = queueMapper.selectByExample(queueDetailExample);
if (CollectionUtils.isNotEmpty(executionQueues)) {
executionQueues.forEach(item -> {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null && StringUtils.equalsAnyIgnoreCase(report.getStatus(), TestPlanReportStatus.RUNNING.name())
&& (report.getUpdateTime() < timeBeforeTimeOutStemp)) {
&& (report.getUpdateTime() < twentyMinutesAgo)) {
report.setStatus(ScenarioStatus.Timeout.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
}

View File

@ -72,7 +72,7 @@ public class ApiJmeterFileService {
}
HashTree hashTree;
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, runMode, envMap);
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, envMap);
} else {
if (scenario == null) {
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);