fix(性能测试): 接口、场景转性能测试时记录选择的环境

接口、场景转性能测试时记录选择的环境
This commit is contained in:
song-tianyang 2022-07-12 19:02:38 +08:00 committed by TIanyang
parent f29e9841ee
commit b4474f6879
28 changed files with 653 additions and 338 deletions

View File

@ -3,6 +3,7 @@ package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.automation.parse.ScenarioToPerformanceInfoDTO;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest;
@ -444,8 +445,13 @@ public class APITestController {
}
@PostMapping(value = "/genPerformanceTestXml", consumes = {"multipart/form-data"})
public JmxInfoDTO genPerformanceTest(@RequestPart("request") RunDefinitionRequest runRequest, @RequestPart(value = "files", required = false) List<MultipartFile> bodyFiles) throws Exception {
return apiTestService.getJmxInfoDTO(runRequest, bodyFiles);
public ScenarioToPerformanceInfoDTO genPerformanceTest(@RequestPart("request") RunDefinitionRequest runRequest, @RequestPart(value = "files", required = false) List<MultipartFile> bodyFiles) throws Exception {
JmxInfoDTO jmxInfoDTO = apiTestService.getJmxInfoDTO(runRequest, bodyFiles);
ScenarioToPerformanceInfoDTO returnDTO = new ScenarioToPerformanceInfoDTO();
returnDTO.setJmxInfoDTO(jmxInfoDTO);
Map<String, List<String>> projectEnvMap = apiTestService.selectEnvironmentByHashTree(runRequest.getProjectId(), runRequest.getTestElement());
returnDTO.setProjectEnvMap(projectEnvMap);
return returnDTO;
}

View File

@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.automation.parse.ScenarioImport;
import io.metersphere.api.dto.automation.parse.ScenarioToPerformanceInfoDTO;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.ApiScenario;
@ -291,13 +292,13 @@ public class ApiAutomationController {
}
@PostMapping(value = "/genPerformanceTestJmx")
public JmxInfoDTO genPerformanceTestJmx(@RequestBody GenScenarioRequest runRequest) throws Exception {
public ScenarioToPerformanceInfoDTO genPerformanceTestJmx(@RequestBody GenScenarioRequest runRequest) throws Exception {
runRequest.setExecuteType(ExecuteType.Completed.name());
return apiAutomationService.genPerformanceTestJmx(runRequest);
}
@PostMapping("/batchGenPerformanceTestJmx")
public List<JmxInfoDTO> batchGenPerformanceTestJmx(@RequestBody ApiScenarioBatchRequest request) {
public ScenarioToPerformanceInfoDTO batchGenPerformanceTestJmx(@RequestBody ApiScenarioBatchRequest request) {
return apiAutomationService.batchGenPerformanceTestJmx(request);
}
@ -366,7 +367,7 @@ public class ApiAutomationController {
@PostMapping(value = "/export/jmx")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EXPORT_SCENARIO)
@MsAuditLog(module = OperLogModule.API_AUTOMATION, type = OperLogConstants.EXPORT, sourceId = "#request.id", title = "#request.name", project = "#request.projectId")
public List<ApiScenarioExportJmxDTO> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
public ScenarioToPerformanceInfoDTO exportJmx(@RequestBody ApiScenarioBatchRequest request) {
return apiAutomationService.exportJmx(request);
}

View File

@ -5,6 +5,7 @@ import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
@Getter
@Setter
@ -16,6 +17,8 @@ public class ApiScenarioExportJmxDTO {
//性能测试引用场景时需要场景下的附件
private List<FileMetadata> fileMetadataList;
//项目-环境id
private Map<String, List<String>> projectEnvMap;
public ApiScenarioExportJmxDTO(String name, String jmx) {
this.name = name;

View File

@ -0,0 +1,22 @@
package io.metersphere.api.dto.automation.parse;
import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.automation.ApiScenarioExportJmxDTO;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
@Getter
@Setter
public class ScenarioToPerformanceInfoDTO {
//批量导出时加载jmx的对象
private List<ApiScenarioExportJmxDTO> scenarioJmxList;
//单独导出时加载jmx的对象
private JmxInfoDTO jmxInfoDTO;
//多个场景批量导出性能测试时
List<JmxInfoDTO> jmxInfoDTOList;
//项目-环境id
private Map<String, List<String>> projectEnvMap;
}

View File

@ -24,8 +24,11 @@ import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.service.ProjectService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -48,6 +51,11 @@ public class ApiScenarioEnvService {
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
@Lazy
@Resource
private ProjectService projectService;
@Resource
private ApiTestEnvironmentService apiTestEnvironmentService;
public ScenarioEnv getApiScenarioEnv(String definition) {
ScenarioEnv env = new ScenarioEnv();
@ -314,7 +322,7 @@ public class ApiScenarioEnvService {
return projectEnvMap;
}
public Map<String, List<String>> selectApiScenarioEnv(List<ApiScenarioWithBLOBs> list) {
public Map<String, List<String>> selectApiScenarioEnv(List<? extends ApiScenarioWithBLOBs> list) {
Map<String, List<String>> projectEnvMap = new LinkedHashMap<>();
for (int i = 0; i < list.size(); i++) {
try {
@ -445,4 +453,22 @@ public class ApiScenarioEnvService {
}
return planEnvMap;
}
public LinkedHashMap<String, List<String>> selectProjectNameAndEnvName(Map<String, List<String>> projectEnvIdMap) {
LinkedHashMap<String, List<String>> returnMap = new LinkedHashMap<>();
if (MapUtils.isNotEmpty(projectEnvIdMap)) {
for (Map.Entry<String, List<String>> entry : projectEnvIdMap.entrySet()) {
String projectId = entry.getKey();
List<String> envIdList = entry.getValue();
String projectName = projectService.selectNameById(projectId);
List<String> envNameList = apiTestEnvironmentService.selectNameByIds(envIdList);
if (CollectionUtils.isNotEmpty(envNameList) && StringUtils.isNotEmpty(projectName)) {
returnMap.put(projectName, new ArrayList<>() {{
this.addAll(envNameList);
}});
}
}
}
return returnMap;
}
}

View File

@ -5,6 +5,9 @@ import io.github.ningyu.jmeter.plugin.dubbo.sample.ProviderService;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
import io.metersphere.api.dto.parse.ApiImport;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
@ -31,6 +34,7 @@ import io.metersphere.dto.ScheduleDao;
import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.ApiTestJob;
import io.metersphere.performance.parse.EngineSourceParserFactory;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.service.FileService;
import io.metersphere.service.ScheduleService;
import io.metersphere.track.service.TestCaseService;
@ -640,4 +644,43 @@ public class APITestService {
dto.setName(runRequest.getName() + ".jmx");
return dto;
}
public Map<String, List<String>> selectEnvironmentByHashTree(String projectId, MsTestElement testElement) {
Map<String, List<String>> projectEnvMap = new HashMap<>();
if (testElement != null) {
List<String> envIdList = this.getEnvIdByHashTree(testElement);
projectEnvMap.put(projectId, envIdList);
}
return projectEnvMap;
}
private List<String> getEnvIdByHashTree(MsTestElement testElement) {
List<String> envIdList = new ArrayList<>();
if (testElement instanceof MsHTTPSamplerProxy) {
String envId = ((MsHTTPSamplerProxy) testElement).getUseEnvironment();
if (StringUtils.isNotEmpty(envId)) {
envIdList.add(envId);
}
} else if (testElement instanceof MsTCPSampler) {
String envId = ((MsTCPSampler) testElement).getUseEnvironment();
if (StringUtils.isNotEmpty(envId)) {
envIdList.add(envId);
}
} else if (testElement instanceof MsJDBCSampler) {
String envId = ((MsJDBCSampler) testElement).getUseEnvironment();
if (StringUtils.isNotEmpty(envId)) {
envIdList.add(envId);
}
} else if (CollectionUtils.isNotEmpty(testElement.getHashTree())) {
for (MsTestElement child : testElement.getHashTree()) {
List<String> childEnvId = this.getEnvIdByHashTree(child);
childEnvId.forEach(envId -> {
if (StringUtils.isNotEmpty(envId) && !envIdList.contains(envId)) {
envIdList.add(envId);
}
});
}
}
return envIdList;
}
}

View File

@ -11,6 +11,7 @@ import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.automation.parse.ApiScenarioImportUtil;
import io.metersphere.api.dto.automation.parse.ScenarioImport;
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
import io.metersphere.api.dto.automation.parse.ScenarioToPerformanceInfoDTO;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.datacount.response.CoverageDTO;
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
@ -1093,7 +1094,8 @@ public class ApiAutomationService {
}
public JmxInfoDTO genPerformanceTestJmx(GenScenarioRequest request) {
public ScenarioToPerformanceInfoDTO genPerformanceTestJmx(GenScenarioRequest request) {
ScenarioToPerformanceInfoDTO returnDTO = new ScenarioToPerformanceInfoDTO();
List<String> ids = request.getIds();
List<ApiScenarioDTO> apiScenarios = extApiScenarioMapper.selectIds(ids);
String id = "";
@ -1103,15 +1105,17 @@ public class ApiAutomationService {
if (CollectionUtils.isEmpty(apiScenarios)) {
return null;
}
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(apiScenarios);
MsTestPlan testPlan = new MsTestPlan();
testPlan.setHashTree(new LinkedList<>());
ApiScenarioDTO scenario = apiScenarios.get(0);
JmxInfoDTO dto = apiTestService.updateJmxString(generateJmx(scenario), scenario.getProjectId(), true);
JmxInfoDTO jmxInfo = apiTestService.updateJmxString(generateJmx(scenario), scenario.getProjectId(), true);
String name = request.getName() + ".jmx";
dto.setName(name);
dto.setId(id);
return dto;
jmxInfo.setName(name);
jmxInfo.setId(id);
returnDTO.setJmxInfoDTO(jmxInfo);
returnDTO.setProjectEnvMap(projectEnvMap);
return returnDTO;
}
public void bathEdit(ApiScenarioBatchRequest request) {
@ -1543,12 +1547,13 @@ public class ApiAutomationService {
}
}
public List<ApiScenarioExportJmxDTO> exportJmx(ApiScenarioBatchRequest request) {
public ScenarioToPerformanceInfoDTO exportJmx(ApiScenarioBatchRequest request) {
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request);
//检查运行环境
checkExportEnv(apiScenarioWithBLOBs);
// 生成jmx
List<ApiScenarioExportJmxDTO> resList = new ArrayList<>();
apiScenarioWithBLOBs.forEach(item -> {
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
String jmx = generateJmx(item);
@ -1559,6 +1564,10 @@ public class ApiAutomationService {
scenariosExportJmx.setVersion(item.getVersion());
//扫描需要哪些文件
scenariosExportJmx.setFileMetadataList(dto.getFileMetadataList());
Map<String, List<String>> projectEnvMap = apiScenarioEnvService.selectApiScenarioEnv(new ArrayList<>() {{
this.add(item);
}});
scenariosExportJmx.setProjectEnvMap(projectEnvMap);
resList.add(scenariosExportJmx);
}
}
@ -1569,7 +1578,10 @@ public class ApiAutomationService {
List<String> ids = apiScenarioWithBLOBs.stream().map(ApiScenarioWithBLOBs::getId).collect(Collectors.toList());
request.setId(JSON.toJSONString(ids));
}
return resList;
ScenarioToPerformanceInfoDTO returnDTO = new ScenarioToPerformanceInfoDTO();
returnDTO.setScenarioJmxList(resList);
return returnDTO;
}
public byte[] exportZip(ApiScenarioBatchRequest request) {
@ -1880,16 +1892,19 @@ public class ApiAutomationService {
LogUtil.info("Reset apiScenarioReferenceId is end.");
}
public List<JmxInfoDTO> batchGenPerformanceTestJmx(ApiScenarioBatchRequest request) {
public ScenarioToPerformanceInfoDTO batchGenPerformanceTestJmx(ApiScenarioBatchRequest request) {
ScenarioToPerformanceInfoDTO returnDTO = new ScenarioToPerformanceInfoDTO();
ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extApiScenarioMapper.selectIdsByQuery(query));
List<JmxInfoDTO> returnList = new ArrayList<>();
List<JmxInfoDTO> jmxInfoList = new ArrayList<>();
List<String> ids = request.getIds();
List<ApiScenarioDTO> apiScenarioList = extApiScenarioMapper.selectIds(ids);
if (CollectionUtils.isEmpty(apiScenarioList)) {
return returnList;
returnDTO.setScenarioJmxList(new ArrayList<>());
return returnDTO;
} else {
Map<String, List<String>> projectEnvironments = apiScenarioEnvService.selectApiScenarioEnv(apiScenarioList);
apiScenarioList.forEach(item -> {
MsTestPlan testPlan = new MsTestPlan();
testPlan.setHashTree(new LinkedList<>());
@ -1897,9 +1912,13 @@ public class ApiAutomationService {
String name = item.getName() + ".jmx";
dto.setId(item.getId());
dto.setName(name);
returnList.add(dto);
jmxInfoList.add(dto);
});
return returnList;
if (MapUtils.isNotEmpty(projectEnvironments)) {
returnDTO.setProjectEnvMap(projectEnvironments);
}
returnDTO.setJmxInfoDTOList(jmxInfoList);
return returnDTO;
}
}

View File

@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import io.metersphere.api.dto.*;
import io.metersphere.api.exec.scenario.ApiScenarioEnvService;
import io.metersphere.api.exec.utils.ResultParseUtil;
import io.metersphere.api.service.vo.ApiDefinitionExecResultVo;
import io.metersphere.base.domain.*;
@ -70,6 +71,9 @@ public class ApiScenarioReportStructureService {
private ProjectService projectService;
@Resource
private ApiTestEnvironmentService apiTestEnvironmentService;
@Lazy
@Resource
private ApiScenarioEnvService apiScenarioEnvService;
public void save(List<ApiScenarioWithBLOBs> apiScenarios, String reportId, String reportType) {
List<StepTreeDTO> dtoList = new LinkedList<>();
@ -563,24 +567,7 @@ public class ApiScenarioReportStructureService {
LogUtil.error("解析RunModeConfig失败!参数:" + envConfig, e);
}
LinkedHashMap<String, List<String>> projectEnvMap = new LinkedHashMap<>();
if (MapUtils.isNotEmpty(envMapByExecution)) {
for (Map.Entry<String, List<String>> entry : envMapByExecution.entrySet()) {
String projectId = entry.getKey();
List<String> envIdList = entry.getValue();
String projectName = projectService.selectNameById(projectId);
List<String> 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);
}
}
LinkedHashMap<String, List<String>> projectEnvMap = apiScenarioEnvService.selectProjectNameAndEnvName(envMapByExecution);
if (MapUtils.isNotEmpty(envMapByRunConfig)) {
for (Map.Entry<String, String> entry : envMapByRunConfig.entrySet()) {
@ -601,6 +588,7 @@ public class ApiScenarioReportStructureService {
}
}
private ApiScenarioReportDTO getReport(String reportId, boolean selectContent) {
List<ApiScenarioReportResultWithBLOBs> reportResults = null;
if (selectContent) {

View File

@ -1,8 +1,7 @@
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
@Data
public class LoadTest implements Serializable {
@ -34,10 +33,10 @@ public class LoadTest implements Serializable {
private Long order;
private String refId;
private String versionId;
private String refId;
private Boolean latest;
private static final long serialVersionUID = 1L;

View File

@ -1034,76 +1034,6 @@ public class LoadTestExample {
return (Criteria) this;
}
public Criteria andRefIdIsNull() {
addCriterion("ref_id is null");
return (Criteria) this;
}
public Criteria andRefIdIsNotNull() {
addCriterion("ref_id is not null");
return (Criteria) this;
}
public Criteria andRefIdEqualTo(String value) {
addCriterion("ref_id =", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotEqualTo(String value) {
addCriterion("ref_id <>", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdGreaterThan(String value) {
addCriterion("ref_id >", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdGreaterThanOrEqualTo(String value) {
addCriterion("ref_id >=", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLessThan(String value) {
addCriterion("ref_id <", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLessThanOrEqualTo(String value) {
addCriterion("ref_id <=", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLike(String value) {
addCriterion("ref_id like", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotLike(String value) {
addCriterion("ref_id not like", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdIn(List<String> values) {
addCriterion("ref_id in", values, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotIn(List<String> values) {
addCriterion("ref_id not in", values, "refId");
return (Criteria) this;
}
public Criteria andRefIdBetween(String value1, String value2) {
addCriterion("ref_id between", value1, value2, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotBetween(String value1, String value2) {
addCriterion("ref_id not between", value1, value2, "refId");
return (Criteria) this;
}
public Criteria andVersionIdIsNull() {
addCriterion("version_id is null");
return (Criteria) this;
@ -1174,6 +1104,76 @@ public class LoadTestExample {
return (Criteria) this;
}
public Criteria andRefIdIsNull() {
addCriterion("ref_id is null");
return (Criteria) this;
}
public Criteria andRefIdIsNotNull() {
addCriterion("ref_id is not null");
return (Criteria) this;
}
public Criteria andRefIdEqualTo(String value) {
addCriterion("ref_id =", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotEqualTo(String value) {
addCriterion("ref_id <>", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdGreaterThan(String value) {
addCriterion("ref_id >", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdGreaterThanOrEqualTo(String value) {
addCriterion("ref_id >=", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLessThan(String value) {
addCriterion("ref_id <", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLessThanOrEqualTo(String value) {
addCriterion("ref_id <=", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdLike(String value) {
addCriterion("ref_id like", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotLike(String value) {
addCriterion("ref_id not like", value, "refId");
return (Criteria) this;
}
public Criteria andRefIdIn(List<String> values) {
addCriterion("ref_id in", values, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotIn(List<String> values) {
addCriterion("ref_id not in", values, "refId");
return (Criteria) this;
}
public Criteria andRefIdBetween(String value1, String value2) {
addCriterion("ref_id between", value1, value2, "refId");
return (Criteria) this;
}
public Criteria andRefIdNotBetween(String value1, String value2) {
addCriterion("ref_id not between", value1, value2, "refId");
return (Criteria) this;
}
public Criteria andLatestIsNull() {
addCriterion("latest is null");
return (Criteria) this;

View File

@ -17,5 +17,7 @@ public class LoadTestReportWithBLOBs extends LoadTestReport implements Serializa
private String advancedConfiguration;
private String envInfo;
private static final long serialVersionUID = 1L;
}

View File

@ -13,5 +13,7 @@ public class LoadTestWithBLOBs extends LoadTest implements Serializable {
private String advancedConfiguration;
private String envInfo;
private static final long serialVersionUID = 1L;
}

View File

@ -16,13 +16,14 @@
<result column="scenario_version" jdbcType="INTEGER" property="scenarioVersion" />
<result column="scenario_id" jdbcType="VARCHAR" property="scenarioId" />
<result column="order" jdbcType="BIGINT" property="order" />
<result column="ref_id" jdbcType="VARCHAR" property="refId" />
<result column="version_id" jdbcType="VARCHAR" property="versionId" />
<result column="ref_id" jdbcType="VARCHAR" property="refId" />
<result column="latest" jdbcType="BIT" property="latest" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.LoadTestWithBLOBs">
<result column="load_configuration" jdbcType="LONGVARCHAR" property="loadConfiguration" />
<result column="advanced_configuration" jdbcType="LONGVARCHAR" property="advancedConfiguration" />
<result column="env_info" jdbcType="LONGVARCHAR" property="envInfo" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -84,11 +85,11 @@
</sql>
<sql id="Base_Column_List">
id, project_id, `name`, description, create_time, update_time, `status`, test_resource_pool_id,
user_id, num, create_user, scenario_version, scenario_id, `order`, ref_id, version_id,
user_id, num, create_user, scenario_version, scenario_id, `order`, version_id, ref_id,
latest
</sql>
<sql id="Blob_Column_List">
load_configuration, advanced_configuration
load_configuration, advanced_configuration, env_info
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestExample" resultMap="ResultMapWithBLOBs">
select
@ -139,20 +140,20 @@
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.LoadTestWithBLOBs">
INSERT INTO load_test (id, project_id, `name`,
insert into load_test (id, project_id, `name`,
description, create_time, update_time,
`status`, test_resource_pool_id, user_id,
num, create_user, scenario_version,
scenario_id, `order`, ref_id,
version_id, latest, load_configuration,
advanced_configuration)
VALUES (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
scenario_id, `order`, version_id,
ref_id, latest, load_configuration,
advanced_configuration, env_info)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{status,jdbcType=VARCHAR}, #{testResourcePoolId,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR},
#{num,jdbcType=INTEGER}, #{createUser,jdbcType=VARCHAR}, #{scenarioVersion,jdbcType=INTEGER},
#{scenarioId,jdbcType=VARCHAR}, #{order,jdbcType=BIGINT}, #{refId,jdbcType=VARCHAR},
#{versionId,jdbcType=VARCHAR}, #{latest,jdbcType=BIT}, #{loadConfiguration,jdbcType=LONGVARCHAR},
#{advancedConfiguration,jdbcType=LONGVARCHAR})
#{scenarioId,jdbcType=VARCHAR}, #{order,jdbcType=BIGINT}, #{versionId,jdbcType=VARCHAR},
#{refId,jdbcType=VARCHAR}, #{latest,jdbcType=BIT}, #{loadConfiguration,jdbcType=LONGVARCHAR},
#{advancedConfiguration,jdbcType=LONGVARCHAR}, #{envInfo,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestWithBLOBs">
insert into load_test
@ -199,12 +200,12 @@
<if test="order != null">
`order`,
</if>
<if test="refId != null">
ref_id,
</if>
<if test="versionId != null">
version_id,
</if>
<if test="refId != null">
ref_id,
</if>
<if test="latest != null">
latest,
</if>
@ -214,6 +215,9 @@
<if test="advancedConfiguration != null">
advanced_configuration,
</if>
<if test="envInfo != null">
env_info,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -258,12 +262,12 @@
<if test="order != null">
#{order,jdbcType=BIGINT},
</if>
<if test="refId != null">
#{refId,jdbcType=VARCHAR},
</if>
<if test="versionId != null">
#{versionId,jdbcType=VARCHAR},
</if>
<if test="refId != null">
#{refId,jdbcType=VARCHAR},
</if>
<if test="latest != null">
#{latest,jdbcType=BIT},
</if>
@ -273,6 +277,9 @@
<if test="advancedConfiguration != null">
#{advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="envInfo != null">
#{envInfo,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.LoadTestExample" resultType="java.lang.Long">
@ -326,12 +333,12 @@
<if test="record.order != null">
`order` = #{record.order,jdbcType=BIGINT},
</if>
<if test="record.refId != null">
ref_id = #{record.refId,jdbcType=VARCHAR},
</if>
<if test="record.versionId != null">
version_id = #{record.versionId,jdbcType=VARCHAR},
</if>
<if test="record.refId != null">
ref_id = #{record.refId,jdbcType=VARCHAR},
</if>
<if test="record.latest != null">
latest = #{record.latest,jdbcType=BIT},
</if>
@ -341,6 +348,9 @@
<if test="record.advancedConfiguration != null">
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="record.envInfo != null">
env_info = #{record.envInfo,jdbcType=LONGVARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -362,11 +372,12 @@
scenario_version = #{record.scenarioVersion,jdbcType=INTEGER},
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
`order` = #{record.order,jdbcType=BIGINT},
ref_id = #{record.refId,jdbcType=VARCHAR},
version_id = #{record.versionId,jdbcType=VARCHAR},
ref_id = #{record.refId,jdbcType=VARCHAR},
latest = #{record.latest,jdbcType=BIT},
load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR},
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR}
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR},
env_info = #{record.envInfo,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -387,8 +398,8 @@
scenario_version = #{record.scenarioVersion,jdbcType=INTEGER},
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
`order` = #{record.order,jdbcType=BIGINT},
ref_id = #{record.refId,jdbcType=VARCHAR},
version_id = #{record.versionId,jdbcType=VARCHAR},
ref_id = #{record.refId,jdbcType=VARCHAR},
latest = #{record.latest,jdbcType=BIT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -436,12 +447,12 @@
<if test="order != null">
`order` = #{order,jdbcType=BIGINT},
</if>
<if test="refId != null">
ref_id = #{refId,jdbcType=VARCHAR},
</if>
<if test="versionId != null">
version_id = #{versionId,jdbcType=VARCHAR},
</if>
<if test="refId != null">
ref_id = #{refId,jdbcType=VARCHAR},
</if>
<if test="latest != null">
latest = #{latest,jdbcType=BIT},
</if>
@ -451,6 +462,9 @@
<if test="advancedConfiguration != null">
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="envInfo != null">
env_info = #{envInfo,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -469,11 +483,12 @@
scenario_version = #{scenarioVersion,jdbcType=INTEGER},
scenario_id = #{scenarioId,jdbcType=VARCHAR},
`order` = #{order,jdbcType=BIGINT},
ref_id = #{refId,jdbcType=VARCHAR},
version_id = #{versionId,jdbcType=VARCHAR},
ref_id = #{refId,jdbcType=VARCHAR},
latest = #{latest,jdbcType=BIT},
load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR},
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR}
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR},
env_info = #{envInfo,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.LoadTest">
@ -491,8 +506,8 @@
scenario_version = #{scenarioVersion,jdbcType=INTEGER},
scenario_id = #{scenarioId,jdbcType=VARCHAR},
`order` = #{order,jdbcType=BIGINT},
ref_id = #{refId,jdbcType=VARCHAR},
version_id = #{versionId,jdbcType=VARCHAR},
ref_id = #{refId,jdbcType=VARCHAR},
latest = #{latest,jdbcType=BIT}
where id = #{id,jdbcType=VARCHAR}
</update>

View File

@ -27,6 +27,7 @@
<result column="load_configuration" jdbcType="LONGVARCHAR" property="loadConfiguration" />
<result column="jmx_content" jdbcType="LONGVARCHAR" property="jmxContent" />
<result column="advanced_configuration" jdbcType="LONGVARCHAR" property="advancedConfiguration" />
<result column="env_info" jdbcType="LONGVARCHAR" property="envInfo" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -92,7 +93,7 @@
test_start_time, test_end_time, test_duration, version_id
</sql>
<sql id="Blob_Column_List">
description, load_configuration, jmx_content, advanced_configuration
description, load_configuration, jmx_content, advanced_configuration, env_info
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReportExample" resultMap="ResultMapWithBLOBs">
select
@ -150,8 +151,8 @@
project_id, test_name, test_resource_pool_id,
test_start_time, test_end_time, test_duration,
version_id, description, load_configuration,
jmx_content, advanced_configuration
)
jmx_content, advanced_configuration,
env_info)
values (#{id,jdbcType=VARCHAR}, #{testId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR},
#{userId,jdbcType=VARCHAR}, #{triggerMode,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR},
@ -159,8 +160,8 @@
#{projectId,jdbcType=VARCHAR}, #{testName,jdbcType=VARCHAR}, #{testResourcePoolId,jdbcType=VARCHAR},
#{testStartTime,jdbcType=BIGINT}, #{testEndTime,jdbcType=BIGINT}, #{testDuration,jdbcType=BIGINT},
#{versionId,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR}, #{loadConfiguration,jdbcType=LONGVARCHAR},
#{jmxContent,jdbcType=LONGVARCHAR}, #{advancedConfiguration,jdbcType=LONGVARCHAR}
)
#{jmxContent,jdbcType=LONGVARCHAR}, #{advancedConfiguration,jdbcType=LONGVARCHAR},
#{envInfo,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestReportWithBLOBs">
insert into load_test_report
@ -234,6 +235,9 @@
<if test="advancedConfiguration != null">
advanced_configuration,
</if>
<if test="envInfo != null">
env_info,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -305,6 +309,9 @@
<if test="advancedConfiguration != null">
#{advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="envInfo != null">
#{envInfo,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.LoadTestReportExample" resultType="java.lang.Long">
@ -385,6 +392,9 @@
<if test="record.advancedConfiguration != null">
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="record.envInfo != null">
env_info = #{record.envInfo,jdbcType=LONGVARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -414,7 +424,8 @@
description = #{record.description,jdbcType=LONGVARCHAR},
load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR},
jmx_content = #{record.jmxContent,jdbcType=LONGVARCHAR},
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR}
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR},
env_info = #{record.envInfo,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -513,6 +524,9 @@
<if test="advancedConfiguration != null">
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR},
</if>
<if test="envInfo != null">
env_info = #{envInfo,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -539,7 +553,8 @@
description = #{description,jdbcType=LONGVARCHAR},
load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR},
jmx_content = #{jmxContent,jdbcType=LONGVARCHAR},
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR}
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR},
env_info = #{envInfo,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.LoadTestReport">

View File

@ -42,6 +42,11 @@ public class WebConfig implements WebMvcConfigurer {
return setTemplate();
}
@Bean
public RestTemplate restTemplateWithTimeOut() {
return setTemplate();
}
@Bean
public HttpClient httpClient() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()

View File

@ -1,6 +1,6 @@
package io.metersphere.dto;
import io.metersphere.base.domain.LoadTest;
import io.metersphere.base.domain.LoadTestWithBLOBs;
import io.metersphere.base.domain.Schedule;
import lombok.Getter;
import lombok.Setter;
@ -9,7 +9,7 @@ import java.util.List;
@Getter
@Setter
public class LoadTestDTO extends LoadTest {
public class LoadTestDTO extends LoadTestWithBLOBs {
private String projectName;
private String userName;
private String versionName;

View File

@ -0,0 +1,15 @@
package io.metersphere.dto;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
@Getter
@Setter
public class LoadTestReportInfoDTO extends LoadTestReportWithBLOBs {
//项目环境
private Map<String, List<String>> projectEnvMap;
}

View File

@ -15,4 +15,5 @@ public class SaveTestPlanRequest extends TestPlanRequest {
private Map<String, Integer> fileSorts;
private List<String> conversionFileIdList;
private List<ApiLoadTest> apiList;
private Map<String, List<String>> projectEnvMap;
}

View File

@ -2,6 +2,7 @@ package io.metersphere.performance.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.exec.scenario.ApiScenarioEnvService;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtFileContentMapper;
@ -9,10 +10,12 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.constants.PerformanceTestStatus;
import io.metersphere.commons.constants.ReportKeys;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.controller.request.OrderRequest;
import io.metersphere.dto.LoadTestReportInfoDTO;
import io.metersphere.dto.LogDetailDTO;
import io.metersphere.dto.ReportDTO;
import io.metersphere.i18n.Translator;
@ -32,11 +35,13 @@ import io.metersphere.service.QuotaService;
import io.metersphere.service.TestResourceService;
import io.metersphere.track.service.TestPlanLoadCaseService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -84,6 +89,9 @@ public class PerformanceReportService {
private ProjectMapper projectMapper;
@Resource
private LoadTestReportFileMapper loadTestReportFileMapper;
@Lazy
@Resource
private ApiScenarioEnvService apiScenarioEnvService;
public List<ReportDTO> getRecentReportList(ReportRequest request) {
List<OrderRequest> orders = new ArrayList<>();
@ -317,8 +325,27 @@ public class PerformanceReportService {
return StringUtils.equals(PerformanceTestStatus.Error.name(), reportStatus);
}
public LoadTestReportWithBLOBs getLoadTestReport(String id) {
return loadTestReportMapper.selectByPrimaryKey(id);
public LoadTestReportInfoDTO getLoadTestReport(String id) {
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
LoadTestReportInfoDTO returnDTO = new LoadTestReportInfoDTO();
BeanUtils.copyBean(returnDTO, loadTestReport);
this.parseRunEnvironment(returnDTO);
return returnDTO;
}
private void parseRunEnvironment(LoadTestReportInfoDTO loadTestReportInfoDTO) {
if (loadTestReportInfoDTO != null && StringUtils.isNotEmpty(loadTestReportInfoDTO.getEnvInfo())) {
Map<String, List<String>> projectEnvIdMap = new HashMap<>();
try {
projectEnvIdMap = JSONObject.parseObject(loadTestReportInfoDTO.getEnvInfo(), Map.class);
LinkedHashMap<String, List<String>> projectEnvNameMap = apiScenarioEnvService.selectProjectNameAndEnvName(projectEnvIdMap);
if (MapUtils.isNotEmpty(projectEnvNameMap)) {
loadTestReportInfoDTO.setProjectEnvMap(projectEnvNameMap);
}
} catch (Exception e) {
LogUtil.error("性能测试报告解析运行环境信息失败!解析参数:" + loadTestReportInfoDTO.getEnvInfo(), e);
}
}
}
public List<LogDetailDTO> getReportLogResource(String reportId) {

View File

@ -49,6 +49,7 @@ import io.metersphere.track.service.TestCaseService;
import io.metersphere.track.service.TestPlanLoadCaseService;
import io.metersphere.track.service.TestPlanProjectService;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
@ -290,6 +291,9 @@ public class PerformanceTestService {
loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration());
loadTest.setStatus(PerformanceTestStatus.Saved.name());
loadTest.setNum(getNextNum(request.getProjectId()));
if (MapUtils.isNotEmpty(request.getProjectEnvMap())) {
loadTest.setEnvInfo(JSONObject.toJSONString(request.getProjectEnvMap()));
}
loadTest.setOrder(ServiceUtils.getNextOrder(request.getProjectId(), extLoadTestMapper::getLastOrder));
loadTest.setVersionId(request.getVersionId());
loadTest.setRefId(request.getId());
@ -487,6 +491,7 @@ public class PerformanceTestService {
testReport.setStatus(PerformanceTestStatus.Starting.name());
testReport.setProjectId(loadTest.getProjectId());
testReport.setTestName(loadTest.getName());
testReport.setEnvInfo(loadTest.getEnvInfo());
loadTestReportMapper.insertSelective(testReport);
// engine
@ -883,7 +888,7 @@ public class PerformanceTestService {
if (!CollectionUtils.isEmpty(scenarioIds)) {
ApiScenarioBatchRequest scenarioRequest = new ApiScenarioBatchRequest();
scenarioRequest.setIds(scenarioIds);
List<ApiScenarioExportJmxDTO> apiScenrioExportJmxes = apiAutomationService.exportJmx(scenarioRequest);
List<ApiScenarioExportJmxDTO> apiScenrioExportJmxes = apiAutomationService.exportJmx(scenarioRequest).getScenarioJmxList();
deleteLoadTestFiles(loadTest.getId());

View File

@ -1336,7 +1336,10 @@ export default {
let param = {};
this.buildBatchParam(param);
this.$post('/api/automation/batchGenPerformanceTestJmx/', param, response => {
let returnDataList = response.data;
let returnDTO = response.data;
let projectEnvMap = returnDTO.projectEnvMap;
let returnDataList = returnDTO.jmxInfoDTOList;
let jmxObjList = [];
returnDataList.forEach(item => {
let jmxObj = {};
@ -1350,7 +1353,8 @@ export default {
});
this.$store.commit('setScenarioJmxs', {
name: 'Scenarios',
jmxs: jmxObjList
jmxs: jmxObjList,
projectEnvMap: projectEnvMap,
});
this.$router.push({
path: "/performance/test/create"

View File

@ -64,20 +64,25 @@ export default {
run.id = getUUID();
run.name = row.name;
this.$post(url, run, response => {
let jmxObj = {};
jmxObj.name = response.data.name;
jmxObj.xml = response.data.xml;
jmxObj.attachFiles = response.data.attachFiles;
jmxObj.attachByteFiles = response.data.attachByteFiles;
jmxObj.scenarioId = row.id;
jmxObj.version = row.version;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj
});
this.$router.push({
path: "/performance/test/create"
});
let jmxInfo = response.data.jmxInfoDTO;
if (jmxInfo) {
let projectEnvMap = response.data.projectEnvMap;
let jmxObj = {};
jmxObj.name = jmxInfo.name;
jmxObj.xml = jmxInfo.xml;
jmxObj.attachFiles = jmxInfo.attachFiles;
jmxObj.attachByteFiles = jmxInfo.attachByteFiles;
jmxObj.scenarioId = row.id;
jmxObj.version = row.version;
jmxObj.projectEnvMap = projectEnvMap;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj
});
this.$router.push({
path: "/performance/test/create"
});
}
});
},
openScenario(item) {

View File

@ -1274,21 +1274,26 @@ export default {
let url = "/api/genPerformanceTestXml";
this.$fileUpload(url, null, bodyFiles, reqObj, response => {
let jmxObj = {};
jmxObj.name = response.data.name;
jmxObj.xml = response.data.xml;
jmxObj.attachFiles = response.data.attachFiles;
jmxObj.attachByteFiles = response.data.attachByteFiles;
jmxObj.caseId = reqObj.id;
jmxObj.version = row.version;
jmxObj.envId = environment.id;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj
});
this.$router.push({
path: "/performance/test/create"
});
let jmxInfo = response.data.jmxInfoDTO;
if (jmxInfo) {
let projectEnvMap = response.data.projectEnvMap;
let jmxObj = {};
jmxObj.name = jmxInfo.name;
jmxObj.xml = jmxInfo.xml;
jmxObj.attachFiles = jmxInfo.attachFiles;
jmxObj.attachByteFiles = jmxInfo.attachByteFiles;
jmxObj.caseId = reqObj.id;
jmxObj.version = row.version;
jmxObj.envId = environment.id;
jmxObj.projectEnvMap = projectEnvMap;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj
});
this.$router.push({
path: "/performance/test/create"
});
}
}, erro => {
this.$emit('runRefresh', {});
});

View File

@ -5,140 +5,150 @@
</el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="ref">{{ $t('api_test.automation.view_ref') }}</el-dropdown-item>
<el-dropdown-item command="create_performance" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_PERFORMANCE']">{{ $t('api_test.create_performance_test') }}</el-dropdown-item>
<el-dropdown-item command="create_performance" v-permission="['PROJECT_API_DEFINITION:READ+CREATE_PERFORMANCE']">
{{ $t('api_test.create_performance_test') }}
</el-dropdown-item>
</el-dropdown-menu>
<ms-reference-view ref="viewRef"/>
</el-dropdown>
</template>
<script>
import MsReferenceView from "./ReferenceView";
import MsTestPlanList from "../../../automation/scenario/testplan/TestPlanList";
import {getBodyUploadFiles, getCurrentProjectID, getUUID, strMapToObj} from "@/common/js/utils";
import TestPlan from "@/business/components/api/definition/components/jmeter/components/test-plan";
import ThreadGroup from "@/business/components/api/definition/components/jmeter/components/thread-group";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
import MsReferenceView from "./ReferenceView";
import MsTestPlanList from "../../../automation/scenario/testplan/TestPlanList";
import {getBodyUploadFiles, getCurrentProjectID} from "@/common/js/utils";
import TestPlan from "@/business/components/api/definition/components/jmeter/components/test-plan";
import ThreadGroup from "@/business/components/api/definition/components/jmeter/components/thread-group";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
export default {
name: "MsApiExtendBtns",
components: {MsReferenceView, MsTestPlanList},
props: {
row: Object,
isCaseEdit: Boolean,
environment: {},
},
data() {
return {
planVisible: false,
export default {
name: "MsApiExtendBtns",
components: {MsReferenceView, MsTestPlanList},
props: {
row: Object,
isCaseEdit: Boolean,
environment: {},
},
data() {
return {
planVisible: false,
}
},
methods: {
handleCommand(cmd) {
if (this.row.id) {
switch (cmd) {
case "ref":
this.$refs.viewRef.open(this.row);
break;
case "create_performance":
this.createPerformance(this.row);
break;
}
} else {
this.$warning(this.$t('api_test.automation.save_case_info'))
}
},
methods: {
handleCommand(cmd) {
if (this.row.id) {
switch (cmd) {
case "ref":
this.$refs.viewRef.open(this.row);
break;
case "create_performance":
this.createPerformance(this.row);
break;
sortHashTree(stepArray) {
if (stepArray) {
for (let i in stepArray) {
if (!stepArray[i].clazzName) {
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
}
} else {
this.$warning(this.$t('api_test.automation.save_case_info'))
}
},
sortHashTree(stepArray) {
if (stepArray) {
for (let i in stepArray) {
if (!stepArray[i].clazzName) {
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
}
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
stepArray[i].document = {type: "JSON", data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}};
}
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
}
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
this.sortHashTree(stepArray[i].hashTree);
}
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
stepArray[i].document = {
type: "JSON",
data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}
};
}
if (stepArray[i] && stepArray[i].authManager && !stepArray[i].authManager.clazzName) {
stepArray[i].authManager.clazzName = TYPE_TO_C.get(stepArray[i].authManager.type);
}
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
this.sortHashTree(stepArray[i].hashTree);
}
}
},
createPerformance(row) {
/**
* 思路调用后台创建性能测试的方法把当前案例的hashTree在后台转化为jmx并文件创建性能测试
* 然后跳转到修改性能测试的页面
*
* 性能测试保存地址 performance/save
*
*/
if (!this.environment || !this.environment) {
this.$warning(this.$t('api_test.environment.select_environment'));
return;
}
},
createPerformance(row) {
/**
* 思路调用后台创建性能测试的方法把当前案例的hashTree在后台转化为jmx并文件创建性能测试
* 然后跳转到修改性能测试的页面
*
* 性能测试保存地址 performance/save
*
*/
if (!this.environment || !this.environment) {
this.$warning(this.$t('api_test.environment.select_environment'));
return;
}
let projectId = getCurrentProjectID();
this.runData = [];
this.singleLoading = true;
this.row.request.name = this.row.id;
this.row.request.useEnvironment = this.environment;
this.runData.push(this.row.request);
/*触发执行操作*/
let testPlan = new TestPlan();
testPlan.clazzName = TYPE_TO_C.get(testPlan.type);
let threadGroup = new ThreadGroup();
threadGroup.clazzName = TYPE_TO_C.get(threadGroup.type);
threadGroup.hashTree = [];
testPlan.hashTree = [threadGroup];
this.runData.forEach(item => {
item.projectId = projectId;
if (!item.clazzName) {
item.clazzName = TYPE_TO_C.get(item.type);
}
let projectId = getCurrentProjectID();
this.runData = [];
this.singleLoading = true;
this.row.request.name = this.row.id;
this.row.request.useEnvironment = this.environment;
this.runData.push(this.row.request);
/*触发执行操作*/
let testPlan = new TestPlan();
testPlan.clazzName = TYPE_TO_C.get(testPlan.type);
let threadGroup = new ThreadGroup();
threadGroup.clazzName = TYPE_TO_C.get(threadGroup.type);
threadGroup.hashTree = [];
testPlan.hashTree = [threadGroup];
this.runData.forEach(item => {
item.projectId = projectId;
if (!item.clazzName) {
item.clazzName = TYPE_TO_C.get(item.type);
}
threadGroup.hashTree.push(item);
});
this.sortHashTree(testPlan.hashTree);
let reqObj = {
id: row.id,
testElement: testPlan,
type: this.type,
name: row.name,
clazzName: this.clazzName ? this.clazzName : TYPE_TO_C.get(this.type),
projectId: getCurrentProjectID(),
environmentMap: new Map([
[projectId, this.environment.id]
]),
};
threadGroup.hashTree.push(item);
});
this.sortHashTree(testPlan.hashTree);
let reqObj = {
id: row.id,
testElement: testPlan,
type: this.type,
name: row.name,
clazzName: this.clazzName ? this.clazzName : TYPE_TO_C.get(this.type),
projectId: getCurrentProjectID(),
environmentMap: new Map([
[projectId, this.environment.id]
]),
};
let bodyFiles = getBodyUploadFiles(reqObj, this.runData);
reqObj.reportId = "run";
let url = "/api/genPerformanceTestXml";
this.$fileUpload(url, null, bodyFiles, reqObj, response => {
let bodyFiles = getBodyUploadFiles(reqObj, this.runData);
reqObj.reportId = "run";
let url = "/api/genPerformanceTestXml";
this.$fileUpload(url, null, bodyFiles, reqObj, response => {
let jmxInfo = response.data.jmxInfoDTO;
if (jmxInfo) {
let projectEnvMap = response.data.projectEnvMap;
let jmxObj = {};
jmxObj.name = response.data.name;
jmxObj.xml = response.data.xml;
jmxObj.attachFiles = response.data.attachFiles;
jmxObj.attachByteFiles = response.data.attachByteFiles;
jmxObj.name = jmxInfo.name;
jmxObj.xml = jmxInfo.xml;
jmxObj.attachFiles = jmxInfo.attachFiles;
jmxObj.attachByteFiles = jmxInfo.attachByteFiles;
jmxObj.caseId = reqObj.id;
jmxObj.version = row.version;
jmxObj.envId = this.environment;
jmxObj.projectEnvMap = projectEnvMap;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj
})
this.$router.push({
path: "/performance/test/create"
})
}, erro => {
this.$emit('runRefresh', {});
});
}
});
}
}, erro => {
this.$emit('runRefresh', {});
});
}
}
}
</script>
<style scoped>
.scenario-ext-btn {
margin-left: 10px;
}
.scenario-ext-btn {
margin-left: 10px;
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<el-dialog
:title="$t('commons.environment')"
:visible.sync="dialogVisible"
width="30%"
:destroy-on-close="true"
:before-close="handleClose">
<div>
<div v-if="projectEnvMap" type="flex">
<div v-for="(values,key) in projectEnvMap" :key="key" style="margin-right: 10px">
{{ key + ":" }}
<ms-tag v-for="(item,index) in values" :key="index" type="success" :content="item"
style="margin-left: 2px"/>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
import MsTag from "@/business/components/common/components/MsTag";
export default {
name: "ProjectEnvironmentDialog",
components: {MsTag},
data() {
return {
projectEnvMap: {},
dialogVisible: false
}
},
methods: {
handleClose() {
this.dialogVisible = false;
this.projectEnvMap = {};
},
open(projectEnvMap) {
this.dialogVisible = true;
this.projectEnvMap = projectEnvMap;
}
}
}
</script>
<style scoped>
</style>

View File

@ -2,8 +2,8 @@
<ms-container>
<ms-main-container>
<el-card v-loading="result.loading">
<el-row>
<el-col :span="16">
<el-row :gutter="10">
<el-col :span="14">
<el-row>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/performance/test/' + this.projectId }">{{ projectName }}
@ -37,7 +37,7 @@
width="300">
<p>{{ shareUrl }}</p>
<span style="color: red;float: left;margin-left: 10px;" v-if="application.typeValue">{{
$t('commons.validity_period')+application.typeValue
$t('commons.validity_period') + application.typeValue
}}</span>
<div style="text-align: right; margin: 0">
<el-button type="primary" size="mini" :disabled="!shareUrl"
@ -62,22 +62,37 @@
</el-button>
</el-row>
</el-col>
<el-col :span="6">
<span class="ms-report-time-desc">
{{ $t('report.test_duration', [this.minutes, this.seconds]) }}
</span>
<span class="ms-report-time-desc" v-if="startTime !== '0'">
{{ $t('report.test_start_time') }}{{ startTime | timestampFormatDate }}
</span>
<span class="ms-report-time-desc" v-else>
{{ $t('report.test_start_time') }}-
</span>
<span class="ms-report-time-desc" v-if="report.status === 'Completed' && endTime !== '0'">
{{ $t('report.test_end_time') }}{{ endTime | timestampFormatDate }}
</span>
<span class="ms-report-time-desc" v-else>
{{ $t('report.test_end_time') }}-
</span>
<el-col :span="8">
<div style="float: right;">
<span class="ms-report-time-desc">
{{ $t('report.test_duration', [this.minutes, this.seconds]) }}
</span>
<span class="ms-report-time-desc" v-if="startTime !== '0'">
{{ $t('report.test_start_time') }}{{ startTime | timestampFormatDate }}
</span>
<span class="ms-report-time-desc" v-else>
{{ $t('report.test_start_time') }}-
</span>
<span class="ms-report-time-desc" v-if="report.status === 'Completed' && endTime !== '0'">
{{ $t('report.test_end_time') }}{{ endTime | timestampFormatDate }}
</span>
<span class="ms-report-time-desc" v-else>
{{ $t('report.test_end_time') }}-
</span>
</div>
<div style="float: right;margin-right: 10px;">
<div v-if="projectEnvMap" type="flex">
<span> {{ $t('commons.environment') + ':' }} </span>
<div v-for="(values,key) in projectEnvMap" :key="key" style="margin-right: 10px">
{{ key + ":" }}
<ms-tag v-for="(item,index) in values" :key="index" type="success" :content="item"
style="margin-left: 2px"/>
</div>
<div v-show="showMoreProjectEnvMap">
<el-link icon="el-icon-more" @click="showAllProjectInfo"></el-link>
</div>
</div>
</div>
</el-col>
<el-col :span="2">
<el-select v-model="refreshTime"
@ -139,6 +154,7 @@
</el-button>
</div>
</el-dialog>
<project-environment-dialog ref="projectEnvDialog"></project-environment-dialog>
</ms-main-container>
<same-test-reports ref="compareReports"/>
</ms-container>
@ -152,7 +168,7 @@ import MsReportTestDetails from './components/TestDetails';
import MsReportTestOverview from './components/TestOverview';
import MsContainer from "../../common/components/MsContainer";
import MsMainContainer from "../../common/components/MsMainContainer";
import MsTag from "@/business/components/common/components/MsTag";
import {exportPdf, getCurrentProjectID, hasPermission} from "@/common/js/utils";
import html2canvas from 'html2canvas';
import MsPerformanceReportExport from "./PerformanceReportExport";
@ -161,6 +177,7 @@ import SameTestReports from "@/business/components/performance/report/components
import MonitorCard from "@/business/components/performance/report/components/MonitorCard";
import MsTestConfiguration from "@/business/components/performance/report/components/TestConfiguration";
import {generateShareInfoWithExpired} from "@/network/share";
import ProjectEnvironmentDialog from "@/business/components/common/dialog/ProjectEnvironmentDialog";
export default {
@ -177,6 +194,8 @@ export default {
MsContainer,
MsMainContainer,
MsReportTestDetails,
MsTag,
ProjectEnvironmentDialog
},
props: {
perReportId: String
@ -203,6 +222,9 @@ export default {
dialogFormVisible: false,
reportExportVisible: false,
test: {testResourcePoolId: null},
projectEnvMap: null,
showMoreProjectEnvMap: false,
allProjectEnvMap: null,
refreshTime: localStorage.getItem("reportRefreshTime") || "10",
refreshTimes: [
{value: '1', label: '1s'},
@ -216,10 +238,13 @@ export default {
],
testDeleted: false,
shareUrl: "",
application:{}
application: {}
};
},
methods: {
showAllProjectInfo() {
this.$refs.projectEnvDialog.open(this.allProjectEnvMap);
},
initBreadcrumb(callback) {
if (this.reportId) {
this.result = this.$get("/performance/report/test/pro/info/" + this.reportId, res => {
@ -375,22 +400,19 @@ export default {
this.shareUrl = thisHost + "/sharePerformanceReport" + data.shareUrl;
});
},
getProjectApplication(){
this.$get('/project_application/get/' + getCurrentProjectID()+"/PERFORMANCE_SHARE_REPORT_TIME", res => {
if(res.data){
getProjectApplication() {
this.$get('/project_application/get/' + getCurrentProjectID() + "/PERFORMANCE_SHARE_REPORT_TIME", res => {
if (res.data) {
let quantity = res.data.typeValue.substring(0, res.data.typeValue.length - 1);
let unit = res.data.typeValue.substring(res.data.typeValue.length - 1);
if(unit==='H'){
res.data.typeValue = quantity+this.$t('commons.date_unit.hour');
}else
if(unit==='D'){
res.data.typeValue = quantity+this.$t('commons.date_unit.day');
}else
if(unit==='M'){
res.data.typeValue = quantity+this.$t('commons.workspace_unit')+this.$t('commons.date_unit.month');
}else
if(unit==='Y'){
res.data.typeValue = quantity+this.$t('commons.date_unit.year');
if (unit === 'H') {
res.data.typeValue = quantity + this.$t('commons.date_unit.hour');
} else if (unit === 'D') {
res.data.typeValue = quantity + this.$t('commons.date_unit.day');
} else if (unit === 'M') {
res.data.typeValue = quantity + this.$t('commons.workspace_unit') + this.$t('commons.date_unit.month');
} else if (unit === 'Y') {
res.data.typeValue = quantity + this.$t('commons.date_unit.year');
}
this.application = res.data;
}
@ -458,10 +480,29 @@ export default {
compareReports() {
this.$refs.compareReports.open(this.report);
},
isProjectEnvShowMore(projectEnvMap) {
this.showMoreProjectEnvMap = false;
this.projectEnvMap = {};
if (projectEnvMap) {
let keySize = 0;
for (let key in projectEnvMap) {
keySize++;
if (keySize > 1) {
this.showMoreProjectEnvMap = true;
return;
} else {
this.projectEnvMap = {};
this.$set(this.projectEnvMap, key, projectEnvMap[key]);
}
}
}
},
getReport(reportId) {
this.result = this.$get("/performance/report/" + reportId, res => {
let data = res.data;
if (data) {
this.allProjectEnvMap = data.projectEnvMap;
this.isProjectEnvShowMore(data.projectEnvMap);
this.status = data.status;
this.$set(this, "report", data);
this.$set(this.test, "testResourcePoolId", data.testResourcePoolId);
@ -504,7 +545,7 @@ export default {
this.getReport(this.reportId);
this.$EventBus.$on('projectChange', this.handleProjectChange);
},
destroyed () {
destroyed() {
this.$EventBus.$off('projectChange', this.handleProjectChange);
},
watch: {

View File

@ -160,6 +160,7 @@ export default {
}],
maintainerOptions: [],
versionData: [],
projectEnvMap: {},
};
},
watch: {
@ -191,7 +192,7 @@ export default {
}
this.$EventBus.$on('projectChange', this.handleProjectChange);
},
destroyed () {
destroyed() {
this.$EventBus.$off('projectChange', this.handleProjectChange);
},
mounted() {
@ -214,6 +215,9 @@ export default {
let apiTest = this.$store.state.test;
if (apiTest && apiTest.name) {
this.$set(this.test, "name", apiTest.name);
if (apiTest.jmx.projectEnvMap) {
this.projectEnvMap = apiTest.jmx.projectEnvMap;
}
if (apiTest.jmx.scenarioId) {
this.$refs.basicConfig.importScenario(apiTest.jmx.scenarioId);
this.$refs.basicConfig.handleUpload();
@ -241,9 +245,6 @@ export default {
for (let fileID in apiTest.jmx.attachFiles) {
attachFiles.push(fileID);
}
// if (attachFiles.length > 0) {
// this.$refs.basicConfig.selectAttachFileById(attachFiles);
// }
}
this.active = '1';
this.$store.commit("clearTest");
@ -252,6 +253,9 @@ export default {
if (scenarioJmxs && scenarioJmxs.name) {
this.$set(this.test, "name", scenarioJmxs.name);
let relateApiList = [];
if (scenarioJmxs.projectEnvMap) {
this.projectEnvMap = scenarioJmxs.projectEnvMap;
}
if (scenarioJmxs.jmxs) {
scenarioJmxs.jmxs.forEach(item => {
if (item.scenarioId) {
@ -271,9 +275,6 @@ export default {
for (let fileID in item.attachFiles) {
attachFiles.push(fileID);
}
// if (attachFiles.length > 0) {
// this.$refs.basicConfig.selectAttachFileById(attachFiles);
// }
}
this.$set(this.test, "apiList", relateApiList);
});
@ -294,6 +295,13 @@ export default {
if (!this.test.schedule) {
this.test.schedule = {};
}
if (this.test.envInfo) {
try {
this.projectEnvMap = JSON.parse(this.test.envInfo);
} catch (e) {
this.projectEnvMap = null;
}
}
this.getDefaultFollow(testId);
}
});
@ -373,12 +381,11 @@ export default {
this.test.testResourcePoolId = this.$refs.pressureConfig.resourcePool;
//
this.test.advancedConfiguration = JSON.stringify(this.$refs.advancedConfig.configurations());
this.test.projectEnvMap = this.projectEnvMap;
// filejson
let requestJson = JSON.stringify(this.test, function (key, value) {
return key === "file" ? undefined : value;
});
formData.append('request', new Blob([requestJson], {
type: "application/json"
}));

View File

@ -58,7 +58,7 @@ import MsSearch from "@/business/components/common/components/search/MsSearch";
export default {
name: "ExistScenarios",
components: {MsTag, MsTablePagination, MsDialogFooter,MsTableSearchBar, MsSearch},
components: {MsTag, MsTablePagination, MsDialogFooter, MsTableSearchBar, MsSearch},
props: {
fileList: Array,
tableData: Array,
@ -74,6 +74,7 @@ export default {
total: 0,
apiScenarios: [],
selectIds: new Set,
environment: {},
condition: {
projectId: getCurrentProjectID(),
filters: {status: ["Prepare", "Underway", "Completed"]}
@ -138,7 +139,8 @@ export default {
ids: [...this.selectIds],
};
this.projectLoadingResult = this.$post('api/automation/export/jmx', condition, response => {
let data = response.data;
let returnData = response.data;
let data = returnData.scenarioJmxList;
data.forEach(d => {
let jmxName = d.name + "_" + new Date().getTime() + ".jmx";
let threadGroups = findThreadGroup(d.jmx, jmxName);
@ -169,7 +171,6 @@ export default {
});
});
});
this.$emit('fileChange', this.scenarios);
this.$success(this.$t('test_track.case.import.success'));
this.loadApiAutomationVisible = false;