feat(测试计划): 优化测试计划报告的执行逻辑以及报告统计方式

优化测试计划报告的执行逻辑以及报告统计方式
This commit is contained in:
song-tianyang 2022-01-10 17:45:01 +08:00 committed by song-tianyang
parent f0c38b30a3
commit 1d6d73a40b
23 changed files with 318 additions and 1201 deletions

View File

@ -1,286 +0,0 @@
package io.metersphere.api.cache;
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
import io.metersphere.api.jmeter.JmeterThreadUtils;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.domain.ApiScenarioReportExample;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.commons.constants.TestPlanApiExecuteStatus;
import io.metersphere.commons.constants.TestPlanResourceType;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.track.dto.TestPlanReportExecuteCheckResultDTO;
import io.metersphere.utils.LoggerUtil;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author song.tianyang
* @Date 2021/8/21 5:15 下午
*/
@Getter
@Setter
public class TestPlanExecuteInfo {
private String reportId;
private String creator;
private Map<String, String> apiCaseExecInfo = new ConcurrentHashMap<>();
private Map<String, String> apiScenarioCaseExecInfo = new ConcurrentHashMap<>();
private Map<String, String> loadCaseExecInfo = new ConcurrentHashMap<>();
private Map<String, String> apiCaseExecuteThreadMap = new ConcurrentHashMap<>();
private Map<String, String> apiScenarioThreadMap = new ConcurrentHashMap<>();
private Map<String, String> loadCaseReportIdMap = new ConcurrentHashMap<>();
private Map<String, String> apiCaseReportMap = new ConcurrentHashMap<>();
private Map<String, String> apiScenarioReportMap = new ConcurrentHashMap<>();
private boolean reportDataInDataBase;
int lastUnFinishedNumCount = 0;
long lastFinishedNumCountTime = 0;
private boolean isApiCaseAllExecuted;
private boolean isScenarioAllExecuted;
private boolean isLoadCaseAllExecuted;
public TestPlanExecuteInfo(String reportId, String creator) {
this.reportId = reportId;
this.creator = creator;
}
public synchronized void updateExecuteInfo(Map<String, String> apiCaseExecInfo, Map<String, String> apiScenarioCaseExecInfo, Map<String, String> loadCaseExecInfo) {
if (MapUtils.isNotEmpty(apiCaseExecInfo)) {
this.apiCaseExecInfo.putAll(apiCaseExecInfo);
}
if (MapUtils.isNotEmpty(apiScenarioCaseExecInfo)) {
this.apiScenarioCaseExecInfo.putAll(apiScenarioCaseExecInfo);
}
if (MapUtils.isNotEmpty(loadCaseExecInfo)) {
this.loadCaseExecInfo.putAll(loadCaseExecInfo);
}
}
public synchronized void updateThreadResult(Map<String, String> apiCaseExecResultInfo, Map<String, String> apiScenarioCaseExecResultInfo, Map<String, String> loadCaseExecResultInfo) {
if (MapUtils.isNotEmpty(apiCaseExecResultInfo)) {
this.apiCaseExecuteThreadMap.putAll(apiCaseExecResultInfo);
}
if (MapUtils.isNotEmpty(apiScenarioCaseExecResultInfo)) {
this.apiScenarioThreadMap.putAll(apiScenarioCaseExecResultInfo);
}
if (MapUtils.isNotEmpty(loadCaseExecResultInfo)) {
this.loadCaseReportIdMap.putAll(loadCaseExecResultInfo);
}
}
public synchronized TestPlanReportExecuteCheckResultDTO countUnFinishedNum() {
TestPlanReportExecuteCheckResultDTO executeCheck = new TestPlanReportExecuteCheckResultDTO();
int unFinishedCount = 0;
this.isApiCaseAllExecuted = true;
this.isScenarioAllExecuted = true;
this.isLoadCaseAllExecuted = true;
boolean isQueue = false;
for (String result : apiCaseExecInfo.values()) {
if (StringUtils.equalsIgnoreCase(result, TestPlanApiExecuteStatus.RUNNING.name())) {
unFinishedCount++;
if (this.isApiCaseAllExecuted) {
this.isApiCaseAllExecuted = false;
}
if (!isQueue) {
isQueue = CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).check(apiCaseExecuteThreadMap.get(result));
}
}
}
for (String result : apiScenarioCaseExecInfo.values()) {
if (StringUtils.equalsIgnoreCase(result, TestPlanApiExecuteStatus.RUNNING.name())) {
unFinishedCount++;
if (this.isScenarioAllExecuted) {
isScenarioAllExecuted = false;
}
if (!isQueue) {
isQueue = CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).check(apiScenarioThreadMap.get(result));
}
}
}
for (String result : loadCaseExecInfo.values()) {
if (StringUtils.equalsIgnoreCase(result, TestPlanApiExecuteStatus.RUNNING.name())) {
unFinishedCount++;
if (this.isLoadCaseAllExecuted) {
isLoadCaseAllExecuted = false;
}
}
}
if (lastUnFinishedNumCount != unFinishedCount) {
lastUnFinishedNumCount = unFinishedCount;
lastFinishedNumCountTime = System.currentTimeMillis();
}
if (lastUnFinishedNumCount == unFinishedCount && isQueue) {
LoggerUtil.info("执行的报告还在队列中,重置超时时间");
lastUnFinishedNumCount = unFinishedCount;
lastFinishedNumCountTime = System.currentTimeMillis();
executeCheck.setFinishedCaseChanged(true);
} else if (unFinishedCount == 0) {
executeCheck.setFinishedCaseChanged(true);
} else {
executeCheck.setFinishedCaseChanged(false);
}
executeCheck.setTimeOut(false);
if (unFinishedCount > 0) {
//20分钟没有案例执行结果更新则定位超时
long nowTime = System.currentTimeMillis();
if (nowTime - lastFinishedNumCountTime > 1200000) {
executeCheck.setTimeOut(true);
}
}
return executeCheck;
}
public Map<String, Map<String, String>> getExecutedResult() {
Map<String, Map<String, String>> resourceTypeMap = new HashMap<>();
for (Map.Entry<String, String> entry : apiCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
String resourceType = TestPlanResourceType.API_CASE.name();
if (resourceTypeMap.containsKey(resourceType)) {
resourceTypeMap.get(resourceType).put(resourceId, executeResult);
} else {
Map<String, String> map = new HashMap<>();
map.put(resourceId, executeResult);
resourceTypeMap.put(resourceType, map);
}
}
for (Map.Entry<String, String> entry : apiScenarioCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
String resourceType = TestPlanResourceType.SCENARIO_CASE.name();
if (resourceTypeMap.containsKey(resourceType)) {
resourceTypeMap.get(resourceType).put(resourceId, executeResult);
} else {
Map<String, String> map = new HashMap<>();
map.put(resourceId, executeResult);
resourceTypeMap.put(resourceType, map);
}
}
for (Map.Entry<String, String> entry : loadCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
String resourceType = TestPlanResourceType.PERFORMANCE_CASE.name();
if (resourceTypeMap.containsKey(resourceType)) {
resourceTypeMap.get(resourceType).put(resourceId, executeResult);
} else {
Map<String, String> map = new HashMap<>();
map.put(resourceId, executeResult);
resourceTypeMap.put(resourceType, map);
}
}
return resourceTypeMap;
}
public void finishAllTask() {
for (Map.Entry<String, String> entry : apiCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
if (StringUtils.equalsIgnoreCase(executeResult, TestPlanApiExecuteStatus.RUNNING.name())) {
apiCaseExecInfo.put(resourceId, TestPlanApiExecuteStatus.FAILD.name());
if (StringUtils.isNotEmpty(apiCaseExecuteThreadMap.get(resourceId))) {
JmeterThreadUtils.stop(apiCaseExecuteThreadMap.get(resourceId));
}
}
}
List<String> updateScenarioReportList = new ArrayList<>();
for (Map.Entry<String, String> entry : apiScenarioCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
if (StringUtils.equalsIgnoreCase(executeResult, TestPlanApiExecuteStatus.RUNNING.name())) {
apiScenarioCaseExecInfo.put(resourceId, TestPlanApiExecuteStatus.FAILD.name());
updateScenarioReportList.add(apiScenarioThreadMap.get(resourceId));
if (StringUtils.isNotEmpty(apiScenarioThreadMap.get(resourceId))) {
JmeterThreadUtils.stop(apiScenarioThreadMap.get(resourceId));
}
}
}
if (CollectionUtils.isNotEmpty(updateScenarioReportList)) {
ApiScenarioReportMapper apiScenarioReportMapper = CommonBeanFactory.getBean(ApiScenarioReportMapper.class);
ApiScenarioReportExample example = new ApiScenarioReportExample();
example.createCriteria().andIdIn(updateScenarioReportList).andStatusEqualTo("Running");
ApiScenarioReport report = new ApiScenarioReport();
report.setStatus("Error");
apiScenarioReportMapper.updateByExampleSelective(report, example);
}
for (Map.Entry<String, String> entry : loadCaseExecInfo.entrySet()) {
String resourceId = entry.getKey();
String executeResult = entry.getValue();
if (StringUtils.equalsIgnoreCase(executeResult, TestPlanApiExecuteStatus.RUNNING.name())) {
if (StringUtils.isNotEmpty(loadCaseReportIdMap.get(resourceId))) {
JmeterThreadUtils.stop(loadCaseReportIdMap.get(resourceId));
}
loadCaseExecInfo.put(resourceId, TestPlanApiExecuteStatus.FAILD.name());
}
}
this.countUnFinishedNum();
}
public synchronized void updateReport(Map<String, String> apiCaseExecResultInfo, Map<String, String> apiScenarioCaseExecResultInfo) {
if (MapUtils.isNotEmpty(apiCaseExecResultInfo)) {
this.apiCaseReportMap.putAll(apiCaseExecResultInfo);
}
if (MapUtils.isNotEmpty(apiScenarioCaseExecResultInfo)) {
this.apiScenarioReportMap.putAll(apiScenarioCaseExecResultInfo);
}
}
public Map<String, String> getRunningApiCaseReportMap() {
//key: reportId, value: testPlanApiCaseId
Map<String, String> returnMap = new HashMap<>();
for (Map.Entry<String, String> entry : apiCaseExecInfo.entrySet()) {
String planCaseId = entry.getKey();
String status = entry.getValue();
if (StringUtils.equalsIgnoreCase(status, TestPlanApiExecuteStatus.RUNNING.name())) {
if (apiCaseExecuteThreadMap.containsKey(planCaseId)) {
returnMap.put(apiCaseExecuteThreadMap.get(planCaseId), planCaseId);
}
}
}
return returnMap;
}
public Map<String, String> getRunningScenarioReportMap() {
//key: reportId, value: testPlanApiScenarioId
Map<String, String> returnMap = new HashMap<>();
for (Map.Entry<String, String> entry : apiScenarioCaseExecInfo.entrySet()) {
String planScenarioId = entry.getKey();
String status = entry.getValue();
if (StringUtils.equalsIgnoreCase(status, TestPlanApiExecuteStatus.RUNNING.name())) {
if (apiScenarioThreadMap.containsKey(planScenarioId)) {
returnMap.put(apiScenarioThreadMap.get(planScenarioId), planScenarioId);
}
}
}
return returnMap;
}
}

View File

@ -1,118 +0,0 @@
package io.metersphere.api.cache;
import io.metersphere.commons.constants.TestPlanApiExecuteStatus;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author song.tianyang
* @Date 2021/8/20 3:29 下午
*/
public class TestPlanReportExecuteCatch {
private static Logger testPlanLog = LoggerFactory.getLogger("testPlanExecuteLog");
private static Map<String, TestPlanExecuteInfo> testPlanReportMap = new HashMap<>();
private TestPlanReportExecuteCatch() {
}
public synchronized static void addApiTestPlanExecuteInfo(String reportId, String creator,
Map<String, String> apiCaseExecInfo, Map<String, String> apiScenarioCaseExecInfo, Map<String, String> loadCaseExecInfo) {
if (testPlanReportMap == null) {
testPlanReportMap = new HashMap<>();
}
if (apiCaseExecInfo == null) {
apiCaseExecInfo = new HashMap<>();
}
if (apiScenarioCaseExecInfo == null) {
apiScenarioCaseExecInfo = new HashMap<>();
}
if (loadCaseExecInfo == null) {
loadCaseExecInfo = new HashMap<>();
}
TestPlanExecuteInfo executeInfo = new TestPlanExecuteInfo(reportId, creator);
executeInfo.setApiCaseExecInfo(apiCaseExecInfo);
executeInfo.setApiScenarioCaseExecInfo(apiScenarioCaseExecInfo);
executeInfo.setLoadCaseExecInfo(loadCaseExecInfo);
testPlanReportMap.put(reportId, executeInfo);
}
public synchronized static String getCreator(String reportId) {
if (testPlanReportMap != null && testPlanReportMap.containsKey(reportId)) {
return testPlanReportMap.get(reportId).getCreator();
} else {
return null;
}
}
public synchronized static boolean containsReport(String reportId) {
if(StringUtils.isEmpty(reportId)){
return false;
}else {
return testPlanReportMap != null && testPlanReportMap.containsKey(reportId);
}
}
public synchronized static void updateApiTestPlanExecuteInfo(String reportId,
Map<String, String> apiCaseExecInfo, Map<String, String> apiScenarioCaseExecInfo, Map<String, String> loadCaseExecInfo) {
if (testPlanReportMap != null && testPlanReportMap.containsKey(reportId)) {
testPlanReportMap.get(reportId).updateExecuteInfo(apiCaseExecInfo, apiScenarioCaseExecInfo, loadCaseExecInfo);
}
}
public synchronized static void updateTestPlanThreadInfo(String reportId,
Map<String, String> apiCaseExecResultInfo, Map<String, String> apiScenarioCaseExecResultInfo, Map<String, String> loadCaseExecResultInfo) {
if (testPlanReportMap != null && testPlanReportMap.containsKey(reportId)) {
testPlanReportMap.get(reportId).updateThreadResult(apiCaseExecResultInfo, apiScenarioCaseExecResultInfo, loadCaseExecResultInfo);
}
}
public synchronized static void updateTestPlanReport(String reportId,
Map<String, String> apiCaseExecResultInfo, Map<String, String> apiScenarioCaseExecResultInfo) {
if (testPlanReportMap != null && testPlanReportMap.containsKey(reportId)) {
testPlanReportMap.get(reportId).updateReport(apiCaseExecResultInfo, apiScenarioCaseExecResultInfo);
}
}
public static TestPlanExecuteInfo getTestPlanExecuteInfo(String reportId) {
return testPlanReportMap.get(reportId);
}
public static synchronized void setReportDataCheckResult(String reportId, boolean result) {
if (testPlanReportMap.containsKey(reportId)) {
testPlanReportMap.get(reportId).setReportDataInDataBase(result);
}
}
public static synchronized void remove(String reportId) {
if (testPlanReportMap.containsKey(reportId)) {
testPlanReportMap.get(reportId).finishAllTask();
testPlanReportMap.remove(reportId);
}
}
public static void finishAllTask(String planReportId) {
testPlanLog.info("ReportId[" + planReportId + "] finish task!");
if (testPlanReportMap.containsKey(planReportId)) {
testPlanReportMap.get(planReportId).finishAllTask();
}
}
public static void set(String planReportId, List<String> executeErrorList) {
if (TestPlanReportExecuteCatch.containsReport(planReportId)) {
if (!executeErrorList.isEmpty()) {
Map<String, String> executeErrorMap = new HashMap<>();
for (String id : executeErrorList) {
executeErrorMap.put(id, TestPlanApiExecuteStatus.FAILD.name());
}
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(planReportId, executeErrorMap, null, null);
}
}
}
}

