From e391fd2f9015b72a8c333ab15c6b15c579b81d4d Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Mon, 23 May 2022 09:00:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=8A=A5=E5=91=8A=E5=A2=9E=E5=8A=A0=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E8=BF=90=E8=A1=8C=E7=8E=AF=E5=A2=83=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --story=1006994 --user=宋天阳 【通用功能】测试报告增加展示运行环境信息 https://www.tapd.cn/55049933/s/1198098 --- .../metersphere/api/dto/APIReportResult.java | 1 - .../api/dto/ApiScenarioReportDTO.java | 4 + .../dto/RunModeConfigWithEnvironmentDTO.java | 15 + .../api/exec/api/ApiCaseExecuteService.java | 78 +- .../exec/scenario/ApiScenarioEnvService.java | 64 +- .../scenario/ApiScenarioExecuteService.java | 43 +- .../utils/ApiDefinitionExecResultUtil.java | 4 +- .../api/service/ApiDefinitionService.java | 34 +- .../api/service/ApiScenarioReportService.java | 3 +- .../ApiScenarioReportStructureService.java | 77 +- .../service/ApiTestEnvironmentService.java | 111 +- .../base/domain/TestPlanReport.java | 2 + .../TestPlanReportContentWithBLOBs.java | 2 + .../mapper/TestPlanReportContentMapper.xml | 27 +- .../base/mapper/TestPlanReportMapper.java | 11 +- .../base/mapper/TestPlanReportMapper.xml | 86 +- .../ext/ExtApiTestEnvironmentMapper.java | 12 + .../ext/ExtApiTestEnvironmentMapper.xml | 26 + .../mapper/ext/ExtTestPlanApiCaseMapper.java | 3 +- .../mapper/ext/ExtTestPlanApiCaseMapper.xml | 686 +++++----- .../ext/ExtTestPlanScenarioCaseMapper.java | 3 +- .../ext/ExtTestPlanScenarioCaseMapper.xml | 12 +- .../service/EnvironmentGroupService.java | 6 +- .../metersphere/service/ProjectService.java | 9 + .../controller/TestPlanReportController.java | 2 +- .../track/dto/TestPlanSimpleReportDTO.java | 11 + .../dto/testplan/TestPlanApiCaseInfoDTO.java | 13 + .../testplan/TestPlanApiScenarioInfoDTO.java | 13 + .../testplan/TestPlanReportRunInfoDTO.java | 37 + .../track/service/TestPlanReportService.java | 155 ++- .../track/service/TestPlanService.java | 14 +- .../src/main/resources/generatorConfig.xml | 3 +- .../resources/i18n/messages_en_US.properties | 4 +- .../resources/i18n/messages_zh_CN.properties | 4 +- .../resources/i18n/messages_zh_TW.properties | 4 +- .../api/automation/report/ApiReportDetail.vue | 1212 +++++++++-------- .../api/automation/report/ApiReportList.vue | 33 +- .../automation/report/ApiReportViewHeader.vue | 129 +- .../api/definition/components/Run.vue | 21 +- .../components/response/RequestMetric.vue | 26 +- .../report/detail/TestPlanOverviewReport.vue | 27 +- .../detail/component/ApiCaseFailureResult.vue | 38 +- 42 files changed, 1903 insertions(+), 1162 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/RunModeConfigWithEnvironmentDTO.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.xml create mode 100644 backend/src/main/java/io/metersphere/track/dto/testplan/TestPlanApiCaseInfoDTO.java create mode 100644 backend/src/main/java/io/metersphere/track/dto/testplan/TestPlanApiScenarioInfoDTO.java create mode 100644 backend/src/main/java/io/metersphere/track/dto/testplan/TestPlanReportRunInfoDTO.java diff --git a/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java b/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java index 91c3c48113..a46fa22a0c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java +++ b/backend/src/main/java/io/metersphere/api/dto/APIReportResult.java @@ -5,7 +5,6 @@ import lombok.Getter; import lombok.Setter; import java.util.List; -import java.util.Map; @Setter @Getter diff --git a/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportDTO.java b/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportDTO.java index 89189e9561..a0b72b2932 100644 --- a/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportDTO.java @@ -2,6 +2,7 @@ package io.metersphere.api.dto; import lombok.Data; +import java.util.LinkedHashMap; import java.util.List; @Data @@ -37,4 +38,7 @@ public class ApiScenarioReportDTO { private String name; private String envConfig; + //<项目名称,<环境名称>> + private LinkedHashMap> projectEnvMap; + } diff --git a/backend/src/main/java/io/metersphere/api/dto/RunModeConfigWithEnvironmentDTO.java b/backend/src/main/java/io/metersphere/api/dto/RunModeConfigWithEnvironmentDTO.java new file mode 100644 index 0000000000..dfc3740927 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/RunModeConfigWithEnvironmentDTO.java @@ -0,0 +1,15 @@ +package io.metersphere.api.dto; + +import io.metersphere.dto.RunModeConfigDTO; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class RunModeConfigWithEnvironmentDTO extends RunModeConfigDTO { + // 接口/用例在运行时采用的环境信息 <项目ID , <环境ID>> + private Map> executionEnvironmentMap; +} diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java index a5c763b05a..e92b707c00 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java @@ -2,6 +2,7 @@ package io.metersphere.api.exec.api; import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.ApiCaseRunRequest; +import io.metersphere.api.dto.RunModeConfigWithEnvironmentDTO; import io.metersphere.api.dto.definition.ApiTestCaseRequest; import io.metersphere.api.dto.definition.BatchRunDefinitionRequest; import io.metersphere.api.dto.scenario.DatabaseConfig; @@ -25,6 +26,7 @@ import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ReportTypeConstants; import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.constants.RunModeConstants; @@ -112,7 +114,18 @@ public class ApiCaseExecuteService { if (!request.isRerun()) { Map planProjects = new HashMap<>(); for (TestPlanApiCase testPlanApiCase : planApiCases) { - ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, caseMap, resourcePoolId); + //处理环境配置为空时的情况 + RunModeConfigDTO runModeConfigDTO = new RunModeConfigDTO(); + BeanUtils.copyBean(runModeConfigDTO, request.getConfig()); + if (MapUtils.isEmpty(runModeConfigDTO.getEnvMap())) { + ApiTestCase testCase = caseMap.get(testPlanApiCase.getApiCaseId()); + if (testCase != null) { + runModeConfigDTO.setEnvMap(new HashMap<>() {{ + this.put(testCase.getProjectId(), testPlanApiCase.getEnvironmentId()); + }}); + } + } + ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.addResult(request, runModeConfigDTO, testPlanApiCase, status, caseMap, resourcePoolId); if (planProjects.containsKey(testPlanApiCase.getTestPlanId())) { report.setProjectId(planProjects.get(testPlanApiCase.getTestPlanId())); } else { @@ -153,7 +166,8 @@ public class ApiCaseExecuteService { return responseDTOS; } - public void checkEnv(List caseList) { + public Map> checkEnv(List caseList) { + Map> projectEnvMap = new HashMap<>(); if (CollectionUtils.isNotEmpty(caseList)) { StringBuilder builderHttp = new StringBuilder(); StringBuilder builderTcp = new StringBuilder(); @@ -163,6 +177,18 @@ public class ApiCaseExecuteService { if (apiCaseNew.has("type") && "HTTPSamplerProxy".equals(apiCaseNew.getString("type"))) { if (!apiCaseNew.has("useEnvironment") || StringUtils.isEmpty(apiCaseNew.getString("useEnvironment"))) { builderHttp.append(apiCase.getName()).append("; "); + } else { + //记录运行环境ID + String envId = apiCaseNew.getString("useEnvironment"); + if (projectEnvMap.containsKey(apiCase.getProjectId())) { + if (!projectEnvMap.get(apiCase.getProjectId()).contains(envId)) { + projectEnvMap.get(apiCase.getProjectId()).add(envId); + } + } else { + projectEnvMap.put(apiCase.getProjectId(), new ArrayList<>() {{ + this.add(envId); + }}); + } } } if (apiCaseNew.has("type") && "JDBCSampler".equals(apiCaseNew.getString("type"))) { @@ -179,6 +205,16 @@ public class ApiCaseExecuteService { for (DatabaseConfig item : envConfig.getDatabaseConfigs()) { if (item.getId().equals(dataSourceId)) { dataSource = item; + //记录运行环境ID + if (projectEnvMap.containsKey(apiCase.getProjectId())) { + if (!projectEnvMap.get(apiCase.getProjectId()).contains(environmentId)) { + projectEnvMap.get(apiCase.getProjectId()).add(environmentId); + } + } else { + projectEnvMap.put(apiCase.getProjectId(), new ArrayList<>() {{ + this.add(environmentId); + }}); + } } } } @@ -196,6 +232,7 @@ public class ApiCaseExecuteService { MSException.throwException("用例:" + builderTcp + "数据源为空!请检查"); } } + return projectEnvMap; } /** @@ -225,16 +262,25 @@ public class ApiCaseExecuteService { example.createCriteria().andIdIn(request.getIds()).andStatusNotEqualTo("Trash"); List caseList = apiTestCaseMapper.selectByExampleWithBLOBs(example); LoggerUtil.debug("查询到执行数据:" + caseList.size()); + Map> testCaseEnvMap = new HashMap<>(); // 环境检查 if (MapUtils.isEmpty(request.getConfig().getEnvMap())) { - this.checkEnv(caseList); + testCaseEnvMap = this.checkEnv(caseList); } // 集合报告设置 String serialReportId = request.isRerun() ? request.getReportId() : null; if (!request.isRerun() && StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString()) && StringUtils.isNotEmpty(request.getConfig().getReportName())) { serialReportId = UUID.randomUUID().toString(); - ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.initBase(null, APITestStatus.Running.name(), serialReportId, request.getConfig()); + + RunModeConfigDTO config = request.getConfig(); + if (MapUtils.isEmpty(config.getEnvMap())) { + RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO(); + BeanUtils.copyBean(runModeConfig, request.getConfig()); + this.setExecutionEnvironmen(runModeConfig, testCaseEnvMap); + config = runModeConfig; + } + ApiDefinitionExecResultWithBLOBs report = ApiDefinitionExecResultUtil.initBase(null, APITestStatus.Running.name(), serialReportId, config); report.setName(request.getConfig().getReportName()); report.setProjectId(request.getProjectId()); report.setReportType(ReportTypeConstants.API_INTEGRATED.name()); @@ -313,4 +359,28 @@ public class ApiCaseExecuteService { } return responseDTOS; } + + public void setExecutionEnvironmen(RunModeConfigWithEnvironmentDTO config, Map> projectEnvMap) { + if (MapUtils.isNotEmpty(projectEnvMap) && config != null) { + config.setExecutionEnvironmentMap(projectEnvMap); + } + } + + public void setRunModeConfigEnvironment(RunModeConfigWithEnvironmentDTO config, Map projectEnvMap) { + if (MapUtils.isNotEmpty(projectEnvMap) && config != null) { + Map> executionEnvMap = new HashMap<>(); + for (Map.Entry entry : projectEnvMap.entrySet()) { + String projectId = entry.getKey(); + String envId = entry.getValue(); + if (StringUtils.isNoneEmpty(projectId, envId)) { + executionEnvMap.put(projectId, new ArrayList<>() {{ + this.add(envId); + }}); + } + } + if (MapUtils.isNotEmpty(executionEnvMap)) { + config.setExecutionEnvironmentMap(executionEnvMap); + } + } + } } diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java index ae18483898..cb504c2df0 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java @@ -29,10 +29,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Service @@ -277,7 +274,15 @@ public class ApiScenarioEnvService { } } - public void checkEnv(RunScenarioRequest request, List apiScenarios) { + /** + * 检查是否存在运行环境。若不存在则报错,存在的话返回所存在的运行环境 + * + * @param request + * @param apiScenarios + * @return + */ + public Map> checkEnv(RunScenarioRequest request, List apiScenarios) { + Map> projectEnvMap = new HashMap<>(); if (StringUtils.equals(request.getRequestOriginator(), "TEST_PLAN")) { this.checkPlanScenarioEnv(request); } else if (StringUtils.isNotBlank(request.getRunMode()) && @@ -306,6 +311,55 @@ public class ApiScenarioEnvService { } } } + return projectEnvMap; + } + + public Map> selectApiScenarioEnv(List list) { + Map> projectEnvMap = new LinkedHashMap<>(); + for (int i = 0; i < list.size(); i++) { + try { + Map map = new HashMap<>(); + String environmentType = list.get(i).getEnvironmentType(); + String environmentGroupId = list.get(i).getEnvironmentGroupId(); + String env = list.get(i).getEnvironmentJson(); + if (StringUtils.equals(environmentType, EnvironmentType.JSON.name())) { + // 环境属性为空 跳过 + if (StringUtils.isBlank(env)) { + continue; + } + map = JSON.parseObject(env, Map.class); + } else if (StringUtils.equals(environmentType, EnvironmentType.GROUP.name())) { + map = environmentGroupProjectService.getEnvMap(environmentGroupId); + } + + Set set = map.keySet(); + HashMap envMap = new HashMap<>(16); + // 项目为空 跳过 + if (set.isEmpty()) { + continue; + } + for (String projectId : set) { + String envId = map.get(projectId); + envMap.put(projectId, envId); + } + for (Map.Entry entry : envMap.entrySet()) { + String projectId = entry.getKey(); + String envId = entry.getValue(); + if (projectEnvMap.containsKey(projectId)) { + if (!projectEnvMap.get(projectId).contains(envId)) { + projectEnvMap.get(projectId).add(envId); + } + } else { + projectEnvMap.put(projectId, new ArrayList<>() {{ + this.add(envId); + }}); + } + } + } catch (Exception e) { + LogUtil.error("api scenario environment map incorrect parsing. api scenario id:" + list.get(i).getId()); + } + } + return projectEnvMap; } public void setApiScenarioEnv(List list) { diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java index 5963a43079..ea8aa175cb 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java @@ -2,6 +2,7 @@ package io.metersphere.api.exec.scenario; import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.EnvironmentType; +import io.metersphere.api.dto.RunModeConfigWithEnvironmentDTO; import io.metersphere.api.dto.RunModeDataDTO; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.ExecuteType; @@ -9,6 +10,7 @@ import io.metersphere.api.dto.automation.RunScenarioRequest; import io.metersphere.api.dto.definition.RunDefinitionRequest; import io.metersphere.api.dto.definition.request.MsTestPlan; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.api.exec.api.ApiCaseExecuteService; import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.utils.GenerateHashTreeUtil; import io.metersphere.api.jmeter.JMeterService; @@ -16,7 +18,10 @@ import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiScenarioReportService; import io.metersphere.api.service.ApiScenarioReportStructureService; import io.metersphere.api.service.TcpApiParamService; -import io.metersphere.base.domain.*; +import io.metersphere.base.domain.ApiScenarioExample; +import io.metersphere.base.domain.ApiScenarioReportWithBLOBs; +import io.metersphere.base.domain.ApiScenarioWithBLOBs; +import io.metersphere.base.domain.TestPlanApiScenario; import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioReportMapper; import io.metersphere.base.mapper.TestPlanApiScenarioMapper; @@ -26,10 +31,7 @@ import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.constants.ReportTypeConstants; import io.metersphere.commons.exception.MSException; -import io.metersphere.commons.utils.FileUtils; -import io.metersphere.commons.utils.LogUtil; -import io.metersphere.commons.utils.ServiceUtils; -import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.commons.utils.*; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.MsExecResponseDTO; @@ -86,6 +88,8 @@ public class ApiScenarioExecuteService { @Resource private TcpApiParamService tcpApiParamService; @Resource + private ApiCaseExecuteService apiCaseExecuteService; + @Resource protected JMeterService jMeterService; public List run(RunScenarioRequest request) { @@ -154,10 +158,18 @@ public class ApiScenarioExecuteService { LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId); request.getConfig().setReportId(UUID.randomUUID().toString()); String reportScenarioIds = generateScenarioIds(scenarioIds); - + if (request.getConfig() == null) { + request.setConfig(new RunModeConfigWithEnvironmentDTO()); + } + if (MapUtils.isEmpty(request.getConfig().getEnvMap())) { + RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO(); + BeanUtils.copyBean(runModeConfig, request.getConfig()); + Map> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios); + apiCaseExecuteService.setExecutionEnvironmen(runModeConfig, projectEnvMap); + request.setConfig(runModeConfig); + } APIScenarioReportResult report = getApiScenarioReportResult(request, serialReportId, scenarioNames, reportScenarioIds); report.setVersionId(apiScenarios.get(0).getVersionId()); - apiScenarioReportMapper.insert(report); responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode())); @@ -206,7 +218,7 @@ public class ApiScenarioExecuteService { } protected APIScenarioReportResult getApiScenarioReportResult(RunScenarioRequest request, String serialReportId, - StringBuilder scenarioNames, String reportScenarioIds) { + StringBuilder scenarioNames, String reportScenarioIds) { APIScenarioReportResult report = apiScenarioReportService.init(request.getConfig().getReportId(), reportScenarioIds, scenarioNames.toString(), request.getTriggerMode(), ExecuteType.Saved.name(), request.getProjectId(), request.getReportUserID(), request.getConfig()); @@ -303,7 +315,12 @@ public class ApiScenarioExecuteService { executeQueue.put(report.getId(), runModeDataDTO); scenarioNames.append(scenario.getName()).append(","); if (request.getConfig() != null) { - report.setEnvConfig(JSON.toJSONString(request.getConfig())); + RunModeConfigWithEnvironmentDTO runModeConfig = new RunModeConfigWithEnvironmentDTO(); + BeanUtils.copyBean(runModeConfig, request.getConfig()); + if (MapUtils.isEmpty(runModeConfig.getEnvMap())) { + apiCaseExecuteService.setRunModeConfigEnvironment(runModeConfig, planEnvMap); + } + report.setEnvConfig(JSON.toJSONString(runModeConfig)); } // 生成文档结构 if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) { @@ -385,6 +402,12 @@ public class ApiScenarioExecuteService { MSException.throwException(e.getMessage()); } if (request.isSaved()) { + //记录环境 + RunModeConfigDTO runModeCconfig = request.getConfig(); + if (runModeCconfig == null) { + runModeCconfig = new RunModeConfigDTO(); + runModeCconfig.setEnvMap(map); + } APIScenarioReportResult report = apiScenarioReportService.init(request.getId(), request.getScenarioId(), request.getScenarioName(), @@ -392,7 +415,7 @@ public class ApiScenarioExecuteService { request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId(), - request.getConfig()); + runModeCconfig); ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(request.getScenarioId()); String reportType = request.getConfig() != null ? request.getConfig().getReportType() : null; if (scenario != null) { diff --git a/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java b/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java index 1cffd2e77c..7936003358 100644 --- a/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java +++ b/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java @@ -43,7 +43,7 @@ public class ApiDefinitionExecResultUtil { return apiResult; } - public static ApiDefinitionExecResultWithBLOBs addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status, + public static ApiDefinitionExecResultWithBLOBs addResult(BatchRunDefinitionRequest request, RunModeConfigDTO runModeConfigDTO, TestPlanApiCase key, String status, Map caseMap, String poolId) { ApiDefinitionExecResultWithBLOBs apiResult = new ApiDefinitionExecResultWithBLOBs(); apiResult.setId(UUID.randomUUID().toString()); @@ -75,7 +75,7 @@ public class ApiDefinitionExecResultUtil { apiResult.setType(ApiRunMode.API_PLAN.name()); apiResult.setStatus(status); apiResult.setContent(request.getPlanReportId()); - apiResult.setEnvConfig(JSON.toJSONString(request.getConfig())); + apiResult.setEnvConfig(JSON.toJSONString(runModeConfigDTO)); return apiResult; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index e141ffdba8..ae5fb62dab 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -42,6 +42,7 @@ import io.metersphere.controller.request.ScheduleRequest; import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.dto.ProjectConfig; import io.metersphere.dto.RelationshipEdgeDTO; +import io.metersphere.dto.RunModeConfigDTO; import io.metersphere.i18n.Translator; import io.metersphere.job.sechedule.SwaggerUrlImportJob; import io.metersphere.log.utils.ReflexObjectUtil; @@ -58,6 +59,7 @@ import io.metersphere.track.service.TestCaseService; import io.metersphere.track.service.TestPlanService; import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.collections4.comparators.FixedOrderComparator; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -152,6 +154,8 @@ public class ApiDefinitionService { @Lazy @Resource private ApiModuleService apiModuleService; + @Resource + private ApiTestEnvironmentService apiTestEnvironmentService; private ThreadLocal currentApiOrder = new ThreadLocal<>(); private ThreadLocal currentApiCaseOrder = new ThreadLocal<>(); @@ -1225,6 +1229,13 @@ public class ApiDefinitionService { result.setName(reportName); result.setProjectId(request.getProjectId()); result.setTriggerMode(TriggerMode.MANUAL.name()); + if (StringUtils.isNotEmpty(request.getEnvironmentId())) { + RunModeConfigDTO runModeConfigDTO = new RunModeConfigDTO(); + runModeConfigDTO.setEnvMap(new HashMap<>() {{ + this.put(request.getProjectId(), request.getEnvironmentId()); + }}); + result.setEnvConfig(JSONObject.toJSONString(runModeConfigDTO)); + } apiDefinitionExecResultMapper.insert(result); } if (request.isEditCaseRequest() && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree()) && @@ -1278,10 +1289,31 @@ public class ApiDefinitionService { } APIReportResult reportResult = new APIReportResult(); reportResult.setStatus(result.getStatus()); - reportResult.setContent(result.getContent()); + if (StringUtils.isNotEmpty(result.getEnvConfig())) { + JSONObject content = JSONObject.parseObject(result.getContent()); + content.put("envName", this.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig())); + reportResult.setContent(content.toJSONString()); + } else { + reportResult.setContent(result.getContent()); + } return reportResult; } + public String getEnvNameByEnvConfig(String projectId, String envConfig) { + String envName = null; + RunModeConfigDTO runModeConfigDTO = null; + try { + runModeConfigDTO = JSONObject.parseObject(envConfig, RunModeConfigDTO.class); + } catch (Exception e) { + LogUtil.error("解析" + envConfig + "为RunModeConfigDTO时失败!", e); + } + if (StringUtils.isNotEmpty(projectId) && runModeConfigDTO != null && MapUtils.isNotEmpty(runModeConfigDTO.getEnvMap())) { + String envId = runModeConfigDTO.getEnvMap().get(projectId); + envName = apiTestEnvironmentService.selectNameById(envId); + } + return envName; + } + public APIReportResult getDbResult(String testId, String type) { ApiDefinitionExecResultWithBLOBs result = extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(testId, type); return buildAPIReportResult(result); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index bf037fa9d8..3377bb63f0 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -155,13 +155,14 @@ public class ApiScenarioReportService { * @return */ public APIScenarioReportResult getApiIntegrated(String reportId) { - ApiDefinitionExecResult result = definitionExecResultMapper.selectByPrimaryKey(reportId); + ApiDefinitionExecResultWithBLOBs result = definitionExecResultMapper.selectByPrimaryKey(reportId); if (result != null) { APIScenarioReportResult reportResult = new APIScenarioReportResult(); BeanUtils.copyBean(reportResult, result); reportResult.setReportVersion(2); reportResult.setTestId(reportId); ApiScenarioReportDTO dto = apiScenarioReportStructureService.apiIntegratedReport(reportId); + apiScenarioReportStructureService.initProjectEnvironmentByEnvConfig(dto, result.getEnvConfig()); reportResult.setContent(JSON.toJSONString(dto)); return reportResult; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java index 883fe6f660..74fb05093f 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java @@ -4,10 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.Feature; -import io.metersphere.api.dto.ApiScenarioReportBaseInfoDTO; -import io.metersphere.api.dto.ApiScenarioReportDTO; -import io.metersphere.api.dto.RequestResultExpandDTO; -import io.metersphere.api.dto.StepTreeDTO; +import io.metersphere.api.dto.*; import io.metersphere.api.exec.utils.ResultParseUtil; import io.metersphere.api.service.vo.ApiDefinitionExecResultVo; import io.metersphere.base.domain.*; @@ -22,10 +19,14 @@ import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.RequestResult; +import io.metersphere.dto.RunModeConfigDTO; +import io.metersphere.service.ProjectService; import io.metersphere.utils.LoggerUtil; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -50,6 +51,11 @@ public class ApiScenarioReportStructureService { private ApiDefinitionExecResultMapper definitionExecResultMapper; @Resource private ExtApiScenarioReportResultMapper extApiScenarioReportResultMapper; + @Lazy + @Resource + private ProjectService projectService; + @Resource + private ApiTestEnvironmentService apiTestEnvironmentService; private static final List requests = Arrays.asList("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "JSR223Processor", "AbstractSampler"); private static final List controls = Arrays.asList("Assertions", "IfController", "ConstantTimer"); @@ -524,10 +530,73 @@ public class ApiScenarioReportStructureService { dto.setActuator(report.getActuator()); dto.setName(report.getName()); dto.setEnvConfig(report.getEnvConfig()); + this.initProjectEnvironmentByEnvConfig(dto, report.getEnvConfig()); return dto; } } + public void initProjectEnvironmentByEnvConfig(ApiScenarioReportDTO dto, String envConfig) { + if (StringUtils.isNotEmpty(envConfig)) { + //运行设置中选择的环境信息(批量执行时在前台选择了执行信息) + Map envMapByRunConfig = null; + //执行时选择的环境信息 (一般在集合报告中会记录) + Map> envMapByExecution = null; + + try { + JSONObject jsonObject = JSONObject.parseObject(envConfig); + if (jsonObject.containsKey("executionEnvironmentMap")) { + RunModeConfigWithEnvironmentDTO configWithEnvironment = JSONObject.parseObject(envConfig, RunModeConfigWithEnvironmentDTO.class); + if (MapUtils.isNotEmpty(configWithEnvironment.getExecutionEnvironmentMap())) { + envMapByExecution = configWithEnvironment.getExecutionEnvironmentMap(); + } else { + envMapByRunConfig = configWithEnvironment.getEnvMap(); + } + } else { + RunModeConfigDTO config = JSONObject.parseObject(envConfig, RunModeConfigDTO.class); + envMapByRunConfig = config.getEnvMap(); + } + } catch (Exception e) { + LogUtil.error("解析RunModeConfig失败!参数:" + envConfig, e); + } + + LinkedHashMap> projectEnvMap = new LinkedHashMap<>(); + + if (MapUtils.isNotEmpty(envMapByExecution)) { + for (Map.Entry> entry : envMapByExecution.entrySet()) { + String projectId = entry.getKey(); + List envIdList = entry.getValue(); + String projectName = projectService.selectNameById(projectId); + List envNameList = apiTestEnvironmentService.selectNameByIds(envIdList); + if (CollectionUtils.isNotEmpty(envNameList) && StringUtils.isNotEmpty(projectName)) { + projectEnvMap.put(projectName, new ArrayList<>() {{ + this.addAll(envNameList); + }}); + } + } + if (MapUtils.isNotEmpty(projectEnvMap)) { + dto.setProjectEnvMap(projectEnvMap); + } + } + + if (MapUtils.isNotEmpty(envMapByRunConfig)) { + for (Map.Entry entry : envMapByRunConfig.entrySet()) { + String projectId = entry.getKey(); + String envId = entry.getValue(); + String projectName = projectService.selectNameById(projectId); + String envName = apiTestEnvironmentService.selectNameById(envId); + if (StringUtils.isNoneEmpty(projectName, envName)) { + projectEnvMap.put(projectName, new ArrayList<>() {{ + this.add(envName); + }}); + } + } + if (MapUtils.isNotEmpty(projectEnvMap)) { + dto.setProjectEnvMap(projectEnvMap); + } + } + } + } + private ApiScenarioReportDTO getReport(String reportId, boolean selectContent) { List reportResults = null; if (selectContent) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java index 6e11a8acc2..7d6f90497b 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java @@ -10,6 +10,7 @@ import io.metersphere.base.domain.ApiTestEnvironmentExample; import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; import io.metersphere.base.domain.Project; import io.metersphere.base.mapper.ApiTestEnvironmentMapper; +import io.metersphere.base.mapper.ext.ExtApiTestEnvironmentMapper; import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; @@ -47,6 +48,8 @@ public class ApiTestEnvironmentService { private EnvironmentGroupProjectService environmentGroupProjectService; @Resource private ProjectApplicationService projectApplicationService; + @Resource + private ExtApiTestEnvironmentMapper extApiTestEnvironmentMapper; public List list(String projectId) { ApiTestEnvironmentExample example = new ApiTestEnvironmentExample(); @@ -102,7 +105,7 @@ public class ApiTestEnvironmentService { checkEnvironmentExist(request); FileUtils.createFiles(request.getUploadIds(), sslFiles, FileUtils.BODY_FILE_DIR + "/ssl"); //检查Config,判断isMock参数是否给True - request = this.updateConfig(request,false); + request = this.updateConfig(request, false); request.setCreateTime(System.currentTimeMillis()); request.setUpdateTime(System.currentTimeMillis()); apiTestEnvironmentMapper.insert(request); @@ -110,29 +113,31 @@ public class ApiTestEnvironmentService { } private ApiTestEnvironmentDTO updateConfig(ApiTestEnvironmentDTO request, boolean isMock) { - if(StringUtils.isNotEmpty(request.getConfig())){ - try{ + if (StringUtils.isNotEmpty(request.getConfig())) { + try { JSONObject configObj = JSONObject.parseObject(request.getConfig()); - if(configObj.containsKey("httpConfig")){ + if (configObj.containsKey("httpConfig")) { JSONObject httpObj = configObj.getJSONObject("httpConfig"); - httpObj.put("isMock",isMock); + httpObj.put("isMock", isMock); } request.setConfig(configObj.toJSONString()); - }catch (Exception e){ + } catch (Exception e) { + LogUtil.error("设置是否为mock环境出错!参数:" + request.getConfig(), e); } } return request; } - public void update(ApiTestEnvironmentDTO apiTestEnvironment,List sslFiles) { + public void update(ApiTestEnvironmentDTO apiTestEnvironment, List sslFiles) { checkEnvironmentExist(apiTestEnvironment); FileUtils.createFiles(apiTestEnvironment.getUploadIds(), sslFiles, FileUtils.BODY_FILE_DIR + "/ssl"); apiTestEnvironment.setUpdateTime(System.currentTimeMillis()); apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(apiTestEnvironment); } + private void checkEnvironmentExist(ApiTestEnvironmentWithBLOBs environment) { if (environment.getName() != null) { - if(StringUtils.isEmpty(environment.getProjectId())){ + if (StringUtils.isEmpty(environment.getProjectId())) { MSException.throwException(Translator.get("项目ID不能为空")); } ApiTestEnvironmentExample example = new ApiTestEnvironmentExample(); @@ -177,16 +182,16 @@ public class ApiTestEnvironmentService { String projectNumber = this.getSystemIdByProjectId(projectId); if (list.isEmpty()) { - returnModel = this.genHttpApiTestEnvironmentByUrl(projectId,projectNumber, protocal, apiName, baseUrl); + returnModel = this.genHttpApiTestEnvironmentByUrl(projectId, projectNumber, protocal, apiName, baseUrl); this.add(returnModel); } else { returnModel = list.get(0); - returnModel = this.checkMockEvnIsRightful(returnModel, protocal, projectId,projectNumber, apiName, baseUrl); + returnModel = this.checkMockEvnIsRightful(returnModel, protocal, projectId, projectNumber, apiName, baseUrl); } return returnModel; } - private ApiTestEnvironmentWithBLOBs checkMockEvnIsRightful(ApiTestEnvironmentWithBLOBs returnModel, String protocal, String projectId,String projectNumber, String name, String url) { + private ApiTestEnvironmentWithBLOBs checkMockEvnIsRightful(ApiTestEnvironmentWithBLOBs returnModel, String protocal, String projectId, String projectNumber, String name, String url) { boolean needUpdate = false; ProjectService projectService = CommonBeanFactory.getBean(ProjectService.class); Project project = projectService.getProjectById(projectId); @@ -209,7 +214,7 @@ public class ApiTestEnvironmentService { } else if (socket.startsWith("https://")) { socket = socket.substring(8); } - if (!obj.containsKey("socket") || !StringUtils.startsWith(String.valueOf(obj.get("socket")),socket)) { + if (!obj.containsKey("socket") || !StringUtils.startsWith(String.valueOf(obj.get("socket")), socket)) { needUpdate = true; break; } else if (!obj.containsKey("protocol") || !StringUtils.equals(protocal, String.valueOf(obj.get("protocol")))) { @@ -218,7 +223,7 @@ public class ApiTestEnvironmentService { } String projectSocket = String.valueOf(obj.get("socket")); - if(!StringUtils.contains(projectSocket,"/mock/"+projectNumber)){ + if (!StringUtils.contains(projectSocket, "/mock/" + projectNumber)) { needUpdate = true; break; } @@ -229,22 +234,22 @@ public class ApiTestEnvironmentService { } ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.MOCK_TCP_PORT.name()); Integer mockPortStr = config.getMockTcpPort(); - if(mockPortStr != null && mockPortStr != 0){ - if(configObj.containsKey("tcpConfig")){ + if (mockPortStr != null && mockPortStr != 0) { + if (configObj.containsKey("tcpConfig")) { JSONObject tcpConfigObj = configObj.getJSONObject("tcpConfig"); - if(tcpConfigObj.containsKey("port")){ - if(tcpConfigObj.getInteger("port").intValue() != mockPortStr){ + if (tcpConfigObj.containsKey("port")) { + if (tcpConfigObj.getInteger("port").intValue() != mockPortStr) { needUpdate = true; } - }else { + } else { needUpdate = true; } - if(tcpConfigObj.containsKey("server")){ - if(!StringUtils.equals(tcpConfigObj.getString("server"),url)){ + if (tcpConfigObj.containsKey("server")) { + if (!StringUtils.equals(tcpConfigObj.getString("server"), url)) { needUpdate = true; } - }else { + } else { needUpdate = true; } } @@ -256,23 +261,23 @@ public class ApiTestEnvironmentService { } if (needUpdate) { String id = returnModel.getId(); - returnModel = this.genHttpApiTestEnvironmentByUrl(id,project,projectNumber, protocal, name, url); + returnModel = this.genHttpApiTestEnvironmentByUrl(id, project, projectNumber, protocal, name, url); apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(returnModel); } return returnModel; } - private ApiTestEnvironmentWithBLOBs genHttpApiTestEnvironmentByUrl(String projectId,String projectNumber, String protocal, String name, String baseUrl) { + private ApiTestEnvironmentWithBLOBs genHttpApiTestEnvironmentByUrl(String projectId, String projectNumber, String protocal, String name, String baseUrl) { ProjectService projectService = CommonBeanFactory.getBean(ProjectService.class); Project project = projectService.getProjectById(projectId); - if(project != null){ - return this.genHttpApiTestEnvironmentByUrl(null,project,projectNumber, protocal, name, baseUrl); + if (project != null) { + return this.genHttpApiTestEnvironmentByUrl(null, project, projectNumber, protocal, name, baseUrl); } return null; } - private ApiTestEnvironmentWithBLOBs genHttpApiTestEnvironmentByUrl(String envId,Project project,String projectNumber, String protocal, String name, String baseUrl) { - if(project == null){ + private ApiTestEnvironmentWithBLOBs genHttpApiTestEnvironmentByUrl(String envId, Project project, String projectNumber, String protocal, String name, String baseUrl) { + if (project == null) { return null; } String socket = ""; @@ -284,7 +289,7 @@ public class ApiTestEnvironmentService { } socket = url; String tcpSocket = socket; - if(StringUtils.isNotEmpty(tcpSocket) && tcpSocket.contains(":")){ + if (StringUtils.isNotEmpty(tcpSocket) && tcpSocket.contains(":")) { tcpSocket = socket.split(":")[0]; } @@ -318,7 +323,7 @@ public class ApiTestEnvironmentService { JSONObject httpItem = new JSONObject(); httpItem.put("id", UUID.randomUUID().toString()); httpItem.put("type", "NONE"); - httpItem.put("socket", socket+"/mock/"+projectNumber); + httpItem.put("socket", socket + "/mock/" + projectNumber); httpItem.put("protocol", protocal); JSONArray protocolVariablesArr = new JSONArray(); Map protocolMap = new HashMap<>(); @@ -348,25 +353,25 @@ public class ApiTestEnvironmentService { tcpConfigObj.put("reUseConnection", false); tcpConfigObj.put("nodelay", false); tcpConfigObj.put("closeConnection", false); - if(project != null){ + if (project != null) { ProjectConfig config = projectApplicationService.getSpecificTypeValue(project.getId(), ProjectApplicationType.MOCK_TCP_PORT.name()); Integer mockPort = config.getMockTcpPort(); - if(mockPort != null && mockPort != 0){ + if (mockPort != null && mockPort != 0) { tcpConfigObj.put("server", tcpSocket); tcpConfigObj.put("port", mockPort); } } ApiTestEnvironmentWithBLOBs blobs = null; - if(StringUtils.isNotEmpty(envId)) { + if (StringUtils.isNotEmpty(envId)) { blobs = this.get(envId); } - if(blobs != null && StringUtils.isNotEmpty(blobs.getConfig())){ + if (blobs != null && StringUtils.isNotEmpty(blobs.getConfig())) { JSONObject object = JSONObject.parseObject(blobs.getConfig()); object.put("httpConfig", httpConfig); object.put("tcpConfig", tcpConfigObj); blobs.setConfig(object.toString()); - }else { + } else { blobs = new ApiTestEnvironmentWithBLOBs(); JSONObject commonConfigObj = new JSONObject(); JSONArray commonVariablesArr = new JSONArray(); @@ -403,18 +408,18 @@ public class ApiTestEnvironmentService { protocal = "https"; } String projectNumber = this.getSystemIdByProjectId(model.getProjectId()); - model = this.checkMockEvnIsRightful(model, protocal, model.getProjectId(),projectNumber, model.getName(), baseUrl); + model = this.checkMockEvnIsRightful(model, protocal, model.getProjectId(), projectNumber, model.getName(), baseUrl); } } } - private String getSystemIdByProjectId(String projectId){ + private String getSystemIdByProjectId(String projectId) { ProjectService projectService = CommonBeanFactory.getBean(ProjectService.class); Project project = projectService.getProjectById(projectId); - if(project != null){ + if (project != null) { project = projectService.checkSystemId(project); - return projectService.getSystemIdByProjectId(projectId); - }else { + return projectService.getSystemIdByProjectId(projectId); + } else { return ""; } } @@ -436,28 +441,40 @@ public class ApiTestEnvironmentService { try { JSONObject configObj = JSONObject.parseObject(mockEnv.getConfig()); - if(configObj.containsKey("tcpConfig")){ + if (configObj.containsKey("tcpConfig")) { JSONObject tcpConfigObj = configObj.getJSONObject("tcpConfig"); int tcpPort = 0; - if(tcpConfigObj.containsKey("port")){ + if (tcpConfigObj.containsKey("port")) { tcpPort = tcpConfigObj.getInteger("port").intValue(); - if(tcpPort == 0 || !TCPPool.isTcpOpen(tcpPort)){ + if (tcpPort == 0 || !TCPPool.isTcpOpen(tcpPort)) { return returnStr; } - }else { + } else { return returnStr; } - if(tcpConfigObj.containsKey("server")){ + if (tcpConfigObj.containsKey("server")) { String server = tcpConfigObj.getString("server"); - returnStr = server +":"+ tcpPort; - }else { + returnStr = server + ":" + tcpPort; + } else { return returnStr; } } - }catch (Exception e){ + } catch (Exception e) { LogUtil.error(e); } } return returnStr; } + + public List selectNameByIds(Collection envIds) { + if (CollectionUtils.isNotEmpty(envIds)) { + return extApiTestEnvironmentMapper.selectNameByIds(envIds); + } else { + return new ArrayList<>(0); + } + } + + public String selectNameById(String id) { + return extApiTestEnvironmentMapper.selectNameById(id); + } } diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java index afc6ed0945..e5006dfce0 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java @@ -37,5 +37,7 @@ public class TestPlanReport implements Serializable { private Boolean isNew; + private String runInfo; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java index 5510f3839f..3299cfaf24 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java @@ -51,5 +51,7 @@ public class TestPlanReportContentWithBLOBs extends TestPlanReportContent implem private String unExecuteScenarios; + private String apiBaseCount; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml index 3afd8df1b1..e2fb768ff0 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml @@ -33,6 +33,7 @@ + @@ -101,7 +102,7 @@ issue_list, api_all_cases, api_failure_cases, scenario_all_cases, scenario_failure_cases, load_all_Cases, load_failure_cases, plan_scenario_report_struct, plan_api_case_report_struct, plan_load_case_report_struct, error_report_cases, error_report_scenarios, un_execute_cases, - un_execute_scenarios + un_execute_scenarios, api_base_count @@ -454,6 +463,9 @@ un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR}, + + api_base_count = #{record.apiBaseCount,jdbcType=LONGVARCHAR}, + @@ -489,7 +501,8 @@ error_report_cases = #{record.errorReportCases,jdbcType=LONGVARCHAR}, error_report_scenarios = #{record.errorReportScenarios,jdbcType=LONGVARCHAR}, un_execute_cases = #{record.unExecuteCases,jdbcType=LONGVARCHAR}, - un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR} + un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR}, + api_base_count = #{record.apiBaseCount,jdbcType=LONGVARCHAR} @@ -595,6 +608,9 @@ un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR}, + + api_base_count = #{apiBaseCount,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} @@ -627,7 +643,8 @@ error_report_cases = #{errorReportCases,jdbcType=LONGVARCHAR}, error_report_scenarios = #{errorReportScenarios,jdbcType=LONGVARCHAR}, un_execute_cases = #{unExecuteCases,jdbcType=LONGVARCHAR}, - un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR} + un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR}, + api_base_count = #{apiBaseCount,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java index bb02f5767e..c7beeb8a31 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java @@ -1,13 +1,8 @@ package io.metersphere.base.mapper; -import io.metersphere.api.dto.definition.ParamsDTO; import io.metersphere.base.domain.TestPlanReport; import io.metersphere.base.domain.TestPlanReportExample; import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.Param; public interface TestPlanReportMapper { @@ -21,15 +16,21 @@ public interface TestPlanReportMapper { int insertSelective(TestPlanReport record); + List selectByExampleWithBLOBs(TestPlanReportExample example); + List selectByExample(TestPlanReportExample example); TestPlanReport selectByPrimaryKey(String id); int updateByExampleSelective(@Param("record") TestPlanReport record, @Param("example") TestPlanReportExample example); + int updateByExampleWithBLOBs(@Param("record") TestPlanReport record, @Param("example") TestPlanReportExample example); + int updateByExample(@Param("record") TestPlanReport record, @Param("example") TestPlanReportExample example); int updateByPrimaryKeySelective(TestPlanReport record); + int updateByPrimaryKeyWithBLOBs(TestPlanReport record); + int updateByPrimaryKey(TestPlanReport record); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml index a2b277876a..b84321155f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml @@ -19,6 +19,9 @@ + + + @@ -82,6 +85,25 @@ start_time, end_time, is_api_case_executing, is_scenario_executing, is_performance_executing, principal, components, is_new + + run_info + + - select + , + from test_plan_report where id = #{id,jdbcType=VARCHAR} @@ -118,13 +142,13 @@ trigger_mode, creator, start_time, end_time, is_api_case_executing, is_scenario_executing, is_performance_executing, principal, components, - is_new) + is_new, run_info) values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{triggerMode,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR}, #{startTime,jdbcType=BIGINT}, #{endTime,jdbcType=BIGINT}, #{isApiCaseExecuting,jdbcType=BIT}, #{isScenarioExecuting,jdbcType=BIT}, #{isPerformanceExecuting,jdbcType=BIT}, #{principal,jdbcType=VARCHAR}, #{components,jdbcType=VARCHAR}, - #{isNew,jdbcType=BIT}) + #{isNew,jdbcType=BIT}, #{runInfo,jdbcType=LONGVARCHAR}) insert into test_plan_report @@ -177,6 +201,9 @@ is_new, + + run_info, + @@ -227,6 +254,9 @@ #{isNew,jdbcType=BIT}, + + #{runInfo,jdbcType=LONGVARCHAR}, + - update test_plan_report @@ -287,11 +316,37 @@ is_new = #{record.isNew,jdbcType=BIT}, + + run_info = #{record.runInfo,jdbcType=LONGVARCHAR}, + + + update test_plan_report + set id = #{record.id,jdbcType=VARCHAR}, + test_plan_id = #{record.testPlanId,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + update_time = #{record.updateTime,jdbcType=BIGINT}, + `name` = #{record.name,jdbcType=VARCHAR}, + `status` = #{record.status,jdbcType=VARCHAR}, + trigger_mode = #{record.triggerMode,jdbcType=VARCHAR}, + creator = #{record.creator,jdbcType=VARCHAR}, + start_time = #{record.startTime,jdbcType=BIGINT}, + end_time = #{record.endTime,jdbcType=BIGINT}, + is_api_case_executing = #{record.isApiCaseExecuting,jdbcType=BIT}, + is_scenario_executing = #{record.isScenarioExecuting,jdbcType=BIT}, + is_performance_executing = #{record.isPerformanceExecuting,jdbcType=BIT}, + principal = #{record.principal,jdbcType=VARCHAR}, + components = #{record.components,jdbcType=VARCHAR}, + is_new = #{record.isNew,jdbcType=BIT}, + run_info = #{record.runInfo,jdbcType=LONGVARCHAR} + + + + update test_plan_report set id = #{record.id,jdbcType=VARCHAR}, @@ -362,9 +417,32 @@ is_new = #{isNew,jdbcType=BIT}, + + run_info = #{runInfo,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} + + update test_plan_report + set test_plan_id = #{testPlanId,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + update_time = #{updateTime,jdbcType=BIGINT}, + `name` = #{name,jdbcType=VARCHAR}, + `status` = #{status,jdbcType=VARCHAR}, + trigger_mode = #{triggerMode,jdbcType=VARCHAR}, + creator = #{creator,jdbcType=VARCHAR}, + start_time = #{startTime,jdbcType=BIGINT}, + end_time = #{endTime,jdbcType=BIGINT}, + is_api_case_executing = #{isApiCaseExecuting,jdbcType=BIT}, + is_scenario_executing = #{isScenarioExecuting,jdbcType=BIT}, + is_performance_executing = #{isPerformanceExecuting,jdbcType=BIT}, + principal = #{principal,jdbcType=VARCHAR}, + components = #{components,jdbcType=VARCHAR}, + is_new = #{isNew,jdbcType=BIT}, + run_info = #{runInfo,jdbcType=LONGVARCHAR} + where id = #{id,jdbcType=VARCHAR} + update test_plan_report set test_plan_id = #{testPlanId,jdbcType=VARCHAR}, diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.java new file mode 100644 index 0000000000..f8ce31200a --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.java @@ -0,0 +1,12 @@ +package io.metersphere.base.mapper.ext; + +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; + +public interface ExtApiTestEnvironmentMapper { + List selectNameByIds(@Param("ids") Collection envIdSet); + + String selectNameById(String id); +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.xml new file mode 100644 index 0000000000..82a2c96347 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiTestEnvironmentMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java index 065ab080b0..c5edc2290d 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java @@ -6,6 +6,7 @@ import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; import io.metersphere.base.domain.TestPlanApiCase; import io.metersphere.track.dto.PlanReportCaseDTO; +import io.metersphere.track.dto.testplan.TestPlanApiCaseInfoDTO; import org.apache.ibatis.annotations.Param; import java.util.Collection; @@ -30,7 +31,7 @@ public interface ExtTestPlanApiCaseMapper { String getApiTestCaseIdById(String testPlanApiCaseId); - List selectLegalDataByTestPlanId(String planId); + List selectLegalDataByTestPlanId(String planId); List selectForPlanReport(String planId); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml index 8cac642a6b..5c40a93973 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml @@ -3,360 +3,386 @@ - - INSERT INTO test_plan_api_case(id, test_plan_id, api_case_id, environment_id, create_time, update_time, create_user, `order`) - SELECT #{request.id}, #{request.testPlanId}, #{request.apiCaseId}, #{request.environmentId}, #{request.createTime}, #{request.updateTime}, #{request.createUser}, #{request.order} - FROM DUAL - WHERE NOT EXISTS( - SELECT id FROM - test_plan_api_case - WHERE test_plan_id = #{request.testPlanId} and api_case_id = #{request.apiCaseId} - ) - - - - - + SELECT t.* + FROM api_test_case t + INNER JOIN test_plan_api_case tpac ON t.id = tpac.api_case_id + WHERE tpac.id = #{0} + + + + + - - + + + and a.projectId = #{request.projectId} + + and t.id in + + #{caseId} + + + + and (c.name like CONCAT('%', #{request.name},'%') + or c.tags like CONCAT('%', #{request.name},'%') + or c.num like CONCAT('%', #{request.name},'%') + ) + + + and a.module_id in + + #{nodeId} + + + + + + + + and c.priority in + + + + and c.create_user_id in + + + + and a.version_id in + + + + and t.status in + + + + + + + + + + + order by + + + + t.${order.name} ${order.type} + + + create_user_id ${order.type} + + + ${order.name} ${order.type} + + + + - + + + - - + + + + - + - - + + - + - + - - - and ${versionTable}.version_id = #{request.versionId} - - - and ${versionTable}.ref_id = #{request.refId} - - + + + and ${versionTable}.version_id = #{request.versionId} + + + and ${versionTable}.ref_id = #{request.refId} + + diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java index 488391891a..ca5cb6fd83 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java @@ -5,6 +5,7 @@ import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO; import io.metersphere.api.dto.automation.TestPlanScenarioRequest; import io.metersphere.base.domain.TestPlanApiScenario; import io.metersphere.track.dto.PlanReportCaseDTO; +import io.metersphere.track.dto.testplan.TestPlanApiScenarioInfoDTO; import org.apache.ibatis.annotations.Param; import java.util.Collection; @@ -25,7 +26,7 @@ public interface ExtTestPlanScenarioCaseMapper { List selectByIds(@Param("ids")String ids ,@Param("oderId")String oderId ); - List selectLegalDataByTestPlanId(String planId); + List selectLegalDataByTestPlanId(String planId); List selectForPlanReport(String planId); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.xml index b35a506efb..90dd066a8d 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.xml @@ -15,12 +15,12 @@ ) - + SELECT tpas.id, tpas.api_scenario_id,tpas.environment,apis.project_id FROM + test_plan_api_scenario tpas INNER JOIN api_scenario apis ON tpas.api_scenario_id = apis.id + WHERE (apis.`status` IS NULL OR apis.`status` != 'Trash') + AND tpas.test_plan_id = #{0} + ORDER BY tpas.`order` DESC;