fix (接口自动化): 优化场景串行执行,避免频繁和数据库交互;增加get请求可加请求体

--bug=1006978 --user=赵勇 【github#6559】http请求,get中带有body的请求执行后,后台服务收到的请求里没有请求体 https://www.tapd.cn/55049933/s/1052908
This commit is contained in:
fit2-zhao 2021-09-28 18:14:59 +08:00 committed by fit2-zhao
parent 74c4c55672
commit 3e1936bc69
5 changed files with 44 additions and 30 deletions

View File

@ -1,7 +1,6 @@
package io.metersphere.api.dto.definition.request.sampler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
@ -225,16 +224,14 @@ public class MsHTTPSamplerProxy extends MsTestElement {
setSamplerPath(config, httpConfig, sampler);
// 请求体
if (!StringUtils.equals(this.getMethod(), "GET")) {
if (this.body != null) {
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
if (StringUtils.isNotEmpty(this.body.getType()) && "Form Data".equals(this.body.getType())) {
sampler.setDoMultipart(true);
}
if (CollectionUtils.isNotEmpty(bodyParams)) {
sampler.setArguments(httpArguments(bodyParams));
}
// 请求体处理
if (this.body != null) {
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
if (StringUtils.isNotEmpty(this.body.getType()) && "Form Data".equals(this.body.getType())) {
sampler.setDoMultipart(true);
}
if (CollectionUtils.isNotEmpty(bodyParams)) {
sampler.setArguments(httpArguments(bodyParams));
}
}

View File

@ -56,5 +56,8 @@ public class APIBackendListenerHandler {
if (!MessageCache.reportCache.containsKey(testId) && resultService.getProcessCache().containsKey(testId)) {
resultService.getProcessCache().remove(testId);
}
if(StringUtils.isNotEmpty(testId)) {
MessageCache.executionQueue.remove(testId);
}
}
}

View File

@ -20,4 +20,7 @@ public class MessageCache {
public static ConcurrentHashMap<String, ApiDefinitionExecResult> batchTestCases = new ConcurrentHashMap<>();
// 串行执行队列 KEY=报告ID VALUE=开始时间
public static Map<String, Long> executionQueue = new HashMap<>();
}

View File

@ -51,7 +51,9 @@ import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.FileOperationRequest;
import io.metersphere.track.service.TestPlanScenarioCaseService;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.comparators.FixedOrderComparator;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
@ -997,11 +999,19 @@ public class ApiAutomationService {
// 生成集成报告
String serialReportId = null;
StringBuilder idStr = new StringBuilder();
ids.forEach(item -> {
idStr.append("\"").append(item).append("\"").append(",");
});
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectByIds(idStr.toString().substring(0, idStr.toString().length() - 1), "\"" + StringUtils.join(ids, ",") + "\"");
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(ids);
List<ApiScenarioWithBLOBs> apiScenarios = apiScenarioMapper.selectByExampleWithBLOBs(example);
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
if (request.getCondition() == null || !request.getCondition().isSelectAll()) {
// 按照id指定顺序排序
FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(ids);
fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
BeanComparator beanComparator = new BeanComparator("id", fixedOrderComparator);
Collections.sort(apiScenarios, beanComparator);
}
}
// 只有一个场景且没有测试步骤则提示
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
MSException.throwException((apiScenarios.get(0).getName() + "" + Translator.get("automation_exec_info")));
@ -1162,6 +1172,7 @@ public class ApiAutomationService {
MessageCache.terminationOrderDeque.remove(key);
break;
}
MessageCache.executionQueue.put(key, System.currentTimeMillis());
reportIds.add(key);
APIScenarioReportResult report = executeQueue.get(key).getReport();
if (StringUtils.isNotEmpty(serialReportId)) {
@ -1193,6 +1204,7 @@ public class ApiAutomationService {
executeEnvParams = hashTreeUtil.mergeParamDataMap(executeEnvParams, envParamsMap);
} catch (Exception e) {
reportIds.remove(key);
MessageCache.executionQueue.remove(key);
LogUtil.error("执行终止:" + e.getMessage());
break;
}

View File

@ -34,7 +34,7 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
@Override
public T call() {
try {
if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
return null;
}
@ -43,25 +43,24 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
} else {
jMeterService.runLocal(runModeDataDTO.getReport().getId(), runModeDataDTO.getHashTree(), TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode());
}
// 轮询查看报告状态最多200次防止死循环
int index = 1;
while (index < 200) {
Thread.sleep(3000);
index++;
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
if (report != null && !report.getStatus().equals(APITestStatus.Running.name())) {
while (MessageCache.executionQueue.containsKey(runModeDataDTO.getReport().getId())) {
long currentSecond = (System.currentTimeMillis() - MessageCache.executionQueue.get(runModeDataDTO.getReport().getId())) / 1000 / 60;
// 设置五分钟超时
if (currentSecond > 5) {
// 执行失败了恢复报告状态
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
if (report != null) {
report.setStatus(APITestStatus.Error.name());
apiScenarioReportMapper.updateByPrimaryKey(report);
}
break;
}
if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
break;
}
}
// 执行失败了恢复报告状态
if (index == 200 && report != null && report.getStatus().equals(APITestStatus.Running.name())) {
report.setStatus(APITestStatus.Error.name());
apiScenarioReportMapper.updateByPrimaryKey(report);
}
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
return (T) report;
} catch (Exception ex) {
LogUtil.error(ex);