fix(测试计划): 修复测试计划串行报告统计问题,加强超时处理机制

This commit is contained in:
fit2-zhao 2021-12-22 12:46:11 +08:00 committed by BugKing
parent bae4c71167
commit 0f581b9625
12 changed files with 110 additions and 66 deletions

View File

@ -1,5 +1,7 @@
package io.metersphere.api.dto.automation; package io.metersphere.api.dto.automation;
import org.junit.internal.runners.statements.Fail;
public enum ScenarioStatus { public enum ScenarioStatus {
Saved, Success, Fail, Trash,Underway Saved, Success, Error, Timeout, Fail, Trash, Underway
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.api.exec.queue; package io.metersphere.api.exec.queue;
import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.JmeterThreadUtils;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
@ -23,7 +24,7 @@ public class ExecTask implements Runnable {
jMeterService.addQueue(request); jMeterService.addQueue(request);
if (request.getPool() == null || !request.getPool().isPool()) { if (request.getPool() == null || !request.getPool().isPool()) {
Object res = PoolExecBlockingQueueUtil.take(request.getReportId()); Object res = PoolExecBlockingQueueUtil.take(request.getReportId());
if (res == null) { if (res == null && !JmeterThreadUtils.isRunning(request.getReportId(), request.getTestId())) {
LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时"); LoggerUtil.info("执行报告:【 " + request.getReportId() + " 】,资源ID【 " + request.getTestId() + " 】执行超时");
} }
} }

View File

@ -33,7 +33,7 @@ public class PoolExecBlockingQueueUtil {
if (StringUtils.isNotEmpty(key) && !queue.containsKey(key)) { if (StringUtils.isNotEmpty(key) && !queue.containsKey(key)) {
BlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE); BlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE);
queue.put(key, blockingQueue); queue.put(key, blockingQueue);
return blockingQueue.poll(5, TimeUnit.MINUTES); return blockingQueue.poll(10, TimeUnit.MINUTES);
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.error("初始化队列失败:" + e.getMessage()); LogUtil.error("初始化队列失败:" + e.getMessage());

View File

@ -91,7 +91,6 @@ public class ApiDefinitionExecResultUtil {
apiResult.setStartTime(System.currentTimeMillis()); apiResult.setStartTime(System.currentTimeMillis());
apiResult.setType(ApiRunMode.DEFINITION.name()); apiResult.setType(ApiRunMode.DEFINITION.name());
apiResult.setStatus(status); apiResult.setStatus(status);
return apiResult; return apiResult;
} }
} }

View File

@ -5,10 +5,12 @@ import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.MsResultService; import io.metersphere.api.service.MsResultService;
import io.metersphere.api.service.TestResultService; import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
import io.metersphere.jmeter.MsExecListener; import io.metersphere.jmeter.MsExecListener;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Map; import java.util.Map;
@ -18,13 +20,19 @@ public class APISingleResultListener extends MsExecListener {
LoggerUtil.info("处理单条执行结果报告【" + dto.getReportId() + " 】,资源【 " + dto.getTestId() + ""); LoggerUtil.info("处理单条执行结果报告【" + dto.getReportId() + " 】,资源【 " + dto.getTestId() + "");
dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId())); dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId()));
CommonBeanFactory.getBean(TestResultService.class).saveResults(dto); CommonBeanFactory.getBean(TestResultService.class).saveResults(dto);
// 更新报告最后接收到请求的时间
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
CommonBeanFactory.getBean(TestResultService.class).editReportTime(dto);
}
} }
@Override @Override
public void testEnded(ResultDTO dto, Map<String, Object> kafkaConfig) { public void testEnded(ResultDTO dto, Map<String, Object> kafkaConfig) {
try { try {
LoggerUtil.info("进入TEST-END处理报告【" + dto.getReportId() + " 】整体执行完成;" + dto.getRunMode()); LoggerUtil.info("进入TEST-END处理报告【" + dto.getReportId() + " 】整体执行完成;" + dto.getRunMode());
// 全局并发队列 // 全局并发队列
PoolExecBlockingQueueUtil.offer(dto.getReportId()); PoolExecBlockingQueueUtil.offer(dto.getReportId());
dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId())); dto.setConsole(CommonBeanFactory.getBean(MsResultService.class).getJmeterLogger(dto.getReportId()));

View File

@ -7,9 +7,7 @@ public class JmeterThreadUtils {
private final static String THREAD_SPLIT = " "; private final static String THREAD_SPLIT = " ";
public static String stop(String name) { public static String stop(String name) {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup(); ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount(); int noThreads = currentGroup.activeCount();
Thread[] lstThreads = new Thread[noThreads]; Thread[] lstThreads = new Thread[noThreads];
currentGroup.enumerate(lstThreads); currentGroup.enumerate(lstThreads);
@ -24,4 +22,19 @@ public class JmeterThreadUtils {
} }
return threadNames.toString(); return threadNames.toString();
} }
public static boolean isRunning(String reportId, String testId) {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] lstThreads = new Thread[noThreads];
currentGroup.enumerate(lstThreads);
for (int i = 0; i < noThreads; i++) {
if (StringUtils.isNotEmpty(reportId) && StringUtils.isNotEmpty(lstThreads[i].getName()) && lstThreads[i].getName().startsWith(reportId)) {
return true;
} else if (StringUtils.isNotEmpty(testId) && StringUtils.isNotEmpty(lstThreads[i].getName()) && lstThreads[i].getName().startsWith(testId)) {
return true;
}
}
return false;
}
} }

View File

@ -7,6 +7,7 @@ import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
import io.metersphere.api.service.ApiEnvironmentRunningParamService; import io.metersphere.api.service.ApiEnvironmentRunningParamService;
import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiExecutionQueueService;
import io.metersphere.api.service.TestResultService; import io.metersphere.api.service.TestResultService;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.config.KafkaConfig; import io.metersphere.config.KafkaConfig;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
@ -34,6 +35,13 @@ public class MsKafkaListener {
// 全局并发队列 // 全局并发队列
PoolExecBlockingQueueUtil.offer(testResult.getReportId()); PoolExecBlockingQueueUtil.offer(testResult.getReportId());
} else { } else {
// 更新报告最后接收到请求的时间
if (StringUtils.equalsAny(testResult.getRunMode(), ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
CommonBeanFactory.getBean(TestResultService.class).editReportTime(testResult);
}
testResultService.saveResults(testResult); testResultService.saveResults(testResult);
} }
LoggerUtil.info("执行内容存储结束"); LoggerUtil.info("执行内容存储结束");

View File

@ -187,8 +187,6 @@ public class ApiDefinitionExecResultService {
* 定时任务时userID要改为定时任务中的用户 * 定时任务时userID要改为定时任务中的用户
*/ */
public void saveApiResultByScheduleTask(List<RequestResult> requestResults, ResultDTO dto) { public void saveApiResultByScheduleTask(List<RequestResult> requestResults, ResultDTO dto) {
Map<String, String> apiIdResultMap = new HashMap<>();
Map<String, String> caseReportMap = new HashMap<>();
boolean isFirst = true; boolean isFirst = true;
int countExpectProcessResultCount = 0; int countExpectProcessResultCount = 0;
if (CollectionUtils.isNotEmpty(requestResults)) { if (CollectionUtils.isNotEmpty(requestResults)) {
@ -201,7 +199,7 @@ public class ApiDefinitionExecResultService {
for (RequestResult item : requestResults) { for (RequestResult item : requestResults) {
if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) { if (!StringUtils.startsWithAny(item.getName(), "PRE_PROCESSOR_ENV_", "POST_PROCESSOR_ENV_")) {
ApiDefinitionExecResult saveResult = this.save(item, dto.getReportId(), dto.getConsole(), countExpectProcessResultCount, dto.getRunMode(), dto.getTestId(), isFirst); this.save(item, dto.getReportId(), dto.getConsole(), countExpectProcessResultCount, dto.getRunMode(), dto.getTestId(), isFirst);
String status = item.isSuccess() ? "success" : "error"; String status = item.isSuccess() ? "success" : "error";
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) { if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(dto.getTestId()); TestPlanApiCase apiCase = testPlanApiCaseService.getById(dto.getTestId());
@ -214,19 +212,19 @@ public class ApiDefinitionExecResultService {
testPlanApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime()); testPlanApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime());
testCaseReviewApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime()); testCaseReviewApiCaseService.setExecResult(dto.getTestId(), status, item.getStartTime());
} }
if (StringUtils.isNotEmpty(dto.getTestId())) {
apiIdResultMap.put(dto.getTestId(), item.isSuccess() ? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
}
//更新报告ID
caseReportMap.put(dto.getTestId(), saveResult.getId());
isFirst = false; isFirst = false;
} }
} }
} }
updateTestCaseStates(dto.getTestId()); updateTestCaseStates(dto.getTestId());
Map<String, String> apiIdResultMap = new HashMap<>();
long errorSize = requestResults.stream().filter(requestResult -> requestResult.getError() > 0).count();
String status = errorSize > 0 || requestResults.isEmpty() ? TestPlanApiExecuteStatus.FAILD.name() : TestPlanApiExecuteStatus.SUCCESS.name();
if (StringUtils.isNotEmpty(dto.getReportId())) {
apiIdResultMap.put(dto.getReportId(), status);
}
testPlanLog.info("TestPlanReportId[" + dto.getTestPlanReportId() + "] APICASE OVER. API CASE STATUS:" + JSONObject.toJSONString(apiIdResultMap)); testPlanLog.info("TestPlanReportId[" + dto.getTestPlanReportId() + "] APICASE OVER. API CASE STATUS:" + JSONObject.toJSONString(apiIdResultMap));
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(dto.getTestPlanReportId(), apiIdResultMap, null, null); TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(dto.getTestPlanReportId(), apiIdResultMap, null, null);
TestPlanReportExecuteCatch.updateTestPlanReport(dto.getTestPlanReportId(), caseReportMap, null);
} }
/** /**

View File

@ -22,6 +22,7 @@ import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult; import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult;
import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest; import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest;
import io.metersphere.api.exec.api.ApiExecuteService; import io.metersphere.api.exec.api.ApiExecuteService;
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
import io.metersphere.api.parse.ApiImportParser; import io.metersphere.api.parse.ApiImportParser;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
@ -102,16 +103,12 @@ public class ApiDefinitionService {
@Resource @Resource
private ApiTestCaseMapper apiTestCaseMapper; private ApiTestCaseMapper apiTestCaseMapper;
@Resource @Resource
private ApiTestEnvironmentService environmentService;
@Resource
private EsbApiParamService esbApiParamService; private EsbApiParamService esbApiParamService;
@Resource @Resource
private TcpApiParamService tcpApiParamService; private TcpApiParamService tcpApiParamService;
@Resource @Resource
private ApiModuleMapper apiModuleMapper; private ApiModuleMapper apiModuleMapper;
@Resource @Resource
private SystemParameterService systemParameterService;
@Resource
private TestPlanMapper testPlanMapper; private TestPlanMapper testPlanMapper;
@Resource @Resource
private NoticeSendService noticeSendService; private NoticeSendService noticeSendService;
@ -855,6 +852,15 @@ public class ApiDefinitionService {
* @return * @return
*/ */
public MsExecResponseDTO run(RunDefinitionRequest request, List<MultipartFile> bodyFiles) { public MsExecResponseDTO run(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {
if (!request.isDebug()) {
String testId = request.getTestElement() != null &&
CollectionUtils.isNotEmpty(request.getTestElement().getHashTree()) &&
CollectionUtils.isNotEmpty(request.getTestElement().getHashTree().get(0).getHashTree()) ?
request.getTestElement().getHashTree().get(0).getHashTree().get(0).getName() : request.getId();
ApiDefinitionExecResult result = ApiDefinitionExecResultUtil.add(testId, APITestStatus.Running.name(), request.getId());
result.setTriggerMode(TriggerMode.MANUAL.name());
apiDefinitionExecResultMapper.insert(result);
}
return apiExecuteService.debug(request, bodyFiles); return apiExecuteService.debug(request, bodyFiles);
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.RunModeDataDTO; import io.metersphere.api.dto.RunModeDataDTO;
import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.scenario.ApiScenarioSerialService; import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
@ -179,9 +180,8 @@ public class ApiExecutionQueueService {
public void timeOut() { public void timeOut() {
final int SECOND_MILLIS = 1000; final int SECOND_MILLIS = 1000;
final int MINUTE_MILLIS = 60 * SECOND_MILLIS; final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
long now = System.currentTimeMillis(); // 二十分钟前的超时报告
// 八分钟前的数据 final long now = System.currentTimeMillis() - (20 * MINUTE_MILLIS);
now = now - 8 * MINUTE_MILLIS;
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample(); ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andCreateTimeLessThan(now); example.createCriteria().andCreateTimeLessThan(now);
List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example); List<ApiExecutionQueueDetail> queueDetails = executionQueueDetailMapper.selectByExample(example);
@ -190,14 +190,14 @@ public class ApiExecutionQueueService {
queueDetails.forEach(item -> { queueDetails.forEach(item -> {
if (StringUtils.equalsAny(item.getType(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { if (StringUtils.equalsAny(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()); ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null && StringUtils.equalsAny(report.getStatus(), TestPlanReportStatus.RUNNING.name())) { if (report != null && StringUtils.equalsAny(report.getStatus(), TestPlanReportStatus.RUNNING.name()) && report.getUpdateTime() < now) {
report.setStatus("timeout"); report.setStatus(ScenarioStatus.Timeout.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report); apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} }
} else { } else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId()); ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(item.getReportId());
if (result != null && StringUtils.equalsAny(result.getStatus(), TestPlanReportStatus.RUNNING.name())) { if (result != null && StringUtils.equalsAny(result.getStatus(), TestPlanReportStatus.RUNNING.name())) {
result.setStatus("timeout"); result.setStatus(ScenarioStatus.Timeout.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result); apiDefinitionExecResultMapper.updateByPrimaryKeySelective(result);
} }
} }
@ -211,8 +211,8 @@ public class ApiExecutionQueueService {
if (CollectionUtils.isNotEmpty(executionQueues)) { if (CollectionUtils.isNotEmpty(executionQueues)) {
executionQueues.forEach(item -> { executionQueues.forEach(item -> {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId()); ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(item.getReportId());
if (report != null && StringUtils.equalsAny(report.getStatus(), TestPlanReportStatus.RUNNING.name())) { if (report != null && StringUtils.equalsAny(report.getStatus(), TestPlanReportStatus.RUNNING.name()) && report.getUpdateTime() < now) {
report.setStatus("timeout"); report.setStatus(ScenarioStatus.Timeout.name());
apiScenarioReportMapper.updateByPrimaryKeySelective(report); apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} }
}); });

View File

@ -87,6 +87,7 @@ public class ApiScenarioReportService {
apiScenarioReportResultService.save(dto.getReportId(), requestResults); apiScenarioReportResultService.save(dto.getReportId(), requestResults);
} }
public ApiScenarioReport testEnded(ResultDTO dto) { public ApiScenarioReport testEnded(ResultDTO dto) {
if (!StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) { if (!StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
// 更新控制台信息 // 更新控制台信息
@ -96,6 +97,15 @@ public class ApiScenarioReportService {
example.createCriteria().andReportIdEqualTo(dto.getReportId()); example.createCriteria().andReportIdEqualTo(dto.getReportId());
List<ApiScenarioReportResult> requestResults = apiScenarioReportResultMapper.selectByExample(example); List<ApiScenarioReportResult> requestResults = apiScenarioReportResultMapper.selectByExample(example);
if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) {
String status = getStatus(requestResults, dto);
Map<String, String> reportMap = new HashMap<String, String>() {{
this.put(dto.getReportId(), status);
}};
testPlanLog.info("TestPlanReportId" + JSONArray.toJSONString(dto.getReportId()) + " EXECUTE OVER. SCENARIO STATUS : " + JSONObject.toJSONString(reportMap));
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(dto.getTestPlanReportId(), null, reportMap, null);
}
ApiScenarioReport scenarioReport; ApiScenarioReport scenarioReport;
if (StringUtils.equals(dto.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) { if (StringUtils.equals(dto.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
scenarioReport = updatePlanCase(requestResults, dto); scenarioReport = updatePlanCase(requestResults, dto);
@ -226,7 +236,7 @@ public class ApiScenarioReportService {
} }
public ApiScenarioReport updatePlanCase(List<ApiScenarioReportResult> requestResults, ResultDTO dto) { public ApiScenarioReport updatePlanCase(List<ApiScenarioReportResult> requestResults, ResultDTO dto) {
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Error")).count(); long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count();
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId()); TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId());
if (testPlanApiScenario != null) { if (testPlanApiScenario != null) {
if (errorSize > 0) { if (errorSize > 0) {
@ -234,7 +244,7 @@ public class ApiScenarioReportService {
} else { } else {
testPlanApiScenario.setLastResult(ScenarioStatus.Success.name()); testPlanApiScenario.setLastResult(ScenarioStatus.Success.name());
} }
long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Success")).count(); long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count();
String passRate = new DecimalFormat("0%").format((float) successSize / requestResults.size()); String passRate = new DecimalFormat("0%").format((float) successSize / requestResults.size());
testPlanApiScenario.setPassRate(passRate); testPlanApiScenario.setPassRate(passRate);
@ -245,7 +255,7 @@ public class ApiScenarioReportService {
// 更新场景状态 // 更新场景状态
ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId()); ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
if (scenario != null) { if (scenario != null) {
scenario.setLastResult(errorSize > 0 ? "Fail" : "Success"); scenario.setLastResult(errorSize > 0 ? "Fail" : ScenarioStatus.Success.name());
scenario.setPassRate(passRate); scenario.setPassRate(passRate);
scenario.setReportId(dto.getReportId()); scenario.setReportId(dto.getReportId());
int executeTimes = 0; int executeTimes = 0;
@ -256,11 +266,7 @@ public class ApiScenarioReportService {
apiScenarioMapper.updateByPrimaryKey(scenario); apiScenarioMapper.updateByPrimaryKey(scenario);
} }
} }
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success"; String status = getStatus(requestResults, dto);
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
return report; return report;
} }
@ -269,15 +275,8 @@ public class ApiScenarioReportService {
List<String> testPlanReportIdList = new ArrayList<>(); List<String> testPlanReportIdList = new ArrayList<>();
StringBuilder scenarioNames = new StringBuilder(); StringBuilder scenarioNames = new StringBuilder();
Map<String, String> scenarioAndErrorMap = new HashMap<>(); long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count();
Map<String, String> planScenarioReportMap = new HashMap<>(); String status = getStatus(requestResults, dto);
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Error")).count();
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success";
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
if (report != null) { if (report != null) {
if (StringUtils.isNotEmpty(dto.getTestPlanReportId()) && !testPlanReportIdList.contains(dto.getTestPlanReportId())) { if (StringUtils.isNotEmpty(dto.getTestPlanReportId()) && !testPlanReportIdList.contains(dto.getTestPlanReportId())) {
@ -288,15 +287,12 @@ public class ApiScenarioReportService {
report.setScenarioId(testPlanApiScenario.getApiScenarioId()); report.setScenarioId(testPlanApiScenario.getApiScenarioId());
report.setEndTime(System.currentTimeMillis()); report.setEndTime(System.currentTimeMillis());
apiScenarioReportMapper.updateByPrimaryKeySelective(report); apiScenarioReportMapper.updateByPrimaryKeySelective(report);
planScenarioReportMap.put(dto.getTestId(), report.getId());
if (errorSize > 0) { if (errorSize > 0) {
scenarioAndErrorMap.put(testPlanApiScenario.getId(), TestPlanApiExecuteStatus.FAILD.name());
testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name()); testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name());
} else { } else {
scenarioAndErrorMap.put(testPlanApiScenario.getId(), TestPlanApiExecuteStatus.SUCCESS.name());
testPlanApiScenario.setLastResult(ScenarioStatus.Success.name()); testPlanApiScenario.setLastResult(ScenarioStatus.Success.name());
} }
long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Success")).count(); long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count();
String passRate = new DecimalFormat("0%").format((float) successSize / requestResults.size()); String passRate = new DecimalFormat("0%").format((float) successSize / requestResults.size());
testPlanApiScenario.setPassRate(passRate); testPlanApiScenario.setPassRate(passRate);
@ -312,7 +308,7 @@ public class ApiScenarioReportService {
if (errorSize > 0) { if (errorSize > 0) {
scenario.setLastResult("Fail"); scenario.setLastResult("Fail");
} else { } else {
scenario.setLastResult("Success"); scenario.setLastResult(ScenarioStatus.Success.name());
} }
scenario.setPassRate(passRate); scenario.setPassRate(passRate);
scenario.setReportId(report.getId()); scenario.setReportId(report.getId());
@ -325,11 +321,6 @@ public class ApiScenarioReportService {
apiScenarioMapper.updateByPrimaryKey(scenario); apiScenarioMapper.updateByPrimaryKey(scenario);
} }
} }
testPlanLog.info("TestPlanReportId" + JSONArray.toJSONString(testPlanReportIdList) + " EXECUTE OVER. SCENARIO STATUS : " + JSONObject.toJSONString(scenarioAndErrorMap));
for (String item : testPlanReportIdList) {
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(item, null, scenarioAndErrorMap, null);
TestPlanReportExecuteCatch.updateTestPlanReport(item, null, planScenarioReportMap);
}
} }
return report; return report;
} }
@ -339,9 +330,9 @@ public class ApiScenarioReportService {
if (report != null) { if (report != null) {
// 更新场景状态 // 更新场景状态
ApiScenarioReportResultExample example = new ApiScenarioReportResultExample(); ApiScenarioReportResultExample example = new ApiScenarioReportResultExample();
example.createCriteria().andReportIdEqualTo(reportId).andStatusEqualTo("Error"); example.createCriteria().andReportIdEqualTo(reportId).andStatusEqualTo(ScenarioStatus.Error.name());
long size = apiScenarioReportResultMapper.countByExample(example); long size = apiScenarioReportResultMapper.countByExample(example);
report.setStatus(size > 0 ? "Error" : "Success"); report.setStatus(size > 0 ? ScenarioStatus.Error.name() : ScenarioStatus.Success.name());
report.setEndTime(System.currentTimeMillis()); report.setEndTime(System.currentTimeMillis());
// 更新控制台信息 // 更新控制台信息
apiScenarioReportStructureService.update(reportId, resultService.getJmeterLogger(reportId)); apiScenarioReportStructureService.update(reportId, resultService.getJmeterLogger(reportId));
@ -351,13 +342,10 @@ public class ApiScenarioReportService {
} }
public ApiScenarioReport updateScenario(List<ApiScenarioReportResult> requestResults, ResultDTO dto) { public ApiScenarioReport updateScenario(List<ApiScenarioReportResult> requestResults, ResultDTO dto) {
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Error")).count(); long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count();
// 更新报告状态 // 更新报告状态
String status = errorSize > 0 || requestResults.isEmpty() ? "Error" : "Success"; String status = getStatus(requestResults, dto);
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = "Timeout";
}
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode());
// 更新场景状态 // 更新场景状态
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(dto.getTestId()); ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(dto.getTestId());
@ -365,8 +353,8 @@ public class ApiScenarioReportService {
scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
} }
if (scenario != null) { if (scenario != null) {
scenario.setLastResult(errorSize > 0 ? "Fail" : "Success"); scenario.setLastResult(errorSize > 0 ? "Fail" : ScenarioStatus.Success.name());
long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), "Success")).count(); long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count();
scenario.setPassRate(new DecimalFormat("0%").format((float) successSize / requestResults.size())); scenario.setPassRate(new DecimalFormat("0%").format((float) successSize / requestResults.size()));
scenario.setReportId(dto.getReportId()); scenario.setReportId(dto.getReportId());
int executeTimes = 0; int executeTimes = 0;
@ -417,7 +405,7 @@ public class ApiScenarioReportService {
String event; String event;
String status; String status;
if (StringUtils.equals(scenario.getLastResult(), "Success")) { if (StringUtils.equals(scenario.getLastResult(), ScenarioStatus.Success.name())) {
event = NoticeConstants.Event.EXECUTE_SUCCESSFUL; event = NoticeConstants.Event.EXECUTE_SUCCESSFUL;
status = "成功"; status = "成功";
} else { } else {
@ -707,4 +695,14 @@ public class ApiScenarioReportService {
report.setScenarioId(scenarioId); report.setScenarioId(scenarioId);
return report; return report;
} }
private String getStatus(List<ApiScenarioReportResult> requestResults, ResultDTO dto) {
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count();
String status = errorSize > 0 || requestResults.isEmpty() ? ScenarioStatus.Error.name() : ScenarioStatus.Success.name();
if (dto != null && dto.getArbitraryData() != null && dto.getArbitraryData().containsKey("TIMEOUT") && (Boolean) dto.getArbitraryData().get("TIMEOUT")) {
LoggerUtil.info("报告 【 " + dto.getReportId() + " 】资源 " + dto.getTestId() + " 执行超时");
status = ScenarioStatus.Timeout.name();
}
return status;
}
} }

View File

@ -3,6 +3,7 @@ package io.metersphere.api.service;
import io.metersphere.api.dto.automation.ApiTestReportVariable; import io.metersphere.api.dto.automation.ApiTestReportVariable;
import io.metersphere.api.jmeter.ExecutedHandleSingleton; import io.metersphere.api.jmeter.ExecutedHandleSingleton;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.NoticeConstants; import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.constants.ReportTriggerMode;
@ -47,6 +48,8 @@ public class TestResultService {
private TestPlanTestCaseService testPlanTestCaseService; private TestPlanTestCaseService testPlanTestCaseService;
@Resource @Resource
private ApiTestCaseService apiTestCaseService; private ApiTestCaseService apiTestCaseService;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
public void saveResults(ResultDTO dto) { public void saveResults(ResultDTO dto) {
// 处理环境 // 处理环境
@ -70,6 +73,14 @@ public class TestResultService {
updateTestCaseStates(requestResults, dto.getRunMode()); updateTestCaseStates(requestResults, dto.getRunMode());
} }
public void editReportTime(ResultDTO dto) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(dto.getReportId());
if (report != null) {
report.setUpdateTime(System.currentTimeMillis());
apiScenarioReportMapper.updateByPrimaryKey(report);
}
}
public void testEnded(ResultDTO dto) { public void testEnded(ResultDTO dto) {
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport scenarioReport = apiScenarioReportService.testEnded(dto); ApiScenarioReport scenarioReport = apiScenarioReportService.testEnded(dto);