fix(测试跟踪): 测试计划执行结束后计算报告详情时增加报告结果重试操作

--bug=1031243 --user=宋天阳
【测试跟踪】github#26737,测试跟踪-测试计划手动执行任务中心显示成功,但是报告却显示running
https://www.tapd.cn/55049933/s/1426583
This commit is contained in:
song-tianyang 2023-10-16 15:38:22 +08:00 committed by 刘瑞斌
parent 9d86f375cb
commit d5190bc62b
3 changed files with 77 additions and 4 deletions

View File

@ -65,6 +65,7 @@ import java.util.stream.Collectors;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class TestPlanReportService { public class TestPlanReportService {
private final String GROUP = "GROUP";
@Resource @Resource
TestPlanReportMapper testPlanReportMapper; TestPlanReportMapper testPlanReportMapper;
@Resource @Resource
@ -133,8 +134,6 @@ public class TestPlanReportService {
@Resource @Resource
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper; private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
private final String GROUP = "GROUP";
//这个方法是消息通知时获取报告内容的 //这个方法是消息通知时获取报告内容的
public List<TestPlanReport> getReports(List<String> reportIdList) { public List<TestPlanReport> getReports(List<String> reportIdList) {
List<TestPlanReport> reportList = new ArrayList<>(); List<TestPlanReport> reportList = new ArrayList<>();
@ -360,7 +359,7 @@ public class TestPlanReportService {
} }
if (testPlanReport == null) { if (testPlanReport == null) {
if(runInfoDTO == null){ if (runInfoDTO == null) {
runInfoDTO = new TestPlanReportRunInfoDTO(); runInfoDTO = new TestPlanReportRunInfoDTO();
} }
if (!saveRequest.isApiCaseIsExecuting() && !saveRequest.isScenarioIsExecuting()) { if (!saveRequest.isApiCaseIsExecuting() && !saveRequest.isScenarioIsExecuting()) {
@ -1476,9 +1475,58 @@ public class TestPlanReportService {
returnMap = apiDefinitionExecResultList.stream().collect(Collectors.toMap(ApiDefinitionExecResult::getId, ApiDefinitionExecResult::getStatus, (k1, k2) -> k1)); returnMap = apiDefinitionExecResultList.stream().collect(Collectors.toMap(ApiDefinitionExecResult::getId, ApiDefinitionExecResult::getStatus, (k1, k2) -> k1));
} }
} }
this.checkApiCaseAndScenarioRunningResult(returnMap, true);
return returnMap; return returnMap;
} }
//检查是否有未完成的报告 由于微服务架构可能在api服务的事务没有提交会出现这样的情况
private void checkApiCaseAndScenarioRunningResult(Map<String, String> checkMap, boolean isApiCase) {
if (MapUtils.isEmpty(checkMap)) {
return;
}
String checkStatus = "running";
Map<String, String> runningReportMap = new HashMap<>();
for (Map.Entry<String, String> entry : checkMap.entrySet()) {
if (StringUtils.equalsAnyIgnoreCase(entry.getValue(), checkStatus)) {
runningReportMap.put(entry.getKey(), entry.getValue());
}
}
//等待sleepSeconds时间api服务的事务来提交 重复foreachTimes次
int foreachTimes = 2;
int sleepSeconds = 3000;
try {
for (int i = 0; i < foreachTimes; i++) {
//延迟3s进行计算等待事务提交
Thread.sleep(sleepSeconds);
if (isApiCase) {
List<ApiDefinitionExecResult> apiDefinitionExecResultList = planTestPlanApiCaseService.selectReportStatusByReportIds(new ArrayList<>(runningReportMap.keySet()));
runningReportMap = new HashMap<>();
for (ApiDefinitionExecResult result : apiDefinitionExecResultList) {
if (StringUtils.equalsIgnoreCase(result.getStatus(), checkStatus)) {
runningReportMap.put(result.getId(), result.getStatus());
} else {
checkMap.put(result.getId(), result.getStatus());
}
}
} else {
List<ApiScenarioReport> scenarioReportList = planTestPlanScenarioCaseService.selectReportStatusByReportIds(new ArrayList<>(runningReportMap.keySet()));
runningReportMap = new HashMap<>();
for (ApiScenarioReport result : scenarioReportList) {
if (StringUtils.equalsIgnoreCase(result.getStatus(), checkStatus)) {
runningReportMap.put(result.getId(), result.getStatus());
} else {
checkMap.put(result.getId(), result.getStatus());
}
}
}
}
} catch (Exception e) {
LogUtil.error("用例报告重新查询报错", e);
}
}
private Map<String, String> selectScenarioRunResultByIds(List<String> scenarioReportIdList) { private Map<String, String> selectScenarioRunResultByIds(List<String> scenarioReportIdList) {
Map<String, String> returnMap = new HashMap<>(); Map<String, String> returnMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(scenarioReportIdList)) { if (CollectionUtils.isNotEmpty(scenarioReportIdList)) {
@ -1487,6 +1535,7 @@ public class TestPlanReportService {
returnMap = apiDefinitionExecResultList.stream().collect(Collectors.toMap(ApiScenarioReport::getId, ApiScenarioReport::getStatus, (k1, k2) -> k1)); returnMap = apiDefinitionExecResultList.stream().collect(Collectors.toMap(ApiScenarioReport::getId, ApiScenarioReport::getStatus, (k1, k2) -> k1));
} }
} }
this.checkApiCaseAndScenarioRunningResult(returnMap, false);
return returnMap; return returnMap;
} }

View File

@ -1,6 +1,8 @@
package io.metersphere.plan.service.remote.api; package io.metersphere.plan.service.remote.api;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs; import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.commons.constants.MicroServiceName; import io.metersphere.commons.constants.MicroServiceName;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
@ -11,7 +13,6 @@ import io.metersphere.plan.request.api.ApiTestCaseRequest;
import io.metersphere.plan.service.TestPlanService; import io.metersphere.plan.service.TestPlanService;
import io.metersphere.plan.utils.TestPlanReportUtil; import io.metersphere.plan.utils.TestPlanReportUtil;
import io.metersphere.plan.utils.TestPlanStatusCalculator; import io.metersphere.plan.utils.TestPlanStatusCalculator;
import io.metersphere.utils.BatchProcessingUtil;
import io.metersphere.utils.DiscoveryUtil; import io.metersphere.utils.DiscoveryUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -31,6 +32,8 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
@Resource @Resource
PlanApiDefinitionExecResultService planApiDefinitionExecResultService; PlanApiDefinitionExecResultService planApiDefinitionExecResultService;
@Resource @Resource
ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
@Lazy @Lazy
TestPlanService testPlanService; TestPlanService testPlanService;
@ -200,4 +203,11 @@ public class PlanTestPlanApiCaseService extends ApiTestService {
return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/ext/" + planId, ApiDefinitionExecResultWithBLOBs.class); return microService.getForDataArray(serviceName, BASE_UEL + "/get/report/ext/" + planId, ApiDefinitionExecResultWithBLOBs.class);
} }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public List<ApiDefinitionExecResult> selectReportStatusByReportIds(List<String> reportIds) {
if (CollectionUtils.isEmpty(reportIds)) {
return new ArrayList<>();
}
return extTestPlanApiCaseMapper.selectReportStatusByReportIds(reportIds);
}
} }

