refactor(接口测试): 调试结果优化
Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
parent
78bdc78ef6
commit
5b220beb65
|
@ -56,6 +56,8 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
|
||||
private String runMode;
|
||||
|
||||
private ApiDefinitionEnvService apiDefinitionEnvService;
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
MsDebugListener clone = (MsDebugListener) super.clone();
|
||||
|
@ -119,6 +121,9 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
@Override
|
||||
public void testStarted(String host) {
|
||||
LogUtil.debug("TestStarted " + this.getName());
|
||||
if (apiDefinitionEnvService == null) {
|
||||
apiDefinitionEnvService = CommonBeanFactory.getBean(ApiDefinitionEnvService.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,33 +168,30 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
dto.setRunMode(runMode);
|
||||
|
||||
String console = FixedCapacityUtil.getJmeterLogger(this.getName(), false);
|
||||
ApiDefinitionEnvService apiDefinitionEnvService = CommonBeanFactory.getBean(ApiDefinitionEnvService.class);
|
||||
if (StringUtils.isNotEmpty(requestResult.getName()) && requestResult.getName().startsWith("Transaction=")) {
|
||||
requestResult.getSubRequestResults().forEach(transactionResult -> {
|
||||
transactionResult.getResponseResult().setConsole(console);
|
||||
//对响应内容进行进一步解析和处理。
|
||||
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(transactionResult);
|
||||
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) {
|
||||
apiDefinitionEnvService.setEnvAndPoolName(transactionResult, expandDTO);
|
||||
}
|
||||
dto.setContent("result_" + JSON.toJSONString(expandDTO));
|
||||
WebSocketUtil.sendMessageSingle(dto);
|
||||
this.sendResult(transactionResult, console, dto);
|
||||
});
|
||||
} else {
|
||||
requestResult.getResponseResult().setConsole(console);
|
||||
//对响应内容进行进一步解析和处理。
|
||||
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(requestResult);
|
||||
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) {
|
||||
apiDefinitionEnvService.setEnvAndPoolName(requestResult, expandDTO);
|
||||
}
|
||||
dto.setContent("result_" + JSON.toJSONString(expandDTO));
|
||||
WebSocketUtil.sendMessageSingle(dto);
|
||||
this.sendResult(requestResult, console, dto);
|
||||
}
|
||||
LoggerUtil.debug("send. " + this.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendResult(RequestResult requestResult, String console, MsgDTO dto) {
|
||||
requestResult.getResponseResult().setConsole(console);
|
||||
//对响应内容进行进一步解析和处理。
|
||||
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(requestResult);
|
||||
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) {
|
||||
apiDefinitionEnvService.setEnvAndPoolName(requestResult, expandDTO);
|
||||
}
|
||||
dto.setContent("result_" + JSON.toJSONString(expandDTO));
|
||||
WebSocketUtil.sendMessageSingle(dto);
|
||||
|
||||
}
|
||||
|
||||
private void setVars(SampleResult result) {
|
||||
if (StringUtils.isNotEmpty(result.getSampleLabel()) && result.getSampleLabel().startsWith("Transaction=")) {
|
||||
for (int i = 0; i < result.getSubResults().length; i++) {
|
||||
|
|
|
@ -101,23 +101,4 @@ public class MsKafkaListener {
|
|||
LoggerUtil.error("KAFKA消费失败:", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void outKafkaPoolLogger() {
|
||||
StringBuffer buffer = new StringBuffer()
|
||||
.append(StringUtils.LF)
|
||||
.append("KAFKA Consume 线程池详情:")
|
||||
.append(StringUtils.LF)
|
||||
.append(" KAFKA Consume 核心线程数:" + threadPool.getCorePoolSize())
|
||||
.append(StringUtils.LF)
|
||||
.append(" KAFKA Consume 活动线程数:" + threadPool.getActiveCount())
|
||||
.append(StringUtils.LF)
|
||||
.append(" KAFKA Consume 最大线程数:" + threadPool.getMaximumPoolSize())
|
||||
.append(StringUtils.LF)
|
||||
.append(" KAFKA Consume 最大队列数:" + (threadPool.getQueue().size() + threadPool.getQueue().remainingCapacity()))
|
||||
.append(StringUtils.LF)
|
||||
.append(" KAFKA Consume 当前排队线程数:" + (threadPool.getQueue().size()))
|
||||
.append(StringUtils.LF);
|
||||
LoggerUtil.info(buffer.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,17 +6,11 @@ import io.metersphere.base.domain.TestResourcePool;
|
|||
import io.metersphere.base.domain.TestResourcePoolExample;
|
||||
import io.metersphere.base.mapper.TestResourceMapper;
|
||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.dto.JvmInfoDTO;
|
||||
import io.metersphere.dto.NodeDTO;
|
||||
import io.metersphere.dto.TestResourceDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -28,18 +22,6 @@ public class ResourcePoolCalculation {
|
|||
TestResourcePoolMapper testResourcePoolMapper;
|
||||
@Resource
|
||||
TestResourceMapper testResourceMapper;
|
||||
@Resource
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
private static final String BASE_URL = "http://%s:%d";
|
||||
|
||||
private JvmInfoDTO getNodeJvmInfo(String uri) {
|
||||
try {
|
||||
return restTemplate.getForObject(uri, JvmInfoDTO.class);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<TestResource> getResourcePools(String resourcePoolId) {
|
||||
TestResourcePoolExample example = new TestResourcePoolExample();
|
||||
|
@ -55,26 +37,4 @@ public class ResourcePoolCalculation {
|
|||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<JvmInfoDTO> getPools(String resourcePoolId) {
|
||||
// 按照NODE节点的可用内存空间大小排序
|
||||
List<JvmInfoDTO> availableNodes = new ArrayList<>();
|
||||
List<TestResource> testResources = getResourcePools(resourcePoolId);
|
||||
for (TestResource testResource : testResources) {
|
||||
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-jvm-info", nodeIp, port);
|
||||
JvmInfoDTO nodeJvm = this.getNodeJvmInfo(uri);
|
||||
if (nodeJvm == null) {
|
||||
continue;
|
||||
}
|
||||
TestResourceDTO dto = new TestResourceDTO();
|
||||
BeanUtils.copyBean(dto, testResource);
|
||||
nodeJvm.setTestResource(dto);
|
||||
availableNodes.add(nodeJvm);
|
||||
}
|
||||
return availableNodes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import io.metersphere.dto.RequestResult;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ScenarioResult {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private long responseTime;
|
||||
|
||||
private int error = 0;
|
||||
|
||||
private int success = 0;
|
||||
|
||||
private int totalAssertions = 0;
|
||||
|
||||
private int passAssertions = 0;
|
||||
|
||||
private List<RequestResult> requestResults = new ArrayList<>();
|
||||
|
||||
public void addResponseTime(long time) {
|
||||
this.responseTime += time;
|
||||
}
|
||||
|
||||
public void addError(int count) {
|
||||
this.error += count;
|
||||
}
|
||||
|
||||
public void addSuccess() {
|
||||
this.success++;
|
||||
}
|
||||
|
||||
public void addTotalAssertions(int count) {
|
||||
this.totalAssertions += count;
|
||||
}
|
||||
|
||||
public void addPassAssertions(int count) {
|
||||
this.passAssertions += count;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return error + success;
|
||||
}
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import io.metersphere.commons.constants.DelimiterConstants;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.dto.RequestResult;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class TestResult {
|
||||
|
||||
private String testId;
|
||||
|
||||
private String setReportId;
|
||||
|
||||
private int scenarioTotal;
|
||||
|
||||
private int scenarioSuccess;
|
||||
|
||||
private int scenarioError;
|
||||
|
||||
private String userId;
|
||||
|
||||
private boolean isDebug;
|
||||
|
||||
private boolean end;
|
||||
|
||||
private String runMode;
|
||||
|
||||
private int success = 0;
|
||||
|
||||
private int error = 0;
|
||||
|
||||
private int total = 0;
|
||||
|
||||
private int totalAssertions = 0;
|
||||
|
||||
private int passAssertions = 0;
|
||||
|
||||
private String console;
|
||||
|
||||
private String runningDebugSampler;
|
||||
|
||||
private List<ScenarioResult> scenarios = new ArrayList<>();
|
||||
|
||||
private Map<String, Boolean> margeScenarioMap = new HashMap<>();
|
||||
|
||||
private Map<String, Boolean> scenarioStepMap = new HashMap<>();
|
||||
|
||||
private int scenarioStepSuccess = 0;
|
||||
private int scenarioStepError = 0;
|
||||
private int scenarioStepTotal = 0;
|
||||
|
||||
public void addError(int count) {
|
||||
this.error += count;
|
||||
}
|
||||
|
||||
public void addSuccess() {
|
||||
this.success++;
|
||||
}
|
||||
|
||||
public void addTotalAssertions(int count) {
|
||||
this.totalAssertions += count;
|
||||
}
|
||||
|
||||
public void addPassAssertions(int count) {
|
||||
this.passAssertions += count;
|
||||
}
|
||||
|
||||
private static final String SEPARATOR = DelimiterConstants.SEPARATOR.toString();
|
||||
|
||||
private void setStatus(List<String> id_names, boolean status) {
|
||||
if (CollectionUtils.isNotEmpty(id_names)) {
|
||||
id_names.forEach(item -> {
|
||||
if (!margeScenarioMap.containsKey(item) || status) {
|
||||
margeScenarioMap.put(item, status);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setStatus(String id_names, boolean status) {
|
||||
if (!margeScenarioMap.containsKey(id_names) || status) {
|
||||
margeScenarioMap.put(id_names, status);
|
||||
}
|
||||
}
|
||||
|
||||
private void setStepStatus(String step_names, boolean status) {
|
||||
if (!scenarioStepMap.containsKey(step_names) || status) {
|
||||
scenarioStepMap.put(step_names, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addScenario(ScenarioResult result) {
|
||||
/**
|
||||
* 1.10.2统计逻辑修改:
|
||||
* 不统计所有的请求,改为统计场景和场景步骤
|
||||
* 场景里的第一层视为步骤,不考虑深层情况
|
||||
*/
|
||||
if (result != null && CollectionUtils.isNotEmpty(result.getRequestResults())) {
|
||||
|
||||
//如果有全局前后置脚本,会出现前后置的测试步骤,影响统计。此处略过不处理。
|
||||
// 同时,jmeter会将前后置脚本步骤作为一个请求来计算。当检测到有前后置脚本步骤执行时,请求数也要做处理
|
||||
List<RequestResult> formattedResult = new ArrayList<>();
|
||||
|
||||
int successStep = 0;
|
||||
int errorStep = 0;
|
||||
for (RequestResult item : result.getRequestResults()) {
|
||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||
formattedResult.add(item);
|
||||
} else {
|
||||
if (StringUtils.equalsAnyIgnoreCase(item.getName(), "PRE_PROCESSOR_ENV_false", "POST_PROCESSOR_ENV_false")) {
|
||||
if (item.isSuccess()) {
|
||||
successStep++;
|
||||
} else {
|
||||
errorStep++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setSuccess(result.getSuccess() - successStep);
|
||||
result.setError(result.getError() - errorStep);
|
||||
this.success = this.success - successStep;
|
||||
this.error = this.error - errorStep;
|
||||
this.total = this.total - successStep - errorStep;
|
||||
|
||||
result.setRequestResults(formattedResult);
|
||||
|
||||
result.getRequestResults().forEach(item -> {
|
||||
String itemAndScenarioName = StringUtils.EMPTY;
|
||||
if (StringUtils.isNotEmpty(item.getScenario())) {
|
||||
//第1个:当前场景, 第all_id_names个:最后一层场景
|
||||
List<String> all_id_names = JSON.parseObject(item.getScenario(), List.class);
|
||||
if (all_id_names.size() > 1) {
|
||||
StringBuffer scenarioNames = new StringBuffer();
|
||||
//因为要进行步骤统计,第一层级下的场景算作步骤,所以统计视角只按照第一级别场景来计算
|
||||
scenarioNames.append(all_id_names.get(all_id_names.size() - 1) + all_id_names.get(all_id_names.size() - 2));
|
||||
this.setStatus(scenarioNames.toString(), item.getError() > 0);
|
||||
itemAndScenarioName = scenarioNames.toString();
|
||||
} else {
|
||||
//不存在多场景时需要补上步骤名字做唯一判断 添加UUID进行处理
|
||||
itemAndScenarioName = item.getName() + ":" + JSON.toJSONString(all_id_names.get(0)) + UUID.randomUUID().toString();
|
||||
this.setStatus(all_id_names, item.getError() > 0);
|
||||
}
|
||||
|
||||
}
|
||||
if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) {
|
||||
String array[] = item.getName().split(SEPARATOR);
|
||||
item.setName(array[1] + array[0]);
|
||||
// item.getSubRequestResults().forEach(subItem -> {
|
||||
// subItem.setName(array[0]);
|
||||
// });
|
||||
} else {
|
||||
this.genScenarioInSubRequestResult(item);
|
||||
}
|
||||
this.setStepStatus(itemAndScenarioName, item.getError() > 0);
|
||||
});
|
||||
scenarios.add(result);
|
||||
}
|
||||
/**
|
||||
* 1.10.2 场景成功/失败统计,不再按照请求为纬度,按照场景为纬度,
|
||||
*/
|
||||
for (String key : scenarioStepMap.keySet()) {
|
||||
if (scenarioStepMap.get(key)) {
|
||||
this.scenarioStepError++;
|
||||
} else {
|
||||
this.scenarioStepSuccess++;
|
||||
}
|
||||
}
|
||||
boolean hasError = false;
|
||||
for (String key : margeScenarioMap.keySet()) {
|
||||
if (margeScenarioMap.get(key)) {
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!margeScenarioMap.isEmpty()) {
|
||||
if (hasError) {
|
||||
this.scenarioError++;
|
||||
} else {
|
||||
this.scenarioSuccess++;
|
||||
}
|
||||
this.scenarioTotal++;
|
||||
}
|
||||
|
||||
|
||||
this.setScenarioStepTotal(this.scenarioStepMap.size());
|
||||
|
||||
}
|
||||
|
||||
//一般多层的事务控制器会出现这种情况
|
||||
private String genScenarioInSubRequestResult(RequestResult item) {
|
||||
|
||||
if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) {
|
||||
String array[] = item.getName().split(SEPARATOR);
|
||||
item.setName(array[0]);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(item.getScenario())) {
|
||||
List<String> id_names = JSON.parseObject(item.getScenario(), List.class);
|
||||
this.setStatus(id_names, item.getError() > 0);
|
||||
return item.getScenario();
|
||||
} else {
|
||||
if (CollectionUtils.isNotEmpty(item.getSubRequestResults())) {
|
||||
for (RequestResult requestResult : item.getSubRequestResults()) {
|
||||
this.genScenarioInSubRequestResult(requestResult);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue