Merge branch 'main' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
9dca2cbbaa
|
@ -5,7 +5,7 @@ import lombok.Setter;
|
|||
|
||||
@Setter
|
||||
@Getter
|
||||
public class ApiReportEnvConfigUtil {
|
||||
public class ApiReportEnvConfigDTO {
|
||||
|
||||
private String envName;
|
||||
|
|
@ -11,7 +11,10 @@ import io.metersphere.commons.config.KafkaConfig;
|
|||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.ExtendedParameter;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.commons.utils.FixedCapacityUtil;
|
||||
import io.metersphere.commons.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.commons.utils.HashTreeUtil;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.config.JmeterProperties;
|
||||
import io.metersphere.constants.BackendListenerConstants;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
|
@ -21,9 +24,9 @@ import io.metersphere.dto.RunModeConfigDTO;
|
|||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.jmeter.JMeterBase;
|
||||
import io.metersphere.jmeter.LocalRunner;
|
||||
import io.metersphere.service.ApiPoolDebugService;
|
||||
import io.metersphere.service.RemakeReportService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import io.metersphere.service.ApiPoolDebugService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
@ -91,12 +94,13 @@ public class JMeterService {
|
|||
* @param testId
|
||||
* @param testPlan
|
||||
*/
|
||||
private void addDebugListener(String testId, HashTree testPlan) {
|
||||
private void addDebugListener(String testId, HashTree testPlan, String runMode) {
|
||||
MsDebugListener resultCollector = new MsDebugListener();
|
||||
resultCollector.setName(testId);
|
||||
resultCollector.setProperty(TestElement.TEST_CLASS, MsDebugListener.class.getName());
|
||||
resultCollector.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ViewResultsFullVisualizer"));
|
||||
resultCollector.setEnabled(true);
|
||||
resultCollector.setRunMode(runMode);
|
||||
|
||||
// 添加DEBUG标示
|
||||
HashTree test = ArrayUtils.isNotEmpty(testPlan.getArray()) ? testPlan.getTree(testPlan.getArray()[0]) : null;
|
||||
|
@ -127,12 +131,12 @@ public class JMeterService {
|
|||
&& request.getExtendedParameters().containsKey(ExtendedParameter.SYNC_STATUS)
|
||||
&& (Boolean) request.getExtendedParameters().get(ExtendedParameter.SYNC_STATUS)) {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加Debug Listener");
|
||||
addDebugListener(request.getReportId(), request.getHashTree());
|
||||
addDebugListener(request.getReportId(), request.getHashTree(), request.getRunMode());
|
||||
}
|
||||
|
||||
if (request.isDebug()) {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加Debug Listener");
|
||||
addDebugListener(request.getReportId(), request.getHashTree());
|
||||
addDebugListener(request.getReportId(), request.getHashTree(), request.getRunMode());
|
||||
} else {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
|
||||
JMeterBase.addBackendListener(request, request.getHashTree(), MsApiBackendListener.class.getCanonicalName());
|
||||
|
|
|
@ -54,6 +54,8 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
|
||||
public static final String TEST_END = "MS_TEST_END";
|
||||
|
||||
private String runMode;
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
MsDebugListener clone = (MsDebugListener) super.clone();
|
||||
|
@ -64,6 +66,10 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
return getPropertyAsBoolean(ERROR_LOGGING);
|
||||
}
|
||||
|
||||
public void setRunMode(String runMode) {
|
||||
this.runMode = runMode;
|
||||
}
|
||||
|
||||
public final void setSuccessOnlyLogging(boolean value) {
|
||||
if (value) {
|
||||
setProperty(new BooleanProperty(SUCCESS_ONLY_LOGGING, true));
|
||||
|
@ -151,6 +157,7 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
dto.setExecEnd(false);
|
||||
dto.setReportId("send." + this.getName());
|
||||
dto.setToReport(this.getName());
|
||||
dto.setRunMode(runMode);
|
||||
|
||||
String console = FixedCapacityUtil.getJmeterLogger(this.getName(), false);
|
||||
ApiDefinitionEnvService apiDefinitionEnvService = CommonBeanFactory.getBean(ApiDefinitionEnvService.class);
|
||||
|
|
|
@ -11,4 +11,7 @@ public class CommonConstants {
|
|||
public static final String USER_ID = "userId";
|
||||
public static final String METHODS_KEY = "methods";
|
||||
public static final String CASE = "CASE";
|
||||
public static final String USER = "user";
|
||||
public static final String USER_NAME = "userName";
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.service.definition;
|
||||
|
||||
import io.metersphere.api.dto.ApiReportEnvConfigUtil;
|
||||
import io.metersphere.api.dto.ApiReportEnvConfigDTO;
|
||||
import io.metersphere.api.dto.MsgDTO;
|
||||
import io.metersphere.api.dto.RequestResultExpandDTO;
|
||||
import io.metersphere.base.domain.ApiDefinitionEnv;
|
||||
|
@ -80,7 +80,7 @@ public class ApiDefinitionEnvService {
|
|||
if (StringUtils.isNotBlank(baseResult.getThreadName())) {
|
||||
ApiDefinitionExecResultWithBLOBs result = apiDefinitionExecResultMapper.selectByPrimaryKey(baseResult.getThreadName());
|
||||
if (result != null && StringUtils.isNotEmpty(result.getEnvConfig())) {
|
||||
ApiReportEnvConfigUtil envConfig = apiDefinitionService.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
ApiReportEnvConfigDTO envConfig = apiDefinitionService.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
if (envConfig != null) {
|
||||
expandDTO.setEnvName(envConfig.getEnvName());
|
||||
expandDTO.setPoolName(envConfig.getResourcePoolName());
|
||||
|
@ -93,7 +93,7 @@ public class ApiDefinitionEnvService {
|
|||
if (StringUtils.isNotBlank(dto.getToReport())) {
|
||||
ApiDefinitionExecResultWithBLOBs result = apiDefinitionExecResultMapper.selectByPrimaryKey(dto.getToReport());
|
||||
if (result != null && StringUtils.isNotEmpty(result.getEnvConfig())) {
|
||||
ApiReportEnvConfigUtil envConfig = apiDefinitionService.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
ApiReportEnvConfigDTO envConfig = apiDefinitionService.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
if (envConfig != null) {
|
||||
Map map = JSON.parseObject(dto.getContent().substring(7), Map.class);
|
||||
map.put("envName", envConfig.getEnvName());
|
||||
|
|
|
@ -95,18 +95,7 @@ public class ApiDefinitionExecResultService {
|
|||
if (result != null) {
|
||||
result.setResourceId(dto.getTestId());
|
||||
apiExecutionInfoService.insertExecutionInfo(result);
|
||||
User user = null;
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters())) {
|
||||
if (dto.getExtendedParameters().containsKey(CommonConstants.USER_ID) && dto.getExtendedParameters().containsKey("userName")) {
|
||||
user = new User() {{
|
||||
this.setId(dto.getExtendedParameters().get(CommonConstants.USER_ID).toString());
|
||||
this.setName(dto.getExtendedParameters().get("userName").toString());
|
||||
}};
|
||||
result.setUserId(user.getId());
|
||||
} else if (dto.getExtendedParameters().containsKey(CommonConstants.USER_ID)) {
|
||||
result.setUserId(dto.getExtendedParameters().get(CommonConstants.USER_ID).toString());
|
||||
}
|
||||
}
|
||||
User user = getUser(dto, result);
|
||||
//如果是测试计划用例,更新接口用例的上次执行结果
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(dto.getTestId());
|
||||
if (testPlanApiCase != null) {
|
||||
|
@ -147,10 +136,12 @@ public class ApiDefinitionExecResultService {
|
|||
// 批量更新关联关系状态
|
||||
batchEditStatus(dto.getRunMode(), result.getStatus(), result.getId(), dto.getTestId(), planApiCaseMapper, batchApiTestCaseMapper);
|
||||
}
|
||||
if (result != null && !StringUtils.startsWithAny(dto.getRunMode(), "SCHEDULE")) {
|
||||
User user = null;
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters()) && dto.getExtendedParameters().containsKey("user") && dto.getExtendedParameters().get("user") instanceof User) {
|
||||
user = (User) dto.getExtendedParameters().get("user");
|
||||
if (result != null && !StringUtils.startsWithAny(dto.getRunMode(), NoticeConstants.Mode.SCHEDULE)) {
|
||||
User user = getUser(dto, result);
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters())
|
||||
&& dto.getExtendedParameters().containsKey(CommonConstants.USER)
|
||||
&& dto.getExtendedParameters().get(CommonConstants.USER) instanceof User) {
|
||||
user = (User) dto.getExtendedParameters().get(CommonConstants.USER);
|
||||
}
|
||||
// 发送通知
|
||||
result.setResourceId(dto.getTestId());
|
||||
|
@ -166,6 +157,23 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
}
|
||||
|
||||
private User getUser(ResultDTO dto, ApiDefinitionExecResult result) {
|
||||
User user = null;
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters())) {
|
||||
if (dto.getExtendedParameters().containsKey(CommonConstants.USER_ID)
|
||||
&& dto.getExtendedParameters().containsKey(CommonConstants.USER_NAME)) {
|
||||
user = new User() {{
|
||||
this.setId(dto.getExtendedParameters().get(CommonConstants.USER_ID).toString());
|
||||
this.setName(dto.getExtendedParameters().get(CommonConstants.USER_NAME).toString());
|
||||
}};
|
||||
result.setUserId(user.getId());
|
||||
} else if (dto.getExtendedParameters().containsKey(CommonConstants.USER_ID)) {
|
||||
result.setUserId(dto.getExtendedParameters().get(CommonConstants.USER_ID).toString());
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private void sendNotice(ApiDefinitionExecResult result, User user) {
|
||||
try {
|
||||
String resourceId = result.getResourceId();
|
||||
|
|
|
@ -960,7 +960,7 @@ public class ApiDefinitionService {
|
|||
if (StringUtils.isNotBlank(contentStr)) {
|
||||
JSONObject content = JSONUtil.parseObject(contentStr);
|
||||
if (StringUtils.isNotEmpty(result.getEnvConfig())) {
|
||||
ApiReportEnvConfigUtil envNameByEnvConfig = this.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
ApiReportEnvConfigDTO envNameByEnvConfig = this.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
|
||||
if (envNameByEnvConfig != null) {
|
||||
content.put("envName", envNameByEnvConfig.getEnvName());
|
||||
content.put("poolName", envNameByEnvConfig.getResourcePoolName());
|
||||
|
@ -975,8 +975,8 @@ public class ApiDefinitionService {
|
|||
return reportResult;
|
||||
}
|
||||
|
||||
public ApiReportEnvConfigUtil getEnvNameByEnvConfig(String projectId, String envConfig) {
|
||||
ApiReportEnvConfigUtil apiReportEnvConfig = new ApiReportEnvConfigUtil();
|
||||
public ApiReportEnvConfigDTO getEnvNameByEnvConfig(String projectId, String envConfig) {
|
||||
ApiReportEnvConfigDTO apiReportEnvConfig = new ApiReportEnvConfigDTO();
|
||||
RunModeConfigDTO runModeConfigDTO = null;
|
||||
try {
|
||||
runModeConfigDTO = JSON.parseObject(envConfig, RunModeConfigDTO.class);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package io.metersphere.websocket;
|
||||
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import io.metersphere.api.dto.MsgDTO;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.WebSocketUtil;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.websocket.*;
|
||||
|
@ -60,4 +61,12 @@ public class IndexWebSocket {
|
|||
public void onError(Session session, Throwable throwable) throws IOException {
|
||||
session.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 每一分钟群发一次心跳检查
|
||||
*/
|
||||
@Scheduled(cron = "0 0/1 * * * ?")
|
||||
public void heartbeatCheck() {
|
||||
WebSocketUtil.sendMessageAll("heartbeat check");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card class="api-component">
|
||||
<div class="header" @click="active">
|
||||
<div :class="[response && response.envName && response.poolName ? 'env-header' : 'header']" @click="active">
|
||||
<i class="icon el-icon-arrow-right" :class="{ 'is-active': isActive }" />
|
||||
<ms-request-metric :response="response" />
|
||||
</div>
|
||||
|
@ -94,6 +94,11 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.header {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.env-header {
|
||||
height: 60px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,28 +19,30 @@
|
|||
|
||||
<el-container>
|
||||
<el-main>
|
||||
<div v-for="item in apiCaseList" :key="item.id ? item.id : item.uuid">
|
||||
<api-case-item
|
||||
:loading="(singleLoading && singleRunId === item.id) || batchLoadingIds.indexOf(item.id) > -1"
|
||||
@refresh="refresh"
|
||||
@refreshCaseList="refreshCaseList"
|
||||
@singleRun="singleRun"
|
||||
@stop="stop"
|
||||
@refreshModule="refreshModule"
|
||||
@copyCase="copyCase"
|
||||
@showExecResult="showExecResult"
|
||||
@showHistory="showHistory"
|
||||
@reLoadCase="reLoadCase"
|
||||
:environment="environment"
|
||||
@setSelectedCaseId="setSelectedCaseId"
|
||||
:is-case-edit="isCaseEdit"
|
||||
:api="api"
|
||||
:currentApi="currentApi"
|
||||
:loaded="loaded"
|
||||
:maintainerOptions="maintainerOptions"
|
||||
:api-case="item"
|
||||
ref="apiCaseItem" />
|
||||
</div>
|
||||
<fieldset :disabled="loaded">
|
||||
<div v-for="item in apiCaseList" :key="item.id ? item.id : item.uuid">
|
||||
<api-case-item
|
||||
:loading="(singleLoading && singleRunId === item.id) || batchLoadingIds.indexOf(item.id) > -1"
|
||||
@refresh="refresh"
|
||||
@refreshCaseList="refreshCaseList"
|
||||
@singleRun="singleRun"
|
||||
@stop="stop"
|
||||
@refreshModule="refreshModule"
|
||||
@copyCase="copyCase"
|
||||
@showExecResult="showExecResult"
|
||||
@showHistory="showHistory"
|
||||
@reLoadCase="reLoadCase"
|
||||
:environment="environment"
|
||||
@setSelectedCaseId="setSelectedCaseId"
|
||||
:is-case-edit="isCaseEdit"
|
||||
:api="api"
|
||||
:currentApi="currentApi"
|
||||
:loaded="loaded"
|
||||
:maintainerOptions="maintainerOptions"
|
||||
:api-case="item"
|
||||
ref="apiCaseItem" />
|
||||
</div>
|
||||
</fieldset>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</ms-drawer>
|
||||
|
@ -233,6 +235,9 @@ export default {
|
|||
this.selectCaseId = caseId;
|
||||
},
|
||||
saveCase(hideAlert) {
|
||||
if (this.loaded) {
|
||||
this.close();
|
||||
}
|
||||
let index = 0;
|
||||
if (this.selectCaseId && this.selectCaseId !== '') {
|
||||
for (let i = 0; i < this.apiCaseList.length; i++) {
|
||||
|
@ -684,4 +689,15 @@ export default {
|
|||
.ms-drawer-case-header :deep(.ms-drawer-header) {
|
||||
margin-left: 0px;
|
||||
}
|
||||
fieldset {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
min-width: 100%;
|
||||
min-inline-size: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.ms-fieldset .ms-step-tree-cell::-webkit-scrollbar {
|
||||
width: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -114,7 +114,6 @@
|
|||
|
||||
<script>
|
||||
import { citedApiScenarioCount, getDefinitionVersions, getMockEnvironment, updateDefinition } from '@/api/definition';
|
||||
import { getLastResultDetail } from '@/api/definition-report';
|
||||
import { relationGet, updateRuleRelation, versionEnableByProjectId } from '@/api/xpack';
|
||||
import MsApiRequestForm from '../request/http/ApiHttpRequestForm';
|
||||
import { hasLicense, hasPermission } from 'metersphere-frontend/src/utils/permission';
|
||||
|
|
|
@ -301,9 +301,9 @@ export default {
|
|||
let result = {};
|
||||
result.actualResult = this.testCase.steptResults[i].actualResult;
|
||||
result.executeResult = this.testCase.steptResults[i].executeResult;
|
||||
if (result.actualResult && result.actualResult.length > 300) {
|
||||
if (result.actualResult && result.actualResult.length > 500) {
|
||||
this.$warning(this.$t('test_track.plan_view.actual_result')
|
||||
+ this.$t('test_track.length_less_than') + '300');
|
||||
+ this.$t('test_track.length_less_than') + '500');
|
||||
return;
|
||||
}
|
||||
if (result.executeResult === 'Failure' && this.testCase.status === 'Pass') {
|
||||
|
|
Loading…
Reference in New Issue