View File

@ -46,5 +46,7 @@ public class RunScenarioRequest {
//生成测试报告当isTestPlanScheduleJob为ture时使用 //生成测试报告当isTestPlanScheduleJob为ture时使用
private String testPlanReportId; private String testPlanReportId;
private String testPlanReportContentId;
private String requestOriginator; private String requestOriginator;
} }

View File

@ -33,9 +33,11 @@ public class SchedulePlanScenarioExecuteRequest {
private String reportUserID; private String reportUserID;
//key: test_plan.id, value: test_plan_api_scenario <->scenarioValue //key: test_plan.id, value: test_plan_api_scenario <->scenarioValue
private Map<String,Map<String,String>> testPlanScenarioIDMap; private Map<String, Map<String, String>> testPlanScenarioIDMap;
private String testPlanReportId; private String testPlanReportId;
private String planReportContentId;
private RunModeConfigDTO config; private RunModeConfigDTO config;
} }

View File

@ -17,8 +17,11 @@ public class BatchRunDefinitionRequest {
private RunModeConfigDTO config; private RunModeConfigDTO config;
private String userId;
//测试计划报告ID 测试计划执行时使用 //测试计划报告ID 测试计划执行时使用
private String planReportId; private String planReportId;
private String userId; private String planReportContentId;
} }

View File

@ -1,7 +1,6 @@
package io.metersphere.api.exec.api; package io.metersphere.api.exec.api;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.ApiCaseRunRequest; import io.metersphere.api.dto.ApiCaseRunRequest;
import io.metersphere.api.dto.definition.ApiTestCaseRequest; import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest; import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
@ -17,11 +16,13 @@ import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.RunModeConfigDTO; import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.service.EnvironmentGroupProjectService; import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -88,13 +89,12 @@ public class ApiCaseExecuteService {
List<MsExecResponseDTO> responseDTOS = new LinkedList<>(); List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>(); Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>();
//记录案例线程结果以及执行失败的案例ID Map<String, String> testPlanCaseIdAndReportIdMap = new HashMap<>();
Map<String, String> executeThreadIdMap = new HashMap<>();
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name(); String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
planApiCases.forEach(testPlanApiCase -> { planApiCases.forEach(testPlanApiCase -> {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, batchMapper); ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, batchMapper);
executeQueue.put(testPlanApiCase.getId(), report); executeQueue.put(testPlanApiCase.getId(), report);
executeThreadIdMap.put(testPlanApiCase.getId(), report.getId()); testPlanCaseIdAndReportIdMap.put(testPlanApiCase.getId(), report.getId());
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode())); responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
}); });
sqlSession.flushStatements(); sqlSession.flushStatements();
@ -109,10 +109,9 @@ public class ApiCaseExecuteService {
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap()); DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap());
//如果是测试计划生成报告的执行则更新执行信息执行线程信息 //如果是测试计划生成报告的执行则更新执行信息执行线程信息
if (TestPlanReportExecuteCatch.containsReport(request.getPlanReportId())) { if (StringUtils.isNotEmpty(request.getPlanReportContentId())) {
if (!executeThreadIdMap.isEmpty()) { TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(request.getPlanReportId(), executeThreadIdMap, null, null); testPlanReportService.updateTestPlanReportContentReportIds(request.getPlanReportContentId(),testPlanCaseIdAndReportIdMap,null,null);
}
} }
// 开始选择执行模式 // 开始选择执行模式
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {

View File

@ -1,7 +1,6 @@
package io.metersphere.api.exec.scenario; package io.metersphere.api.exec.scenario;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.EnvironmentType; import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.RunModeDataDTO; import io.metersphere.api.dto.RunModeDataDTO;
import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.APIScenarioReportResult;
@ -25,10 +24,7 @@ import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.FileUtils; import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.dto.MsExecResponseDTO;
@ -36,6 +32,7 @@ import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.plugin.core.MsTestElement; import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.service.EnvironmentGroupProjectService; import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.track.service.TestPlanScenarioCaseService; import io.metersphere.track.service.TestPlanScenarioCaseService;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.beanutils.BeanComparator;
@ -227,6 +224,7 @@ public class ApiScenarioExecuteService {
} }
String projectId = request.getProjectId(); String projectId = request.getProjectId();
Map<String, ApiScenarioWithBLOBs> scenarioMap = apiScenarios.stream().collect(Collectors.toMap(ApiScenarioWithBLOBs::getId, Function.identity(), (t1, t2) -> t1)); Map<String, ApiScenarioWithBLOBs> scenarioMap = apiScenarios.stream().collect(Collectors.toMap(ApiScenarioWithBLOBs::getId, Function.identity(), (t1, t2) -> t1));
Map<String, String> scenarioReportIdMap = new HashMap<>();
for (Map.Entry<String, String> entry : planScenarioIdMap.entrySet()) { for (Map.Entry<String, String> entry : planScenarioIdMap.entrySet()) {
String testPlanScenarioId = entry.getKey(); String testPlanScenarioId = entry.getKey();
String scenarioId = entry.getValue(); String scenarioId = entry.getValue();
@ -258,10 +256,8 @@ public class ApiScenarioExecuteService {
report = apiScenarioReportService.init(reportId, testPlanScenarioId, scenario.getName(), request.getTriggerMode(), report = apiScenarioReportService.init(reportId, testPlanScenarioId, scenario.getName(), request.getTriggerMode(),
request.getExecuteType(), projectId, request.getReportUserID(), request.getConfig(), scenario.getId()); request.getExecuteType(), projectId, request.getReportUserID(), request.getConfig(), scenario.getId());
if (report != null && StringUtils.isNotEmpty(request.getTestPlanReportId())) { if (report != null && StringUtils.isNotEmpty(request.getTestPlanReportContentId())) {
Map<String, String> scenarioReportIdMap = new HashMap<>();
scenarioReportIdMap.put(testPlanScenarioId, report.getId()); scenarioReportIdMap.put(testPlanScenarioId, report.getId());
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(request.getTestPlanReportId(), null, scenarioReportIdMap, null);
} }
scenarioIds.add(scenario.getId()); scenarioIds.add(scenario.getId());
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) { if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
@ -298,6 +294,10 @@ public class ApiScenarioExecuteService {
// 重置报告ID // 重置报告ID
reportId = UUID.randomUUID().toString(); reportId = UUID.randomUUID().toString();
} }
if(StringUtils.isNotEmpty(request.getTestPlanReportContentId())){
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
testPlanReportService.updateTestPlanReportContentReportIds(request.getTestPlanReportContentId(),null,scenarioReportIdMap,null);
}
} }
/** /**

View File

@ -1,39 +0,0 @@
package io.metersphere.api.exec.schedule;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.exec.queue.ExecThreadPoolExecutor;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TestPlanReportListenerScheduled {
/**
* 定时调用监听检查报告状态
*/
@Scheduled(cron = "*/9 * * * * ?")
public void testPlanScheduled() {
//判断缓冲队列是否存在记录
if (CollectionUtils.isNotEmpty(MessageCache.jobReportCache)) {
for (int i = 0; i < MessageCache.jobReportCache.size(); i++) {
this.listener(MessageCache.jobReportCache.get(i));
}
}
}
private void listener(String planReportId) {
if (TestPlanReportExecuteCatch.getTestPlanExecuteInfo(planReportId) != null) {
if (!CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).checkPlanReport(planReportId)) {
LoggerUtil.info("检查测试计划执行报告:【" + planReportId + "");
CommonBeanFactory.getBean(TestPlanReportService.class).countReport(planReportId);
}
} else {
MessageCache.jobReportCache.remove(planReportId);
LoggerUtil.info("测试计划执行报告:【" + planReportId + "】执行完成,剩余队列:" + MessageCache.jobReportCache.size());
}
}
}

View File

