Merge branch 'master' of https://github.com/metersphere/metersphere into master
This commit is contained in:
commit
05dc583719
|
@ -32,6 +32,7 @@ import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||||
import io.metersphere.commons.constants.LoopConstants;
|
import io.metersphere.commons.constants.LoopConstants;
|
||||||
import io.metersphere.commons.constants.MsTestElementConstants;
|
import io.metersphere.commons.constants.MsTestElementConstants;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -48,6 +49,7 @@ import org.apache.jorphan.collections.HashTree;
|
||||||
import org.apache.jorphan.collections.ListedHashTree;
|
import org.apache.jorphan.collections.ListedHashTree;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -211,6 +213,9 @@ public abstract class MsTestElement {
|
||||||
csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName());
|
csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName());
|
||||||
csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding());
|
csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding());
|
||||||
if (CollectionUtils.isNotEmpty(item.getFiles())) {
|
if (CollectionUtils.isNotEmpty(item.getFiles())) {
|
||||||
|
if (new File(BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName()).exists()) {
|
||||||
|
MSException.throwException(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName() + ":[ CSV文件不存在 ]");
|
||||||
|
}
|
||||||
csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName());
|
csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName());
|
||||||
}
|
}
|
||||||
csvDataSet.setIgnoreFirstLine(false);
|
csvDataSet.setIgnoreFirstLine(false);
|
||||||
|
|
|
@ -3,11 +3,14 @@ package io.metersphere.api.dto.definition.request.unknown;
|
||||||
import com.alibaba.fastjson.annotation.JSONType;
|
import com.alibaba.fastjson.annotation.JSONType;
|
||||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||||
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
import io.metersphere.api.dto.definition.request.ParameterConfig;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.jmeter.config.CSVDataSet;
|
||||||
import org.apache.jmeter.save.SaveService;
|
import org.apache.jmeter.save.SaveService;
|
||||||
import org.apache.jmeter.testelement.TestElement;
|
import org.apache.jmeter.testelement.TestElement;
|
||||||
import org.apache.jmeter.testelement.TestPlan;
|
import org.apache.jmeter.testelement.TestPlan;
|
||||||
|
@ -15,6 +18,7 @@ import org.apache.jmeter.threads.ThreadGroup;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -53,6 +57,13 @@ public class MsJmeterElement extends MsTestElement {
|
||||||
if (!config.isOperating() && scriptWrapper instanceof ThreadGroup && !((ThreadGroup) scriptWrapper).isEnabled()) {
|
if (!config.isOperating() && scriptWrapper instanceof ThreadGroup && !((ThreadGroup) scriptWrapper).isEnabled()) {
|
||||||
LogUtil.info(((ThreadGroup) scriptWrapper).getName() + "是被禁用线程组不加入执行");
|
LogUtil.info(((ThreadGroup) scriptWrapper).getName() + "是被禁用线程组不加入执行");
|
||||||
} else {
|
} else {
|
||||||
|
// CSV数据检查文件路径是否还存在
|
||||||
|
if (scriptWrapper instanceof CSVDataSet) {
|
||||||
|
String path = ((CSVDataSet) scriptWrapper).getPropertyAsString("filename");
|
||||||
|
if (!new File(path).exists()) {
|
||||||
|
MSException.throwException(StringUtils.isEmpty(((CSVDataSet) scriptWrapper).getName()) ? "CSVDataSet" : ((CSVDataSet) scriptWrapper).getName() + ":[ CSV文件不存在 ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||||
for (MsTestElement el : hashTree) {
|
for (MsTestElement el : hashTree) {
|
||||||
el.toHashTree(elementTree, el.getHashTree(), config);
|
el.toHashTree(elementTree, el.getHashTree(), config);
|
||||||
|
@ -62,6 +73,7 @@ public class MsJmeterElement extends MsTestElement {
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
MSException.throwException(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -535,8 +535,12 @@ public class ApiAutomationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成报告和HashTree
|
// 生成报告和HashTree
|
||||||
HashTree hashTree = generateHashTree(item, reportId, planEnvMap);
|
HashTree hashTree = null;
|
||||||
|
try {
|
||||||
|
hashTree = generateHashTree(item, reportId, planEnvMap);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
MSException.throwException(ex.getMessage());
|
||||||
|
}
|
||||||
//存储报告
|
//存储报告
|
||||||
batchMapper.insert(report);
|
batchMapper.insert(report);
|
||||||
|
|
||||||
|
@ -602,7 +606,12 @@ public class ApiAutomationService {
|
||||||
}
|
}
|
||||||
ParameterConfig config = new ParameterConfig();
|
ParameterConfig config = new ParameterConfig();
|
||||||
config.setConfig(envConfig);
|
config.setConfig(envConfig);
|
||||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
HashTree hashTree = null;
|
||||||
|
try {
|
||||||
|
hashTree = request.getTestElement().generateHashTree(config);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MSException.throwException(e.getMessage());
|
||||||
|
}
|
||||||
// 调用执行方法
|
// 调用执行方法
|
||||||
APIScenarioReportResult reportResult = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
APIScenarioReportResult reportResult = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||||
SessionUtils.getUserId());
|
SessionUtils.getUserId());
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.base.mapper.ext;
|
||||||
import io.metersphere.base.domain.FileMetadata;
|
import io.metersphere.base.domain.FileMetadata;
|
||||||
import io.metersphere.base.domain.LoadTest;
|
import io.metersphere.base.domain.LoadTest;
|
||||||
import io.metersphere.dto.LoadTestDTO;
|
import io.metersphere.dto.LoadTestDTO;
|
||||||
|
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||||
import io.metersphere.performance.request.QueryTestPlanRequest;
|
import io.metersphere.performance.request.QueryTestPlanRequest;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ public interface ExtLoadTestMapper {
|
||||||
|
|
||||||
LoadTest getNextNum(@Param("projectId") String projectId);
|
LoadTest getNextNum(@Param("projectId") String projectId);
|
||||||
|
|
||||||
List<FileMetadata> getProjectFiles(@Param("projectId") String projectId, @Param("loadTypes") List<String> loadType);
|
List<FileMetadata> getProjectFiles(@Param("projectId") String projectId, @Param("loadTypes") List<String> loadType,
|
||||||
|
@Param("request") QueryProjectFileRequest request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,5 +145,8 @@
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
AND project_id = #{projectId,jdbcType=VARCHAR}
|
AND project_id = #{projectId,jdbcType=VARCHAR}
|
||||||
|
<if test="request.name!=null">
|
||||||
|
AND file_metadata.name LIKE CONCAT('%', #{request.name}, '%')
|
||||||
|
</if>
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.base.mapper.ext;
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
import io.metersphere.track.dto.TestCaseReportStatusResultDTO;
|
import io.metersphere.track.dto.TestCaseReportStatusResultDTO;
|
||||||
|
import io.metersphere.track.dto.TestCaseTestDTO;
|
||||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
@ -47,4 +48,6 @@ public interface ExtTestPlanTestCaseMapper {
|
||||||
List<String> getExecResultByPlanId(String planId);
|
List<String> getExecResultByPlanId(String planId);
|
||||||
|
|
||||||
List<TestPlanCaseDTO> listForMinder(@Param("planId") String planId);
|
List<TestPlanCaseDTO> listForMinder(@Param("planId") String planId);
|
||||||
|
|
||||||
|
List<TestCaseTestDTO> listTestCaseTest(@Param("caseId") String caseId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,6 +421,9 @@
|
||||||
pc.plan_id = #{planId}
|
pc.plan_id = #{planId}
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
<select id="listTestCaseTest" resultType="io.metersphere.track.dto.TestCaseTestDTO">
|
||||||
|
select * from test_case_test where test_case_id = #{caseId};
|
||||||
|
</select>
|
||||||
|
|
||||||
<update id="updateTestCaseStates" parameterType="java.lang.String">
|
<update id="updateTestCaseStates" parameterType="java.lang.String">
|
||||||
update test_plan_test_case
|
update test_plan_test_case
|
||||||
|
|
|
@ -120,12 +120,13 @@ public class PerformanceTestController {
|
||||||
return performanceTestService.exportJmx(fileIds);
|
return performanceTestService.exportJmx(fileIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/project/{loadType}/{projectId}/{goPage}/{pageSize}")
|
@PostMapping("/project/{loadType}/{projectId}/{goPage}/{pageSize}")
|
||||||
public Pager<List<FileMetadata>> getProjectFiles(@PathVariable String projectId, @PathVariable String loadType,
|
public Pager<List<FileMetadata>> getProjectFiles(@PathVariable String projectId, @PathVariable String loadType,
|
||||||
@PathVariable int goPage, @PathVariable int pageSize) {
|
@PathVariable int goPage, @PathVariable int pageSize,
|
||||||
|
@RequestBody QueryProjectFileRequest request) {
|
||||||
checkPermissionService.checkProjectOwner(projectId);
|
checkPermissionService.checkProjectOwner(projectId);
|
||||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||||
return PageUtils.setPageInfo(page, performanceTestService.getProjectFiles(projectId, loadType));
|
return PageUtils.setPageInfo(page, performanceTestService.getProjectFiles(projectId, loadType, request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
|
|
|
@ -19,8 +19,8 @@ import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class AbstractEngine implements Engine {
|
public abstract class AbstractEngine implements Engine {
|
||||||
protected String JMETER_IMAGE;
|
protected String JMETER_IMAGE;
|
||||||
|
@ -106,17 +106,20 @@ public abstract class AbstractEngine implements Engine {
|
||||||
String loadConfiguration = t.getLoadConfiguration();
|
String loadConfiguration = t.getLoadConfiguration();
|
||||||
JSONArray jsonArray = JSON.parseArray(loadConfiguration);
|
JSONArray jsonArray = JSON.parseArray(loadConfiguration);
|
||||||
for (int i = 0; i < jsonArray.size(); i++) {
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
if (jsonArray.get(i) instanceof Map) {
|
|
||||||
JSONObject o = jsonArray.getJSONObject(i);
|
|
||||||
if (StringUtils.equals(o.getString("key"), "TargetLevel")) {
|
|
||||||
s = o.getInteger("value");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (jsonArray.get(i) instanceof List) {
|
if (jsonArray.get(i) instanceof List) {
|
||||||
JSONArray o = jsonArray.getJSONArray(i);
|
JSONArray o = jsonArray.getJSONArray(i);
|
||||||
for (int j = 0; j < o.size(); j++) {
|
List<JSONObject> enabledConfig = o.stream()
|
||||||
JSONObject b = o.getJSONObject(j);
|
.filter(b -> {
|
||||||
|
JSONObject c = JSON.parseObject(b.toString());
|
||||||
|
if (StringUtils.equals(c.getString("deleted"), "true")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !StringUtils.equals(c.getString("enabled"), "false");
|
||||||
|
})
|
||||||
|
.map(b -> JSON.parseObject(b.toString()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (JSONObject b : enabledConfig) {
|
||||||
if (StringUtils.equals(b.getString("key"), "TargetLevel")) {
|
if (StringUtils.equals(b.getString("key"), "TargetLevel")) {
|
||||||
s += b.getInteger("value");
|
s += b.getInteger("value");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,5 +4,5 @@ import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class QueryProjectFileRequest {
|
public class QueryProjectFileRequest {
|
||||||
private String filename;
|
private String name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,19 +561,23 @@ public class PerformanceTestService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FileMetadata> getProjectFiles(String projectId, String loadType) {
|
public List<FileMetadata> getProjectFiles(String projectId, String loadType, QueryProjectFileRequest request) {
|
||||||
List<String> loadTypes = new ArrayList<>();
|
List<String> loadTypes = new ArrayList<>();
|
||||||
loadTypes.add(StringUtils.upperCase(loadType));
|
loadTypes.add(StringUtils.upperCase(loadType));
|
||||||
if (StringUtils.equalsIgnoreCase(loadType, "resource")) {
|
if (StringUtils.equalsIgnoreCase(loadType, "resource")) {
|
||||||
loadTypes.add(FileType.CSV.name());
|
List<String> fileTypes = Arrays.stream(FileType.values())
|
||||||
loadTypes.add(FileType.JAR.name());
|
.filter(fileType -> !fileType.equals(FileType.JMX))
|
||||||
|
.map(FileType::name)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
loadTypes.addAll(fileTypes);
|
||||||
}
|
}
|
||||||
if (StringUtils.equalsIgnoreCase(loadType, "all")) {
|
if (StringUtils.equalsIgnoreCase(loadType, "all")) {
|
||||||
loadTypes.add(FileType.CSV.name());
|
List<String> fileTypes = Arrays.stream(FileType.values())
|
||||||
loadTypes.add(FileType.JAR.name());
|
.map(FileType::name)
|
||||||
loadTypes.add(FileType.JMX.name());
|
.collect(Collectors.toList());
|
||||||
|
loadTypes.addAll(fileTypes);
|
||||||
}
|
}
|
||||||
return extLoadTestMapper.getProjectFiles(projectId, loadTypes);
|
return extLoadTestMapper.getProjectFiles(projectId, loadTypes, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LoadTestExportJmx> exportJmx(List<String> fileIds) {
|
public List<LoadTestExportJmx> exportJmx(List<String> fileIds) {
|
||||||
|
|
|
@ -202,8 +202,8 @@ public class FileService {
|
||||||
FileMetadataExample example = new FileMetadataExample();
|
FileMetadataExample example = new FileMetadataExample();
|
||||||
FileMetadataExample.Criteria criteria = example.createCriteria();
|
FileMetadataExample.Criteria criteria = example.createCriteria();
|
||||||
criteria.andProjectIdEqualTo(projectId);
|
criteria.andProjectIdEqualTo(projectId);
|
||||||
if (!StringUtils.isEmpty(request.getFilename())) {
|
if (!StringUtils.isEmpty(request.getName())) {
|
||||||
criteria.andNameEqualTo(request.getFilename());
|
criteria.andNameEqualTo(request.getName());
|
||||||
}
|
}
|
||||||
return fileMetadataMapper.selectByExample(example);
|
return fileMetadataMapper.selectByExample(example);
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ public class ProjectService {
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
for (MultipartFile file : files) {
|
for (MultipartFile file : files) {
|
||||||
QueryProjectFileRequest request = new QueryProjectFileRequest();
|
QueryProjectFileRequest request = new QueryProjectFileRequest();
|
||||||
request.setFilename(file.getOriginalFilename());
|
request.setName(file.getOriginalFilename());
|
||||||
if (CollectionUtils.isEmpty(fileService.getProjectFiles(projectId, request))) {
|
if (CollectionUtils.isEmpty(fileService.getProjectFiles(projectId, request))) {
|
||||||
fileService.saveFile(file, projectId);
|
fileService.saveFile(file, projectId);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.track.dto;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCaseTest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestCaseTestDTO extends TestCaseTest {
|
||||||
|
private String testName;
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package io.metersphere.track.dto;
|
||||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -18,4 +20,6 @@ public class TestPlanCaseDTO extends TestCaseWithBLOBs {
|
||||||
private String reportId;
|
private String reportId;
|
||||||
private String model;
|
private String model;
|
||||||
private String projectName;
|
private String projectName;
|
||||||
|
|
||||||
|
private List<TestCaseTestDTO> list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package io.metersphere.track.service;
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.base.domain.TestPlan;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.domain.TestPlanTestCaseExample;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.domain.TestPlanTestCaseWithBLOBs;
|
|
||||||
import io.metersphere.base.domain.User;
|
|
||||||
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
|
||||||
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
||||||
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
|
@ -14,6 +11,7 @@ import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||||
import io.metersphere.service.UserService;
|
import io.metersphere.service.UserService;
|
||||||
|
import io.metersphere.track.dto.TestCaseTestDTO;
|
||||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||||
import io.metersphere.track.request.testcase.TestPlanCaseBatchRequest;
|
import io.metersphere.track.request.testcase.TestPlanCaseBatchRequest;
|
||||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||||
|
@ -42,6 +40,14 @@ public class TestPlanTestCaseService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
|
ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private TestCaseTestMapper testCaseTestMapper;
|
||||||
|
@Resource
|
||||||
|
private LoadTestMapper loadTestMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
|
|
||||||
public List<TestPlanCaseDTO> list(QueryTestPlanCaseRequest request) {
|
public List<TestPlanCaseDTO> list(QueryTestPlanCaseRequest request) {
|
||||||
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
||||||
|
@ -134,7 +140,40 @@ public class TestPlanTestCaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestPlanCaseDTO get(String testplanTestCaseId) {
|
public TestPlanCaseDTO get(String testplanTestCaseId) {
|
||||||
return extTestPlanTestCaseMapper.get(testplanTestCaseId);
|
TestPlanCaseDTO testPlanCaseDTO = extTestPlanTestCaseMapper.get(testplanTestCaseId);
|
||||||
|
List<TestCaseTestDTO> testCaseTestDTOS = extTestPlanTestCaseMapper.listTestCaseTest(testPlanCaseDTO.getCaseId());
|
||||||
|
testCaseTestDTOS.forEach(dto -> {
|
||||||
|
setTestName(dto);
|
||||||
|
});
|
||||||
|
testPlanCaseDTO.setList(testCaseTestDTOS);
|
||||||
|
return testPlanCaseDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTestName(TestCaseTestDTO dto) {
|
||||||
|
String type = dto.getTestType();
|
||||||
|
String id = dto.getTestId();
|
||||||
|
switch (type) {
|
||||||
|
case "performance":
|
||||||
|
LoadTest loadTest = loadTestMapper.selectByPrimaryKey(id);
|
||||||
|
if (loadTest != null) {
|
||||||
|
dto.setTestName(loadTest.getName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "testcase":
|
||||||
|
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(id);
|
||||||
|
if (apiTestCaseWithBLOBs != null) {
|
||||||
|
dto.setTestName(apiTestCaseWithBLOBs.getName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "automation":
|
||||||
|
ApiScenarioWithBLOBs apiScenarioWithBLOBs = apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
|
if (apiScenarioWithBLOBs != null) {
|
||||||
|
dto.setTestName(apiScenarioWithBLOBs.getName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteTestCaseBath(TestPlanCaseBatchRequest request) {
|
public void deleteTestCaseBath(TestPlanCaseBatchRequest request) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2fb883803fa9909162ce9f6fab8a15b63af66923
|
Subproject commit e20541d8c864216ebdaade01226b795efeb10c48
|
|
@ -69,7 +69,7 @@
|
||||||
<el-table-column v-if="item.id == 'tags'" prop="tags" min-width="120px"
|
<el-table-column v-if="item.id == 'tags'" prop="tags" min-width="120px"
|
||||||
:label="$t('api_test.automation.tag')" :key="index">
|
:label="$t('api_test.automation.tag')" :key="index">
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :content="itemName" style="margin-left: 5px"/>
|
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :content="itemName" :show-tooltip="true" tooltip style="margin-left: 5px"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column v-if="item.id == 'userId'" prop="userId" min-width="120px"
|
<el-table-column v-if="item.id == 'userId'" prop="userId" min-width="120px"
|
||||||
|
@ -758,7 +758,6 @@
|
||||||
z-index: auto !important;
|
z-index: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/deep/ .el-table__fixed-right {
|
/deep/ .el-table__fixed-right {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
<div class="header-right" @click.stop>
|
<div class="header-right" @click.stop>
|
||||||
<slot name="message"></slot>
|
<slot name="message"></slot>
|
||||||
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn">
|
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top" v-if="showBtn">
|
||||||
<el-switch v-model="data.enable" class="enable-switch" size="mini"/>
|
<el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled"/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<slot name="button"></slot>
|
<slot name="button"></slot>
|
||||||
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn"/>
|
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && !data.disabled"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -219,8 +219,12 @@
|
||||||
return this.selection.includes(row.id)
|
return this.selection.includes(row.id)
|
||||||
},
|
},
|
||||||
open: function (variables, headers, disabled) {
|
open: function (variables, headers, disabled) {
|
||||||
|
if(variables){
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
|
}
|
||||||
|
if(headers){
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
|
}
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.editData = {type: "CONSTANT"};
|
this.editData = {type: "CONSTANT"};
|
||||||
this.addParameters(this.editData);
|
this.addParameters(this.editData);
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
min-width="120px"
|
min-width="120px"
|
||||||
:key="index">
|
:key="index">
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :content="itemName" style="margin-left: 5px"/>
|
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain" :show-tooltip="true" :content="itemName" style="margin-left: 5px"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,12 @@ export default {
|
||||||
component: () => import('@/business/components/api/report/ApiReportView'),
|
component: () => import('@/business/components/api/report/ApiReportView'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "definition",
|
path: "definition/:redirectID?/:dataType?/:dataSelectRange?",
|
||||||
name: "ApiDefinition",
|
name: "ApiDefinition",
|
||||||
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "automation",
|
path: "automation/:redirectID?/:dataType?/:dataSelectRange?",
|
||||||
name: "ApiAutomation",
|
name: "ApiAutomation",
|
||||||
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
|
<el-tooltip placement="top" v-if="showTooltip">
|
||||||
|
<div slot="content">{{content}}</div>
|
||||||
<el-tag :type="type" :effect="effect" :color="color" size="mini">{{content}}</el-tag>
|
<el-tag :type="type" :effect="effect" :color="color" size="mini">{{content}}</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tag :type="type" :effect="effect" :color="color" size="mini" v-else>{{content}}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -20,6 +24,10 @@
|
||||||
effect: {
|
effect: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'dark',
|
default: 'dark',
|
||||||
|
},
|
||||||
|
showTooltip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:title="$t('load_test.exist_jmx')" width="70%"
|
:title="$t('load_test.exist_jmx')" width="70%"
|
||||||
:visible.sync="loadFileVisible">
|
:visible.sync="loadFileVisible">
|
||||||
<el-row>
|
<ms-table-header :is-tester-permission="true" title="" :condition.sync="condition" @search="getProjectFiles" :show-create="false">
|
||||||
|
<template v-slot:button>
|
||||||
<el-upload
|
<el-upload
|
||||||
v-if="loadType === 'jmx'"
|
v-if="loadType === 'jmx'"
|
||||||
style="padding-right: 10px;"
|
style="margin-bottom: 10px"
|
||||||
accept=".jmx"
|
accept=".jmx"
|
||||||
action=""
|
action=""
|
||||||
multiple
|
multiple
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-upload
|
<el-upload
|
||||||
v-else
|
v-else
|
||||||
style="padding-right: 10px;"
|
style="margin-bottom: 10px"
|
||||||
accept=".jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
|
accept=".jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
|
||||||
action=""
|
action=""
|
||||||
:limit="fileNumLimit"
|
:limit="fileNumLimit"
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
|
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
|
||||||
:content="$t('load_test.upload_file')"/>
|
:content="$t('load_test.upload_file')"/>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-row>
|
</template>
|
||||||
|
</ms-table-header>
|
||||||
<el-table v-loading="projectLoadingResult.loading"
|
<el-table v-loading="projectLoadingResult.loading"
|
||||||
class="basic-config"
|
class="basic-config"
|
||||||
:data="existFiles"
|
:data="existFiles"
|
||||||
|
@ -78,10 +78,11 @@ import {getCurrentProjectID} from "@/common/js/utils";
|
||||||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||||
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ExistFiles",
|
name: "ExistFiles",
|
||||||
components: {MsTableButton, MsTablePagination, MsDialogFooter},
|
components: {MsTableHeader, MsTableButton, MsTablePagination, MsDialogFooter},
|
||||||
props: {
|
props: {
|
||||||
fileList: Array,
|
fileList: Array,
|
||||||
tableData: Array,
|
tableData: Array,
|
||||||
|
@ -100,6 +101,7 @@ export default {
|
||||||
existFiles: [],
|
existFiles: [],
|
||||||
selectIds: new Set,
|
selectIds: new Set,
|
||||||
fileNumLimit: 10,
|
fileNumLimit: 10,
|
||||||
|
condition: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -133,7 +135,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getProjectFiles() {
|
getProjectFiles() {
|
||||||
this.projectLoadingResult = this.$get('/performance/project/' + this.loadType + '/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, res => {
|
this.projectLoadingResult = this.$post('/performance/project/' + this.loadType + '/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
this.existFiles = data.listObject;
|
this.existFiles = data.listObject;
|
||||||
|
|
|
@ -341,7 +341,7 @@ export default {
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.basic-config {
|
.basic-config {
|
||||||
width: 100%
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.last-modified {
|
.last-modified {
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:title="$t('load_test.exist_jmx')" width="70%"
|
:title="$t('load_test.exist_jmx')" width="70%"
|
||||||
:visible.sync="loadFileVisible">
|
:visible.sync="loadFileVisible">
|
||||||
<el-row>
|
|
||||||
|
<ms-table-header :is-tester-permission="true" title="" :condition.sync="condition" @search="getProjectFiles" :show-create="false">
|
||||||
|
<template v-slot:button>
|
||||||
<el-upload
|
<el-upload
|
||||||
style="padding-right: 10px;"
|
style="margin-bottom: 10px;"
|
||||||
accept=".jmx,.jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
|
accept=".jmx,.jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
|
||||||
action=""
|
action=""
|
||||||
:limit="fileNumLimit"
|
:limit="fileNumLimit"
|
||||||
|
@ -18,7 +20,8 @@
|
||||||
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
|
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
|
||||||
:content="$t('load_test.upload_file')"/>
|
:content="$t('load_test.upload_file')"/>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-row>
|
</template>
|
||||||
|
</ms-table-header>
|
||||||
|
|
||||||
<el-table v-loading="projectLoadingResult.loading"
|
<el-table v-loading="projectLoadingResult.loading"
|
||||||
class="basic-config"
|
class="basic-config"
|
||||||
|
@ -64,10 +67,12 @@ import MsDialogFooter from "@/business/components/common/components/MsDialogFoot
|
||||||
import {getCurrentProjectID} from "@/common/js/utils";
|
import {getCurrentProjectID} from "@/common/js/utils";
|
||||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||||
import {Message} from "element-ui";
|
import {Message} from "element-ui";
|
||||||
|
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||||
|
import MsTableSearchBar from "@/business/components/common/components/MsTableSearchBar";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsResourceFiles",
|
name: "MsResourceFiles",
|
||||||
components: {MsTableOperatorButton, MsDialogFooter, MsTableButton, MsTablePagination},
|
components: {MsTableSearchBar, MsTableHeader, MsTableOperatorButton, MsDialogFooter, MsTableButton, MsTablePagination},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loadFileVisible: false,
|
loadFileVisible: false,
|
||||||
|
@ -79,6 +84,7 @@ export default {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
uploadList: [],
|
uploadList: [],
|
||||||
fileNumLimit: 10,
|
fileNumLimit: 10,
|
||||||
|
condition: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -91,7 +97,7 @@ export default {
|
||||||
this.selectIds.clear();
|
this.selectIds.clear();
|
||||||
},
|
},
|
||||||
getProjectFiles() {
|
getProjectFiles() {
|
||||||
this.projectLoadingResult = this.$get('/performance/project/all/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, res => {
|
this.projectLoadingResult = this.$post('/performance/project/all/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
this.existFiles = data.listObject;
|
this.existFiles = data.listObject;
|
||||||
|
|
|
@ -85,6 +85,15 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :offset="1">
|
||||||
|
<span class="cast_label">关联测试:</span>
|
||||||
|
<span v-for="(item,index) in testCase.list" :key="index">
|
||||||
|
<el-button @click="openTest(item)" type="text" style="margin-left: 7px;">{{ item.testName }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :offset="1">
|
<el-col :offset="1">
|
||||||
<span class="cast_label">{{ $t('test_track.case.prerequisite') }}:</span>
|
<span class="cast_label">{{ $t('test_track.case.prerequisite') }}:</span>
|
||||||
|
@ -351,7 +360,7 @@ import ApiTestDetail from "../test/ApiTestDetail";
|
||||||
import ApiTestResult from "../test/ApiTestResult";
|
import ApiTestResult from "../test/ApiTestResult";
|
||||||
import PerformanceTestDetail from "../test/PerformanceTestDetail";
|
import PerformanceTestDetail from "../test/PerformanceTestDetail";
|
||||||
import PerformanceTestResult from "../test/PerformanceTestResult";
|
import PerformanceTestResult from "../test/PerformanceTestResult";
|
||||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {getUUID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||||
import CaseComment from "@/business/components/track/case/components/CaseComment";
|
import CaseComment from "@/business/components/track/case/components/CaseComment";
|
||||||
import MsPreviousNextButton from "../../../../../common/components/MsPreviousNextButton";
|
import MsPreviousNextButton from "../../../../../common/components/MsPreviousNextButton";
|
||||||
|
@ -559,6 +568,29 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
openTest(item) {
|
||||||
|
const type = item.testType;
|
||||||
|
const id = item.testId;
|
||||||
|
switch (type) {
|
||||||
|
case "performance": {
|
||||||
|
let performanceData = this.$router.resolve({
|
||||||
|
path: '/performance/test/edit/' + id,
|
||||||
|
})
|
||||||
|
window.open(performanceData.href, '_blank');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "testcase": {
|
||||||
|
let caseData = this.$router.resolve({name:'ApiDefinition',params:{redirectID:getUUID(),dataType:"apiTestCase",dataSelectRange:'single:'+id}});
|
||||||
|
window.open(caseData.href, '_blank');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "automation": {
|
||||||
|
let automationData = this.$router.resolve({name:'ApiAutomation',params:{redirectID:getUUID(),dataType:"scenario",dataSelectRange:'edit:'+id}});
|
||||||
|
window.open(automationData.href, '_blank');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
getRelatedTest() {
|
getRelatedTest() {
|
||||||
if (this.testCase.method === 'auto' && this.testCase.testId && this.testCase.testId !== 'other') {
|
if (this.testCase.method === 'auto' && this.testCase.testId && this.testCase.testId !== 'other') {
|
||||||
this.$get('/' + this.testCase.type + '/get/' + this.testCase.testId, response => {
|
this.$get('/' + this.testCase.type + '/get/' + this.testCase.testId, response => {
|
||||||
|
|
Loading…
Reference in New Issue