refactor(测试跟踪): 同一个测试计划禁止重复执行
【【测试计划】执行中的计划禁止再次执行,防止重复执行堆积任务过多】https://www.tapd.cn/55049933/prong/tasks/view/1155049933001012434 Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
parent
e229eb3ae4
commit
ba167cee86
|
@ -1,8 +1,5 @@
|
|||
package io.metersphere.api.exec.queue;
|
||||
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.JMeterThreadUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
|
||||
|
@ -19,10 +16,6 @@ public class ExecTask implements Runnable {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
CommonBeanFactory.getBean(JMeterService.class).addQueue(request);
|
||||
Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
|
||||
if (res == null && !JMeterThreadUtils.isRunning(request.getReportId(), request.getTestId())) {
|
||||
LoggerUtil.info("任务执行超时", request.getReportId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,15 @@ import io.metersphere.api.jmeter.utils.ServerConfig;
|
|||
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
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.ApiFileUtil;
|
||||
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;
|
||||
import io.metersphere.dto.*;
|
||||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.jmeter.JMeterBase;
|
||||
import io.metersphere.service.ApiPoolDebugService;
|
||||
import io.metersphere.service.PluginService;
|
||||
import io.metersphere.service.RedisTemplateService;
|
||||
|
@ -29,13 +28,8 @@ import jakarta.annotation.PostConstruct;
|
|||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jmeter.threads.ThreadGroup;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -88,65 +82,6 @@ public class JMeterService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加调试监听
|
||||
*/
|
||||
private void addDebugListener(JmeterRunRequestDTO request) {
|
||||
MsDebugListener resultCollector = new MsDebugListener();
|
||||
resultCollector.setName(request.getReportId());
|
||||
resultCollector.setProperty(TestElement.TEST_CLASS, MsDebugListener.class.getName());
|
||||
resultCollector.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ViewResultsFullVisualizer"));
|
||||
resultCollector.setEnabled(true);
|
||||
resultCollector.setRunMode(request.getRunMode());
|
||||
resultCollector.setFakeErrorMap(request.getFakeErrorMap());
|
||||
// 添加DEBUG标示
|
||||
HashTree test = ArrayUtils.isNotEmpty(request.getHashTree().getArray())
|
||||
? request.getHashTree().getTree(request.getHashTree().getArray()[0]) : null;
|
||||
|
||||
if (test != null && ArrayUtils.isNotEmpty(test.getArray())
|
||||
&& test.getArray()[0] instanceof ThreadGroup) {
|
||||
ThreadGroup group = (ThreadGroup) test.getArray()[0];
|
||||
group.setProperty(BackendListenerConstants.MS_DEBUG.name(), true);
|
||||
}
|
||||
request.getHashTree().add(request.getHashTree().getArray()[0], resultCollector);
|
||||
}
|
||||
|
||||
private void runLocal(JmeterRunRequestDTO request) {
|
||||
init();
|
||||
// 接口用例集成报告/测试计划报告日志记录
|
||||
if (StringUtils.isNotEmpty(request.getTestPlanReportId())
|
||||
&& StringUtils.equals(request.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||
FixedCapacityUtil.put(request.getTestPlanReportId(), new StringBuffer());
|
||||
} else {
|
||||
// 报告日志记录
|
||||
FixedCapacityUtil.put(request.getReportId(), new StringBuffer());
|
||||
}
|
||||
LoggerUtil.debug("监听MessageCache.tasks当前容量:" + FixedCapacityUtil.size());
|
||||
if (request.isDebug() && !StringUtils.equalsAny(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
|
||||
JMeterBase.addBackendListener(request, request.getHashTree(), MsApiBackendListener.class.getCanonicalName());
|
||||
}
|
||||
|
||||
if (MapUtils.isNotEmpty(request.getExtendedParameters())
|
||||
&& request.getExtendedParameters().containsKey(ExtendedParameter.SYNC_STATUS)
|
||||
&& (Boolean) request.getExtendedParameters().get(ExtendedParameter.SYNC_STATUS)) {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加Debug Listener");
|
||||
addDebugListener(request);
|
||||
}
|
||||
|
||||
if (request.isDebug()) {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加Debug Listener");
|
||||
addDebugListener(request);
|
||||
} else {
|
||||
LoggerUtil.debug("为请求 [ " + request.getReportId() + " ] 添加同步接收结果 Listener");
|
||||
JMeterBase.addBackendListener(request, request.getHashTree(), MsApiBackendListener.class.getCanonicalName());
|
||||
}
|
||||
|
||||
LoggerUtil.info("资源:[" + request.getTestId() + "] 加入JMETER中开始执行", request.getReportId());
|
||||
ApiLocalRunner runner = new ApiLocalRunner(request.getHashTree());
|
||||
runner.run(request.getReportId());
|
||||
}
|
||||
|
||||
private void fileProcessing(JmeterRunRequestDTO request) {
|
||||
ElementUtil.coverArguments(request.getHashTree());
|
||||
//解析HashTree里的文件信息
|
||||
|
@ -251,10 +186,6 @@ public class JMeterService {
|
|||
}
|
||||
}
|
||||
|
||||
public void addQueue(JmeterRunRequestDTO request) {
|
||||
this.runLocal(request);
|
||||
}
|
||||
|
||||
public boolean getRunningQueue(String poolId, String reportId) {
|
||||
try {
|
||||
List<TestResource> resources = GenerateHashTreeUtil.setPoolResource(poolId);
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||
import io.metersphere.utils.ReportStatusUtil;
|
||||
import io.metersphere.commons.constants.CommonConstants;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.vo.ResultVO;
|
||||
import io.metersphere.constants.BackendListenerConstants;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.MsRegexDTO;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
import io.metersphere.jmeter.JMeterBase;
|
||||
import io.metersphere.service.ApiExecutionQueueService;
|
||||
import io.metersphere.service.RedisTemplateService;
|
||||
import io.metersphere.service.TestResultService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import io.metersphere.utils.RetryResultUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.samplers.SampleResult;
|
||||
import org.apache.jmeter.services.FileServer;
|
||||
import org.apache.jmeter.visualizers.backend.AbstractBackendListenerClient;
|
||||
import org.apache.jmeter.visualizers.backend.BackendListenerContext;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MsApiBackendListener extends AbstractBackendListenerClient implements Serializable {
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
private TestResultService testResultService;
|
||||
private List<SampleResult> queues;
|
||||
private ResultDTO dto;
|
||||
// 当前场景报告/用例结果状态
|
||||
private ResultVO resultVO;
|
||||
|
||||
private RedisTemplateService redisTemplateService;
|
||||
|
||||
/**
|
||||
* 参数初始化方法
|
||||
*/
|
||||
@Override
|
||||
public void setupTest(BackendListenerContext context) throws Exception {
|
||||
LoggerUtil.info("初始化监听");
|
||||
queues = new LinkedList<>();
|
||||
this.setParam(context);
|
||||
if (apiExecutionQueueService == null) {
|
||||
apiExecutionQueueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class);
|
||||
}
|
||||
if (testResultService == null) {
|
||||
testResultService = CommonBeanFactory.getBean(TestResultService.class);
|
||||
}
|
||||
if (redisTemplateService == null) {
|
||||
redisTemplateService = CommonBeanFactory.getBean(RedisTemplateService.class);
|
||||
}
|
||||
resultVO = new ResultVO();
|
||||
super.setupTest(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSampleResults(List<SampleResult> sampleResults, BackendListenerContext context) {
|
||||
LoggerUtil.info("接收到JMETER执行数据【" + sampleResults.size() + " 】", dto.getReportId());
|
||||
if (dto.isRetryEnable()) {
|
||||
queues.addAll(sampleResults);
|
||||
} else {
|
||||
if (!StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||
dto.setConsole(FixedCapacityUtil.getJmeterLogger(getReportId(), false));
|
||||
}
|
||||
sampleResults = RetryResultUtil.clearLoops(sampleResults);
|
||||
JMeterBase.resultFormatting(sampleResults, dto);
|
||||
testResultService.saveResults(dto);
|
||||
resultVO = ReportStatusUtil.getStatus(dto, resultVO);
|
||||
dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, resultVO);
|
||||
sampleResults.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardownTest(BackendListenerContext context) {
|
||||
try {
|
||||
LoggerUtil.info("进入TEST-END处理报告" + dto.getRunMode(), dto.getReportId());
|
||||
super.teardownTest(context);
|
||||
// 获取执行日志
|
||||
if (!StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||
dto.setConsole(FixedCapacityUtil.getJmeterLogger(getReportId(), true));
|
||||
}
|
||||
if (dto.isRetryEnable()) {
|
||||
LoggerUtil.info("重试结果处理开始", dto.getReportId());
|
||||
// 清理过程步骤
|
||||
queues = RetryResultUtil.clearLoops(queues);
|
||||
JMeterBase.resultFormatting(queues, dto);
|
||||
|
||||
LoggerUtil.info("合并重试结果集", dto.getReportId());
|
||||
RetryResultUtil.mergeRetryResults(dto.getRequestResults());
|
||||
|
||||
LoggerUtil.info("执行结果入库存储", dto.getReportId());
|
||||
testResultService.saveResults(dto);
|
||||
resultVO = ReportStatusUtil.getStatus(dto, resultVO);
|
||||
dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, resultVO);
|
||||
LoggerUtil.info("重试结果处理结束", dto.getReportId());
|
||||
}
|
||||
// 全局并发队列
|
||||
PoolExecBlockingQueueUtil.offer(dto.getReportId());
|
||||
// 整体执行结束更新资源状态
|
||||
testResultService.testEnded(dto);
|
||||
if (StringUtils.isNotEmpty(dto.getQueueId())) {
|
||||
LoggerUtil.info("串行进入下一个执行点", dto.getReportId());
|
||||
apiExecutionQueueService.queueNext(dto);
|
||||
}
|
||||
// 更新测试计划报告
|
||||
LoggerUtil.info("Check Processing Test Plan report status:" + dto.getQueueId() + "," + dto.getTestId());
|
||||
apiExecutionQueueService.checkTestPlanCaseTestEnd(dto.getTestId(), dto.getRunMode(), dto.getTestPlanReportId());
|
||||
LoggerUtil.info("TEST-END处理结果集完成", dto.getReportId());
|
||||
|
||||
JvmUtil.memoryInfo();
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("结果集处理异常", dto.getReportId(), e);
|
||||
} finally {
|
||||
queues.clear();
|
||||
redisTemplateService.delFilePath(dto.getReportId());
|
||||
FileUtils.deleteBodyFiles(dto.getReportId());
|
||||
if (FileServer.getFileServer() != null) {
|
||||
LoggerUtil.info("进入监听,开始关闭CSV", dto.getReportId());
|
||||
FileServer.getFileServer().closeCsv(dto.getReportId());
|
||||
}
|
||||
ApiLocalRunner.clearCache(dto.getReportId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化参数
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private void setParam(BackendListenerContext context) {
|
||||
dto = new ResultDTO();
|
||||
dto.setTestId(context.getParameter(BackendListenerConstants.TEST_ID.name()));
|
||||
dto.setRunMode(context.getParameter(BackendListenerConstants.RUN_MODE.name()));
|
||||
dto.setReportId(context.getParameter(BackendListenerConstants.REPORT_ID.name()));
|
||||
dto.setReportType(context.getParameter(BackendListenerConstants.REPORT_TYPE.name()));
|
||||
dto.setTestPlanReportId(context.getParameter(BackendListenerConstants.MS_TEST_PLAN_REPORT_ID.name()));
|
||||
if (context.getParameter(BackendListenerConstants.RETRY_ENABLE.name()) != null) {
|
||||
dto.setRetryEnable(Boolean.parseBoolean(context.getParameter(BackendListenerConstants.RETRY_ENABLE.name())));
|
||||
}
|
||||
dto.setQueueId(context.getParameter(BackendListenerConstants.QUEUE_ID.name()));
|
||||
dto.setRunType(context.getParameter(BackendListenerConstants.RUN_TYPE.name()));
|
||||
if (dto.getArbitraryData() == null) {
|
||||
dto.setArbitraryData(new LinkedHashMap<>());
|
||||
}
|
||||
String ept = context.getParameter(BackendListenerConstants.EPT.name());
|
||||
if (StringUtils.isNotEmpty(ept)) {
|
||||
dto.setExtendedParameters(JSON.parseObject(context.getParameter(BackendListenerConstants.EPT.name()), Map.class));
|
||||
}
|
||||
if (StringUtils.isNotBlank(context.getParameter(BackendListenerConstants.FAKE_ERROR.name()))) {
|
||||
Map<String, List<MsRegexDTO>> fakeErrorMap = JSON.parseObject(
|
||||
context.getParameter(BackendListenerConstants.FAKE_ERROR.name()),
|
||||
new TypeReference<Map<String, List<MsRegexDTO>>>() {});
|
||||
dto.setFakeErrorMap(fakeErrorMap);
|
||||
}
|
||||
}
|
||||
|
||||
private String getReportId() {
|
||||
String reportId = dto.getReportId();
|
||||
if (StringUtils.isNotEmpty(dto.getTestPlanReportId())
|
||||
&& !FixedCapacityUtil.containsKey(dto.getTestPlanReportId())
|
||||
&& StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||
reportId = dto.getTestPlanReportId();
|
||||
}
|
||||
return reportId;
|
||||
}
|
||||
}
|
|
@ -49,8 +49,6 @@ public class TestResultService {
|
|||
@Resource
|
||||
private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService;
|
||||
@Resource
|
||||
private RedisTemplateService redisTemplateService;
|
||||
@Resource
|
||||
private ApiScenarioExecutionInfoService scenarioExecutionInfoService;
|
||||
@Resource
|
||||
private ApiScenarioReportStructureService apiScenarioReportStructureService;
|
||||
|
@ -80,54 +78,12 @@ public class TestResultService {
|
|||
this.add(ApiRunMode.JENKINS_SCENARIO_PLAN.name());
|
||||
}};
|
||||
|
||||
// 接口测试 用例/接口
|
||||
private static final List<String> caseRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.DEFINITION.name());
|
||||
this.add(ApiRunMode.JENKINS.name());
|
||||
this.add(ApiRunMode.API_PLAN.name());
|
||||
}};
|
||||
|
||||
// 测试计划 用例/接口
|
||||
private static final List<String> planCaseRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.SCHEDULE_API_PLAN.name());
|
||||
this.add(ApiRunMode.JENKINS_API_PLAN.name());
|
||||
this.add(ApiRunMode.MANUAL_PLAN.name());
|
||||
}};
|
||||
|
||||
private static final List<String> apiRunModes = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.DEFINITION.name());
|
||||
this.add(ApiRunMode.API_PLAN.name());
|
||||
this.add(ApiRunMode.SCHEDULE_API_PLAN.name());
|
||||
}};
|
||||
|
||||
/**
|
||||
* 执行结果存储
|
||||
*
|
||||
* @param dto 执行结果
|
||||
*/
|
||||
public void saveResults(ResultDTO dto) {
|
||||
// 处理环境
|
||||
List<String> environmentList = new LinkedList<>();
|
||||
if (dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("ENV")) {
|
||||
environmentList = (List<String>) dto.getArbitraryData().get("ENV");
|
||||
}
|
||||
//处理环境参数
|
||||
if (CollectionUtils.isNotEmpty(environmentList)) {
|
||||
apiEnvironmentRunningParamService.parseEnvironment(environmentList);
|
||||
}
|
||||
|
||||
// 测试计划用例触发结果处理
|
||||
if (planCaseRunModes.contains(dto.getRunMode())) {
|
||||
apiDefinitionExecResultService.saveApiResultByScheduleTask(dto);
|
||||
} else if (caseRunModes.contains(dto.getRunMode())) {
|
||||
// 手动触发/批量触发 用例结果处理
|
||||
apiDefinitionExecResultService.saveApiResult(dto);
|
||||
} else if (scenarioRunModes.contains(dto.getRunMode())) {
|
||||
// 场景报告结果处理
|
||||
apiScenarioReportService.saveResult(dto);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量存储来自NODE/K8s的执行结果
|
||||
*/
|
||||
|
|
|
@ -5,15 +5,12 @@ import io.metersphere.api.dto.RequestResultExpandDTO;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.CommonConstants;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.TriggerMode;
|
||||
import io.metersphere.commons.enums.ApiReportStatus;
|
||||
import io.metersphere.commons.enums.ExecutionExecuteTypeEnum;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.dto.PlanReportCaseDTO;
|
||||
import io.metersphere.dto.RequestResult;
|
||||
|
@ -49,8 +46,6 @@ public class ApiDefinitionExecResultService {
|
|||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
@Resource
|
||||
private NoticeSendService noticeSendService;
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
@ -61,14 +56,6 @@ public class ApiDefinitionExecResultService {
|
|||
@Resource
|
||||
private ApiExecutionInfoService apiExecutionInfoService;
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
@Resource
|
||||
private ApiCaseExecutionInfoService apiCaseExecutionInfoService;
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
@Resource
|
||||
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
|
||||
@Resource
|
||||
private RedisTemplateService redisTemplateService;
|
||||
|
||||
/**
|
||||
|
@ -89,65 +76,43 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
}
|
||||
|
||||
public void saveApiResult(ResultDTO dto) {
|
||||
LoggerUtil.info("接收到API/CASE执行结果【 " + dto.getRequestResults().size() + " 】条");
|
||||
this.mergeRetryResults(dto);
|
||||
for (RequestResult item : dto.getRequestResults()) {
|
||||
if (item.getResponseResult() != null && item.getResponseResult().getResponseTime() <= 0) {
|
||||
item.getResponseResult().setResponseTime((item.getEndTime() - item.getStartTime()));
|
||||
}
|
||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||
ApiDefinitionExecResult result = this.editResult(item, dto.getReportId(), dto.getConsole(), dto.getRunMode(), dto.getTestId(), null);
|
||||
if (result != null) {
|
||||
result.setResourceId(dto.getTestId());
|
||||
apiExecutionInfoService.insertExecutionInfo(result);
|
||||
User user = getUser(dto, result);
|
||||
//如果是测试计划用例,更新接口用例的上次执行结果
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(dto.getTestId());
|
||||
if (testPlanApiCase != null) {
|
||||
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
||||
if (apiTestCase != null) {
|
||||
apiTestCase.setLastResultId(dto.getReportId());
|
||||
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
|
||||
}
|
||||
redisTemplateService.unlock(dto.getTestId(), dto.getReportId());
|
||||
}
|
||||
// 发送通知
|
||||
LoggerUtil.info("执行结果【 " + result.getName() + " 】入库存储完成");
|
||||
sendNotice(result, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void batchSaveApiResult(List<ResultDTO> resultDTOS) {
|
||||
if (CollectionUtils.isEmpty(resultDTOS)) {
|
||||
LoggerUtil.info("未接收到处理结果 ");
|
||||
return;
|
||||
}
|
||||
LoggerUtil.info("接收到API/CASE执行结果【 " + resultDTOS.size() + " 】");
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper definitionExecResultMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
ApiDefinitionExecResultMapper batchExecResultMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
ApiTestCaseMapper batchApiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
TestPlanApiCaseMapper planApiCaseMapper = sqlSession.getMapper(TestPlanApiCaseMapper.class);
|
||||
|
||||
for (ResultDTO dto : resultDTOS) {
|
||||
this.mergeRetryResults(dto);
|
||||
LoggerUtil.info("开始存储报告结果[ " + dto.getRequestResults().size() + " ]", dto.getReportId());
|
||||
if (CollectionUtils.isNotEmpty(dto.getRequestResults())) {
|
||||
for (RequestResult item : dto.getRequestResults()) {
|
||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||
ApiDefinitionExecResult result = this.editResult(item, dto.getReportId(), dto.getConsole(), dto.getRunMode(), dto.getTestId(), definitionExecResultMapper);
|
||||
if (result != null) {
|
||||
if (CollectionUtils.isEmpty(dto.getRequestResults())) {
|
||||
LoggerUtil.info("未解析到执行结果", dto.getReportId());
|
||||
continue;
|
||||
}
|
||||
// 过滤掉全局脚本
|
||||
List<RequestResult> requestResults = dto.getRequestResults().stream()
|
||||
.filter(item -> !StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (RequestResult item : requestResults) {
|
||||
ApiDefinitionExecResultWithBLOBs result = this.initResult(item, dto);
|
||||
if (StringUtils.isBlank(result.getProjectId()) && dto.getExtendedParameters().containsKey(MsHashTreeService.PROJECT_ID)) {
|
||||
result.setProjectId(this.getProjectIdByResultDTO(dto.getExtendedParameters().get(MsHashTreeService.PROJECT_ID).toString()));
|
||||
result.setProjectId(this.getProjectId(dto.getExtendedParameters().get(MsHashTreeService.PROJECT_ID).toString()));
|
||||
}
|
||||
result.setResourceId(dto.getTestId());
|
||||
// 更新结果数据
|
||||
batchExecResultMapper.updateByPrimaryKeySelective(result);
|
||||
|
||||
apiExecutionInfoService.insertExecutionInfo(result);
|
||||
// 批量更新关联关系状态
|
||||
batchEditStatus(dto.getRunMode(), result.getStatus(), result.getId(), dto.getTestId(), planApiCaseMapper, batchApiTestCaseMapper);
|
||||
}
|
||||
if (result != null && !StringUtils.startsWithAny(dto.getRunMode(), NoticeConstants.Mode.SCHEDULE)) {
|
||||
batchEditStatus(result.getStatus(), result.getId(), dto, planApiCaseMapper, batchApiTestCaseMapper);
|
||||
// 发送通知
|
||||
if (!StringUtils.startsWithAny(dto.getRunMode(), NoticeConstants.Mode.SCHEDULE)) {
|
||||
User user = getUser(dto, result);
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters())
|
||||
&& dto.getExtendedParameters().containsKey(CommonConstants.USER)
|
||||
|
@ -160,15 +125,13 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
private String getProjectIdByResultDTO(String projectIdFromResultDTO) {
|
||||
private String getProjectId(String projectIdFromResultDTO) {
|
||||
String returnStr = projectIdFromResultDTO;
|
||||
if (StringUtils.startsWith(projectIdFromResultDTO, "[") && StringUtils.endsWith(projectIdFromResultDTO, "]")) {
|
||||
try {
|
||||
|
@ -239,142 +202,33 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
}
|
||||
|
||||
public void setExecResult(String id, String status, Long time) {
|
||||
TestPlanApiCase apiCase = new TestPlanApiCase();
|
||||
apiCase.setId(id);
|
||||
apiCase.setStatus(status);
|
||||
apiCase.setUpdateTime(time);
|
||||
testPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||
}
|
||||
|
||||
public void editStatus(ApiDefinitionExecResult saveResult, String type, String status, Long time, String reportId, String testId) {
|
||||
String name = testId;
|
||||
String version = StringUtils.EMPTY;
|
||||
String projectId = StringUtils.EMPTY;
|
||||
if (StringUtils.equalsAnyIgnoreCase(type,
|
||||
ApiRunMode.API_PLAN.name(),
|
||||
ApiRunMode.SCHEDULE_API_PLAN.name(),
|
||||
ApiRunMode.JENKINS_API_PLAN.name(),
|
||||
ApiRunMode.MANUAL_PLAN.name())) {
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
||||
if (testPlanApiCase != null) {
|
||||
this.setExecResult(testId, status, time);
|
||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
||||
testPlanApiCase.setStatus(status);
|
||||
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanApiCaseMapper.updateByPrimaryKeySelective(testPlanApiCase);
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("更新测试计划用例【 " + testPlanApiCase.getId() + " 】");
|
||||
}
|
||||
redisTemplateService.unlock(testId, saveResult.getId());
|
||||
}
|
||||
if (caseWithBLOBs != null) {
|
||||
name = caseWithBLOBs.getName();
|
||||
version = caseWithBLOBs.getVersionId();
|
||||
projectId = caseWithBLOBs.getProjectId();
|
||||
}
|
||||
} else {
|
||||
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(testId);
|
||||
if (apiDefinition != null) {
|
||||
name = apiDefinition.getName();
|
||||
projectId = apiDefinition.getProjectId();
|
||||
} else {
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
||||
if (caseWithBLOBs != null) {
|
||||
// 更新用例最后执行结果
|
||||
caseWithBLOBs.setLastResultId(reportId);
|
||||
caseWithBLOBs.setStatus(status);
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("更新用例【 " + caseWithBLOBs.getId() + " 】");
|
||||
}
|
||||
name = caseWithBLOBs.getName();
|
||||
version = caseWithBLOBs.getVersionId();
|
||||
projectId = caseWithBLOBs.getProjectId();
|
||||
redisTemplateService.unlock(testId, saveResult.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(saveResult.getProjectId()) && StringUtils.isNotEmpty(projectId)) {
|
||||
saveResult.setProjectId(projectId);
|
||||
}
|
||||
saveResult.setVersionId(version);
|
||||
saveResult.setName(name);
|
||||
}
|
||||
|
||||
public void batchEditStatus(String type, String status, String reportId, String testId,
|
||||
public void batchEditStatus(
|
||||
String status, String reportId, ResultDTO dto,
|
||||
TestPlanApiCaseMapper batchTestPlanApiCaseMapper,
|
||||
ApiTestCaseMapper batchApiTestCaseMapper) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(type,
|
||||
ApiRunMode.API_PLAN.name(),
|
||||
ApiRunMode.SCHEDULE_API_PLAN.name(),
|
||||
ApiRunMode.JENKINS_API_PLAN.name(),
|
||||
ApiRunMode.MANUAL_PLAN.name())) {
|
||||
ApiRunMode runMode = ApiRunMode.fromString(dto.getRunMode());
|
||||
|
||||
switch (runMode) {
|
||||
case API_PLAN:
|
||||
case SCHEDULE_API_PLAN:
|
||||
case JENKINS_API_PLAN:
|
||||
case MANUAL_PLAN:
|
||||
TestPlanApiCase apiCase = new TestPlanApiCase();
|
||||
apiCase.setId(testId);
|
||||
apiCase.setId(dto.getTestId());
|
||||
apiCase.setStatus(status);
|
||||
apiCase.setUpdateTime(System.currentTimeMillis());
|
||||
batchTestPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||
TestCaseReviewApiCase reviewApiCase = new TestCaseReviewApiCase();
|
||||
reviewApiCase.setId(testId);
|
||||
reviewApiCase.setStatus(status);
|
||||
reviewApiCase.setUpdateTime(System.currentTimeMillis());
|
||||
redisTemplateService.unlock(testId, reportId);
|
||||
} else {
|
||||
// 更新用例最后执行结果
|
||||
redisTemplateService.unlock(dto.getTestId(), reportId);
|
||||
break;
|
||||
|
||||
default:
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = new ApiTestCaseWithBLOBs();
|
||||
caseWithBLOBs.setId(testId);
|
||||
caseWithBLOBs.setId(dto.getTestId());
|
||||
caseWithBLOBs.setLastResultId(reportId);
|
||||
caseWithBLOBs.setStatus(status);
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
batchApiTestCaseMapper.updateByPrimaryKeySelective(caseWithBLOBs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务触发的保存逻辑
|
||||
* 定时任务时,userID要改为定时任务中的用户
|
||||
*/
|
||||
public void saveApiResultByScheduleTask(ResultDTO dto) {
|
||||
if (CollectionUtils.isNotEmpty(dto.getRequestResults())) {
|
||||
LoggerUtil.info("接收到API/CASE执行结果【 " + dto.getRequestResults().size() + " 】条");
|
||||
for (RequestResult item : dto.getRequestResults()) {
|
||||
LoggerUtil.info("执行结果【 " + item.getName() + " 】入库存储");
|
||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||
ApiDefinitionExecResult reportResult = this.editResult(item, dto.getReportId(), dto.getConsole(), dto.getRunMode(), dto.getTestId(), null);
|
||||
if (MapUtils.isNotEmpty(dto.getExtendedParameters()) && dto.getExtendedParameters().containsKey(CommonConstants.USER_ID)) {
|
||||
reportResult.setUserId(String.valueOf(dto.getExtendedParameters().get(CommonConstants.USER_ID)));
|
||||
}
|
||||
String triggerMode = StringUtils.EMPTY;
|
||||
if (reportResult != null) {
|
||||
triggerMode = reportResult.getTriggerMode();
|
||||
}
|
||||
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(dto.getTestId());
|
||||
if (apiCase != null && redisTemplateService.has(dto.getTestId(), dto.getReportId())) {
|
||||
String projectId = extTestPlanApiCaseMapper.selectProjectId(apiCase.getId());
|
||||
ApiDefinition apiDefinition = extApiTestCaseMapper.selectApiBasicInfoByCaseId(apiCase.getId());
|
||||
String version = apiDefinition == null ? "" : apiDefinition.getVersionId();
|
||||
apiCaseExecutionInfoService.insertExecutionInfo(apiCase.getId(), reportResult.getStatus(), triggerMode, projectId, ExecutionExecuteTypeEnum.TEST_PLAN.name(), version);
|
||||
apiCase.setStatus(reportResult.getStatus());
|
||||
apiCase.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||
|
||||
ApiTestCaseWithBLOBs apiTestCase = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
||||
if (apiTestCase != null) {
|
||||
apiTestCase.setLastResultId(dto.getReportId());
|
||||
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
|
||||
}
|
||||
redisTemplateService.unlock(dto.getTestId(), dto.getReportId());
|
||||
}
|
||||
} else {
|
||||
this.setExecResult(dto.getTestId(), reportResult.getStatus(), item.getStartTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,11 +242,10 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
}
|
||||
|
||||
private ApiDefinitionExecResult editResult(RequestResult item, String reportId, String console, String type, String testId, ApiDefinitionExecResultMapper batchMapper) {
|
||||
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
|
||||
private ApiDefinitionExecResultWithBLOBs initResult(RequestResult item, ResultDTO dto) {
|
||||
ApiDefinitionExecResultWithBLOBs saveResult = new ApiDefinitionExecResultWithBLOBs();
|
||||
item.getResponseResult().setConsole(console);
|
||||
saveResult.setId(reportId);
|
||||
item.getResponseResult().setConsole(dto.getConsole());
|
||||
saveResult.setId(dto.getReportId());
|
||||
//对响应内容进行进一步解析。如果有附加信息(比如误报库信息),则根据附加信息内的数据进行其他判读
|
||||
RequestResultExpandDTO expandDTO = ResponseUtil.parseByRequestResult(item);
|
||||
String status = item.isSuccess() ? ApiReportStatus.SUCCESS.name() : ApiReportStatus.ERROR.name();
|
||||
|
@ -404,7 +257,7 @@ public class ApiDefinitionExecResultService {
|
|||
} else {
|
||||
saveResult.setContent(JSON.toJSONString(item));
|
||||
}
|
||||
saveResult.setType(type);
|
||||
saveResult.setType(dto.getRunMode());
|
||||
saveResult.setStatus(status);
|
||||
saveResult.setStartTime(item.getStartTime());
|
||||
saveResult.setEndTime(item.getEndTime());
|
||||
|
@ -414,16 +267,9 @@ public class ApiDefinitionExecResultService {
|
|||
if (StringUtils.isNotEmpty(saveResult.getTriggerMode()) && saveResult.getTriggerMode().equals(CommonConstants.CASE)) {
|
||||
saveResult.setTriggerMode(TriggerMode.MANUAL.name());
|
||||
}
|
||||
if (batchMapper == null) {
|
||||
editStatus(saveResult, type, status, saveResult.getCreateTime(), saveResult.getId(), testId);
|
||||
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(saveResult);
|
||||
} else {
|
||||
batchMapper.updateByPrimaryKeySelective(saveResult);
|
||||
}
|
||||
saveResult.setResourceId(dto.getTestId());
|
||||
return saveResult;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, String> selectReportResultByReportIds(Collection<String> values) {
|
||||
if (CollectionUtils.isEmpty(values)) {
|
||||
|
|
|
@ -89,11 +89,6 @@ public class ApiScenarioReportService {
|
|||
@Resource
|
||||
private RedisTemplateService redisTemplateService;
|
||||
|
||||
public void saveResult(ResultDTO dto) {
|
||||
// 报告详情内容
|
||||
apiScenarioReportResultService.save(dto.getReportId(), dto.getRequestResults());
|
||||
}
|
||||
|
||||
public void batchSaveResult(List<ResultDTO> dtos) {
|
||||
apiScenarioReportResultService.batchSave(dtos);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,41 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum ApiRunMode {
|
||||
RUN, DEBUG, DEFINITION, TEST_CASE, SCENARIO, API_PLAN, JENKINS_API_PLAN, JENKINS_SCENARIO_PLAN, JENKINS_PERFORMANCE_TEST, JENKINS,
|
||||
RUN,
|
||||
DEBUG,
|
||||
DEFINITION,
|
||||
TEST_CASE,
|
||||
SCENARIO,
|
||||
API_PLAN,
|
||||
JENKINS_API_PLAN,
|
||||
JENKINS_SCENARIO_PLAN,
|
||||
JENKINS_PERFORMANCE_TEST,
|
||||
JENKINS,
|
||||
TEST_PLAN_PERFORMANCE_TEST,
|
||||
SCENARIO_PLAN, API, SCHEDULE_API_PLAN, SCHEDULE_SCENARIO, SCHEDULE_SCENARIO_PLAN, SCHEDULE_PERFORMANCE_TEST, MANUAL_PLAN,
|
||||
UI_SCENARIO, UI_SCENARIO_PLAN, UI_SCHEDULE_SCENARIO_PLAN, UI_JENKINS_SCENARIO_PLAN, UI_SCHEDULE_SCENARIO
|
||||
SCENARIO_PLAN,
|
||||
API,
|
||||
SCHEDULE_API_PLAN,
|
||||
SCHEDULE_SCENARIO,
|
||||
SCHEDULE_SCENARIO_PLAN,
|
||||
SCHEDULE_PERFORMANCE_TEST,
|
||||
MANUAL_PLAN,
|
||||
UI_SCENARIO,
|
||||
UI_SCENARIO_PLAN,
|
||||
UI_SCHEDULE_SCENARIO_PLAN,
|
||||
UI_JENKINS_SCENARIO_PLAN,
|
||||
UI_SCHEDULE_SCENARIO,
|
||||
DEFAULT;
|
||||
|
||||
public static ApiRunMode fromString(String mode) {
|
||||
if (StringUtils.isNotBlank(mode)) {
|
||||
for (ApiRunMode runMode : ApiRunMode.values()) {
|
||||
if (runMode.name().equalsIgnoreCase(mode)) {
|
||||
return runMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DEFAULT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,6 @@ public interface ExtTestPlanReportMapper {
|
|||
void setApiBaseCountAndPassRateIsNullById(String id);
|
||||
|
||||
void updateAllStatus();
|
||||
|
||||
String selectLastReportByTestPlanId(@Param("testPlanId") String testPlanId);
|
||||
}
|
||||
|
|
|
@ -154,6 +154,10 @@
|
|||
GROUP BY t.test_plan_id
|
||||
</select>
|
||||
|
||||
<select id="selectLastReportByTestPlanId" resultType="java.lang.String">
|
||||
select `status` from test_plan_report where test_plan_id = #{testPlanId} ORDER BY create_time DESC LIMIT 1
|
||||
</select>
|
||||
|
||||
|
||||
<update id="setApiBaseCountAndPassRateIsNullById">
|
||||
update test_plan_report_content
|
||||
|
|
|
@ -2,10 +2,12 @@ package io.metersphere.plan.service;
|
|||
|
||||
import io.metersphere.base.domain.TestPlanWithBLOBs;
|
||||
import io.metersphere.base.mapper.TestPlanMapper;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.*;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.plan.dto.ExecutionWay;
|
||||
import io.metersphere.plan.request.api.TestPlanRunRequest;
|
||||
import io.metersphere.plan.service.remote.api.PlanTestPlanApiCaseService;
|
||||
|
@ -51,6 +53,11 @@ public class TestPlanExecuteService {
|
|||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||
public String runTestPlan(String testPlanId, String projectId, String userId, String triggerMode, String planReportId, String executionWay, String apiRunConfig) {
|
||||
// 校验测试计划是否在执行中
|
||||
if (testPlanService.checkTestPlanIsRunning(testPlanId)) {
|
||||
LogUtil.info("当前测试计划正在执行中,请稍后再试", testPlanId);
|
||||
MSException.throwException(Translator.get("test_plan_run_message"));
|
||||
}
|
||||
RunModeConfigDTO runModeConfig = null;
|
||||
try {
|
||||
runModeConfig = JSON.parseObject(apiRunConfig, RunModeConfigDTO.class);
|
||||
|
|
|
@ -1769,4 +1769,8 @@ public class TestPlanReportService {
|
|||
testPlanReportContentMapper.updateByExampleSelective(reportContentWithBLOBs, example);
|
||||
}
|
||||
}
|
||||
|
||||
public String selectLastReportByTestPlanId(String testPlanId) {
|
||||
return extTestPlanReportMapper.selectLastReportByTestPlanId(testPlanId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2359,4 +2359,9 @@ public class TestPlanService {
|
|||
// 进行中:0 < 测试进度 < 100%
|
||||
return TestPlanStatus.Underway.name();
|
||||
}
|
||||
|
||||
public boolean checkTestPlanIsRunning(String testPlanId) {
|
||||
String status = testPlanReportService.selectLastReportByTestPlanId(testPlanId);
|
||||
return StringUtils.equalsIgnoreCase(status, TestPlanReportStatus.RUNNING.name());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,3 +240,4 @@ rerun_warning=The report is being rerun, check it later
|
|||
case_export_text_validate_tip=Contains extremely long text, currently supported up to %s!
|
||||
case_import_table_header_missing=Header information is missing!
|
||||
relate_resource=relate
|
||||
test_plan_run_message=The current test plan is running, please try again later !
|
|
@ -211,3 +211,4 @@ rerun_warning=报告正在重跑中,稍后查看
|
|||
case_export_text_validate_tip=包含超长文本,目前支持最大长度为 %s !
|
||||
case_import_table_header_not_exist=缺少表头信息!
|
||||
relate_resource=关联
|
||||
test_plan_run_message=当前测试计划正在执行中,请稍后再试!
|
|
@ -211,3 +211,4 @@ rerun_warning=報告正在重跑中,稻後查看
|
|||
case_export_text_validate_tip=包含超長文本,目前支持最大長度為 %s !
|
||||
case_import_table_header_not_exist=缺少表頭信息!
|
||||
relate_resource=關聯
|
||||
test_plan_run_message=當前測試計劃正在執行中,請稍後再試!
|
Loading…
Reference in New Issue