@ -2,7 +2,6 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult; import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
@ -229,7 +228,6 @@ public class ApiDefinitionExecResultService {
apiIdResultMap.put(dto.getReportId(), status); 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);
} }
/** /**

View File

@ -3,7 +3,6 @@ package io.metersphere.api.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.APIReportBatchRequest; import io.metersphere.api.dto.APIReportBatchRequest;
import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.DeleteAPIReportRequest;
import io.metersphere.api.dto.EnvironmentType; import io.metersphere.api.dto.EnvironmentType;
@ -103,7 +102,6 @@ public class ApiScenarioReportService {
this.put(dto.getReportId(), status); this.put(dto.getReportId(), status);
}}; }};
testPlanLog.info("TestPlanReportId" + JSONArray.toJSONString(dto.getReportId()) + " EXECUTE OVER. SCENARIO STATUS : " + JSONObject.toJSONString(reportMap)); 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;

View File

@ -37,5 +37,11 @@ public class TestPlanReportContentWithBLOBs extends TestPlanReportContent implem
private String loadFailureCases; private String loadFailureCases;
private String scenarioReportId;
private String apiCaseReportId;
private String loadCaseReportId;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -26,6 +26,9 @@
<result column="scenario_failure_cases" jdbcType="LONGVARCHAR" property="scenarioFailureCases" /> <result column="scenario_failure_cases" jdbcType="LONGVARCHAR" property="scenarioFailureCases" />
<result column="load_all_Cases" jdbcType="LONGVARCHAR" property="loadAllCases" /> <result column="load_all_Cases" jdbcType="LONGVARCHAR" property="loadAllCases" />
<result column="load_failure_cases" jdbcType="LONGVARCHAR" property="loadFailureCases" /> <result column="load_failure_cases" jdbcType="LONGVARCHAR" property="loadFailureCases" />
<result column="scenario_report_id" jdbcType="LONGVARCHAR" property="scenarioReportId" />
<result column="api_case_report_id" jdbcType="LONGVARCHAR" property="apiCaseReportId" />
<result column="load_case_report_id" jdbcType="LONGVARCHAR" property="loadCaseReportId" />
</resultMap> </resultMap>
<sql id="Example_Where_Clause"> <sql id="Example_Where_Clause">
<where> <where>
@ -92,7 +95,7 @@
<sql id="Blob_Column_List"> <sql id="Blob_Column_List">
config, summary, function_result, api_result, load_result, function_all_cases, function_failure_cases, config, summary, function_result, api_result, load_result, function_all_cases, function_failure_cases,
issue_list, api_all_cases, api_failure_cases, scenario_all_cases, scenario_failure_cases, issue_list, api_all_cases, api_failure_cases, scenario_all_cases, scenario_failure_cases,
load_all_Cases, load_failure_cases load_all_Cases, load_failure_cases, scenario_report_id, api_case_report_id, load_case_report_id
</sql> </sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.TestPlanReportContentExample" resultMap="ResultMapWithBLOBs"> <select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.TestPlanReportContentExample" resultMap="ResultMapWithBLOBs">
select select
@ -150,7 +153,9 @@
load_result, function_all_cases, function_failure_cases, load_result, function_all_cases, function_failure_cases,
issue_list, api_all_cases, api_failure_cases, issue_list, api_all_cases, api_failure_cases,
scenario_all_cases, scenario_failure_cases, scenario_all_cases, scenario_failure_cases,
load_all_Cases, load_failure_cases) load_all_Cases, load_failure_cases,
scenario_report_id, api_case_report_id,
load_case_report_id)
values (#{id,jdbcType=VARCHAR}, #{testPlanReportId,jdbcType=VARCHAR}, #{startTime,jdbcType=BIGINT}, values (#{id,jdbcType=VARCHAR}, #{testPlanReportId,jdbcType=VARCHAR}, #{startTime,jdbcType=BIGINT},
#{caseCount,jdbcType=BIGINT}, #{endTime,jdbcType=BIGINT}, #{executeRate,jdbcType=DOUBLE}, #{caseCount,jdbcType=BIGINT}, #{endTime,jdbcType=BIGINT}, #{executeRate,jdbcType=DOUBLE},
#{passRate,jdbcType=DOUBLE}, #{isThirdPartIssue,jdbcType=BIT}, #{config,jdbcType=LONGVARCHAR}, #{passRate,jdbcType=DOUBLE}, #{isThirdPartIssue,jdbcType=BIT}, #{config,jdbcType=LONGVARCHAR},
@ -158,7 +163,9 @@
#{loadResult,jdbcType=LONGVARCHAR}, #{functionAllCases,jdbcType=LONGVARCHAR}, #{functionFailureCases,jdbcType=LONGVARCHAR}, #{loadResult,jdbcType=LONGVARCHAR}, #{functionAllCases,jdbcType=LONGVARCHAR}, #{functionFailureCases,jdbcType=LONGVARCHAR},
#{issueList,jdbcType=LONGVARCHAR}, #{apiAllCases,jdbcType=LONGVARCHAR}, #{apiFailureCases,jdbcType=LONGVARCHAR}, #{issueList,jdbcType=LONGVARCHAR}, #{apiAllCases,jdbcType=LONGVARCHAR}, #{apiFailureCases,jdbcType=LONGVARCHAR},
#{scenarioAllCases,jdbcType=LONGVARCHAR}, #{scenarioFailureCases,jdbcType=LONGVARCHAR}, #{scenarioAllCases,jdbcType=LONGVARCHAR}, #{scenarioFailureCases,jdbcType=LONGVARCHAR},
#{loadAllCases,jdbcType=LONGVARCHAR}, #{loadFailureCases,jdbcType=LONGVARCHAR}) #{loadAllCases,jdbcType=LONGVARCHAR}, #{loadFailureCases,jdbcType=LONGVARCHAR},
#{scenarioReportId,jdbcType=LONGVARCHAR}, #{apiCaseReportId,jdbcType=LONGVARCHAR},
#{loadCaseReportId,jdbcType=LONGVARCHAR})
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlanReportContentWithBLOBs"> <insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlanReportContentWithBLOBs">
insert into test_plan_report_content insert into test_plan_report_content
@ -229,6 +236,15 @@
<if test="loadFailureCases != null"> <if test="loadFailureCases != null">
load_failure_cases, load_failure_cases,
</if> </if>
<if test="scenarioReportId != null">
scenario_report_id,
</if>
<if test="apiCaseReportId != null">
api_case_report_id,
</if>
<if test="loadCaseReportId != null">
load_case_report_id,
</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null"> <if test="id != null">
@ -297,6 +313,15 @@
<if test="loadFailureCases != null"> <if test="loadFailureCases != null">
#{loadFailureCases,jdbcType=LONGVARCHAR}, #{loadFailureCases,jdbcType=LONGVARCHAR},
</if> </if>
<if test="scenarioReportId != null">
#{scenarioReportId,jdbcType=LONGVARCHAR},
</if>
<if test="apiCaseReportId != null">
#{apiCaseReportId,jdbcType=LONGVARCHAR},
</if>
<if test="loadCaseReportId != null">
#{loadCaseReportId,jdbcType=LONGVARCHAR},
</if>
</trim> </trim>
</insert> </insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.TestPlanReportContentExample" resultType="java.lang.Long"> <select id="countByExample" parameterType="io.metersphere.base.domain.TestPlanReportContentExample" resultType="java.lang.Long">
@ -374,6 +399,15 @@
<if test="record.loadFailureCases != null"> <if test="record.loadFailureCases != null">
load_failure_cases = #{record.loadFailureCases,jdbcType=LONGVARCHAR}, load_failure_cases = #{record.loadFailureCases,jdbcType=LONGVARCHAR},
</if> </if>
<if test="record.scenarioReportId != null">
scenario_report_id = #{record.scenarioReportId,jdbcType=LONGVARCHAR},
</if>
<if test="record.apiCaseReportId != null">
api_case_report_id = #{record.apiCaseReportId,jdbcType=LONGVARCHAR},
</if>
<if test="record.loadCaseReportId != null">
load_case_report_id = #{record.loadCaseReportId,jdbcType=LONGVARCHAR},
</if>
</set> </set>
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
@ -402,7 +436,10 @@
scenario_all_cases = #{record.scenarioAllCases,jdbcType=LONGVARCHAR}, scenario_all_cases = #{record.scenarioAllCases,jdbcType=LONGVARCHAR},
scenario_failure_cases = #{record.scenarioFailureCases,jdbcType=LONGVARCHAR}, scenario_failure_cases = #{record.scenarioFailureCases,jdbcType=LONGVARCHAR},
load_all_Cases = #{record.loadAllCases,jdbcType=LONGVARCHAR}, load_all_Cases = #{record.loadAllCases,jdbcType=LONGVARCHAR},
load_failure_cases = #{record.loadFailureCases,jdbcType=LONGVARCHAR} load_failure_cases = #{record.loadFailureCases,jdbcType=LONGVARCHAR},
scenario_report_id = #{record.scenarioReportId,jdbcType=LONGVARCHAR},
api_case_report_id = #{record.apiCaseReportId,jdbcType=LONGVARCHAR},
load_case_report_id = #{record.loadCaseReportId,jdbcType=LONGVARCHAR}
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
</if> </if>
@ -487,6 +524,15 @@
<if test="loadFailureCases != null"> <if test="loadFailureCases != null">
load_failure_cases = #{loadFailureCases,jdbcType=LONGVARCHAR}, load_failure_cases = #{loadFailureCases,jdbcType=LONGVARCHAR},
</if> </if>
<if test="scenarioReportId != null">
scenario_report_id = #{scenarioReportId,jdbcType=LONGVARCHAR},
</if>
<if test="apiCaseReportId != null">
api_case_report_id = #{apiCaseReportId,jdbcType=LONGVARCHAR},
</if>
<if test="loadCaseReportId != null">
load_case_report_id = #{loadCaseReportId,jdbcType=LONGVARCHAR},
</if>
</set> </set>
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
</update> </update>
@ -512,7 +558,10 @@
scenario_all_cases = #{scenarioAllCases,jdbcType=LONGVARCHAR}, scenario_all_cases = #{scenarioAllCases,jdbcType=LONGVARCHAR},
scenario_failure_cases = #{scenarioFailureCases,jdbcType=LONGVARCHAR}, scenario_failure_cases = #{scenarioFailureCases,jdbcType=LONGVARCHAR},
load_all_Cases = #{loadAllCases,jdbcType=LONGVARCHAR}, load_all_Cases = #{loadAllCases,jdbcType=LONGVARCHAR},
load_failure_cases = #{loadFailureCases,jdbcType=LONGVARCHAR} load_failure_cases = #{loadFailureCases,jdbcType=LONGVARCHAR},
scenario_report_id = #{scenarioReportId,jdbcType=LONGVARCHAR},
api_case_report_id = #{apiCaseReportId,jdbcType=LONGVARCHAR},
load_case_report_id = #{loadCaseReportId,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
</update> </update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestPlanReportContent"> <update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestPlanReportContent">

View File

@ -74,7 +74,7 @@ public class ShareController {
@GetMapping("/test/plan/report/{shareId}/{planId}") @GetMapping("/test/plan/report/{shareId}/{planId}")
public TestPlanSimpleReportDTO getReport(@PathVariable String shareId, @PathVariable String planId) { public TestPlanSimpleReportDTO getReport(@PathVariable String shareId, @PathVariable String planId) {
shareInfoService.validate(shareId, planId); shareInfoService.validate(shareId, planId);
return testPlanService.getReport(planId); return testPlanService.getReport(planId, null);
} }
@GetMapping("/report/export/{shareId}/{planId}") @GetMapping("/report/export/{shareId}/{planId}")

View File

@ -0,0 +1,16 @@
package io.metersphere.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.Map;
@Getter
@Setter
@AllArgsConstructor
public class TestPlanExecuteReportDTO {
private Map<String,String> testPlanApiCaseIdAndReportIdMap;
private Map<String,String> testPlanScenarioIdAndReportIdMap;
private Map<String,String> testPlanLoadCaseIdAndReportIdMap;
}

View File

@ -128,8 +128,8 @@ public class TestPlanController {
@PostMapping("/edit/follows/{planId}") @PostMapping("/edit/follows/{planId}")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_PLAN_READ_EDIT) @RequiresPermissions(PermissionConstants.PROJECT_TRACK_PLAN_READ_EDIT)
public void editTestFollows(@PathVariable String planId,@RequestBody List<String> follows) { public void editTestFollows(@PathVariable String planId, @RequestBody List<String> follows) {
testPlanService.editTestFollows(planId,follows); testPlanService.editTestFollows(planId, follows);
} }
@PostMapping("/delete/{testPlanId}") @PostMapping("/delete/{testPlanId}")
@ -232,7 +232,7 @@ public class TestPlanController {
@GetMapping("/report/{planId}") @GetMapping("/report/{planId}")
public TestPlanSimpleReportDTO getReport(@PathVariable String planId) { public TestPlanSimpleReportDTO getReport(@PathVariable String planId) {
return testPlanService.getReport(planId); return testPlanService.getReport(planId, null);
} }
@GetMapping("/report/functional/result") @GetMapping("/report/functional/result")

View File

@ -12,6 +12,7 @@ import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.notice.annotation.SendNotice; import io.metersphere.notice.annotation.SendNotice;
import io.metersphere.track.dto.TestPlanReportDTO; import io.metersphere.track.dto.TestPlanReportDTO;
import io.metersphere.track.dto.TestPlanScheduleReportInfoDTO;
import io.metersphere.track.dto.TestPlanSimpleReportDTO; import io.metersphere.track.dto.TestPlanSimpleReportDTO;
import io.metersphere.track.request.report.QueryTestPlanReportRequest; import io.metersphere.track.request.report.QueryTestPlanReportRequest;
import io.metersphere.track.request.report.TestPlanReportSaveRequest; import io.metersphere.track.request.report.TestPlanReportSaveRequest;
@ -82,8 +83,8 @@ public class TestPlanReportController {
public void apiExecuteFinish(@PathVariable String planId, @PathVariable String userId) { public void apiExecuteFinish(@PathVariable String planId, @PathVariable String userId) {
String reportId = UUID.randomUUID().toString(); String reportId = UUID.randomUUID().toString();
TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(reportId, planId, userId, ReportTriggerMode.API.name()); TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(reportId, planId, userId, ReportTriggerMode.API.name());
TestPlanReport report = testPlanReportService.genTestPlanReport(saveRequest); TestPlanScheduleReportInfoDTO report = testPlanReportService.genTestPlanReport(saveRequest);
testPlanReportService.countReportByTestPlanReportId(report.getId(), null, ReportTriggerMode.API.name(), null); testPlanReportService.countReportByTestPlanReportId(report.getTestPlanReport().getId(), null, ReportTriggerMode.API.name());
} }
@GetMapping("/saveTestPlanReport/{planId}/{triggerMode}") @GetMapping("/saveTestPlanReport/{planId}/{triggerMode}")
@ -91,8 +92,8 @@ public class TestPlanReportController {
String userId = SessionUtils.getUser().getId(); String userId = SessionUtils.getUser().getId();
String reportId = UUID.randomUUID().toString(); String reportId = UUID.randomUUID().toString();
TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(reportId, planId, userId, triggerMode); TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(reportId, planId, userId, triggerMode);
TestPlanReport report = testPlanReportService.genTestPlanReport(saveRequest); TestPlanScheduleReportInfoDTO report = testPlanReportService.genTestPlanReport(saveRequest);
testPlanReportService.countReportByTestPlanReportId(report.getId(), null, triggerMode, null); testPlanReportService.countReportByTestPlanReportId(report.getTestPlanReport().getId(), null, triggerMode);
return "success"; return "success";
} }
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.track.dto; package io.metersphere.track.dto;
import io.metersphere.base.domain.TestPlanReport; import io.metersphere.base.domain.TestPlanReport;
import io.metersphere.base.domain.TestPlanReportContent;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -15,6 +16,7 @@ import java.util.Map;
@Setter @Setter
public class TestPlanScheduleReportInfoDTO { public class TestPlanScheduleReportInfoDTO {
private TestPlanReport testPlanReport; private TestPlanReport testPlanReport;
private TestPlanReportContent testPlanReportContent;
private Map<String, String> planScenarioIdMap = new LinkedHashMap<>(); private Map<String, String> planScenarioIdMap = new LinkedHashMap<>();
private Map<String, String> apiTestCaseDataMap = new LinkedHashMap<>(); private Map<String, String> apiTestCaseDataMap = new LinkedHashMap<>();
private Map<String, String> performanceIdMap = new LinkedHashMap<>(); private Map<String, String> performanceIdMap = new LinkedHashMap<>();

View File

@ -412,14 +412,11 @@ public class TestPlanApiCaseService {
testPlanApiCaseMapper::updateByPrimaryKeySelective); testPlanApiCaseMapper::updateByPrimaryKeySelective);
} }
public List<TestPlanFailureApiDTO> getByApiExecReportIds(Map<String, String> testPlanApiCaseReportMap, boolean isFinish) { public List<TestPlanFailureApiDTO> getByApiExecReportIds(Map<String, String> testPlanApiCaseReportMap) {
if (testPlanApiCaseReportMap.isEmpty()) { if (testPlanApiCaseReportMap.isEmpty()) {
return new ArrayList<>(); return new ArrayList<>();
} }
String defaultStatus = "Running"; String defaultStatus = "error";
if (isFinish) {
defaultStatus = "error";
}
List<TestPlanFailureApiDTO> apiTestCases = extTestPlanApiCaseMapper.getFailureListByIds(testPlanApiCaseReportMap.keySet(), null); List<TestPlanFailureApiDTO> apiTestCases = extTestPlanApiCaseMapper.getFailureListByIds(testPlanApiCaseReportMap.keySet(), null);
Map<String, String> reportResult = apiDefinitionExecResultService.selectReportResultByReportIds(testPlanApiCaseReportMap.values()); Map<String, String> reportResult = apiDefinitionExecResultService.selectReportResultByReportIds(testPlanApiCaseReportMap.values());
for (TestPlanFailureApiDTO dto : apiTestCases) { for (TestPlanFailureApiDTO dto : apiTestCases) {

View File

@ -3,22 +3,16 @@ package io.metersphere.track.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.cache.TestPlanExecuteInfo;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanFailureApiDTO; import io.metersphere.api.dto.automation.TestPlanFailureApiDTO;
import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO; import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
import io.metersphere.api.service.ShareInfoService; import io.metersphere.api.service.ShareInfoService;
import io.metersphere.api.exec.utils.NamedThreadFactory;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.*; import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.dto.BaseSystemConfigDTO; import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.TestPlanExecuteReportDTO;
import io.metersphere.dto.UserDTO; import io.metersphere.dto.UserDTO;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.OperatingLogDetails;
@ -27,7 +21,6 @@ import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.service.ProjectService; import io.metersphere.service.ProjectService;
import io.metersphere.service.SystemParameterService; import io.metersphere.service.SystemParameterService;
import io.metersphere.service.UserService; import io.metersphere.service.UserService;
import io.metersphere.track.domain.ReportResultComponent;
import io.metersphere.track.dto.*; import io.metersphere.track.dto.*;
import io.metersphere.track.request.report.QueryTestPlanReportRequest; import io.metersphere.track.request.report.QueryTestPlanReportRequest;
import io.metersphere.track.request.report.TestPlanReportSaveRequest; import io.metersphere.track.request.report.TestPlanReportSaveRequest;
@ -45,8 +38,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -63,10 +54,6 @@ public class TestPlanReportService {
@Resource @Resource
TestPlanReportMapper testPlanReportMapper; TestPlanReportMapper testPlanReportMapper;
@Resource @Resource
ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
TestPlanReportDataMapper testPlanReportDataMapper; TestPlanReportDataMapper testPlanReportDataMapper;
@Resource @Resource
ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper; ExtTestPlanScenarioCaseMapper extTestPlanScenarioCaseMapper;
@ -80,14 +67,6 @@ public class TestPlanReportService {
ExtTestPlanMapper extTestPlanMapper; ExtTestPlanMapper extTestPlanMapper;
@Resource @Resource
ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper; ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
@Resource
ExtApiScenarioReportMapper extApiScenarioReportMapper;
@Resource
LoadTestReportMapper loadTestReportMapper;
@Resource
TestPlanLoadCaseMapper testPlanLoadCaseMapper;
@Lazy @Lazy
@Resource @Resource
TestPlanService testPlanService; TestPlanService testPlanService;
@ -103,8 +82,6 @@ public class TestPlanReportService {
@Resource @Resource
private ProjectService projectService; private ProjectService projectService;
private final ExecutorService executorService = Executors.newFixedThreadPool(20, new NamedThreadFactory("TestPlanReportService"));
public List<TestPlanReportDTO> list(QueryTestPlanReportRequest request) { public List<TestPlanReportDTO> list(QueryTestPlanReportRequest request) {
List<TestPlanReportDTO> list = new ArrayList<>(); List<TestPlanReportDTO> list = new ArrayList<>();
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
@ -171,9 +148,7 @@ public class TestPlanReportService {
TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, planId, userId, triggerMode, TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, planId, userId, triggerMode,
planTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0, planTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0,
apiCaseInfoMap, scenarioInfoMap, performanceInfoMap); apiCaseInfoMap, scenarioInfoMap, performanceInfoMap);
TestPlanReport report = this.genTestPlanReport(saveRequest); TestPlanScheduleReportInfoDTO returnDTO = this.genTestPlanReport(saveRequest);
TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO();
returnDTO.setTestPlanReport(report);
returnDTO.setPlanScenarioIdMap(planScenarioIdMap); returnDTO.setPlanScenarioIdMap(planScenarioIdMap);
returnDTO.setApiTestCaseDataMap(planTestCaseIdMap); returnDTO.setApiTestCaseDataMap(planTestCaseIdMap);
returnDTO.setPerformanceIdMap(performanceIdMap); returnDTO.setPerformanceIdMap(performanceIdMap);
@ -190,7 +165,7 @@ public class TestPlanReportService {
* saveRequest.scenarioIsExecuting 场景案例是否执行中 * saveRequest.scenarioIsExecuting 场景案例是否执行中
* saveRequest.performanceIsExecuting 性能案例是否执行中 * saveRequest.performanceIsExecuting 性能案例是否执行中
*/ */
public TestPlanReport genTestPlanReport(TestPlanReportSaveRequest saveRequest) { public TestPlanScheduleReportInfoDTO genTestPlanReport(TestPlanReportSaveRequest saveRequest) {
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(saveRequest.getPlanId()); TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(saveRequest.getPlanId());
String testPlanReportID = saveRequest.getReportID(); String testPlanReportID = saveRequest.getReportID();
TestPlanReport testPlanReport = new TestPlanReport(); TestPlanReport testPlanReport = new TestPlanReport();
@ -219,10 +194,6 @@ public class TestPlanReportService {
testPlanReportContent.setEndTime(System.currentTimeMillis()); testPlanReportContent.setEndTime(System.currentTimeMillis());
} }
Map<String, String> apiCaseInfoMap = new HashMap<>();
Map<String, String> scenarioInfoMap = new HashMap<>();
Map<String, String> performanceInfoMap = new HashMap<>();
if (saveRequest.isCountResources()) { if (saveRequest.isCountResources()) {
List<TestPlanApiCase> testPlanApiCaseList = extTestPlanApiCaseMapper.selectLegalDataByTestPlanId(saveRequest.getPlanId()); List<TestPlanApiCase> testPlanApiCaseList = extTestPlanApiCaseMapper.selectLegalDataByTestPlanId(saveRequest.getPlanId());
List<String> apiCaseIdList = testPlanApiCaseList.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList()); List<String> apiCaseIdList = testPlanApiCaseList.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
@ -238,28 +209,12 @@ public class TestPlanReportService {
List<String> performanceIdList = extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(loadCaseRequest) List<String> performanceIdList = extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(loadCaseRequest)
.stream().map(TestPlanLoadCaseDTO::getLoadCaseId).collect(Collectors.toList()); .stream().map(TestPlanLoadCaseDTO::getLoadCaseId).collect(Collectors.toList());
testPlanReport.setIsPerformanceExecuting(!performanceIdList.isEmpty()); testPlanReport.setIsPerformanceExecuting(!performanceIdList.isEmpty());
for (String id : apiCaseIdList) {
apiCaseInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name());
}
for (String id : scenarioIdList) {
scenarioInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name());
}
for (String id : performanceIdList) {
performanceInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name());
}
} else { } else {
testPlanReport.setIsApiCaseExecuting(saveRequest.isApiCaseIsExecuting()); testPlanReport.setIsApiCaseExecuting(saveRequest.isApiCaseIsExecuting());
testPlanReport.setIsScenarioExecuting(saveRequest.isScenarioIsExecuting()); testPlanReport.setIsScenarioExecuting(saveRequest.isScenarioIsExecuting());
testPlanReport.setIsPerformanceExecuting(saveRequest.isPerformanceIsExecuting()); testPlanReport.setIsPerformanceExecuting(saveRequest.isPerformanceIsExecuting());
apiCaseInfoMap = saveRequest.getApiCaseIdMap();
scenarioInfoMap = saveRequest.getScenarioIdMap();
performanceInfoMap = saveRequest.getPerformanceIdMap();
} }
TestPlanReportExecuteCatch.addApiTestPlanExecuteInfo(testPlanReportID, saveRequest.getUserId(), apiCaseInfoMap, scenarioInfoMap, performanceInfoMap);
if (testPlanReport.getIsScenarioExecuting() || testPlanReport.getIsApiCaseExecuting() || testPlanReport.getIsPerformanceExecuting()) { if (testPlanReport.getIsScenarioExecuting() || testPlanReport.getIsApiCaseExecuting() || testPlanReport.getIsPerformanceExecuting()) {
testPlanReport.setStatus(TestPlanReportStatus.RUNNING.name()); testPlanReport.setStatus(TestPlanReportStatus.RUNNING.name());
} else { } else {
@ -272,7 +227,11 @@ public class TestPlanReportService {
//更新TestPlan状态改为进行中 //更新TestPlan状态改为进行中
testPlan.setStatus(TestPlanStatus.Underway.name()); testPlan.setStatus(TestPlanStatus.Underway.name());
testPlanMapper.updateByPrimaryKeySelective(testPlan); testPlanMapper.updateByPrimaryKeySelective(testPlan);
return testPlanReport;
TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO();
returnDTO.setTestPlanReport(testPlanReport);
returnDTO.setTestPlanReportContent(testPlanReportContent);
return returnDTO;
} }
public TestPlanReportDTO getMetric(String reportId) { public TestPlanReportDTO getMetric(String reportId) {
@ -343,258 +302,48 @@ public class TestPlanReportService {
public synchronized void updateReport(List<String> testPlanReportIdList, String runMode, String triggerMode) { public synchronized void updateReport(List<String> testPlanReportIdList, String runMode, String triggerMode) {
for (String planReportId : testPlanReportIdList) { for (String planReportId : testPlanReportIdList) {
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode, null); this.countReportByTestPlanReportId(planReportId, runMode, triggerMode);
} }
} }
public synchronized void updateReportByScenarioIdList(List<String> testPlanReportIdList, String runMode, String triggerMode, List<String> scenarioIdList) { public TestPlanReportContentWithBLOBs updateReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs reportContent) {
for (String planReportId : testPlanReportIdList) { if (testPlanReport == null) {
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode, scenarioIdList);
}
}
public TestCaseReportMetricDTO countReportData(TestPlanDTO testPlan, Map<String, Map<String, String>> executeResult) {
TestCaseReportMetricDTO returnDTO = new TestCaseReportMetricDTO();
ReportResultComponent reportResultComponent = new ReportResultComponent(testPlan);
reportResultComponent.afterBuild(returnDTO);
TestCaseReportAdvanceStatusResultDTO statusDTO = new TestCaseReportAdvanceStatusResultDTO();
Map<String, String> apiCaseExecuteMap = executeResult.get(TestPlanResourceType.API_CASE.name());
Map<String, String> scenarioExecuteMap = executeResult.get(TestPlanResourceType.SCENARIO_CASE.name());
Map<String, String> performanceCaseExecuteMap = executeResult.get(TestPlanResourceType.PERFORMANCE_CASE.name());
List<TestCaseReportStatusResultDTO> apiResult = new ArrayList<>();
List<TestCaseReportStatusResultDTO> scenarioResult = new ArrayList<>();
List<TestCaseReportStatusResultDTO> loadResult = new ArrayList<>();
List<String> faliureApiCaseIdList = new ArrayList<>();
List<String> faliureScenarioCaseIdList = new ArrayList<>();
List<String> faliureLoadCaseIdList = new ArrayList<>();
if (MapUtils.isNotEmpty(apiCaseExecuteMap)) {
Map<String, Integer> countMap = new HashMap<>();
for (Map.Entry<String, String> executeEntry : apiCaseExecuteMap.entrySet()) {
String caseResult = executeEntry.getValue();
String id = executeEntry.getKey();
if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.FAILD.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.PREPARE.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
apiResult.add(dto);
}
}
if (MapUtils.isNotEmpty(scenarioExecuteMap)) {
Map<String, Integer> countMap = new HashMap<>();
for (Map.Entry<String, String> executeEntry : scenarioExecuteMap.entrySet()) {
String caseResult = executeEntry.getValue();
String id = executeEntry.getKey();
if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.FAILD.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.PREPARE.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
scenarioResult.add(dto);
}
}
if (MapUtils.isNotEmpty(performanceCaseExecuteMap)) {
Map<String, Integer> countMap = new HashMap<>();
for (Map.Entry<String, String> executeEntry : performanceCaseExecuteMap.entrySet()) {
String caseResult = executeEntry.getValue();
String id = executeEntry.getKey();
if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.FAILD.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(caseResult, TestPlanApiExecuteStatus.PREPARE.name())) {
faliureApiCaseIdList.add(id);
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
loadResult.add(dto);
}
}
statusDTO.setApiResult(apiResult);
statusDTO.setScenarioResult(scenarioResult);
statusDTO.setLoadResult(loadResult);
returnDTO.setExecuteResult(statusDTO);
//统计失败用例
FailureTestCasesAdvanceDTO failureDto = new FailureTestCasesAdvanceDTO();
failureDto.setFunctionalTestCases(new ArrayList<>());
if (!faliureApiCaseIdList.isEmpty()) {
TestPlanApiCaseService testPlanApiCaseService = CommonBeanFactory.getBean(TestPlanApiCaseService.class);
ApiTestCaseRequest request = new ApiTestCaseRequest();
request.setPlanId(testPlan.getId());
request.setIds(faliureApiCaseIdList);
List<TestPlanApiCaseDTO> testPlanApiCaseDTOList = testPlanApiCaseService.list(request);
failureDto.setApiTestCases(testPlanApiCaseDTOList);
} else {
failureDto.setApiTestCases(new ArrayList<>());
}
if (!faliureScenarioCaseIdList.isEmpty()) {
TestPlanScenarioCaseService testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
TestPlanScenarioRequest request = new TestPlanScenarioRequest();
request.setPlanId(testPlan.getId());
request.setScenarioIds(faliureScenarioCaseIdList);
List<ApiScenarioDTO> scenarioDTOS = testPlanScenarioCaseService.list(request);
failureDto.setScenarioTestCases(scenarioDTOS);
} else {
failureDto.setScenarioTestCases(new ArrayList<>());
}
if (!faliureLoadCaseIdList.isEmpty()) {
TestPlanLoadCaseService testPlanLoadCaseService = CommonBeanFactory.getBean(TestPlanLoadCaseService.class);
LoadCaseRequest request = new LoadCaseRequest();
request.setTestPlanId(testPlan.getId());
request.setIds(faliureLoadCaseIdList);
List<TestPlanLoadCaseDTO> loadDTOs = testPlanLoadCaseService.list(request);
failureDto.setLoadTestCases(loadDTOs);
} else {
failureDto.setLoadTestCases(new ArrayList<>());
}
returnDTO.setFailureTestCases(failureDto);
return returnDTO;
}
public TestPlanReport updateReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs reportContent, TestPlanExecuteInfo executeInfo) {
if (testPlanReport == null || executeInfo == null) {
return null; return null;
} }
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
TestPlanSimpleReportDTO reportDTO = testPlanService.buildPlanReport(testPlanReport, reportContent);
reportDTO.setStartTime(testPlanReport.getStartTime());
reportContent = parseReportDaoToReportContent(reportDTO, reportContent);
testPlanReportContentMapper.updateByPrimaryKeySelective(reportContent);
testPlanReportMapper.updateByPrimaryKey(testPlanReport);
boolean apiCaseIsOk = executeInfo.isApiCaseAllExecuted(); return reportContent;
boolean scenarioIsOk = executeInfo.isScenarioAllExecuted(); }
boolean performanceIsOk = executeInfo.isLoadCaseAllExecuted();
if (apiCaseIsOk) {
testPlanReport.setIsApiCaseExecuting(false);
}
if (scenarioIsOk) {
testPlanReport.setIsScenarioExecuting(false);
}
if (performanceIsOk) {
testPlanReport.setIsPerformanceExecuting(false);
}
public TestPlanReport finishedTestPlanReport(String testPlanReportId) {
TestPlanReport testPlanReport = this.getTestPlanReport(testPlanReportId);
//初始化测试计划包含组件信息
int[] componentIndexArr = new int[]{1, 3, 4}; int[] componentIndexArr = new int[]{1, 3, 4};
testPlanReport.setComponents(JSONArray.toJSONString(componentIndexArr)); testPlanReport.setComponents(JSONArray.toJSONString(componentIndexArr));
//计算测试计划状态
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class); String testPlanStatus = this.getTestPlanReportStatus(testPlanReport, null);
Map<String, Map<String, String>> testPlanExecuteResult = executeInfo.getExecutedResult();
testPlanLog.info("ReportId[" + testPlanReport.getId() + "] COUNT OVER. COUNT RESULT :" + JSONObject.toJSONString(testPlanExecuteResult));
TestPlanSimpleReportDTO reportDTO = testPlanService.buildPlanReport(executeInfo, testPlanReport.getTestPlanId(), apiCaseIsOk && scenarioIsOk && performanceIsOk);
reportDTO.setStartTime(testPlanReport.getStartTime());
long endTime = System.currentTimeMillis();
//全部结束时更新时间
if (apiCaseIsOk && scenarioIsOk && performanceIsOk) {
reportDTO.setEndTime(endTime);
//如果测试案例没有未结束的功能用例则更新最后结束日期
TestPlanTestCaseMapper testPlanTestCaseMapper = CommonBeanFactory.getBean(TestPlanTestCaseMapper.class);
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlanReport.getTestPlanId()).andStatusNotEqualTo("Prepare");
long testCaseCount = testPlanTestCaseMapper.countByExample(testPlanTestCaseExample);
boolean updateTestPlanTime = testCaseCount > 0;
if (updateTestPlanTime) {
testPlanReport.setEndTime(endTime);
testPlanReport.setUpdateTime(endTime);
}
TestPlanReportExecuteCatch.remove(testPlanReport.getId());
testPlanLog.info("Task is finish. Remove listener:" + testPlanReport.getId());
}
testPlanReportContentMapper.updateByPrimaryKeySelective(parseReportDaoToReportContent(reportDTO, reportContent));
String testPlanStatus = this.getTestPlanReportStatus(testPlanReport, reportDTO);
testPlanReport.setStatus(testPlanStatus); testPlanReport.setStatus(testPlanStatus);
//如果测试案例没有未结束的功能用例则更新最后结束日期
TestPlanTestCaseMapper testPlanTestCaseMapper = CommonBeanFactory.getBean(TestPlanTestCaseMapper.class);
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlanReport.getTestPlanId()).andStatusNotEqualTo("Prepare");
long endTime = System.currentTimeMillis();
long testCaseCount = testPlanTestCaseMapper.countByExample(testPlanTestCaseExample);
boolean updateTestPlanTime = testCaseCount > 0;
if (updateTestPlanTime) {
testPlanReport.setEndTime(endTime);
testPlanReport.setUpdateTime(endTime);
}
//更新测试计划并发送通知
testPlanReport.setIsApiCaseExecuting(false);
testPlanReport.setIsScenarioExecuting(false);
testPlanReport.setIsPerformanceExecuting(false);
testPlanReport = this.update(testPlanReport); testPlanReport = this.update(testPlanReport);
return testPlanReport; return testPlanReport;
} }
@ -604,7 +353,7 @@ public class TestPlanReportService {
* @param resourceRunMode 资源的运行模式,triggerMode非Scedule可以为null * @param resourceRunMode 资源的运行模式,triggerMode非Scedule可以为null
* @param triggerMode 触发方式 ReportTriggerMode.enum * @param triggerMode 触发方式 ReportTriggerMode.enum
*/ */
public void countReportByTestPlanReportId(String planReportId, String resourceRunMode, String triggerMode, List<String> scenarioIdList) { public void countReportByTestPlanReportId(String planReportId, String resourceRunMode, String triggerMode) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId); TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId);
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest(); QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
@ -656,8 +405,10 @@ public class TestPlanReportService {
public TestPlanReportContentWithBLOBs parseReportDaoToReportContent(TestPlanSimpleReportDTO reportDTO, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) { public TestPlanReportContentWithBLOBs parseReportDaoToReportContent(TestPlanSimpleReportDTO reportDTO, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) {
String id = testPlanReportContentWithBLOBs.getId(); String id = testPlanReportContentWithBLOBs.getId();
String testPlanReportId = testPlanReportContentWithBLOBs.getTestPlanReportId();
BeanUtils.copyBean(testPlanReportContentWithBLOBs, reportDTO); BeanUtils.copyBean(testPlanReportContentWithBLOBs, reportDTO);
testPlanReportContentWithBLOBs.setId(id); testPlanReportContentWithBLOBs.setId(id);
testPlanReportContentWithBLOBs.setTestPlanReportId(testPlanReportId);
if (reportDTO.getFunctionResult() != null) { if (reportDTO.getFunctionResult() != null) {
testPlanReportContentWithBLOBs.setFunctionResult(JSONObject.toJSONString(reportDTO.getFunctionResult())); testPlanReportContentWithBLOBs.setFunctionResult(JSONObject.toJSONString(reportDTO.getFunctionResult()));
} }
@ -730,49 +481,6 @@ public class TestPlanReportService {
return status; return status;
} }
private String getTestPlanReportStatus(TestPlanReport testPlanReport, TestPlanReportDataWithBLOBs testPlanReportData) {
String status = TestPlanReportStatus.COMPLETED.name();
if (testPlanReport != null) {
if (testPlanReport.getIsApiCaseExecuting() || testPlanReport.getIsPerformanceExecuting() || testPlanReport.getIsScenarioExecuting()) {
status = TestPlanReportStatus.RUNNING.name();
} else {
if (testPlanReportData != null) {
String failCaseString = testPlanReportData.getFailurTestCases();
status = TestPlanReportStatus.SUCCESS.name();
try {
JSONObject failurCaseObject = JSONObject.parseObject(failCaseString);
if (failurCaseObject.containsKey("apiTestCases") && failurCaseObject.getJSONArray("apiTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("apiTestCases");
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
}
if (failurCaseObject.containsKey("loadTestCases") && failurCaseObject.getJSONArray("loadTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("loadTestCases");
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
}
if (failurCaseObject.containsKey("scenarioTestCases") && failurCaseObject.getJSONArray("scenarioTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("scenarioTestCases");
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
}
} catch (Exception e) {
status = TestPlanReportStatus.FAILED.name();
}
} else {
status = TestPlanReportStatus.COMPLETED.name();
}
}
}
return status;
}
public TestPlanReport update(TestPlanReport report) { public TestPlanReport update(TestPlanReport report) {
if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting()) if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting())
try { try {
@ -868,88 +576,6 @@ public class TestPlanReportService {
return testPlanReportMapper.selectByPrimaryKey(planId); return testPlanReportMapper.selectByPrimaryKey(planId);
} }
/**
* 更新TestPlanReportData的PerformanceInfo
*
* @param testPlanReport
*/
public void updatePerformanceInfo(TestPlanReport testPlanReport, Map<String, String> performaneReportIDMap, String triggerMode) {
/**
* 虽然kafka已经设置了topic推送但是当执行机器性能不够时会影响到报告状态当修改
* 同时如果执行过程中报告删除那么此时也应当记为失败
*/
Map<String, String> finishLoadTestId = new HashMap<>();
Map<String, String> caseReportMap = new HashMap<>();
executorService.submit(() -> {
//错误数据检查集合 如果错误数据出现超过20次则取消该条数据的检查
Map<String, Integer> errorDataCheckMap = new HashMap<>();
List<String> performaneReportIDList = new ArrayList<>(performaneReportIDMap.keySet());
while (performaneReportIDList.size() > 0) {
List<String> selectList = new ArrayList<>(performaneReportIDList);
testPlanLog.info("TestPlanReportId[" + testPlanReport.getId() + "] SELECT performance BATCH START:" + JSONArray.toJSONString(selectList));
for (String loadTestReportId : selectList) {
try {
LoadTestReportWithBLOBs loadTestReportFromDatabase = loadTestReportMapper.selectByPrimaryKey(loadTestReportId);
if (loadTestReportFromDatabase == null) {
testPlanLog.info("TestPlanReportId[" + testPlanReport.getId() + "] SELECT performance ID:" + loadTestReportId + ",RESULT IS NULL");
//检查错误数据
if (errorDataCheckMap.containsKey(loadTestReportId)) {
if (errorDataCheckMap.get(loadTestReportId) > 10) {
performaneReportIDList.remove(loadTestReportId);
if (performaneReportIDMap.containsKey(loadTestReportId)) {
finishLoadTestId.put(performaneReportIDMap.get(loadTestReportId), TestPlanLoadCaseStatus.error.name());
caseReportMap.put(performaneReportIDMap.get(loadTestReportId), loadTestReportId);
}
} else {
errorDataCheckMap.put(loadTestReportId, errorDataCheckMap.get(loadTestReportId) + 1);
}
} else {
errorDataCheckMap.put(loadTestReportId, 1);
}
} else {
testPlanLog.info("TestPlanReportId[" + testPlanReport.getId() + "] SELECT performance ID:" + loadTestReportId + ",RESULT :" + loadTestReportFromDatabase.getStatus());
if (StringUtils.equalsAny(loadTestReportFromDatabase.getStatus(),
PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
finishLoadTestId.put(performaneReportIDMap.get(loadTestReportId), TestPlanLoadCaseStatus.success.name());
caseReportMap.put(performaneReportIDMap.get(loadTestReportId), loadTestReportId);
performaneReportIDList.remove(loadTestReportId);
}
}
} catch (Exception e) {
performaneReportIDList.remove(loadTestReportId);
finishLoadTestId.put(performaneReportIDMap.get(loadTestReportId), TestPlanLoadCaseStatus.error.name());
caseReportMap.put(performaneReportIDMap.get(loadTestReportId), loadTestReportId);
testPlanLog.error(e.getMessage());
}
}
testPlanLog.info("TestPlanReportId[" + testPlanReport.getId() + "] SELECT performance BATCH OVER:" + JSONArray.toJSONString(selectList));
if (performaneReportIDList.isEmpty()) {
testPlanLog.info("TestPlanReportId[" + testPlanReport.getId() + "] performance EXECUTE OVER. TRIGGER_MODE:" + triggerMode + ",REsult:" + JSONObject.toJSONString(finishLoadTestId));
if (StringUtils.equalsAnyIgnoreCase(triggerMode, ReportTriggerMode.API.name() ,ReportTriggerMode.MANUAL.name())) {
for (String string : finishLoadTestId.keySet()) {
String reportId = caseReportMap.get(string);
TestPlanLoadCaseWithBLOBs updateDTO = new TestPlanLoadCaseWithBLOBs();
updateDTO.setId(string);
updateDTO.setStatus(finishLoadTestId.get(string));
updateDTO.setLoadReportId(reportId);
testPlanLoadCaseMapper.updateByPrimaryKeySelective(updateDTO);
}
}
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(testPlanReport.getId(), null, null, finishLoadTestId);
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(testPlanReport.getId(), null, null, caseReportMap);
} else {
try {
//查询定时任务是否关闭
Thread.sleep(1000 * 10);// 检查 loadtest 的状态
} catch (InterruptedException e) {
}
}
}
return true;
});
}
public void updatePerformanceTestStatus(TestPlanLoadCaseEventDTO eventDTO) { public void updatePerformanceTestStatus(TestPlanLoadCaseEventDTO eventDTO) {
List<String> testPlanReportId = extTestPlanMapper.findIdByPerformanceReportId(eventDTO.getReportId()); List<String> testPlanReportId = extTestPlanMapper.findIdByPerformanceReportId(eventDTO.getReportId());
if (StringUtils.equals(eventDTO.getTriggerMode(), ReportTriggerMode.API.name())) { if (StringUtils.equals(eventDTO.getTriggerMode(), ReportTriggerMode.API.name())) {
@ -1028,44 +654,6 @@ public class TestPlanReportService {
return null; return null;
} }
public synchronized TestPlanReport updateExecuteApis(String planReportId) {
TestPlanExecuteInfo executeInfo = TestPlanReportExecuteCatch.getTestPlanExecuteInfo(planReportId);
if (executeInfo == null) {
return null;
}
Map<String, String> executeApiCaseIdMap = executeInfo.getApiCaseExecInfo();
Map<String, String> executeScenarioCaseIdMap = executeInfo.getApiScenarioCaseExecInfo();
Map<String, String> executePerformanceIdMap = executeInfo.getLoadCaseExecInfo();
if (executeApiCaseIdMap == null) {
executeApiCaseIdMap = new HashMap<>();
}
if (executeScenarioCaseIdMap == null) {
executeScenarioCaseIdMap = new HashMap<>();
}
if (executePerformanceIdMap == null) {
executePerformanceIdMap = new HashMap<>();
}
testPlanLog.info("ReportId[" + planReportId + "] Executed. api :" + JSONObject.toJSONString(executeApiCaseIdMap) + "; scenario:" + JSONObject.toJSONString(executeScenarioCaseIdMap) + "; performance:" + JSONObject.toJSONString(executePerformanceIdMap));
TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(planReportId);
List<TestPlanReportContentWithBLOBs> reportDataList = testPlanReportContentMapper.selectByExampleWithBLOBs(example);
TestPlanReport report = null;
if (!reportDataList.isEmpty()) {
TestPlanReportExecuteCatch.setReportDataCheckResult(planReportId, true);
TestPlanReportContentWithBLOBs reportData = reportDataList.get(0);
report = testPlanReportMapper.selectByPrimaryKey(planReportId);
report = this.updateReport(report, reportData, executeInfo);
} else {
TestPlanReportExecuteCatch.setReportDataCheckResult(planReportId, false);
}
return report;
}
public void deleteByPlanId(String planId) { public void deleteByPlanId(String planId) {
TestPlanReportExample example = new TestPlanReportExample(); TestPlanReportExample example = new TestPlanReportExample();
example.createCriteria().andTestPlanIdEqualTo(planId); example.createCriteria().andTestPlanIdEqualTo(planId);
@ -1077,19 +665,6 @@ public class TestPlanReportService {
this.delete(testPlanReportIdList); this.delete(testPlanReportIdList);
} }
public void countReport(String planReportId) {
TestPlanReportExecuteCheckResultDTO checkResult = this.checkTestPlanReportIsTimeOut(planReportId);
testPlanLog.info("Check PlanReport:" + planReportId + "; result: "+ JSON.toJSONString(checkResult));
if (checkResult.isTimeOut()) {
//判断是否超时超时时强行停止任务
TestPlanReportExecuteCatch.finishAllTask(planReportId);
checkResult.setFinishedCaseChanged(true);
}
if(checkResult.isFinishedCaseChanged()){
this.updateExecuteApis(planReportId);
}
}
public TestPlanSimpleReportDTO getReport(String reportId) { public TestPlanSimpleReportDTO getReport(String reportId) {
TestPlanReportContentExample example = new TestPlanReportContentExample(); TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(reportId); example.createCriteria().andTestPlanReportIdEqualTo(reportId);
@ -1098,8 +673,12 @@ public class TestPlanReportService {
return null; return null;
} }
TestPlanReportContentWithBLOBs testPlanReportContent = testPlanReportContents.get(0); TestPlanReportContentWithBLOBs testPlanReportContent = testPlanReportContents.get(0);
//更新测试报告对应的最后执行结果 if (testPlanReportContent == null) {
this.updateReportExecResult(testPlanReportContent); return null;
}
if (this.isDynamicallyGenerateReports(testPlanReportContent)) {
testPlanReportContent = this.dynamicallyGenerateReports(testPlanReportContent);
}
TestPlanSimpleReportDTO testPlanReportDTO = new TestPlanSimpleReportDTO(); TestPlanSimpleReportDTO testPlanReportDTO = new TestPlanSimpleReportDTO();
BeanUtils.copyBean(testPlanReportDTO, testPlanReportContent); BeanUtils.copyBean(testPlanReportDTO, testPlanReportContent);
if (StringUtils.isNotBlank(testPlanReportContent.getFunctionResult())) { if (StringUtils.isNotBlank(testPlanReportContent.getFunctionResult())) {
@ -1144,149 +723,65 @@ public class TestPlanReportService {
return testPlanReportDTO; return testPlanReportDTO;
} }
private void updateReportExecResult(TestPlanReportContentWithBLOBs testPlanReportContent) { private boolean isDynamicallyGenerateReports(TestPlanReportContentWithBLOBs testPlanReportContent) {
boolean isUpdate = false; return testPlanReportContent != null &&
boolean isTaskRunning = false; (StringUtils.isNotEmpty(testPlanReportContent.getApiCaseReportId()) || StringUtils.isNotEmpty(testPlanReportContent.getApiCaseReportId()) || StringUtils.isNotEmpty(testPlanReportContent.getApiCaseReportId()));
boolean reportHasData = false;
if (StringUtils.isNotBlank(testPlanReportContent.getApiAllCases())) {
reportHasData = true;
List<TestPlanFailureApiDTO> allCases = JSONObject.parseArray(testPlanReportContent.getApiAllCases(), TestPlanFailureApiDTO.class);
for (TestPlanFailureApiDTO dto : allCases) {
String status = dto.getExecResult();
if (StringUtils.equalsAnyIgnoreCase(status, "Running", "Waiting")) {
isUpdate = true;
ApiDefinitionExecResult definitionExecResult = apiDefinitionExecResultMapper.selectByPrimaryKey(dto.getReportId());
if (definitionExecResult != null) {
dto.setExecResult(definitionExecResult.getStatus());
}
}
if (StringUtils.equalsAnyIgnoreCase(dto.getExecResult(), "Running", "Waiting")) {
isTaskRunning = true;
}
}
testPlanReportContent.setApiAllCases(JSONArray.toJSONString(allCases));
}
if (StringUtils.isNotBlank(testPlanReportContent.getScenarioAllCases())) {
reportHasData = true;
List<TestPlanFailureScenarioDTO> allCases = JSONObject.parseArray(testPlanReportContent.getScenarioAllCases(), TestPlanFailureScenarioDTO.class);
for (TestPlanFailureScenarioDTO dto : allCases) {
String lastResult = dto.getLastResult();
if (StringUtils.equalsAnyIgnoreCase(lastResult, "Running", "Waiting", "Underway")) {
isUpdate = true;
ApiScenarioReport apiReport = apiScenarioReportMapper.selectByPrimaryKey(dto.getReportId());
if (apiReport != null) {
dto.setLastResult(apiReport.getStatus());
dto.setStatus(apiReport.getStatus());
}
} else if (StringUtils.equalsAnyIgnoreCase("Error", lastResult)) {
isUpdate = true;
dto.setLastResult("Fail");
dto.setStatus("Fail");
}
if (StringUtils.equalsAnyIgnoreCase(dto.getLastResult(), "Running", "Waiting", "Underway")) {
isTaskRunning = true;
}
}
testPlanReportContent.setScenarioAllCases(JSONArray.toJSONString(allCases));
}
if (StringUtils.isNotBlank(testPlanReportContent.getLoadAllCases())) {
List<TestPlanLoadCaseDTO> allCases = JSONObject.parseArray(testPlanReportContent.getLoadAllCases(), TestPlanLoadCaseDTO.class);
if(!allCases.isEmpty()){
isTaskRunning = true;
}
}
if (isUpdate) {
testPlanReportContentMapper.updateByPrimaryKeyWithBLOBs(testPlanReportContent);
}
if (!isTaskRunning && reportHasData) {
this.finishTestPlanReport(testPlanReportContent.getTestPlanReportId());
}
} }
public void finishReport(TestPlanReport testPlanReport) { private TestPlanReportContentWithBLOBs dynamicallyGenerateReports(TestPlanReportContentWithBLOBs testPlanReportContent) {
long endTime = System.currentTimeMillis(); TestPlanReport report = testPlanReportMapper.selectByPrimaryKey(testPlanReportContent.getTestPlanReportId());
testPlanReport.setEndTime(endTime); testPlanReportContent = this.updateReport(report, testPlanReportContent);
testPlanReport.setUpdateTime(endTime); return testPlanReportContent;
testPlanReport.setStatus(TestPlanReportStatus.FAILED.name());
testPlanReportMapper.updateByPrimaryKeySelective(testPlanReport);
TestPlanReportContentWithBLOBs bloBs = new TestPlanReportContentWithBLOBs();
bloBs.setEndTime(endTime);
TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(testPlanReport.getId());
testPlanReportContentMapper.updateByExampleSelective(bloBs,example);
} }
private TestPlanReportExecuteCheckResultDTO checkTestPlanReportIsTimeOut(String planReportId) { public synchronized void updateTestPlanReportContentReportIds(String testPlanReportContentId, Map<String, String> apiCaseReportMap, Map<String, String> scenarioReportIdMap, Map<String, String> loadCaseReportIdMap) {
//同步数据库更新状态信息 if (StringUtils.isNotEmpty(testPlanReportContentId)) {
try { TestPlanReportContentWithBLOBs content = new TestPlanReportContentWithBLOBs();
this.syncReportStatus(planReportId); content.setId(testPlanReportContentId);
} catch (Exception e) {
LogUtil.info("联动数据库同步执行状态失败! " + e.getMessage());
LogUtil.error(e);
}
TestPlanExecuteInfo executeInfo = TestPlanReportExecuteCatch.getTestPlanExecuteInfo(planReportId);
TestPlanReportExecuteCheckResultDTO checkResult = executeInfo.countUnFinishedNum();
return checkResult;
}
private void syncReportStatus(String planReportId) { if (MapUtils.isNotEmpty(apiCaseReportMap)) {
if (TestPlanReportExecuteCatch.containsReport(planReportId)) { content.setApiCaseReportId(JSONObject.toJSONString(apiCaseReportMap));
TestPlanExecuteInfo executeInfo = TestPlanReportExecuteCatch.getTestPlanExecuteInfo(planReportId); }
if (executeInfo != null) { if (MapUtils.isNotEmpty(scenarioReportIdMap)) {
//同步接口案例结果 content.setScenarioReportId(JSONObject.toJSONString(scenarioReportIdMap));
Map<String, String> updateCaseStatusMap = new HashMap<>(); }
Map<String, String> apiCaseReportMap = executeInfo.getRunningApiCaseReportMap(); if (MapUtils.isNotEmpty(loadCaseReportIdMap)) {
if (MapUtils.isNotEmpty(apiCaseReportMap)) { content.setLoadCaseReportId(JSONObject.toJSONString(loadCaseReportIdMap));
List<ApiDefinitionExecResult> execList = extApiDefinitionExecResultMapper.selectStatusByIdList(apiCaseReportMap.keySet()); }
for (ApiDefinitionExecResult report : execList) {
String reportId = report.getId(); if (StringUtils.isNotEmpty(content.getApiCaseReportId()) || StringUtils.isNotEmpty(content.getScenarioReportId()) || StringUtils.isNotEmpty(content.getLoadCaseReportId())) {
String status = report.getStatus(); testPlanReportContentMapper.updateByPrimaryKeySelective(content);
if (!StringUtils.equalsAnyIgnoreCase(status, "Running", "Waiting")) {
String planCaseId = apiCaseReportMap.get(reportId);
if (StringUtils.isNotEmpty(planCaseId)) {
updateCaseStatusMap.put(planCaseId, status);
}
}
}
}
//同步场景结果
Map<String, String> updateScenarioStatusMap = new HashMap<>();
Map<String, String> scenarioReportMap = executeInfo.getRunningScenarioReportMap();
if (MapUtils.isNotEmpty(scenarioReportMap)) {
List<ApiScenarioReport> reportList = extApiScenarioReportMapper.selectStatusByIds(scenarioReportMap.keySet());
for (ApiScenarioReport report : reportList) {
String reportId = report.getId();
String status = report.getStatus();
if (!StringUtils.equalsAnyIgnoreCase(status, "Running", "Waiting")) {
String planScenarioId = scenarioReportMap.get(reportId);
if (StringUtils.isNotEmpty(planScenarioId)) {
updateScenarioStatusMap.put(planScenarioId, status);
}
}
}
}
testPlanLog.info("ReportID:"+planReportId+" 本次数据库同步,案例ID"+JSON.toJSONString(apiCaseReportMap.keySet())+";场景ID"+JSON.toJSONString(scenarioReportMap.keySet())+"; 同步结果,案例:"+JSON.toJSONString(updateCaseStatusMap)+";场景:"+JSON.toJSONString(updateScenarioStatusMap));
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(planReportId, updateCaseStatusMap, updateScenarioStatusMap, null);
}else {
testPlanLog.info("同步数据库查询执行信息失败! 报告ID在缓存中未找到"+planReportId);
} }
} }
} }
private void finishTestPlanReport(String planReportId) { public TestPlanExecuteReportDTO genTestPlanExecuteReportDTOByTestPlanReportContent(TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId); Map<String, String> testPlanApiCaseIdAndReportIdMap = new HashMap<>();
if (testPlanReport != null && StringUtils.equalsIgnoreCase("Running", testPlanReport.getStatus())) { Map<String, String> testPlanScenarioIdAndReportIdMap = new HashMap<>();
this.finishReport(testPlanReport); Map<String, String> testPlanLoadCaseIdAndReportIdMap = new HashMap<>();
testPlanLog.info("结束测试计划报告:[" + planReportId + "]");
if (testPlanReportContentWithBLOBs != null) {
if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getApiCaseReportId())) {
try {
testPlanApiCaseIdAndReportIdMap = JSONObject.parseObject(testPlanReportContentWithBLOBs.getApiCaseReportId(), Map.class);
} catch (Exception ignore) {
}
}
if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getScenarioReportId())) {
try {
testPlanScenarioIdAndReportIdMap = JSONObject.parseObject(testPlanReportContentWithBLOBs.getScenarioReportId(), Map.class);
} catch (Exception ignore) {
}
}
if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getLoadCaseReportId())) {
try {
testPlanLoadCaseIdAndReportIdMap = JSONObject.parseObject(testPlanReportContentWithBLOBs.getLoadCaseReportId(), Map.class);
} catch (Exception ignore) {
}
}
} }
TestPlanReportExecuteCatch.remove(planReportId); TestPlanExecuteReportDTO returnDTO = new TestPlanExecuteReportDTO(testPlanApiCaseIdAndReportIdMap, testPlanScenarioIdAndReportIdMap, testPlanLoadCaseIdAndReportIdMap);
return returnDTO;
} }
public void cleanUpReport(long time, String projectId) { public void cleanUpReport(long time, String projectId) {

View File

@ -509,14 +509,11 @@ public class TestPlanScenarioCaseService {
return buildCases(apiTestCases); return buildCases(apiTestCases);
} }
public List<TestPlanFailureScenarioDTO> getAllCases(Map<String,String> idMap, boolean isFinish) { public List<TestPlanFailureScenarioDTO> getAllCases(Map<String,String> idMap) {
List<TestPlanFailureScenarioDTO> apiTestCases = List<TestPlanFailureScenarioDTO> apiTestCases =
extTestPlanScenarioCaseMapper.getFailureListByIds(idMap.keySet(), null); extTestPlanScenarioCaseMapper.getFailureListByIds(idMap.keySet(), null);
String defaultStatus = "Running"; String defaultStatus = "Fail";
if(isFinish){
defaultStatus = "Fail";
}
Map<String,String> reportStatus = apiScenarioReportService.getReportStatusByReportIds(idMap.values()); Map<String,String> reportStatus = apiScenarioReportService.getReportStatusByReportIds(idMap.values());
for (TestPlanFailureScenarioDTO dto: apiTestCases) { for (TestPlanFailureScenarioDTO dto: apiTestCases) {
String reportId = idMap.get(dto.getId()); String reportId = idMap.get(dto.getId());

View File

@ -8,8 +8,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.metersphere.api.cache.TestPlanExecuteInfo;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.APIReportResult; import io.metersphere.api.dto.APIReportResult;
import io.metersphere.api.dto.EnvironmentType; import io.metersphere.api.dto.EnvironmentType;
import io.metersphere.api.dto.automation.*; import io.metersphere.api.dto.automation.*;
@ -21,8 +19,6 @@ import io.metersphere.api.dto.definition.request.MsScenario;
import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.MsTestPlan;
import io.metersphere.api.dto.definition.request.MsThreadGroup; import io.metersphere.api.dto.definition.request.MsThreadGroup;
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.MessageCache;
import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.ApiDefinitionService;
import io.metersphere.api.service.ApiScenarioReportService; import io.metersphere.api.service.ApiScenarioReportService;
@ -134,8 +130,6 @@ public class TestPlanService {
@Resource @Resource
private TestPlanLoadCaseService testPlanLoadCaseService; private TestPlanLoadCaseService testPlanLoadCaseService;
@Resource @Resource
private JMeterService jMeterService;
@Resource
private ApiAutomationService apiAutomationService; private ApiAutomationService apiAutomationService;
@Resource @Resource
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper; private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@ -151,8 +145,6 @@ public class TestPlanService {
@Resource @Resource
private ApiTestCaseMapper apiTestCaseMapper; private ApiTestCaseMapper apiTestCaseMapper;
@Resource @Resource
private ApiDefinitionMapper apiDefinitionMapper;
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper; private TestPlanApiCaseMapper testPlanApiCaseMapper;
@Resource @Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper; private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@ -953,7 +945,6 @@ public class TestPlanService {
public List<MsExecResponseDTO> scenarioRunModeConfig(SchedulePlanScenarioExecuteRequest planScenarioExecuteRequest) { public List<MsExecResponseDTO> scenarioRunModeConfig(SchedulePlanScenarioExecuteRequest planScenarioExecuteRequest) {
Map<String, Map<String, String>> testPlanScenarioIdMap = planScenarioExecuteRequest.getTestPlanScenarioIDMap(); Map<String, Map<String, String>> testPlanScenarioIdMap = planScenarioExecuteRequest.getTestPlanScenarioIDMap();
List<MsExecResponseDTO> list = new LinkedList<>(); List<MsExecResponseDTO> list = new LinkedList<>();
String returnStr = null;
for (Map.Entry<String, Map<String, String>> entry : testPlanScenarioIdMap.entrySet()) { for (Map.Entry<String, Map<String, String>> entry : testPlanScenarioIdMap.entrySet()) {
Map<String, String> scenarioMap = entry.getValue(); Map<String, String> scenarioMap = entry.getValue();
@ -969,6 +960,7 @@ public class TestPlanService {
request.setConfig(planScenarioExecuteRequest.getConfig()); request.setConfig(planScenarioExecuteRequest.getConfig());
request.setTestPlanScheduleJob(true); request.setTestPlanScheduleJob(true);
request.setTestPlanReportId(planScenarioExecuteRequest.getTestPlanReportId()); request.setTestPlanReportId(planScenarioExecuteRequest.getTestPlanReportId());
request.setTestPlanReportContentId(planScenarioExecuteRequest.getPlanReportContentId());
request.setId(UUID.randomUUID().toString()); request.setId(UUID.randomUUID().toString());
request.setProjectId(planScenarioExecuteRequest.getProjectId()); request.setProjectId(planScenarioExecuteRequest.getProjectId());
request.setRequestOriginator("TEST_PLAN"); request.setRequestOriginator("TEST_PLAN");
@ -1066,101 +1058,38 @@ public class TestPlanService {
runModeConfig.setEnvMap(new HashMap<>()); runModeConfig.setEnvMap(new HashMap<>());
} }
} }
//创建测试报告然后返回的ID重新赋值为resourceID作为后续的参数 //创建测试报告然后返回的ID重新赋值为resourceID作为后续的参数
TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(projectID, testPlanID, userId, triggerMode); TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(projectID, testPlanID, userId, triggerMode);
TestPlanReport testPlanReport = reportInfoDTO.getTestPlanReport();
Map<String, String> planScenarioIdsMap = reportInfoDTO.getPlanScenarioIdMap(); //测试计划准备执行取消测试计划的实际结束时间
Map<String, String> planApiCaseMap = reportInfoDTO.getApiTestCaseDataMap();
Map<String, String> performanceIdMap = reportInfoDTO.getPerformanceIdMap();
extTestPlanMapper.updateActualEndTimeIsNullById(testPlanID); extTestPlanMapper.updateActualEndTimeIsNullById(testPlanID);
String planReportId = testPlanReport.getId();
String planReportId = reportInfoDTO.getTestPlanReport().getId();
testPlanLog.info("ReportId[" + planReportId + "] created. TestPlanID:[" + testPlanID + "]. " + "API Run Config:【" + apiRunConfig + ""); testPlanLog.info("ReportId[" + planReportId + "] created. TestPlanID:[" + testPlanID + "]. " + "API Run Config:【" + apiRunConfig + "");
//开启测试计划执行状态的监听
MessageCache.jobReportCache.add(planReportId);
//不同任务的执行ID
Map<String, String> executePerformanceIdMap = new HashMap<>();
Map<String, String> executeApiCaseIdMap = new HashMap<>();
Map<String, String> executeScenarioCaseIdMap = new HashMap<>();
//执行性能测试任务
Map<String, String> performaneReportIDMap = new LinkedHashMap<>();
Map<String, String> performaneThreadIDMap = new LinkedHashMap<>();
for (Map.Entry<String, String> entry : performanceIdMap.entrySet()) {
String id = entry.getKey();
String caseID = entry.getValue();
RunTestPlanRequest performanceRequest = new RunTestPlanRequest();
performanceRequest.setId(caseID);
performanceRequest.setTestPlanLoadId(id);
if (StringUtils.isNotBlank(runModeConfig.getResourcePoolId())) {
performanceRequest.setTestResourcePoolId(runModeConfig.getResourcePoolId());
}
if (StringUtils.equals(ReportTriggerMode.API.name(), triggerMode)) {
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_API.name());
} else if (StringUtils.equals(ReportTriggerMode.MANUAL.name(), triggerMode)) {
performanceRequest.setTriggerMode(ReportTriggerMode.MANUAL.name());
} else {
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_SCHEDULE.name());
}
String reportId = null;
try {
reportId = performanceTestService.run(performanceRequest);
if (reportId != null) {
performaneReportIDMap.put(reportId, id);
//更新关联处的报告
TestPlanLoadCaseWithBLOBs loadCase = new TestPlanLoadCaseDTO();
loadCase.setId(id);
loadCase.setLoadReportId(reportId);
loadCase.setStatus(TestPlanLoadCaseStatus.run.name());
testPlanLoadCaseService.update(loadCase);
}
} catch (Exception e) {
TestPlanLoadCaseWithBLOBs testPlanLoadCase = new TestPlanLoadCaseWithBLOBs();
testPlanLoadCase.setId(id);
testPlanLoadCase.setLoadReportId(reportId);
testPlanLoadCase.setStatus(TestPlanLoadCaseStatus.error.name());
testPlanLoadCaseService.update(testPlanLoadCase);
LogUtil.error(e);
}
if (StringUtils.isNotEmpty(reportId)) {
performaneThreadIDMap.put(performanceRequest.getTestPlanLoadId(), reportId);
executePerformanceIdMap.put(performanceRequest.getTestPlanLoadId(), TestPlanApiExecuteStatus.RUNNING.name());
} else {
executePerformanceIdMap.put(performanceRequest.getTestPlanLoadId(), TestPlanApiExecuteStatus.PREPARE.name());
}
}
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(planReportId, null, null, performaneThreadIDMap);
if (!performaneReportIDMap.isEmpty()) {
//性能测试时保存性能测试报告ID在结果返回时用于捕捉并进行
testPlanReportService.updatePerformanceInfo(testPlanReport, performaneReportIDMap, triggerMode);
}
for (Map.Entry<String, String> entry : planApiCaseMap.entrySet()) {
String id = entry.getKey();
executeApiCaseIdMap.put(id, TestPlanApiExecuteStatus.RUNNING.name());
}
for (String id : planScenarioIdsMap.keySet()) {
executeScenarioCaseIdMap.put(id, TestPlanApiExecuteStatus.RUNNING.name());
}
testPlanLog.info("ReportId[" + planReportId + "] start run. TestPlanID:[" + testPlanID + "]. Execute api :" + JSONObject.toJSONString(executeApiCaseIdMap) + "; Execute scenario:" + JSONObject.toJSONString(executeScenarioCaseIdMap) + "; Execute performance:" + JSONObject.toJSONString(executePerformanceIdMap));
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(planReportId, executeApiCaseIdMap, executeScenarioCaseIdMap, executePerformanceIdMap);
//执行接口案例任务 //执行接口案例任务
this.executeApiTestCase(triggerMode, planReportId, userId, new ArrayList<>(planApiCaseMap.keySet()), runModeConfig); this.executeApiTestCase(triggerMode, planReportId, reportInfoDTO.getTestPlanReportContent().getId(), userId, new ArrayList<>(reportInfoDTO.getApiTestCaseDataMap().keySet()), runModeConfig);
//执行场景执行任务 //执行场景执行任务
this.executeScenarioCase(planReportId, testPlanID, projectID, runModeConfig, triggerMode, userId, planScenarioIdsMap); this.executeScenarioCase(planReportId, reportInfoDTO.getTestPlanReportContent().getId(), testPlanID, projectID, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap());
return testPlanReport.getId(); //执行性能测试任务
this.executeLoadCaseTask(runModeConfig, triggerMode, reportInfoDTO.getPerformanceIdMap(), reportInfoDTO.getTestPlanReportContent().getId());
return planReportId;
} }
private void executeApiTestCase(String triggerMode, String planReportId, String userId, List<String> planCaseIds, RunModeConfigDTO runModeConfig) { private void executeApiTestCase(String triggerMode, String planReportId, String reportContentId, String userId, List<String> planCaseIds, RunModeConfigDTO runModeConfig) {
BatchRunDefinitionRequest request = new BatchRunDefinitionRequest(); BatchRunDefinitionRequest request = new BatchRunDefinitionRequest();
request.setTriggerMode(triggerMode); request.setTriggerMode(triggerMode);
request.setPlanIds(planCaseIds); request.setPlanIds(planCaseIds);
request.setPlanReportId(planReportId); request.setPlanReportId(planReportId);
request.setConfig(runModeConfig); request.setConfig(runModeConfig);
request.setUserId(userId); request.setUserId(userId);
request.setPlanReportContentId(reportContentId);
testPlanApiCaseService.run(request); testPlanApiCaseService.run(request);
} }
private void executeScenarioCase(String planReportId, String testPlanID, String projectID, RunModeConfigDTO runModeConfig, String triggerMode, String userId, Map<String, String> planScenarioIdMap) { private void executeScenarioCase(String planReportId, String reportContentId, String testPlanID, String projectID, RunModeConfigDTO runModeConfig, String triggerMode, String userId, Map<String, String> planScenarioIdMap) {
if (!planScenarioIdMap.isEmpty()) { if (!planScenarioIdMap.isEmpty()) {
SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest(); SchedulePlanScenarioExecuteRequest scenarioRequest = new SchedulePlanScenarioExecuteRequest();
String senarionReportID = UUID.randomUUID().toString(); String senarionReportID = UUID.randomUUID().toString();
@ -1183,14 +1112,57 @@ public class TestPlanService {
scenarioRequest.setTestPlanScenarioIDMap(testPlanScenarioIdMap); scenarioRequest.setTestPlanScenarioIDMap(testPlanScenarioIdMap);
scenarioRequest.setReportUserID(userId); scenarioRequest.setReportUserID(userId);
scenarioRequest.setTestPlanID(testPlanID); scenarioRequest.setTestPlanID(testPlanID);
scenarioRequest.setTestPlanReportId(planReportId); scenarioRequest.setTestPlanReportId(planReportId);
scenarioRequest.setPlanReportContentId(reportContentId);
scenarioRequest.setConfig(runModeConfig); scenarioRequest.setConfig(runModeConfig);
this.scenarioRunModeConfig(scenarioRequest); this.scenarioRunModeConfig(scenarioRequest);
} }
} }
private void executeLoadCaseTask(RunModeConfigDTO runModeConfig, String triggerMode, Map<String, String> performanceIdMap, String reportContentId) {
Map<String, String> loadCaseReportMap = new HashMap<>();
for (Map.Entry<String, String> entry : performanceIdMap.entrySet()) {
String id = entry.getKey();
String caseID = entry.getValue();
RunTestPlanRequest performanceRequest = new RunTestPlanRequest();
performanceRequest.setId(caseID);
performanceRequest.setTestPlanLoadId(id);
if (StringUtils.isNotBlank(runModeConfig.getResourcePoolId())) {
performanceRequest.setTestResourcePoolId(runModeConfig.getResourcePoolId());
}
if (StringUtils.equals(ReportTriggerMode.API.name(), triggerMode)) {
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_API.name());
} else if (StringUtils.equals(ReportTriggerMode.MANUAL.name(), triggerMode)) {
performanceRequest.setTriggerMode(ReportTriggerMode.MANUAL.name());
} else {
performanceRequest.setTriggerMode(ReportTriggerMode.TEST_PLAN_SCHEDULE.name());
}
String reportId = null;
try {
reportId = performanceTestService.run(performanceRequest);
if (reportId != null) {
loadCaseReportMap.put(id, reportId);
//更新关联处的报告
TestPlanLoadCaseWithBLOBs loadCase = new TestPlanLoadCaseDTO();
loadCase.setId(id);
loadCase.setLoadReportId(reportId);
loadCase.setStatus(TestPlanLoadCaseStatus.run.name());
testPlanLoadCaseService.update(loadCase);
}
} catch (Exception e) {
TestPlanLoadCaseWithBLOBs testPlanLoadCase = new TestPlanLoadCaseWithBLOBs();
testPlanLoadCase.setId(id);
testPlanLoadCase.setLoadReportId(reportId);
testPlanLoadCase.setStatus(TestPlanLoadCaseStatus.error.name());
testPlanLoadCaseService.update(testPlanLoadCase);
LogUtil.error(e);
}
}
testPlanReportService.updateTestPlanReportContentReportIds(reportContentId, null, null, loadCaseReportMap);
}
public String getLogDetails(String id) { public String getLogDetails(String id) {
TestPlan plan = testPlanMapper.selectByPrimaryKey(id); TestPlan plan = testPlanMapper.selectByPrimaryKey(id);
if (plan != null) { if (plan != null) {
@ -1646,22 +1618,22 @@ public class TestPlanService {
} }
} }
public void buildApiReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo, boolean isFinish) { public void buildApiReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteReportDTO testPlanExecuteReportDTO) {
if (MapUtils.isEmpty(executeInfo.getApiCaseExecInfo()) && MapUtils.isEmpty(executeInfo.getApiScenarioCaseExecInfo())) { if (MapUtils.isEmpty(testPlanExecuteReportDTO.getTestPlanApiCaseIdAndReportIdMap()) && MapUtils.isEmpty(testPlanExecuteReportDTO.getTestPlanScenarioIdAndReportIdMap())) {
return; return;
} }
if (checkReportConfig(config, "api")) { if (checkReportConfig(config, "api")) {
List<TestPlanFailureApiDTO> apiAllCases = null; List<TestPlanFailureApiDTO> apiAllCases = null;
List<TestPlanFailureScenarioDTO> scenarioAllCases = null; List<TestPlanFailureScenarioDTO> scenarioAllCases = null;
if (checkReportConfig(config, "api", "all")) { if (checkReportConfig(config, "api", "all")) {
if (MapUtils.isNotEmpty(executeInfo.getApiCaseExecInfo())) { if (MapUtils.isNotEmpty(testPlanExecuteReportDTO.getTestPlanApiCaseIdAndReportIdMap())) {
// 接口 // 接口
apiAllCases = testPlanApiCaseService.getByApiExecReportIds(executeInfo.getApiCaseExecuteThreadMap(), isFinish); apiAllCases = testPlanApiCaseService.getByApiExecReportIds(testPlanExecuteReportDTO.getTestPlanApiCaseIdAndReportIdMap());
report.setApiAllCases(apiAllCases); report.setApiAllCases(apiAllCases);
} }
if (MapUtils.isNotEmpty(executeInfo.getApiScenarioCaseExecInfo())) { if (MapUtils.isNotEmpty(testPlanExecuteReportDTO.getTestPlanScenarioIdAndReportIdMap())) {
//场景 //场景
scenarioAllCases = testPlanScenarioCaseService.getAllCases(executeInfo.getApiScenarioThreadMap(), isFinish); scenarioAllCases = testPlanScenarioCaseService.getAllCases(testPlanExecuteReportDTO.getTestPlanScenarioIdAndReportIdMap());
report.setScenarioAllCases(scenarioAllCases); report.setScenarioAllCases(scenarioAllCases);
} }
} }
@ -1689,17 +1661,16 @@ public class TestPlanService {
} }
} }
public void buildLoadReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo, String planId, boolean saveResponse) { public void buildLoadReport(TestPlanSimpleReportDTO report, JSONObject config, Map<String, String> loadCaseReportMap, String planId, boolean saveResponse) {
if (MapUtils.isEmpty(executeInfo.getLoadCaseExecInfo())) { if (MapUtils.isEmpty(loadCaseReportMap)) {
return; return;
} }
if (checkReportConfig(config, "load")) { if (checkReportConfig(config, "load")) {
List<TestPlanLoadCaseDTO> allCases = null; List<TestPlanLoadCaseDTO> allCases = null;
if (checkReportConfig(config, "load", "all")) { if (checkReportConfig(config, "load", "all")) {
allCases = testPlanLoadCaseService.getAllCases(executeInfo.getLoadCaseExecInfo().keySet(), planId, null); allCases = testPlanLoadCaseService.getAllCases(loadCaseReportMap.keySet(), planId, null);
for (TestPlanLoadCaseDTO dto : for (TestPlanLoadCaseDTO dto : allCases) {
allCases) { String reportId = loadCaseReportMap.get(dto.getId());
String reportId = executeInfo.getLoadCaseReportIdMap().get(dto.getId());
dto.setReportId(reportId); dto.setReportId(reportId);
} }
if (saveResponse) { if (saveResponse) {
@ -1720,18 +1691,19 @@ public class TestPlanService {
} }
} }
public TestPlanSimpleReportDTO buildPlanReport(TestPlanExecuteInfo executeInfo, String planId, boolean isFinish) { public TestPlanSimpleReportDTO buildPlanReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) {
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(planId); TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId());
if (testPlan != null) { if (testPlan != null) {
String reportConfig = testPlan.getReportConfig(); String reportConfig = testPlan.getReportConfig();
JSONObject config = null; JSONObject config = null;
if (StringUtils.isNotBlank(reportConfig)) { if (StringUtils.isNotBlank(reportConfig)) {
config = JSONObject.parseObject(reportConfig); config = JSONObject.parseObject(reportConfig);
} }
TestPlanSimpleReportDTO report = getReport(planId); TestPlanExecuteReportDTO testPlanExecuteReportDTO = testPlanReportService.genTestPlanExecuteReportDTOByTestPlanReportContent(testPlanReportContentWithBLOBs);
buildFunctionalReport(report, config, planId); TestPlanSimpleReportDTO report = getReport(testPlanReport.getTestPlanId(), testPlanExecuteReportDTO);
buildApiReport(report, config, executeInfo, isFinish); buildFunctionalReport(report, config, testPlanReport.getTestPlanId());
buildLoadReport(report, config, executeInfo, planId, false); buildApiReport(report, config, testPlanExecuteReportDTO);
buildLoadReport(report, config, testPlanExecuteReportDTO.getTestPlanLoadCaseIdAndReportIdMap(), testPlanReport.getTestPlanId(), false);
return report; return report;
} else { } else {
return null; return null;
@ -1747,7 +1719,7 @@ public class TestPlanService {
if (StringUtils.isNotBlank(reportConfig)) { if (StringUtils.isNotBlank(reportConfig)) {
config = JSONObject.parseObject(reportConfig); config = JSONObject.parseObject(reportConfig);
} }
TestPlanSimpleReportDTO report = getReport(planId); TestPlanSimpleReportDTO report = getReport(planId, null);
buildFunctionalReport(report, config, planId); buildFunctionalReport(report, config, planId);
buildApiReport(report, config, planId, saveResponse); buildApiReport(report, config, planId, saveResponse);
buildLoadReport(report, config, planId, saveResponse); buildLoadReport(report, config, planId, saveResponse);
@ -1824,7 +1796,14 @@ public class TestPlanService {
} }
} }
public TestPlanSimpleReportDTO getReport(String planId) { /**
* 生成测试计划报告并进行统计
*
* @param planId
* @param testPlanExecuteReportDTO 测试计划各个资源的报告 如果为空则取当前测试计划资源的最新报告
* @return
*/
public TestPlanSimpleReportDTO getReport(String planId, TestPlanExecuteReportDTO testPlanExecuteReportDTO) {
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(planId); TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(planId);
TestPlanSimpleReportDTO report = new TestPlanSimpleReportDTO(); TestPlanSimpleReportDTO report = new TestPlanSimpleReportDTO();
TestPlanFunctionResultReportDTO functionResult = new TestPlanFunctionResultReportDTO(); TestPlanFunctionResultReportDTO functionResult = new TestPlanFunctionResultReportDTO();
@ -1838,9 +1817,22 @@ public class TestPlanService {
IssueTemplateDao template = issueTemplateService.getTemplate(testPlan.getProjectId()); IssueTemplateDao template = issueTemplateService.getTemplate(testPlan.getProjectId());
testPlanTestCaseService.calculatePlanReport(planId, report); testPlanTestCaseService.calculatePlanReport(planId, report);
issuesService.calculatePlanReport(planId, report); issuesService.calculatePlanReport(planId, report);
testPlanApiCaseService.calculatePlanReport(planId, report); if (testPlanExecuteReportDTO == null) {
testPlanScenarioCaseService.calculatePlanReport(planId, report); testPlanApiCaseService.calculatePlanReport(planId, report);
testPlanLoadCaseService.calculatePlanReport(planId, report); testPlanScenarioCaseService.calculatePlanReport(planId, report);
testPlanLoadCaseService.calculatePlanReport(planId, report);
} else {
if (MapUtils.isNotEmpty(testPlanExecuteReportDTO.getTestPlanApiCaseIdAndReportIdMap())) {
testPlanApiCaseService.calculatePlanReport(new ArrayList<>(testPlanExecuteReportDTO.getTestPlanApiCaseIdAndReportIdMap().values()), report);
}
if (MapUtils.isNotEmpty(testPlanExecuteReportDTO.getTestPlanScenarioIdAndReportIdMap())) {
testPlanScenarioCaseService.calculatePlanReport(new ArrayList<>(testPlanExecuteReportDTO.getTestPlanScenarioIdAndReportIdMap().values()), report);
}
if (MapUtils.isNotEmpty(testPlanExecuteReportDTO.getTestPlanLoadCaseIdAndReportIdMap())) {
testPlanLoadCaseService.calculatePlanReport(new ArrayList<>(testPlanExecuteReportDTO.getTestPlanLoadCaseIdAndReportIdMap().values()), report);
}
}
if (report.getExecuteCount() != 0 && report.getCaseCount() != null) { if (report.getExecuteCount() != 0 && report.getCaseCount() != null) {
report.setExecuteRate(report.getExecuteCount() * 0.1 * 10 / report.getCaseCount()); report.setExecuteRate(report.getExecuteCount() * 0.1 * 10 / report.getCaseCount());
} else { } else {

View File

@ -0,0 +1,3 @@
ALTER TABLE test_plan_report_content ADD scenario_report_id longtext NULL;
ALTER TABLE test_plan_report_content ADD api_case_report_id longtext NULL;
ALTER TABLE test_plan_report_content ADD load_case_report_id longtext NULL;

View File

@ -71,7 +71,7 @@
<!--<table tableName="test_plan"/>--> <!--<table tableName="test_plan"/>-->
<!--<table tableName="api_scenario_report"/>--> <!--<table tableName="api_scenario_report"/>-->
<!--<table tableName="test_case_review"/>--> <!--<table tableName="test_case_review"/>-->
<table tableName="test_case"/> <table tableName="test_plan_report_content"/>
<!--<table tableName="enterprise_test_report_send_record"/>--> <!--<table tableName="enterprise_test_report_send_record"/>-->
<!--<table tableName="test_case_review_api_case"/> <!--<table tableName="test_case_review_api_case"/>
<table tableName="test_case_review_load"/> <table tableName="test_case_review_load"/>