View File

@ -1,6 +1,8 @@
package io.metersphere.plan.service.remote.api; package io.metersphere.plan.service.remote.api;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.domain.TestPlanReport; import io.metersphere.base.domain.TestPlanReport;
import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
import io.metersphere.commons.constants.MicroServiceName; import io.metersphere.commons.constants.MicroServiceName;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
@ -19,6 +21,8 @@ import org.apache.commons.collections.CollectionUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -34,6 +38,8 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService {
@Resource @Resource
PlanApiScenarioReportService planApiScenarioReportService; PlanApiScenarioReportService planApiScenarioReportService;
@Resource
ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
public void calculatePlanReport(String planId, TestPlanReportDataStruct report) { public void calculatePlanReport(String planId, TestPlanReportDataStruct report) {
if (DiscoveryUtil.hasService(MicroServiceName.API_TEST)) { if (DiscoveryUtil.hasService(MicroServiceName.API_TEST)) {
@ -212,4 +218,12 @@ public class PlanTestPlanScenarioCaseService extends ApiTestService {
request.setAllowedRepeatCase(testPlanService.isAllowedRepeatCase(request.getPlanId())); request.setAllowedRepeatCase(testPlanService.isAllowedRepeatCase(request.getPlanId()));
return microService.postForData(serviceName, BASE_UEL + String.format("/relevance/list/%s/%s", pageNum, pageSize), request); return microService.postForData(serviceName, BASE_UEL + String.format("/relevance/list/%s/%s", pageNum, pageSize), request);
} }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public List<ApiScenarioReport> selectReportStatusByReportIds(List<String> reportIds) {
if (CollectionUtils.isEmpty(reportIds)) {
return new ArrayList<>();
}
return extTestPlanScenarioCaseMapper.selectReportStatusByReportIds(reportIds);
}
} }