Merge branch 'dev'
This commit is contained in:
commit
3d39d312e5
|
@ -22,6 +22,7 @@ import io.metersphere.task.service.TaskService;
|
|||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import io.metersphere.track.request.testplan.FileOperationRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -96,7 +97,7 @@ public class ApiAutomationController {
|
|||
|
||||
@PostMapping(value = "/create")
|
||||
@MsAuditLog(module = "api_automation", type = OperLogConstants.CREATE, title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = ApiAutomationService.class)
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_CREATE)
|
||||
@RequiresPermissions(value={PermissionConstants.PROJECT_API_SCENARIO_READ_CREATE, PermissionConstants.PROJECT_API_SCENARIO_READ_COPY}, logical = Logical.OR)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.API_AUTOMATION_TASK, event = NoticeConstants.Event.CREATE, mailTemplate = "api/AutomationCreate", subject = "接口自动化通知")
|
||||
public ApiScenario create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "bodyFiles", required = false) List<MultipartFile> bodyFiles,
|
||||
@RequestPart(value = "scenarioFiles", required = false) List<MultipartFile> scenarioFiles) {
|
||||
|
@ -105,7 +106,7 @@ public class ApiAutomationController {
|
|||
|
||||
@PostMapping(value = "/update")
|
||||
@MsAuditLog(module = "api_automation", type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = ApiAutomationService.class)
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EDIT)
|
||||
@RequiresPermissions(value={PermissionConstants.PROJECT_API_SCENARIO_READ_EDIT, PermissionConstants.PROJECT_API_SCENARIO_READ_COPY}, logical = Logical.OR)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.API_AUTOMATION_TASK, event = NoticeConstants.Event.UPDATE, mailTemplate = "api/AutomationUpdate", subject = "接口自动化通知")
|
||||
public ApiScenario update(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "bodyFiles", required = false) List<MultipartFile> bodyFiles,
|
||||
@RequestPart(value = "scenarioFiles", required = false) List<MultipartFile> scenarioFiles) {
|
||||
|
@ -335,7 +336,7 @@ public class ApiAutomationController {
|
|||
return apiAutomationService.setDomain(request.getDefinition());
|
||||
}
|
||||
|
||||
@PostMapping(value = "/export/jmx")
|
||||
@PostMapping(value = "/export/zip")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EXPORT_SCENARIO)
|
||||
@MsAuditLog(module = "api_automation", type = OperLogConstants.EXPORT, sourceId = "#request.id", title = "#request.name", project = "#request.projectId")
|
||||
public ResponseEntity<byte[]> downloadBodyFiles(@RequestBody ApiScenarioBatchRequest request) {
|
||||
|
@ -345,5 +346,19 @@ public class ApiAutomationController {
|
|||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "场景JMX文件集.zip")
|
||||
.body(bytes);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/export/jmx")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_EXPORT_SCENARIO)
|
||||
@MsAuditLog(module = "api_automation", type = OperLogConstants.EXPORT, sourceId = "#request.id", title = "#request.name", project = "#request.projectId")
|
||||
public List<ApiScenrioExportJmx> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
|
||||
return apiAutomationService.exportJmx(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/checkScenarioEnv")
|
||||
public boolean checkScenarioEnv(@RequestBody ApiScenarioWithBLOBs request) {
|
||||
return apiAutomationService.checkScenarioEnv(request);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.dto;
|
||||
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.controller.request.BaseQueryRequest;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
|
@ -15,5 +16,5 @@ public class ApiCaseBatchRequest extends ApiTestCaseWithBLOBs {
|
|||
private List<OrderRequest> orders;
|
||||
private String projectId;
|
||||
private String environmentId;
|
||||
private BaseQueryRequest condition;
|
||||
private ApiTestCaseRequest condition;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigImportDTO;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
|
||||
|
@ -17,4 +18,5 @@ public class MsApiExportResult extends ApiExportResult {
|
|||
private String version;
|
||||
private List<ApiDefinitionWithBLOBs> data;
|
||||
private List<ApiTestCaseWithBLOBs> cases;
|
||||
private List<MockConfigImportDTO> mocks;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -16,4 +18,8 @@ public class RunCaseRequest {
|
|||
private String environmentId;
|
||||
|
||||
private String testPlanId;
|
||||
|
||||
private ApiTestCaseWithBLOBs bloBs;
|
||||
|
||||
private ApiDefinitionExecResult report;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import io.metersphere.api.dto.definition.parse.ms.NodeTree;
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigImportDTO;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.EsbApiParamsWithBLOBs;
|
||||
|
@ -21,5 +22,8 @@ public class ApiDefinitionImport {
|
|||
//ESB文件导入的附属数据类
|
||||
private Map<String,EsbApiParamsWithBLOBs> esbApiParamsMap;
|
||||
|
||||
//Mock数据相关
|
||||
private List<MockConfigImportDTO> mocks;
|
||||
|
||||
private List<NodeTree> nodeTree;
|
||||
}
|
||||
|
|
|
@ -268,18 +268,33 @@ public class ElementUtil {
|
|||
}
|
||||
};
|
||||
|
||||
private static void formatSampler(JSONObject element) {
|
||||
if (element == null || StringUtils.isEmpty(element.getString("type"))) {
|
||||
return;
|
||||
}
|
||||
if (element.get("clazzName") == null && element.getString("type").equals("TCPSampler")) {
|
||||
if (element.getString("tcpPreProcessor") != null) {
|
||||
JSONObject tcpPreProcessor = JSON.parseObject(element.getString("tcpPreProcessor"));
|
||||
if (tcpPreProcessor != null && tcpPreProcessor.get("clazzName") == null) {
|
||||
tcpPreProcessor.fluentPut("clazzName", clazzMap.get(tcpPreProcessor.getString("type")));
|
||||
element.fluentPut("tcpPreProcessor", tcpPreProcessor);
|
||||
}
|
||||
}
|
||||
} else if (element.getString("type").equals("HTTPSamplerProxy")) {
|
||||
if (element.getString("authManager") != null) {
|
||||
JSONObject authManager = JSON.parseObject(element.getString("authManager"));
|
||||
if (authManager != null && authManager.get("clazzName") == null) {
|
||||
authManager.fluentPut("clazzName", clazzMap.get(authManager.getString("type")));
|
||||
element.fluentPut("authManager", authManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void dataFormatting(JSONArray hashTree) {
|
||||
for (int i = 0; i < hashTree.size(); i++) {
|
||||
JSONObject element = hashTree.getJSONObject(i);
|
||||
if (element != null && element.get("clazzName") == null && element.getString("type").equals("TCPSampler")) {
|
||||
if (element.getString("tcpPreProcessor") != null) {
|
||||
JSONObject tcpPreProcessor = JSON.parseObject(element.getString("tcpPreProcessor"));
|
||||
if (tcpPreProcessor != null && tcpPreProcessor.get("clazzName") == null) {
|
||||
tcpPreProcessor.fluentPut("clazzName", clazzMap.get(tcpPreProcessor.getString("type")));
|
||||
element.fluentPut("tcpPreProcessor", tcpPreProcessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
formatSampler(element);
|
||||
if (element != null && element.get("clazzName") == null && clazzMap.containsKey(element.getString("type"))) {
|
||||
element.fluentPut("clazzName", clazzMap.get(element.getString("type")));
|
||||
}
|
||||
|
@ -294,6 +309,7 @@ public class ElementUtil {
|
|||
if (element != null && element.get("clazzName") == null && clazzMap.containsKey(element.getString("type"))) {
|
||||
element.fluentPut("clazzName", clazzMap.get(element.getString("type")));
|
||||
}
|
||||
formatSampler(element);
|
||||
if (element != null && element.containsKey("hashTree")) {
|
||||
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
||||
dataFormatting(elementJSONArray);
|
||||
|
@ -304,7 +320,28 @@ public class ElementUtil {
|
|||
try {
|
||||
for (int i = 0; i < hashTree.size(); i++) {
|
||||
JSONObject element = hashTree.getJSONObject(i);
|
||||
if (element != null && element.get("type").toString().equals("HTTPSamplerProxy")) {
|
||||
boolean isScenarioEnv = false;
|
||||
ParameterConfig config = new ParameterConfig();
|
||||
if (element != null && element.get("type").toString().equals("scenario")) {
|
||||
MsScenario scenario = JSONObject.toJavaObject(element, MsScenario.class);
|
||||
if (scenario.isEnvironmentEnable()) {
|
||||
isScenarioEnv = true;
|
||||
Map<String, EnvironmentConfig> envConfig = new HashMap<>(16);
|
||||
Map<String, String> environmentMap = (Map<String, String>) element.get("environmentMap");
|
||||
if (environmentMap != null && !environmentMap.isEmpty()) {
|
||||
environmentMap.keySet().forEach(projectId -> {
|
||||
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||
ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentMap.get(projectId));
|
||||
if (environment != null && environment.getConfig() != null) {
|
||||
EnvironmentConfig env = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
|
||||
env.setApiEnvironmentid(environment.getId());
|
||||
envConfig.put(projectId, env);
|
||||
}
|
||||
});
|
||||
config.setConfig(envConfig);
|
||||
}
|
||||
}
|
||||
} else if (element != null && element.get("type").toString().equals("HTTPSamplerProxy")) {
|
||||
MsHTTPSamplerProxy httpSamplerProxy = JSON.toJavaObject(element, MsHTTPSamplerProxy.class);
|
||||
if (httpSamplerProxy != null
|
||||
&& (!httpSamplerProxy.isCustomizeReq() || (httpSamplerProxy.isCustomizeReq() && httpSamplerProxy.getIsRefEnvironment()))) {
|
||||
|
@ -320,7 +357,11 @@ public class ElementUtil {
|
|||
}
|
||||
if (element.containsKey("hashTree")) {
|
||||
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
||||
dataSetDomain(elementJSONArray, msParameter);
|
||||
if (isScenarioEnv) {
|
||||
dataSetDomain(elementJSONArray, config);
|
||||
} else {
|
||||
dataSetDomain(elementJSONArray, msParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -64,9 +64,12 @@ public class MsScenario extends MsTestElement {
|
|||
@JSONField(ordinal = 27)
|
||||
private Map<String, String> environmentMap;
|
||||
|
||||
@JSONField(ordinal = 24)
|
||||
@JSONField(ordinal = 28)
|
||||
private Boolean onSampleError;
|
||||
|
||||
@JSONField(ordinal = 29)
|
||||
private boolean environmentEnable;
|
||||
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
|
||||
public MsScenario() {
|
||||
|
@ -152,8 +155,7 @@ public class MsScenario extends MsTestElement {
|
|||
}
|
||||
} else {
|
||||
Map<String, EnvironmentConfig> map = config.getConfig();
|
||||
for (EnvironmentConfig evnConfig :
|
||||
map.values()) {
|
||||
for (EnvironmentConfig evnConfig : map.values()) {
|
||||
if (evnConfig.getHttpConfig() != null) {
|
||||
this.setMockEnvironment(evnConfig.getHttpConfig().isMock());
|
||||
}
|
||||
|
@ -174,12 +176,32 @@ public class MsScenario extends MsTestElement {
|
|||
//setHeader(tree, this.headers);
|
||||
config.setHeaders(this.headers);
|
||||
}
|
||||
ParameterConfig newConfig = new ParameterConfig();
|
||||
if (this.isEnvironmentEnable() && this.environmentMap != null && !this.environmentMap.isEmpty()) {
|
||||
environmentMap.keySet().forEach(projectId -> {
|
||||
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||
ApiTestEnvironmentWithBLOBs environment = environmentService.get(this.environmentMap.get(projectId));
|
||||
if (environment != null && environment.getConfig() != null) {
|
||||
EnvironmentConfig env = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
|
||||
env.setApiEnvironmentid(environment.getId());
|
||||
envConfig.put(projectId, env);
|
||||
if (StringUtils.equals(environment.getName(), MockConfigStaticData.MOCK_EVN_NAME)) {
|
||||
this.setMockEnvironment(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
newConfig.setConfig(envConfig);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
for (MsTestElement el : hashTree) {
|
||||
// 给所有孩子加一个父亲标志
|
||||
el.setParent(this);
|
||||
el.setMockEnvironment(this.isMockEnvironment());
|
||||
el.toHashTree(tree, el.getHashTree(), config);
|
||||
if (this.isEnvironmentEnable()) {
|
||||
el.toHashTree(tree, el.getHashTree(), newConfig);
|
||||
} else {
|
||||
el.toHashTree(tree, el.getHashTree(), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class MsDNSCacheManager extends MsTestElement {
|
|||
}
|
||||
|
||||
public static void addEnvironmentDNS(HashTree samplerHashTree, String name, EnvironmentConfig config, HttpConfig httpConfig) {
|
||||
if (config.getCommonConfig().isEnableHost() && CollectionUtils.isNotEmpty(config.getCommonConfig().getHosts()) && httpConfig != null) {
|
||||
if (config.getCommonConfig().isEnableHost() && CollectionUtils.isNotEmpty(config.getCommonConfig().getHosts()) && httpConfig != null && httpConfig.getDomain() != null) {
|
||||
String domain = httpConfig.getDomain().trim();
|
||||
List<Host> hosts = new ArrayList<>();
|
||||
config.getCommonConfig().getHosts().forEach(host -> {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.metersphere.api.dto.definition.request.sampler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.alibaba.fastjson.annotation.JSONType;
|
||||
|
@ -225,16 +224,14 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
|
||||
setSamplerPath(config, httpConfig, sampler);
|
||||
|
||||
// 请求体
|
||||
if (!StringUtils.equals(this.getMethod(), "GET")) {
|
||||
if (this.body != null) {
|
||||
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
|
||||
if (StringUtils.isNotEmpty(this.body.getType()) && "Form Data".equals(this.body.getType())) {
|
||||
sampler.setDoMultipart(true);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(bodyParams)) {
|
||||
sampler.setArguments(httpArguments(bodyParams));
|
||||
}
|
||||
// 请求体处理
|
||||
if (this.body != null) {
|
||||
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
|
||||
if (StringUtils.isNotEmpty(this.body.getType()) && "Form Data".equals(this.body.getType())) {
|
||||
sampler.setDoMultipart(true);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(bodyParams)) {
|
||||
sampler.setArguments(httpArguments(bodyParams));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +302,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
}
|
||||
preProcessor.toHashTree(httpSamplerTree, preProcessor.getHashTree(), config);
|
||||
}
|
||||
if (postProcessor != null && StringUtils.isNotEmpty(preProcessor.getScript())) {
|
||||
if (postProcessor != null && StringUtils.isNotEmpty(postProcessor.getScript())) {
|
||||
if (postProcessor.getEnvironmentId() == null) {
|
||||
if (this.getEnvironmentId() == null) {
|
||||
postProcessor.setEnvironmentId(useEnvironment);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package io.metersphere.api.dto.mockconfig;
|
||||
|
||||
import io.metersphere.base.domain.MockExpectConfigWithBLOBs;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/9/27 5:54 下午
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class MockConfigImportDTO extends MockExpectConfigWithBLOBs {
|
||||
public String apiId;
|
||||
}
|
|
@ -56,5 +56,8 @@ public class APIBackendListenerHandler {
|
|||
if (!MessageCache.reportCache.containsKey(testId) && resultService.getProcessCache().containsKey(testId)) {
|
||||
resultService.getProcessCache().remove(testId);
|
||||
}
|
||||
if(StringUtils.isNotEmpty(testId)) {
|
||||
MessageCache.executionQueue.remove(testId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ public class FixedTask {
|
|||
MessageCache.cache.remove(key);
|
||||
} else {
|
||||
try {
|
||||
int number = 0;
|
||||
if (guardTask.containsKey(key)) {
|
||||
number = guardTask.get(key);
|
||||
guardTask.put(key, number++);
|
||||
} else {
|
||||
int number = guardTask.get(key);
|
||||
number +=1;
|
||||
guardTask.put(key, number);
|
||||
} else {
|
||||
guardTask.put(key, 0);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(counter.getPoolUrls()) && counter.getNumber() > 0 && guardTask.get(key) > 200) {
|
||||
// 资源池中已经没有执行的请求了
|
||||
|
|
|
@ -43,6 +43,7 @@ public class JMeterVars {
|
|||
for (String item : extracts) {
|
||||
String nrKey = item + "_matchNr";
|
||||
Object nr = vars.get(nrKey);
|
||||
JMeterVariables jMeterVariables = new JMeterVariables();
|
||||
if (nr != null) {
|
||||
int nrv = 0;
|
||||
try {
|
||||
|
@ -55,10 +56,14 @@ public class JMeterVars {
|
|||
data.add(vars.get(item + "_" + i));
|
||||
}
|
||||
String array = JSON.toJSONString(data);
|
||||
vars.put(item, array);
|
||||
jMeterVariables.put(item, array);
|
||||
}
|
||||
}
|
||||
vs.put(item, vars.get(item) == null ? "" : vars.get(item));
|
||||
if (jMeterVariables.get(item) != null) {
|
||||
vs.put(item, jMeterVariables.get(item));
|
||||
} else {
|
||||
vs.put(item, vars.get(item) == null ? "" : vars.get(item));
|
||||
}
|
||||
}
|
||||
vs.remove("TESTSTART.MS"); // 标示变量移除
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||
import org.apache.jmeter.engine.StandardJMeterEngine;
|
||||
|
||||
import javax.websocket.Session;
|
||||
|
@ -16,4 +17,10 @@ public class MessageCache {
|
|||
public static ConcurrentHashMap<String, StandardJMeterEngine> runningEngine = new ConcurrentHashMap<>();
|
||||
|
||||
public static ConcurrentLinkedDeque<String> terminationOrderDeque = new ConcurrentLinkedDeque<>();
|
||||
|
||||
public static ConcurrentHashMap<String, ApiDefinitionExecResult> batchTestCases = new ConcurrentHashMap<>();
|
||||
|
||||
// 串行执行队列 KEY=报告ID VALUE=开始时间
|
||||
public static Map<String, Long> executionQueue = new HashMap<>();
|
||||
|
||||
}
|
||||
|
|
|
@ -121,9 +121,9 @@ public class TestResult {
|
|||
if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) {
|
||||
String array[] = item.getName().split(SEPARATOR);
|
||||
item.setName(array[1] + array[0]);
|
||||
item.getSubRequestResults().forEach(subItem -> {
|
||||
subItem.setName(array[0]);
|
||||
});
|
||||
// item.getSubRequestResults().forEach(subItem -> {
|
||||
// subItem.setName(array[0]);
|
||||
// });
|
||||
} else {
|
||||
this.genScenarioInSubRequestResult(item);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,9 @@ import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
|||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testplan.FileOperationRequest;
|
||||
import io.metersphere.track.service.TestPlanScenarioCaseService;
|
||||
import org.apache.commons.beanutils.BeanComparator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections4.comparators.FixedOrderComparator;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
|
@ -714,6 +716,10 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
if (StringUtils.equals(tr.getType(), "scenario")) {
|
||||
MsScenario scenario = (MsScenario) tr;
|
||||
if (scenario.isEnvironmentEnable()) {
|
||||
continue;
|
||||
}
|
||||
env.getProjectIds().add(tr.getProjectId());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(tr.getHashTree())) {
|
||||
|
@ -786,6 +792,10 @@ public class ApiAutomationService {
|
|||
}
|
||||
}
|
||||
if (StringUtils.equals(tr.getType(), "scenario")) {
|
||||
MsScenario scenario = (MsScenario) tr;
|
||||
if (scenario.isEnvironmentEnable()) {
|
||||
continue;
|
||||
}
|
||||
env.getProjectIds().add(tr.getProjectId());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(tr.getHashTree())) {
|
||||
|
@ -989,11 +999,19 @@ public class ApiAutomationService {
|
|||
// 生成集成报告
|
||||
String serialReportId = null;
|
||||
|
||||
StringBuilder idStr = new StringBuilder();
|
||||
ids.forEach(item -> {
|
||||
idStr.append("\"").append(item).append("\"").append(",");
|
||||
});
|
||||
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectByIds(idStr.toString().substring(0, idStr.toString().length() - 1), "\"" + StringUtils.join(ids, ",") + "\"");
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
List<ApiScenarioWithBLOBs> apiScenarios = apiScenarioMapper.selectByExampleWithBLOBs(example);
|
||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
if (request.getCondition() == null || !request.getCondition().isSelectAll()) {
|
||||
// 按照id指定顺序排序
|
||||
FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(ids);
|
||||
fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
|
||||
BeanComparator beanComparator = new BeanComparator("id", fixedOrderComparator);
|
||||
Collections.sort(apiScenarios, beanComparator);
|
||||
}
|
||||
}
|
||||
|
||||
// 只有一个场景且没有测试步骤,则提示
|
||||
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
|
||||
MSException.throwException((apiScenarios.get(0).getName() + "," + Translator.get("automation_exec_info")));
|
||||
|
@ -1154,6 +1172,7 @@ public class ApiAutomationService {
|
|||
MessageCache.terminationOrderDeque.remove(key);
|
||||
break;
|
||||
}
|
||||
MessageCache.executionQueue.put(key, System.currentTimeMillis());
|
||||
reportIds.add(key);
|
||||
APIScenarioReportResult report = executeQueue.get(key).getReport();
|
||||
if (StringUtils.isNotEmpty(serialReportId)) {
|
||||
|
@ -1185,6 +1204,7 @@ public class ApiAutomationService {
|
|||
executeEnvParams = hashTreeUtil.mergeParamDataMap(executeEnvParams, envParamsMap);
|
||||
} catch (Exception e) {
|
||||
reportIds.remove(key);
|
||||
MessageCache.executionQueue.remove(key);
|
||||
LogUtil.error("执行终止:" + e.getMessage());
|
||||
break;
|
||||
}
|
||||
|
@ -1852,6 +1872,7 @@ public class ApiAutomationService {
|
|||
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
|
||||
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
|
||||
scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId()));
|
||||
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
|
||||
batchMapper.insert(scenarioWithBLOBs);
|
||||
apiScenarioReferenceIdService.saveByApiScenario(scenarioWithBLOBs);
|
||||
}
|
||||
|
@ -1952,21 +1973,21 @@ public class ApiAutomationService {
|
|||
hashTree.set(i, object);
|
||||
}
|
||||
} else {
|
||||
ApiScenarioWithBLOBs bloBs = this.getDto(object.getString("id"));
|
||||
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString("id"));
|
||||
if (bloBs != null) {
|
||||
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
||||
hashTree.set(i, object);
|
||||
}
|
||||
}
|
||||
} else if ("scenario".equals(object.getString("type"))) {
|
||||
ApiScenarioWithBLOBs bloBs = this.getDto(object.getString("id"));
|
||||
ApiScenarioWithBLOBs bloBs = apiScenarioMapper.selectByPrimaryKey(object.getString("id"));
|
||||
if (bloBs != null) {
|
||||
object = JSON.parseObject(bloBs.getScenarioDefinition());
|
||||
hashTree.set(i, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(object.getJSONArray("hashTree"))) {
|
||||
if (object != null && CollectionUtils.isNotEmpty(object.getJSONArray("hashTree"))) {
|
||||
setHashTree(object.getJSONArray("hashTree"));
|
||||
}
|
||||
}
|
||||
|
@ -1985,8 +2006,10 @@ public class ApiAutomationService {
|
|||
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
|
||||
JSONObject scenario = JSONObject.parseObject(item.getScenarioDefinition());
|
||||
JSONArray hashTree = scenario.getJSONArray("hashTree");
|
||||
setHashTree(hashTree);
|
||||
scenario.put("hashTree", hashTree);
|
||||
if (hashTree != null) {
|
||||
setHashTree(hashTree);
|
||||
scenario.put("hashTree", hashTree);
|
||||
}
|
||||
item.setScenarioDefinition(JSON.toJSONString(scenario));
|
||||
}
|
||||
});
|
||||
|
@ -2608,4 +2631,9 @@ public class ApiAutomationService {
|
|||
extApiScenarioMapper::getLastOrder,
|
||||
apiScenarioMapper::updateByPrimaryKeySelective);
|
||||
}
|
||||
|
||||
public boolean checkScenarioEnv(ApiScenarioWithBLOBs request) {
|
||||
return this.checkScenarioEnv(request, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
|
||||
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
|
||||
import io.metersphere.api.jmeter.MessageCache;
|
||||
import io.metersphere.api.jmeter.TestResult;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
|
@ -57,7 +58,8 @@ public class ApiDefinitionExecResultService {
|
|||
TestCaseReviewApiCaseMapper testCaseReviewApiCaseMapper;
|
||||
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
|
||||
@Resource
|
||||
private NoticeSendService noticeSendService;
|
||||
|
||||
|
@ -67,13 +69,14 @@ public class ApiDefinitionExecResultService {
|
|||
|
||||
public void saveApiResult(TestResult result, String type, String triggerMode) {
|
||||
if (CollectionUtils.isNotEmpty(result.getScenarios())) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper definitionExecResultMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
final boolean[] isFirst = {true};
|
||||
result.getScenarios().forEach(scenarioResult -> {
|
||||
if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) {
|
||||
scenarioResult.getRequestResults().forEach(item -> {
|
||||
ApiDefinitionExecResult saveResult = definitionExecResultMapper.selectByPrimaryKey(result.getTestId());
|
||||
ApiDefinitionExecResult saveResult = MessageCache.batchTestCases.get(result.getTestId());
|
||||
if (saveResult == null) {
|
||||
saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(result.getTestId());
|
||||
}
|
||||
item.getResponseResult().setConsole(result.getConsole());
|
||||
boolean saved = true;
|
||||
if (saveResult == null || scenarioResult.getRequestResults().size() > 1) {
|
||||
|
@ -88,6 +91,7 @@ public class ApiDefinitionExecResultService {
|
|||
saveResult.setName(item.getName());
|
||||
saveResult.setTriggerMode(triggerMode);
|
||||
saveResult.setType(type);
|
||||
saveResult.setCreateTime(item.getStartTime());
|
||||
if (StringUtils.isNotEmpty(result.getUserId())) {
|
||||
saveResult.setUserId(result.getUserId());
|
||||
} else {
|
||||
|
@ -98,7 +102,6 @@ public class ApiDefinitionExecResultService {
|
|||
String status = item.isSuccess() ? "success" : "error";
|
||||
saveResult.setName(getName(type, item.getName(), status, saveResult.getCreateTime(), saveResult.getId()));
|
||||
saveResult.setStatus(status);
|
||||
saveResult.setCreateTime(item.getStartTime());
|
||||
saveResult.setResourceId(item.getName());
|
||||
saveResult.setContent(JSON.toJSONString(item));
|
||||
saveResult.setStartTime(item.getStartTime());
|
||||
|
@ -108,23 +111,23 @@ public class ApiDefinitionExecResultService {
|
|||
ApiDefinitionExecResult prevResult = extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(item.getName(), type);
|
||||
if (prevResult != null) {
|
||||
prevResult.setContent(null);
|
||||
definitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult);
|
||||
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(saveResult.getTriggerMode()) && saveResult.getTriggerMode().equals("CASE")) {
|
||||
saveResult.setTriggerMode(TriggerMode.MANUAL.name());
|
||||
}
|
||||
if (!saved) {
|
||||
definitionExecResultMapper.insert(saveResult);
|
||||
apiDefinitionExecResultMapper.insert(saveResult);
|
||||
} else {
|
||||
definitionExecResultMapper.updateByPrimaryKeyWithBLOBs(saveResult);
|
||||
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(saveResult);
|
||||
}
|
||||
apiDefinitionService.removeCache(result.getTestId());
|
||||
// 发送通知
|
||||
sendNotice(saveResult);
|
||||
});
|
||||
}
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,6 +208,7 @@ public class ApiDefinitionExecResultService {
|
|||
// 更新用例最后执行结果
|
||||
caseWithBLOBs.setLastResultId(resourceId);
|
||||
caseWithBLOBs.setStatus(status);
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
return caseWithBLOBs.getName();
|
||||
}
|
||||
|
@ -283,7 +287,7 @@ public class ApiDefinitionExecResultService {
|
|||
|
||||
if (StringUtils.equals(type, ApiRunMode.SCHEDULE_API_PLAN.name())) {
|
||||
TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName());
|
||||
if(StringUtils.isEmpty(creator)){
|
||||
if (StringUtils.isEmpty(creator)) {
|
||||
creator = testPlanService.findScheduleCreateUserById(apiCase.getTestPlanId());
|
||||
}
|
||||
apiCase.setStatus(status);
|
||||
|
@ -298,7 +302,7 @@ public class ApiDefinitionExecResultService {
|
|||
testPlanApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
|
||||
testCaseReviewApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
|
||||
}
|
||||
if(creator == null){
|
||||
if (creator == null) {
|
||||
creator = "";
|
||||
}
|
||||
saveResult.setUserId(creator);
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.metersphere.api.dto.definition.parse.Swagger3Parser;
|
|||
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.MsTCPSampler;
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigImportDTO;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
|
@ -97,8 +98,6 @@ public class ApiDefinitionService {
|
|||
@Resource
|
||||
private ExtSwaggerUrlScheduleMapper extSwaggerUrlScheduleMapper;
|
||||
@Resource
|
||||
private ScheduleMapper scheduleMapper;
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiTestEnvironmentService environmentService;
|
||||
|
@ -117,7 +116,7 @@ public class ApiDefinitionService {
|
|||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
|
||||
private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24);
|
||||
private static Cache cache = Cache.newHardMemoryCache(0, 3600);
|
||||
|
||||
private ThreadLocal<Long> currentApiOrder = new ThreadLocal<>();
|
||||
private ThreadLocal<Long> currentApiCaseOrder = new ThreadLocal<>();
|
||||
|
@ -212,6 +211,8 @@ public class ApiDefinitionService {
|
|||
extApiDefinitionExecResultMapper.deleteByResourceId(apiId);
|
||||
apiDefinitionMapper.deleteByPrimaryKey(apiId);
|
||||
esbApiParamService.deleteByResourceId(apiId);
|
||||
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
|
||||
mockConfigService.deleteMockConfigByApiId(apiId);
|
||||
FileUtils.deleteBodyFiles(apiId);
|
||||
}
|
||||
|
||||
|
@ -220,6 +221,11 @@ public class ApiDefinitionService {
|
|||
example.createCriteria().andIdIn(apiIds);
|
||||
esbApiParamService.deleteByResourceIdIn(apiIds);
|
||||
apiDefinitionMapper.deleteByExample(example);
|
||||
apiTestCaseService.deleteBatchByDefinitionId(apiIds);
|
||||
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
|
||||
for (String apiId : apiIds) {
|
||||
mockConfigService.deleteMockConfigByApiId(apiId);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeToGc(List<String> apiIds) {
|
||||
|
@ -467,7 +473,7 @@ public class ApiDefinitionService {
|
|||
}
|
||||
|
||||
private ApiDefinition importCreate(ApiDefinitionWithBLOBs apiDefinition, ApiDefinitionMapper batchMapper,
|
||||
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases,
|
||||
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases, List<MockConfigImportDTO> mocks,
|
||||
Boolean repeatable) {
|
||||
SaveApiDefinitionRequest saveReq = new SaveApiDefinitionRequest();
|
||||
BeanUtils.copyBean(saveReq, apiDefinition);
|
||||
|
@ -494,7 +500,7 @@ public class ApiDefinitionService {
|
|||
sameRequest = getSameRequestById(apiDefinition.getId(), apiTestImportRequest.getProjectId());
|
||||
}
|
||||
if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
|
||||
_importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest, cases);
|
||||
_importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest, cases, mocks);
|
||||
} else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
|
||||
if (CollectionUtils.isEmpty(sameRequest)) {
|
||||
//postman 可能含有前置脚本,接口定义去掉脚本
|
||||
|
@ -505,10 +511,10 @@ public class ApiDefinitionService {
|
|||
String requestStr = setImportHashTree(apiDefinition);
|
||||
reSetImportCasesApiId(cases, originId, apiDefinition.getId());
|
||||
apiDefinition.setRequest(requestStr);
|
||||
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true);
|
||||
importApiCase(apiDefinition, apiTestImportRequest);
|
||||
}
|
||||
} else {
|
||||
_importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest, cases);
|
||||
_importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest, cases, mocks);
|
||||
}
|
||||
|
||||
return apiDefinition;
|
||||
|
@ -535,17 +541,18 @@ public class ApiDefinitionService {
|
|||
}
|
||||
|
||||
private void _importCreate(List<ApiDefinition> sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition,
|
||||
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases) {
|
||||
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest, List<ApiTestCaseWithBLOBs> cases ,List<MockConfigImportDTO> mocks) {
|
||||
String originId = apiDefinition.getId();
|
||||
if (CollectionUtils.isEmpty(sameRequest)) {
|
||||
apiDefinition.setId(UUID.randomUUID().toString());
|
||||
apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
|
||||
reSetImportCasesApiId(cases, originId, apiDefinition.getId());
|
||||
reSetImportMocksApiId(mocks, originId, apiDefinition.getId());
|
||||
if (StringUtils.equalsIgnoreCase(apiDefinition.getProtocol(), RequestType.HTTP)) {
|
||||
batchMapper.insert(apiDefinition);
|
||||
String request = setImportHashTree(apiDefinition);
|
||||
apiDefinition.setRequest(request);
|
||||
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true);
|
||||
importApiCase(apiDefinition, apiTestImportRequest);
|
||||
} else {
|
||||
if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) {
|
||||
setImportTCPHashTree(apiDefinition);
|
||||
|
@ -565,7 +572,7 @@ public class ApiDefinitionService {
|
|||
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
|
||||
apiDefinition.setRequest(request);
|
||||
reSetImportCasesApiId(cases, originId, apiDefinition.getId());
|
||||
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, false);
|
||||
importApiCase(apiDefinition, apiTestImportRequest);
|
||||
} else {
|
||||
apiDefinition.setId(sameRequest.get(0).getId());
|
||||
if (StringUtils.equalsAnyIgnoreCase(apiDefinition.getProtocol(), RequestType.TCP)) {
|
||||
|
@ -596,6 +603,16 @@ public class ApiDefinitionService {
|
|||
}
|
||||
}
|
||||
|
||||
private void reSetImportMocksApiId(List<MockConfigImportDTO> mocks, String originId, String newId) {
|
||||
if (CollectionUtils.isNotEmpty(mocks)) {
|
||||
mocks.forEach(item -> {
|
||||
if (StringUtils.equals(item.getApiId(), originId)) {
|
||||
item.setApiId(newId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String setImportHashTree(ApiDefinitionWithBLOBs apiDefinition) {
|
||||
String request = apiDefinition.getRequest();
|
||||
MsHTTPSamplerProxy msHTTPSamplerProxy = JSONObject.parseObject(request, MsHTTPSamplerProxy.class);
|
||||
|
@ -614,7 +631,7 @@ public class ApiDefinitionService {
|
|||
return request;
|
||||
}
|
||||
|
||||
private void importMsCase(ApiDefinitionImport apiImport, SqlSession sqlSession, ApiTestCaseMapper apiTestCaseMapper,
|
||||
private void importMsCase(ApiDefinitionImport apiImport, SqlSession sqlSession,
|
||||
ApiTestImportRequest request) {
|
||||
List<ApiTestCaseWithBLOBs> cases = apiImport.getCases();
|
||||
if (CollectionUtils.isNotEmpty(cases)) {
|
||||
|
@ -625,7 +642,7 @@ public class ApiDefinitionService {
|
|||
if (apiDefinitionWithBLOBs == null) {
|
||||
continue;
|
||||
}
|
||||
insertOrUpdateImportCase(item, request);
|
||||
insertOrUpdateImportCase(item, request, apiDefinitionWithBLOBs);
|
||||
}
|
||||
if (batchCount % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
|
@ -637,8 +654,7 @@ public class ApiDefinitionService {
|
|||
* 导入是插件或者postman时创建用例
|
||||
* postman考虑是否有前置脚本
|
||||
*/
|
||||
private void importApiCase(ApiDefinitionWithBLOBs apiDefinition, ApiTestCaseMapper apiTestCaseMapper,
|
||||
ApiTestImportRequest apiTestImportRequest, Boolean isInsert) {
|
||||
private void importApiCase(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest apiTestImportRequest) {
|
||||
try {
|
||||
if (StringUtils.equalsAnyIgnoreCase(apiTestImportRequest.getPlatform(), ApiImportPlatform.Plugin.name(), ApiImportPlatform.Postman.name())) {
|
||||
ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs();
|
||||
|
@ -648,14 +664,14 @@ public class ApiDefinitionService {
|
|||
if (apiTestCase.getName().length() > 255) {
|
||||
apiTestCase.setName(apiTestCase.getName().substring(0, 255));
|
||||
}
|
||||
insertOrUpdateImportCase(apiTestCase, apiTestImportRequest);
|
||||
insertOrUpdateImportCase(apiTestCase, apiTestImportRequest, apiDefinition);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("导入创建用例异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertOrUpdateImportCase(ApiTestCaseWithBLOBs apiTestCase, ApiTestImportRequest apiTestImportRequest) {
|
||||
private void insertOrUpdateImportCase(ApiTestCaseWithBLOBs apiTestCase, ApiTestImportRequest apiTestImportRequest, ApiDefinitionWithBLOBs apiDefinition) {
|
||||
SaveApiTestCaseRequest checkRequest = new SaveApiTestCaseRequest();
|
||||
checkRequest.setName(apiTestCase.getName());
|
||||
checkRequest.setApiDefinitionId(apiTestCase.getApiDefinitionId());
|
||||
|
@ -667,7 +683,7 @@ public class ApiDefinitionService {
|
|||
apiTestCase.setUpdateUserId(SessionUtils.getUserId());
|
||||
if (sameCase == null) {
|
||||
apiTestCase.setId(UUID.randomUUID().toString());
|
||||
apiTestCase.setNum(apiTestCaseService.getNextNum(apiTestCase.getApiDefinitionId()));
|
||||
apiTestCase.setNum(apiTestCaseService.getNextNum(apiTestCase.getApiDefinitionId(), apiDefinition.getNum()));
|
||||
apiTestCase.setCreateTime(System.currentTimeMillis());
|
||||
apiTestCase.setUpdateTime(System.currentTimeMillis());
|
||||
apiTestCase.setCreateUserId(SessionUtils.getUserId());
|
||||
|
@ -800,6 +816,12 @@ public class ApiDefinitionService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void removeCache(String testId) {
|
||||
if (StringUtils.isNotEmpty(testId)) {
|
||||
cache.remove(testId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储执行结果报告
|
||||
*
|
||||
|
@ -932,14 +954,14 @@ public class ApiDefinitionService {
|
|||
if (apiImport.getEsbApiParamsMap() != null) {
|
||||
String apiId = item.getId();
|
||||
EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId);
|
||||
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), project.getRepeatable());
|
||||
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), apiImport.getMocks(), project.getRepeatable());
|
||||
if (model != null) {
|
||||
apiImport.getEsbApiParamsMap().remove(apiId);
|
||||
model.setResourceId(item.getId());
|
||||
apiImport.getEsbApiParamsMap().put(item.getId(), model);
|
||||
}
|
||||
} else {
|
||||
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), project.getRepeatable());
|
||||
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), apiImport.getMocks(), project.getRepeatable());
|
||||
}
|
||||
if (i % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
|
@ -963,8 +985,13 @@ public class ApiDefinitionService {
|
|||
}
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(apiImport.getMocks())) {
|
||||
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
|
||||
mockConfigService.importMock(apiImport, sqlSession, request);
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(apiImport.getCases())) {
|
||||
importMsCase(apiImport, sqlSession, apiTestCaseMapper, request);
|
||||
importMsCase(apiImport, sqlSession, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1051,6 +1078,7 @@ public class ApiDefinitionService {
|
|||
|
||||
public void deleteByParams(ApiBatchRequest request) {
|
||||
apiDefinitionMapper.deleteByExample(getBatchExample(request));
|
||||
apiTestCaseService.deleteBatchByDefinitionId(request.getIds());
|
||||
}
|
||||
|
||||
public ApiDefinitionExample getBatchExample(ApiBatchRequest request) {
|
||||
|
@ -1248,9 +1276,11 @@ public class ApiDefinitionService {
|
|||
example.createCriteria().andIdIn(request.getIds());
|
||||
|
||||
if (StringUtils.equals(type, "MS")) { // 导出为 Metersphere 格式
|
||||
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
|
||||
apiExportResult = new MsApiExportResult();
|
||||
((MsApiExportResult) apiExportResult).setData(apiDefinitionMapper.selectByExampleWithBLOBs(example));
|
||||
((MsApiExportResult) apiExportResult).setCases(apiTestCaseService.selectCasesBydApiIds(request.getIds()));
|
||||
((MsApiExportResult) apiExportResult).setMocks(mockConfigService.selectMockExpectConfigByApiIdIn(request.getIds()));
|
||||
((MsApiExportResult) apiExportResult).setProjectName(request.getProjectId());
|
||||
((MsApiExportResult) apiExportResult).setProtocol(request.getProtocol());
|
||||
((MsApiExportResult) apiExportResult).setProjectId(request.getProjectId());
|
||||
|
|
|
@ -342,7 +342,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionMapper apiDefinitionMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
|
||||
apiModule.forEach((value) -> {
|
||||
apiDefinitionMapper.updateByPrimaryKey(value);
|
||||
apiDefinitionMapper.updateByPrimaryKeySelective(value);
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
private void batchUpdateApiScenario(List<ApiScenarioDTO> apiScenarios) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiScenarioMapper apiScenarioMapper = sqlSession.getMapper(ApiScenarioMapper.class);
|
||||
apiScenarios.forEach(apiScenarioMapper::updateByPrimaryKey);
|
||||
apiScenarios.forEach(apiScenarioMapper::updateByPrimaryKeySelective);
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
|||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.MessageCache;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.*;
|
||||
|
@ -396,6 +397,18 @@ public class ApiTestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
public int getNextNum(String definitionId, Integer definitionNum) {
|
||||
ApiTestCase apiTestCase = extApiTestCaseMapper.getNextNum(definitionId);
|
||||
if (apiTestCase == null) {
|
||||
if (definitionNum == null) {
|
||||
return apiDefinitionMapper.selectByPrimaryKey(definitionId).getNum() * 1000 + 1;
|
||||
}
|
||||
return definitionNum * 1000 + 1;
|
||||
} else {
|
||||
return Optional.of(apiTestCase.getNum() + 1)
|
||||
.orElse(apiDefinitionMapper.selectByPrimaryKey(definitionId).getNum() * 1000 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteFileByTestId(String testId) {
|
||||
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
||||
|
@ -433,6 +446,17 @@ public class ApiTestCaseService {
|
|||
apiTestCaseMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public void deleteBatchByDefinitionId(List<String> definitionIds) {
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andApiDefinitionIdIn(definitionIds);
|
||||
apiTestCaseMapper.deleteByExample(example);
|
||||
List<ApiTestCase> apiTestCases = apiTestCaseMapper.selectByExample(example);
|
||||
List<String> caseIds = apiTestCases.stream().map(ApiTestCase::getId).collect(Collectors.toList());
|
||||
for (String testId : caseIds) {
|
||||
extTestPlanTestCaseMapper.deleteByTestCaseID(testId);
|
||||
}
|
||||
}
|
||||
|
||||
public void relevanceByApi(ApiCaseRelevanceRequest request) {
|
||||
if (CollectionUtils.isEmpty(request.getSelectIds())) {
|
||||
return;
|
||||
|
@ -471,7 +495,7 @@ public class ApiTestCaseService {
|
|||
ExtTestPlanApiCaseMapper batchMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
||||
Long nextOrder = ServiceUtils.getNextOrder(request.getPlanId(), extTestPlanApiCaseMapper::getLastOrder);
|
||||
|
||||
for (ApiTestCase apiTestCase: apiTestCases) {
|
||||
for (ApiTestCase apiTestCase : apiTestCases) {
|
||||
TestPlanApiCase testPlanApiCase = new TestPlanApiCase();
|
||||
testPlanApiCase.setId(UUID.randomUUID().toString());
|
||||
testPlanApiCase.setCreateUser(SessionUtils.getUserId());
|
||||
|
@ -678,50 +702,54 @@ public class ApiTestCaseService {
|
|||
|
||||
public void batchRun(ApiCaseBatchRequest request) {
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiTestCaseMapper.selectIdsByQuery(query));
|
||||
Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>();
|
||||
(query) -> extApiTestCaseMapper.selectIdsByQuery((ApiTestCaseRequest) query));
|
||||
List<RunCaseRequest> executeQueue = new LinkedList<>();
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
|
||||
for (String testCaseId : request.getIds()) {
|
||||
ApiDefinitionExecResult report = addResult(testCaseId, APITestStatus.Running.name());
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testCaseId);
|
||||
if (caseWithBLOBs != null) {
|
||||
report.setName(caseWithBLOBs.getName());
|
||||
caseWithBLOBs.setLastResultId(report.getId());
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
caseWithBLOBs.setStatus(APITestStatus.Running.name());
|
||||
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
}
|
||||
batchMapper.insert(report);
|
||||
executeQueue.put(testCaseId, report);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
for (String caseId : executeQueue.keySet()) {
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
List<ApiTestCaseWithBLOBs> list = apiTestCaseMapper.selectByExampleWithBLOBs(example);
|
||||
|
||||
ApiTestCaseMapper sqlSessionMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
for (ApiTestCaseWithBLOBs caseWithBLOBs : list) {
|
||||
ApiDefinitionExecResult report = addResult(caseWithBLOBs.getId(), APITestStatus.Running.name());
|
||||
report.setName(caseWithBLOBs.getName());
|
||||
caseWithBLOBs.setLastResultId(report.getId());
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
caseWithBLOBs.setStatus(APITestStatus.Running.name());
|
||||
sqlSessionMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
|
||||
// 执行对象
|
||||
RunCaseRequest runCaseRequest = new RunCaseRequest();
|
||||
runCaseRequest.setRunMode(ApiRunMode.DEFINITION.name());
|
||||
runCaseRequest.setCaseId(caseId);
|
||||
runCaseRequest.setReportId(executeQueue.get(caseId).getId());
|
||||
runCaseRequest.setCaseId(caseWithBLOBs.getId());
|
||||
runCaseRequest.setReportId(report.getId());
|
||||
runCaseRequest.setEnvironmentId(request.getEnvironmentId());
|
||||
runCaseRequest.setBloBs(caseWithBLOBs);
|
||||
runCaseRequest.setReport(report);
|
||||
|
||||
batchMapper.insert(report);
|
||||
executeQueue.add(runCaseRequest);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
for (RunCaseRequest runCaseRequest : executeQueue) {
|
||||
run(runCaseRequest);
|
||||
MessageCache.batchTestCases.put(runCaseRequest.getReportId(), runCaseRequest.getReport());
|
||||
}
|
||||
}
|
||||
|
||||
public String run(RunCaseRequest request) {
|
||||
ApiTestCaseWithBLOBs testCaseWithBLOBs = null;
|
||||
ApiTestCaseWithBLOBs testCaseWithBLOBs = request.getBloBs();
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
testCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getReportId());
|
||||
request.setCaseId(request.getReportId());
|
||||
} else {
|
||||
testCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId());
|
||||
//通过测试计划id查询环境
|
||||
request.setReportId(request.getTestPlanId());
|
||||
}
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS.name())) {
|
||||
request.setReportId(request.getEnvironmentId());
|
||||
}
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
//通过测试计划id查询环境
|
||||
request.setReportId(request.getTestPlanId());
|
||||
}
|
||||
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
|
||||
if (testCaseWithBLOBs != null && StringUtils.isNotEmpty(testCaseWithBLOBs.getRequest())) {
|
||||
try {
|
||||
|
@ -1066,6 +1094,7 @@ public class ApiTestCaseService {
|
|||
|
||||
/**
|
||||
* 用例自定义排序
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void updateOrder(ResetOrderRequest request) {
|
||||
|
|
|
@ -4,9 +4,12 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.automation.EsbDataStruct;
|
||||
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
|
||||
import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigImportDTO;
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigRequest;
|
||||
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
|
||||
import io.metersphere.api.dto.mockconfig.response.JsonSchemaReturnObj;
|
||||
|
@ -23,6 +26,7 @@ import io.metersphere.jmeter.utils.ScriptEngineUtils;
|
|||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.json.XML;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -65,6 +69,28 @@ public class MockConfigService {
|
|||
return this.assemblyMockConfingResponse(configList);
|
||||
}
|
||||
|
||||
public List<MockExpectConfigWithBLOBs> selectMockExpectConfigByApiId(String apiId){
|
||||
return extMockExpectConfigMapper.selectByApiId(apiId);
|
||||
}
|
||||
|
||||
public List<MockConfigImportDTO> selectMockExpectConfigByApiIdIn(List<String> apiIds){
|
||||
if(CollectionUtils.isNotEmpty(apiIds)){
|
||||
List<MockConfigImportDTO> returnDTO = new ArrayList<>();
|
||||
for (String apiId : apiIds) {
|
||||
List<MockExpectConfigWithBLOBs> mockExpectConfigWithBLOBsList = extMockExpectConfigMapper.selectByApiId(apiId);
|
||||
for (MockExpectConfigWithBLOBs model : mockExpectConfigWithBLOBsList) {
|
||||
MockConfigImportDTO dto = new MockConfigImportDTO();
|
||||
BeanUtils.copyBean(dto, model);
|
||||
dto.setApiId(apiId);
|
||||
returnDTO.add(dto);
|
||||
}
|
||||
}
|
||||
return returnDTO;
|
||||
}else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
private MockConfigResponse assemblyMockConfingResponse(List<MockConfig> configList) {
|
||||
if (!configList.isEmpty()) {
|
||||
MockConfig config = configList.get(0);
|
||||
|
@ -610,6 +636,19 @@ public class MockConfigService {
|
|||
mockExpectConfigMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public void deleteMockConfigByApiId(String apiId){
|
||||
MockConfigExample configExample = new MockConfigExample();
|
||||
configExample.createCriteria().andApiIdEqualTo(apiId);
|
||||
List<MockConfig> mockConfigList = mockConfigMapper.selectByExample(configExample);
|
||||
MockExpectConfigExample example = new MockExpectConfigExample();
|
||||
for (MockConfig mockConfig : mockConfigList) {
|
||||
example.clear();
|
||||
example.createCriteria().andMockConfigIdEqualTo(mockConfig.getId());
|
||||
mockExpectConfigMapper.deleteByExample(example);
|
||||
}
|
||||
mockConfigMapper.deleteByExample(configExample);
|
||||
}
|
||||
|
||||
public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) {
|
||||
JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams);
|
||||
Enumeration<String> paramNameItor = request.getParameterNames();
|
||||
|
@ -1187,4 +1226,51 @@ public class MockConfigService {
|
|||
}
|
||||
return isJson;
|
||||
}
|
||||
|
||||
public void importMock(ApiDefinitionImport apiImport, SqlSession sqlSession, ApiTestImportRequest request) {
|
||||
if(CollectionUtils.isNotEmpty(apiImport.getMocks())){
|
||||
Map<String,List<MockExpectConfigWithBLOBs>> saveMap = new HashMap<>();
|
||||
for (MockConfigImportDTO dto : apiImport.getMocks()) {
|
||||
String apiId = dto.getApiId();//de33108c-26e2-4d4f-826a-a5f8e017d2f4
|
||||
if(saveMap.containsKey(apiId)){
|
||||
saveMap.get(apiId).add(dto);
|
||||
}else {
|
||||
List<MockExpectConfigWithBLOBs> list = new ArrayList<>();
|
||||
list.add(dto);
|
||||
saveMap.put(apiId,list);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String,List<MockExpectConfigWithBLOBs>> entry : saveMap.entrySet()) {
|
||||
String apiId = entry.getKey();
|
||||
this.deleteMockConfigByApiId(apiId);
|
||||
|
||||
List<MockExpectConfigWithBLOBs> list = entry.getValue();
|
||||
|
||||
String mockId = UUID.randomUUID().toString();
|
||||
MockConfig config = new MockConfig();
|
||||
config.setProjectId(request.getProjectId());
|
||||
config.setId(mockId);
|
||||
config.setCreateUserId(SessionUtils.getUserId());
|
||||
config.setCreateTime(System.currentTimeMillis());
|
||||
config.setUpdateTime(System.currentTimeMillis());
|
||||
config.setApiId(apiId);
|
||||
mockConfigMapper.insert(config);
|
||||
|
||||
int batchCount = 0;
|
||||
for (MockExpectConfigWithBLOBs mockExpect : list) {
|
||||
mockExpect.setId(UUID.randomUUID().toString());
|
||||
mockExpect.setMockConfigId(mockId);
|
||||
mockExpect.setCreateTime(System.currentTimeMillis());
|
||||
mockExpect.setUpdateTime(System.currentTimeMillis());
|
||||
mockExpect.setCreateUserId(SessionUtils.getUserId());
|
||||
mockExpectConfigMapper.insert(mockExpect);
|
||||
}
|
||||
if (batchCount % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,11 +150,7 @@ public class TestResultService {
|
|||
testPlanTestCaseService.updateTestCaseStates(ids, TestPlanTestCaseStatus.Failure.name());
|
||||
}
|
||||
}
|
||||
if (reportTask != null) {
|
||||
if (!StringUtils.equals(ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), runMode) && !StringUtils.equals(ApiRunMode.JENKINS_SCENARIO_PLAN.name(), runMode) && StringUtils.equals(ReportTriggerMode.API.name(), reportTask.getTriggerMode()) || StringUtils.equals(ReportTriggerMode.SCHEDULE.name(), reportTask.getTriggerMode())) {
|
||||
sendTask(reportTask, reportUrl, testResult);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
|
@ -193,66 +189,4 @@ public class TestResultService {
|
|||
}
|
||||
}
|
||||
|
||||
private static void sendTask(ApiTestReportVariable report, String reportUrl, TestResult testResult) {
|
||||
if (report == null) {
|
||||
return;
|
||||
}
|
||||
SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);
|
||||
NoticeSendService noticeSendService = CommonBeanFactory.getBean(NoticeSendService.class);
|
||||
assert systemParameterService != null;
|
||||
assert noticeSendService != null;
|
||||
BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
|
||||
String url = baseSystemConfigDTO.getUrl() + "/#/api/report/view/" + report.getId();
|
||||
String url2 = baseSystemConfigDTO.getUrl() + "/#/api/automation/report/view/" + report.getId();
|
||||
|
||||
String successContext = "";
|
||||
String failedContext = "";
|
||||
String subject = "";
|
||||
String event = "";
|
||||
if (StringUtils.equals(ReportTriggerMode.API.name(), report.getTriggerMode())) {
|
||||
successContext = "接口测试 API任务通知:jenkins所执行的" + report.getName() + "'执行成功" + "\n" + "执行环境:" + report.getExecutionEnvironment() + "\n" + "[接口定义暂无报告链接]" + "\n" + "请点击下面链接进入测试报告页面" + "\n" + "(旧版)接口测试路径" + url + "\n" + "(新版)接口测试路径" + url2;
|
||||
failedContext = "接口测试 API任务通知:jenkins所执行的" + report.getName() + "'执行失败" + "\n" + "执行环境:" + report.getExecutionEnvironment() + "\n" + "[接口定义暂无报告链接]" + "\n" + "请点击下面链接进入测试报告页面" + "\n" + "(旧版)接口测试路径" + url + "\n" + "(新版)接口测试路径" + url2;
|
||||
subject = Translator.get("task_notification_jenkins");
|
||||
}
|
||||
if (StringUtils.equals(ReportTriggerMode.SCHEDULE.name(), report.getTriggerMode())) {
|
||||
successContext = "接口测试定时任务通知:定时任务所执行的" + report.getName() + "'执行成功" + "\n" + "执行环境:" + report.getExecutionEnvironment() + "\n" + "[接口定义暂无报告链接]" + "\n" + "请点击下面链接进入测试报告页面" + "\n" + "(旧版)接口测试路径" + url + "\n" + "(新版)接口测试路径" + url2;
|
||||
failedContext = "接口测试定时任务通知:定时任务所执行的" + report.getName() + "'执行失败" + "\n" + "执行环境:" + report.getExecutionEnvironment() + "\n" + "[接口定义暂无报告链接]" + "\n" + "请点击下面链接进入测试报告页面" + "\n" + "(旧版)接口测试路径" + url + "\n" + "(新版)接口测试路径" + url2;
|
||||
subject = Translator.get("task_notification");
|
||||
}
|
||||
if (StringUtils.equals("Success", report.getStatus())) {
|
||||
event = NoticeConstants.Event.EXECUTE_SUCCESSFUL;
|
||||
}
|
||||
if (StringUtils.equals("success", report.getStatus())) {
|
||||
event = NoticeConstants.Event.EXECUTE_SUCCESSFUL;
|
||||
}
|
||||
if (StringUtils.equals("Error", report.getStatus())) {
|
||||
event = NoticeConstants.Event.EXECUTE_FAILED;
|
||||
}
|
||||
if (StringUtils.equals("error", report.getStatus())) {
|
||||
event = NoticeConstants.Event.EXECUTE_FAILED;
|
||||
}
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("testName", report.getName());
|
||||
paramMap.put("id", report.getId());
|
||||
paramMap.put("type", "api");
|
||||
paramMap.put("url", baseSystemConfigDTO.getUrl());
|
||||
paramMap.put("status", report.getStatus());
|
||||
paramMap.put("executor", report.getExecutor());
|
||||
paramMap.put("executionTime", report.getExecutionTime());
|
||||
paramMap.put("executionEnvironment", report.getExecutionEnvironment());
|
||||
paramMap.put("principal", report.getPrincipal());
|
||||
NoticeModel noticeModel = NoticeModel.builder()
|
||||
.operator(SessionUtils.getUserId())
|
||||
.successContext(successContext)
|
||||
.successMailTemplate("ApiSuccessfulNotification")
|
||||
.failedContext(failedContext)
|
||||
.failedMailTemplate("ApiFailedNotification")
|
||||
.testId(testResult.getTestId())
|
||||
.status(report.getStatus())
|
||||
.event(event)
|
||||
.subject(subject)
|
||||
.paramMap(paramMap)
|
||||
.build();
|
||||
noticeSendService.send(report.getTriggerMode(), NoticeConstants.TaskType.API_DEFINITION_TASK, noticeModel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
|
|||
@Override
|
||||
public T call() {
|
||||
try {
|
||||
if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
|
||||
if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
|
||||
MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
|
||||
return null;
|
||||
}
|
||||
|
@ -43,25 +43,24 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
|
|||
} else {
|
||||
jMeterService.runLocal(runModeDataDTO.getReport().getId(), runModeDataDTO.getHashTree(), TriggerMode.BATCH.name().equals(request.getTriggerMode()) ? TriggerMode.BATCH.name() : request.getReportId(), request.getRunMode());
|
||||
}
|
||||
// 轮询查看报告状态,最多200次,防止死循环
|
||||
int index = 1;
|
||||
while (index < 200) {
|
||||
Thread.sleep(3000);
|
||||
index++;
|
||||
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
|
||||
if (report != null && !report.getStatus().equals(APITestStatus.Running.name())) {
|
||||
while (MessageCache.executionQueue.containsKey(runModeDataDTO.getReport().getId())) {
|
||||
long currentSecond = (System.currentTimeMillis() - MessageCache.executionQueue.get(runModeDataDTO.getReport().getId())) / 1000 / 60;
|
||||
// 设置五分钟超时
|
||||
if (currentSecond > 5) {
|
||||
// 执行失败了,恢复报告状态
|
||||
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
|
||||
if (report != null) {
|
||||
report.setStatus(APITestStatus.Error.name());
|
||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (runModeDataDTO.getReport()!=null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
|
||||
if (runModeDataDTO.getReport() != null && MessageCache.terminationOrderDeque.contains(runModeDataDTO.getReport().getId())) {
|
||||
MessageCache.terminationOrderDeque.remove(runModeDataDTO.getReport().getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 执行失败了,恢复报告状态
|
||||
if (index == 200 && report != null && report.getStatus().equals(APITestStatus.Running.name())) {
|
||||
report.setStatus(APITestStatus.Error.name());
|
||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||
}
|
||||
report = apiScenarioReportMapper.selectByPrimaryKey(runModeDataDTO.getReport().getId());
|
||||
return (T) report;
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex);
|
||||
|
|
|
@ -34,7 +34,7 @@ public class TCPServer implements Runnable {
|
|||
}
|
||||
|
||||
public boolean isSocketOpen(){
|
||||
if (this.serverSocket != null && !this.serverSocket.isClosed() &&this.servicer != null) {
|
||||
if (this.serverSocket != null && !this.serverSocket.isClosed()) {
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
|
|
|
@ -23,5 +23,7 @@ public class TestCaseReviewTestCase implements Serializable {
|
|||
|
||||
private String createUser;
|
||||
|
||||
private Long order;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -713,6 +713,66 @@ public class TestCaseReviewTestCaseExample {
|
|||
addCriterion("create_user not between", value1, value2, "createUser");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIsNull() {
|
||||
addCriterion("`order` is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIsNotNull() {
|
||||
addCriterion("`order` is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderEqualTo(Long value) {
|
||||
addCriterion("`order` =", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotEqualTo(Long value) {
|
||||
addCriterion("`order` <>", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderGreaterThan(Long value) {
|
||||
addCriterion("`order` >", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("`order` >=", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderLessThan(Long value) {
|
||||
addCriterion("`order` <", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderLessThanOrEqualTo(Long value) {
|
||||
addCriterion("`order` <=", value, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIn(List<Long> values) {
|
||||
addCriterion("`order` in", values, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotIn(List<Long> values) {
|
||||
addCriterion("`order` not in", values, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderBetween(Long value1, Long value2) {
|
||||
addCriterion("`order` between", value1, value2, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotBetween(Long value1, Long value2) {
|
||||
addCriterion("`order` not between", value1, value2, "order");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
@ -807,4 +867,4 @@ public class TestCaseReviewTestCaseExample {
|
|||
this(condition, value, secondValue, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TestPlanPrincipal implements Serializable {
|
||||
private String testPlanId;
|
||||
|
||||
private String principalId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -0,0 +1,340 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TestPlanPrincipalExample {
|
||||
protected String orderByClause;
|
||||
|
||||
protected boolean distinct;
|
||||
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
public TestPlanPrincipalExample() {
|
||||
oredCriteria = new ArrayList<Criteria>();
|
||||
}
|
||||
|
||||
public void setOrderByClause(String orderByClause) {
|
||||
this.orderByClause = orderByClause;
|
||||
}
|
||||
|
||||
public String getOrderByClause() {
|
||||
return orderByClause;
|
||||
}
|
||||
|
||||
public void setDistinct(boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
||||
public List<Criteria> getOredCriteria() {
|
||||
return oredCriteria;
|
||||
}
|
||||
|
||||
public void or(Criteria criteria) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
|
||||
public Criteria or() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
oredCriteria.add(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public Criteria createCriteria() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
if (oredCriteria.size() == 0) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected Criteria createCriteriaInternal() {
|
||||
Criteria criteria = new Criteria();
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
oredCriteria.clear();
|
||||
orderByClause = null;
|
||||
distinct = false;
|
||||
}
|
||||
|
||||
protected abstract static class GeneratedCriteria {
|
||||
protected List<Criterion> criteria;
|
||||
|
||||
protected GeneratedCriteria() {
|
||||
super();
|
||||
criteria = new ArrayList<Criterion>();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return criteria.size() > 0;
|
||||
}
|
||||
|
||||
public List<Criterion> getAllCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public List<Criterion> getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition) {
|
||||
if (condition == null) {
|
||||
throw new RuntimeException("Value for condition cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value, String property) {
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||
if (value1 == null || value2 == null) {
|
||||
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value1, value2));
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdIsNull() {
|
||||
addCriterion("test_plan_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdIsNotNull() {
|
||||
addCriterion("test_plan_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdEqualTo(String value) {
|
||||
addCriterion("test_plan_id =", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdNotEqualTo(String value) {
|
||||
addCriterion("test_plan_id <>", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdGreaterThan(String value) {
|
||||
addCriterion("test_plan_id >", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("test_plan_id >=", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdLessThan(String value) {
|
||||
addCriterion("test_plan_id <", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("test_plan_id <=", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdLike(String value) {
|
||||
addCriterion("test_plan_id like", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdNotLike(String value) {
|
||||
addCriterion("test_plan_id not like", value, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdIn(List<String> values) {
|
||||
addCriterion("test_plan_id in", values, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdNotIn(List<String> values) {
|
||||
addCriterion("test_plan_id not in", values, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdBetween(String value1, String value2) {
|
||||
addCriterion("test_plan_id between", value1, value2, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTestPlanIdNotBetween(String value1, String value2) {
|
||||
addCriterion("test_plan_id not between", value1, value2, "testPlanId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdIsNull() {
|
||||
addCriterion("principal_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdIsNotNull() {
|
||||
addCriterion("principal_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdEqualTo(String value) {
|
||||
addCriterion("principal_id =", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdNotEqualTo(String value) {
|
||||
addCriterion("principal_id <>", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdGreaterThan(String value) {
|
||||
addCriterion("principal_id >", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("principal_id >=", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdLessThan(String value) {
|
||||
addCriterion("principal_id <", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("principal_id <=", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdLike(String value) {
|
||||
addCriterion("principal_id like", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdNotLike(String value) {
|
||||
addCriterion("principal_id not like", value, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdIn(List<String> values) {
|
||||
addCriterion("principal_id in", values, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdNotIn(List<String> values) {
|
||||
addCriterion("principal_id not in", values, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdBetween(String value1, String value2) {
|
||||
addCriterion("principal_id between", value1, value2, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPrincipalIdNotBetween(String value1, String value2) {
|
||||
addCriterion("principal_id not between", value1, value2, "principalId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
||||
protected Criteria() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criterion {
|
||||
private String condition;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Object secondValue;
|
||||
|
||||
private boolean noValue;
|
||||
|
||||
private boolean singleValue;
|
||||
|
||||
private boolean betweenValue;
|
||||
|
||||
private boolean listValue;
|
||||
|
||||
private String typeHandler;
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getSecondValue() {
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
public boolean isNoValue() {
|
||||
return noValue;
|
||||
}
|
||||
|
||||
public boolean isSingleValue() {
|
||||
return singleValue;
|
||||
}
|
||||
|
||||
public boolean isBetweenValue() {
|
||||
return betweenValue;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public String getTypeHandler() {
|
||||
return typeHandler;
|
||||
}
|
||||
|
||||
protected Criterion(String condition) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.typeHandler = null;
|
||||
this.noValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.typeHandler = typeHandler;
|
||||
if (value instanceof List<?>) {
|
||||
this.listValue = true;
|
||||
} else {
|
||||
this.singleValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value) {
|
||||
this(condition, value, null);
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.secondValue = secondValue;
|
||||
this.typeHandler = typeHandler;
|
||||
this.betweenValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue) {
|
||||
this(condition, value, secondValue, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
|
||||
<result column="order" jdbcType="BIGINT" property="order" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -71,7 +72,8 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, review_id, case_id, `status`, `result`, reviewer, create_time, update_time, create_user
|
||||
id, review_id, case_id, `status`, `result`, reviewer, create_time, update_time, create_user,
|
||||
`order`
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseReviewTestCaseExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -88,7 +90,7 @@
|
|||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||
select
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from test_case_review_test_case
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
|
@ -104,14 +106,14 @@
|
|||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseReviewTestCase">
|
||||
insert into test_case_review_test_case (id, review_id, case_id,
|
||||
`status`, `result`, reviewer,
|
||||
create_time, update_time, create_user
|
||||
)
|
||||
values (#{id,jdbcType=VARCHAR}, #{reviewId,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR},
|
||||
#{status,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR}, #{reviewer,jdbcType=VARCHAR},
|
||||
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR}
|
||||
)
|
||||
insert into test_case_review_test_case (id, review_id, case_id,
|
||||
`status`, `result`, reviewer,
|
||||
create_time, update_time, create_user,
|
||||
`order`)
|
||||
values (#{id,jdbcType=VARCHAR}, #{reviewId,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR},
|
||||
#{status,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR}, #{reviewer,jdbcType=VARCHAR},
|
||||
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR},
|
||||
#{order,jdbcType=BIGINT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseReviewTestCase">
|
||||
insert into test_case_review_test_case
|
||||
|
@ -143,6 +145,9 @@
|
|||
<if test="createUser != null">
|
||||
create_user,
|
||||
</if>
|
||||
<if test="order != null">
|
||||
`order`,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -172,6 +177,9 @@
|
|||
<if test="createUser != null">
|
||||
#{createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="order != null">
|
||||
#{order,jdbcType=BIGINT},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestCaseReviewTestCaseExample" resultType="java.lang.Long">
|
||||
|
@ -210,6 +218,9 @@
|
|||
<if test="record.createUser != null">
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.order != null">
|
||||
`order` = #{record.order,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -225,7 +236,8 @@
|
|||
reviewer = #{record.reviewer,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR}
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
`order` = #{record.order,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -257,6 +269,9 @@
|
|||
<if test="createUser != null">
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="order != null">
|
||||
`order` = #{order,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
@ -269,7 +284,8 @@
|
|||
reviewer = #{reviewer,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
create_user = #{createUser,jdbcType=VARCHAR}
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
`order` = #{order,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
from api_test_case atc
|
||||
left join test_case_test tct on atc.id = tct.test_id
|
||||
inner join api_definition ad on ad.id = atc.api_definition_id
|
||||
where tct.test_id is NULL and ad.status != 'Trash'
|
||||
where tct.test_id is NULL and atc.status != 'Trash'
|
||||
<if test="request.protocol != null and request.protocol!=''">
|
||||
and ad.protocol = #{request.protocol}
|
||||
</if>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.base.mapper;
|
||||
|
||||
import io.metersphere.base.domain.TestPlanPrincipal;
|
||||
import io.metersphere.base.domain.TestPlanPrincipalExample;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface TestPlanPrincipalMapper {
|
||||
long countByExample(TestPlanPrincipalExample example);
|
||||
|
||||
int deleteByExample(TestPlanPrincipalExample example);
|
||||
|
||||
int insert(TestPlanPrincipal record);
|
||||
|
||||
int insertSelective(TestPlanPrincipal record);
|
||||
|
||||
List<TestPlanPrincipal> selectByExample(TestPlanPrincipalExample example);
|
||||
|
||||
int updateByExampleSelective(@Param("record") TestPlanPrincipal record, @Param("example") TestPlanPrincipalExample example);
|
||||
|
||||
int updateByExample(@Param("record") TestPlanPrincipal record, @Param("example") TestPlanPrincipalExample example);
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.base.mapper.TestPlanPrincipalMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.TestPlanPrincipal">
|
||||
<result column="test_plan_id" jdbcType="VARCHAR" property="testPlanId" />
|
||||
<result column="principal_id" jdbcType="VARCHAR" property="principalId" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Update_By_Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
test_plan_id, principal_id
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestPlanPrincipalExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from test_plan_principal
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.TestPlanPrincipalExample">
|
||||
delete from test_plan_principal
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestPlanPrincipal">
|
||||
insert into test_plan_principal (test_plan_id, principal_id)
|
||||
values (#{testPlanId,jdbcType=VARCHAR}, #{principalId,jdbcType=VARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlanPrincipal">
|
||||
insert into test_plan_principal
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="testPlanId != null">
|
||||
test_plan_id,
|
||||
</if>
|
||||
<if test="principalId != null">
|
||||
principal_id,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="testPlanId != null">
|
||||
#{testPlanId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="principalId != null">
|
||||
#{principalId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestPlanPrincipalExample" resultType="java.lang.Long">
|
||||
select count(*) from test_plan_principal
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update test_plan_principal
|
||||
<set>
|
||||
<if test="record.testPlanId != null">
|
||||
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.principalId != null">
|
||||
principal_id = #{record.principalId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update test_plan_principal
|
||||
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
||||
principal_id = #{record.principalId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
</mapper>
|
|
@ -48,7 +48,7 @@ public interface ExtApiTestCaseMapper {
|
|||
List<String> selectNameByIdIn(@Param("ids")List<String> ids);
|
||||
String selectNameById(String id);
|
||||
|
||||
List<String> selectIdsByQuery(BaseQueryRequest query);
|
||||
List<String> selectIdsByQuery(@Param("request") ApiTestCaseRequest request);
|
||||
|
||||
List<String> selectProjectIds();
|
||||
|
||||
|
|
|
@ -559,6 +559,9 @@
|
|||
#{nodeId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.protocol != null and request.protocol !=''">
|
||||
and a.protocol = #{request.protocol}
|
||||
</if>
|
||||
<if test="request.combine != null">
|
||||
<include refid="combine">
|
||||
<property name="condition" value="request.combine"/>
|
||||
|
@ -571,7 +574,7 @@
|
|||
<select id="selectIdsByQuery" resultType="java.lang.String">
|
||||
SELECT t1.id
|
||||
FROM api_test_case t1
|
||||
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
|
||||
<if test="(request.moduleIds != null and request.moduleIds.size() > 0 ) or (request.protocol!=null and request.protocol!='' )">
|
||||
inner join api_definition a on t1.api_definition_id = a.id
|
||||
</if>
|
||||
<include refid="queryWhereCondition"/>
|
||||
|
@ -600,7 +603,7 @@
|
|||
update api_test_case
|
||||
set original_status=status,
|
||||
status = 'Trash',delete_time = #{deleteTime},delete_user_id = #{deleteUserId}
|
||||
where id IN
|
||||
where status != 'Trash' AND id IN
|
||||
<foreach collection="ids" item="v" separator="," open="(" close=")">
|
||||
#{v}
|
||||
</foreach>
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.base.domain.MockExpectConfigWithBLOBs;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtMockExpectConfigMapper {
|
||||
|
||||
List<MockExpectConfigWithBLOBs> selectByProjectIdAndStatusIsOpen(String projectId);
|
||||
|
||||
List<MockExpectConfigWithBLOBs> selectByApiId(String apiId);
|
||||
|
||||
List<MockExpectConfigWithBLOBs> selectByApiIdIn(@Param("values") List<String> apiIds);
|
||||
}
|
|
@ -6,5 +6,19 @@
|
|||
SELECT * FROM mock_expect_config WHERE status = 'true' AND mock_config_id IN
|
||||
(SELECT id FROM mock_config WHERE api_path IS NULL AND project_id = #{0} )
|
||||
</select>
|
||||
|
||||
<select id="selectByApiId" resultType="io.metersphere.base.domain.MockExpectConfigWithBLOBs">
|
||||
SELECT * FROM mock_expect_config WHERE mock_config_id IN
|
||||
(
|
||||
SELECT id FROM mock_config WHERE api_id = #{0}
|
||||
)
|
||||
</select>
|
||||
<select id="selectByApiIdIn" resultType="io.metersphere.base.domain.MockExpectConfigWithBLOBs">
|
||||
SELECT * FROM mock_expect_config WHERE mock_config_id IN
|
||||
(
|
||||
SELECT id FROM mock_config WHERE api_id IN
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
|
||||
import io.metersphere.reportstatistics.dto.TestAnalysisChartRequest;
|
||||
import io.metersphere.reportstatistics.dto.TestAnalysisChartResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtTestAnalysisMapper {
|
||||
|
||||
List<TestAnalysisChartResult> getCraeteCaseReport(TestAnalysisChartRequest request);
|
||||
|
||||
List<TestAnalysisChartResult> getUpdateCaseReport(TestAnalysisChartRequest request);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestAnalysisMapper">
|
||||
|
||||
<select id="getCraeteCaseReport" resultType="io.metersphere.reportstatistics.dto.TestAnalysisChartResult">
|
||||
select dateStr, ifnull(tt.num,0) countNum
|
||||
from
|
||||
(
|
||||
select adddate('2019-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) dateStr from
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4
|
||||
) v
|
||||
left join
|
||||
(select FROM_UNIXTIME(t.create_time/1000, '%Y-%m-%d') as create_times,t.project_id,t.node_id,t.priority,count(id) num ,t.maintainer from test_case t
|
||||
WHERE project_id in
|
||||
<foreach collection="projects" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
<if test="modules != null and modules.size() > 0">
|
||||
and node_id in
|
||||
<foreach collection="modules" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="prioritys != null and prioritys.size() > 0">
|
||||
and priority in
|
||||
<foreach collection="prioritys" item="p" separator="," open="(" close=")">
|
||||
#{p}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="users != null and users.size() > 0">
|
||||
and maintainer in
|
||||
<foreach collection="users" item="p" separator="," open="(" close=")">
|
||||
#{p}
|
||||
</foreach>
|
||||
</if>
|
||||
GROUP BY create_times
|
||||
) tt
|
||||
on dateStr = tt.create_times
|
||||
where dateStr BETWEEN #{startTime} and #{endTime}
|
||||
<if test="order == null or order == ''">
|
||||
order by dateStr
|
||||
</if>
|
||||
<if test="order != null and order != ''">
|
||||
order by countNum ${order}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUpdateCaseReport" resultType="io.metersphere.reportstatistics.dto.TestAnalysisChartResult">
|
||||
select dateStr, ifnull(tt.num,0) countNum
|
||||
from
|
||||
(
|
||||
select adddate('2019-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) dateStr from
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
|
||||
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4
|
||||
) v
|
||||
left join
|
||||
(select FROM_UNIXTIME(t.update_time/1000, '%Y-%m-%d') as update_times,t.project_id,t.node_id,t.priority,t.create_time,t.update_time,count(id) num ,t.maintainer from test_case t
|
||||
WHERE create_time!= update_time
|
||||
and project_id in
|
||||
<foreach collection="projects" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
<if test="modules != null and modules.size() > 0">
|
||||
and node_id in
|
||||
<foreach collection="modules" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="prioritys != null and prioritys.size() > 0">
|
||||
and priority in
|
||||
<foreach collection="prioritys" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="users != null and users.size() > 0">
|
||||
and maintainer in
|
||||
<foreach collection="users" item="p" separator="," open="(" close=")">
|
||||
#{p}
|
||||
</foreach>
|
||||
</if>
|
||||
GROUP BY update_times
|
||||
) tt
|
||||
on dateStr = tt.update_times
|
||||
where dateStr BETWEEN #{startTime} and #{endTime}
|
||||
<if test="order == null or order == ''">
|
||||
order by dateStr
|
||||
</if>
|
||||
<if test="order != null and order != ''">
|
||||
order by countNum ${order}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,65 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.reportstatistics.dto.TestCaseCountChartResult;
|
||||
import io.metersphere.reportstatistics.dto.TestCaseCountRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtTestCaseCountMapper {
|
||||
|
||||
/**
|
||||
* 创建人 维护人 用例类型 用例状态 用例等级
|
||||
*
|
||||
* create_user
|
||||
* maintainer
|
||||
* '功能用例'
|
||||
* status
|
||||
* priority
|
||||
*
|
||||
* @ request
|
||||
* @return
|
||||
*/
|
||||
List<TestCaseCountChartResult> getFunctionCaseCount(TestCaseCountRequest request);
|
||||
|
||||
/**
|
||||
* 创建人 维护人 用例类型 用例状态 用例等级
|
||||
*
|
||||
* create_user_id
|
||||
* ----不知道
|
||||
* '接口用例'
|
||||
* status
|
||||
* ----不知道
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
List<TestCaseCountChartResult> getApiCaseCount(TestCaseCountRequest request);
|
||||
|
||||
/**
|
||||
* 创建人 维护人 用例类型 用例状态 用例等级
|
||||
*
|
||||
* create_user
|
||||
* principal
|
||||
* '场景用例'
|
||||
* status
|
||||
* level
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
List<TestCaseCountChartResult> getScenarioCaseCount(TestCaseCountRequest request);
|
||||
|
||||
/**
|
||||
* 创建人 维护人 用例类型 用例状态 用例等级
|
||||
*
|
||||
* create_user
|
||||
* follow_people
|
||||
* '性能用例'
|
||||
* status
|
||||
* 不知道
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
List<TestCaseCountChartResult> getLoadCaseCount(TestCaseCountRequest request);
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestCaseCountMapper">
|
||||
|
||||
<select id="getFunctionCaseCount" resultType="io.metersphere.reportstatistics.dto.TestCaseCountChartResult">
|
||||
select
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
${testCaseGroupColumn} AS groupName,
|
||||
</if>
|
||||
count(id) AS countNum
|
||||
FROM test_case
|
||||
<where>
|
||||
project_id = #{projectId}
|
||||
AND `status` != 'Trash'
|
||||
<if test="startTime > 0">
|
||||
AND create_time >= #{startTime}
|
||||
</if>
|
||||
<if test="endTime > 0">
|
||||
AND create_time <= #{endTime}
|
||||
</if>
|
||||
<if test="filterSearchList != null and filterSearchList.size() > 0">
|
||||
AND
|
||||
<trim prefix="(" prefixOverrides="AND|OR" suffix=")">
|
||||
<foreach collection="filterSearchList.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
<choose>
|
||||
<when test="key=='caselevel'">
|
||||
${filterType} priority in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='creator'">
|
||||
${filterType} create_user in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='maintainer'">
|
||||
${filterType} maintainer in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='casestatus'">
|
||||
${filterType} UPPER(status) in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</where>
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
GROUP BY ${testCaseGroupColumn}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getApiCaseCount" resultType="io.metersphere.reportstatistics.dto.TestCaseCountChartResult">
|
||||
select
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
${apiCaseGroupColumn} AS groupName,
|
||||
</if>
|
||||
count(id) AS countNum
|
||||
FROM api_test_case
|
||||
<where>
|
||||
project_id = #{projectId}
|
||||
AND `status` != 'Trash'
|
||||
<if test="startTime > 0">
|
||||
AND (create_time >= #{startTime})
|
||||
</if>
|
||||
<if test="endTime > 0">
|
||||
AND ( create_time <= #{endTime})
|
||||
</if>
|
||||
<if test="apiFilterSearchList != null and apiFilterSearchList.size() > 0">
|
||||
AND
|
||||
<trim prefix="(" prefixOverrides="AND|OR" suffix=")">
|
||||
<foreach collection="apiFilterSearchList.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
<choose>
|
||||
<when test="key=='caselevel'">
|
||||
${filterType} priority in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='creator'">
|
||||
${filterType} create_user_id in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='casestatus'">
|
||||
${filterType}
|
||||
(UPPER(status) in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
<if test="values.contains('RUNNING')">
|
||||
OR status IS NULL
|
||||
</if>
|
||||
)
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</where>
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
GROUP BY ${apiCaseGroupColumn}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getScenarioCaseCount" resultType="io.metersphere.reportstatistics.dto.TestCaseCountChartResult">
|
||||
select
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
${scenarioCaseGroupColumn} AS groupName,
|
||||
</if>
|
||||
count(id) AS countNum
|
||||
FROM api_scenario
|
||||
<where>
|
||||
project_id = #{projectId}
|
||||
AND `status` != 'Trash'
|
||||
<if test="startTime > 0">
|
||||
AND (create_time >= #{startTime})
|
||||
</if>
|
||||
<if test="endTime > 0">
|
||||
AND ( create_time <= #{endTime})
|
||||
</if>
|
||||
<if test="filterSearchList != null and filterSearchList.size() > 0">
|
||||
AND
|
||||
<trim prefix="(" prefixOverrides="AND|OR" suffix=")">
|
||||
<foreach collection="filterSearchList.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
<choose>
|
||||
<when test="key=='caselevel'">
|
||||
${filterType} level in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='creator'">
|
||||
${filterType} create_user in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='maintainer'">
|
||||
${filterType} principal in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='casestatus'">
|
||||
${filterType} UPPER(status) in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</where>
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
GROUP BY ${scenarioCaseGroupColumn}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getLoadCaseCount" resultType="io.metersphere.reportstatistics.dto.TestCaseCountChartResult">
|
||||
select
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
${loadCaseGroupColumn} AS groupName,
|
||||
</if>
|
||||
count(id) AS countNum
|
||||
FROM load_test
|
||||
<where>
|
||||
project_id = #{projectId}
|
||||
<if test="startTime > 0">
|
||||
AND (create_time >= #{startTime})
|
||||
</if>
|
||||
<if test="endTime > 0">
|
||||
AND ( create_time <= #{endTime})
|
||||
</if>
|
||||
<if test="loadFilterSearchList != null and loadFilterSearchList.size() > 0">
|
||||
AND
|
||||
<trim prefix="(" prefixOverrides="AND|OR" suffix=")">
|
||||
<foreach collection="loadFilterSearchList.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
<choose>
|
||||
<when test="key=='creator'">
|
||||
${filterType} create_user in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='casestatus'">
|
||||
${filterType} UPPER(status) in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</where>
|
||||
<if test="testCaseGroupColumn != null and testCaseGroupColumn != ''">
|
||||
GROUP BY ${loadCaseGroupColumn}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -390,39 +390,38 @@
|
|||
GROUP BY test_case.priority
|
||||
</select>
|
||||
|
||||
<!-- todo 排除删除的用例统计-->
|
||||
<select id="countCreatedThisWeek" resultType="java.lang.Long">
|
||||
SELECT count(id) AS countNumber FROM test_case WHERE test_case.project_id = #{projectId}
|
||||
SELECT count(id) AS countNumber FROM test_case WHERE test_case.project_id = #{projectId} and test_case.status != 'Trash'
|
||||
AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
</select>
|
||||
<!-- todo 排除删除的用例统计-->
|
||||
<select id="countStatus" resultType="io.metersphere.track.response.TrackCountResult">
|
||||
SELECT review_status AS groupField,count(id) AS countNumber FROM test_case WHERE project_id = #{projectId} GROUP BY test_case.review_status
|
||||
SELECT review_status AS groupField,count(id) AS countNumber FROM test_case WHERE project_id = #{projectId} and test_case.status != 'Trash'
|
||||
GROUP BY test_case.review_status
|
||||
</select>
|
||||
|
||||
<select id="countRelevance" resultType="io.metersphere.track.response.TrackCountResult">
|
||||
SELECT test_case_test.test_type AS groupField, count(test_case_test.test_case_id) AS countNumber
|
||||
FROM test_case join test_case_test on test_case.id = test_case_test.test_case_id
|
||||
WHERE test_case.project_id = #{projectId} GROUP BY test_case_test.test_type
|
||||
WHERE test_case.project_id = #{projectId} and test_case.status != 'Trash' GROUP BY test_case_test.test_type
|
||||
</select>
|
||||
<select id="countRelevanceCreatedThisWeek" resultType="java.lang.Long">
|
||||
SELECT count(distinct test_case_test.test_case_id) AS countNumber FROM test_case join test_case_test on test_case.id = test_case_test.test_case_id
|
||||
WHERE test_case.project_id = #{projectId}
|
||||
WHERE test_case.project_id = #{projectId} and test_case.status != 'Trash'
|
||||
AND test_case_test.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
</select>
|
||||
|
||||
<select id="countCoverage" resultType="int">
|
||||
select count(test_case.id) from test_case where test_case.project_id = #{projectId}
|
||||
select count(test_case.id) from test_case where test_case.project_id = #{projectId} and test_case.status != 'Trash'
|
||||
and test_case.id in (select distinct test_case_test.test_case_id from test_case_test)
|
||||
</select>
|
||||
<select id="countFuncMaintainer" resultType="io.metersphere.track.response.TrackCountResult">
|
||||
select count(tc.id) as countNumber, user.name as groupField from test_case tc right join user on tc.maintainer = user.id
|
||||
where tc.project_id = #{projectId}
|
||||
where tc.project_id = #{projectId} and tc.status != 'Trash'
|
||||
group by tc.maintainer
|
||||
</select>
|
||||
<select id="countRelevanceMaintainer" resultType="io.metersphere.track.response.TrackCountResult">
|
||||
select count(tc.id) as countNumber, user.name as groupField from test_case tc right join user on tc.maintainer = user.id
|
||||
where tc.project_id = #{projectId} and tc.id in (select distinct test_case_test.test_case_id from test_case_test)
|
||||
where tc.project_id = #{projectId} and tc.status != 'Trash' and tc.id in (select distinct test_case_test.test_case_id from test_case_test)
|
||||
group by tc.maintainer
|
||||
</select>
|
||||
<select id="getTestPlanBug" resultType="int">
|
||||
|
|
|
@ -36,4 +36,13 @@ public interface ExtTestReviewCaseMapper {
|
|||
List<String> selectTestCaseIds(@Param("request") QueryCaseReviewRequest request);
|
||||
|
||||
List<TestReviewCaseDTO> listForMinder(@Param("request") QueryCaseReviewRequest request);
|
||||
|
||||
|
||||
List<String> selectReviewIds();
|
||||
|
||||
List<String> getIdsOrderByUpdateTime(@Param("reviewId") String reviewId);
|
||||
|
||||
Long getPreOrder(@Param("reviewId")String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
|
||||
Long getLastOrder(@Param("reviewId")String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
}
|
||||
|
|
|
@ -427,4 +427,28 @@
|
|||
</where>
|
||||
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="selectReviewIds" resultType="java.lang.String">
|
||||
select DISTINCT review_id from test_case_review_test_case;
|
||||
</select>
|
||||
<select id="getIdsOrderByUpdateTime" resultType="java.lang.String">
|
||||
select id from test_case_review_test_case where review_id = #{reviewId} order by update_time ASC;
|
||||
</select>
|
||||
|
||||
<select id="getLastOrder" resultType="java.lang.Long">
|
||||
select `order` from test_case_review_test_case where review_id = #{reviewId}
|
||||
<if test="baseOrder != null">
|
||||
and `order` > #{baseOrder}
|
||||
</if>
|
||||
order by `order` desc limit 1;
|
||||
</select>
|
||||
|
||||
<select id="getPreOrder" resultType="java.lang.Long">
|
||||
select `order` from test_case_review_test_case where review_id = #{reviewId}
|
||||
<if test="baseOrder != null">
|
||||
and `order` < #{baseOrder}
|
||||
</if>
|
||||
order by `order` desc limit 1;
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Set;
|
|||
|
||||
/**
|
||||
* JSON数据结构相关的工具类
|
||||
*
|
||||
* @author song.tianyang
|
||||
* @Date 2021/8/16 3:50 下午
|
||||
*/
|
||||
|
@ -26,14 +27,18 @@ public class JsonStructUtils {
|
|||
if (sourceObj == null && matchObj == null) {
|
||||
return true;
|
||||
} else if (sourceObj != null && matchObj != null) {
|
||||
boolean isMatch = false;
|
||||
boolean lastMatchResultIsTrue = false;
|
||||
boolean hasNotMatchResult = false;
|
||||
try {
|
||||
Set<String> matchKeys = matchObj.keySet();
|
||||
for (String key : matchKeys) {
|
||||
if (sourceObj.containsKey(key)) {
|
||||
Object sourceObjItem = sourceObj.get(key);
|
||||
Object matchObjItem = matchObj.get(key);
|
||||
isMatch = checkObjCompliance(sourceObjItem, matchObjItem);
|
||||
lastMatchResultIsTrue = checkObjCompliance(sourceObjItem, matchObjItem);
|
||||
if (!lastMatchResultIsTrue) {
|
||||
hasNotMatchResult = true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -41,7 +46,7 @@ public class JsonStructUtils {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return isMatch;
|
||||
return lastMatchResultIsTrue && !hasNotMatchResult;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -52,9 +57,9 @@ public class JsonStructUtils {
|
|||
return true;
|
||||
} else if (sourceArray != null && matchArray != null && sourceArray.size() > matchArray.size()) {
|
||||
try {
|
||||
for (int i = 0; i < matchArray.size(); i ++) {
|
||||
for (int i = 0; i < matchArray.size(); i++) {
|
||||
Object obj = matchArray.get(i);
|
||||
if(!sourceArray.contains(obj)){
|
||||
if (!sourceArray.contains(obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -70,13 +75,13 @@ public class JsonStructUtils {
|
|||
public static boolean checkJsonArrayContainsObj(JSONArray sourceArray, JSONObject matchObj) {
|
||||
if (sourceArray == null && matchObj == null) {
|
||||
return true;
|
||||
} else if (sourceArray != null && matchObj != null ) {
|
||||
} else if (sourceArray != null && matchObj != null) {
|
||||
try {
|
||||
for (int i = 0; i < sourceArray.size(); i ++) {
|
||||
for (int i = 0; i < sourceArray.size(); i++) {
|
||||
Object obj = sourceArray.get(i);
|
||||
if(obj instanceof JSONObject){
|
||||
boolean isMatch = checkJsonObjCompliance((JSONObject) obj,matchObj);
|
||||
if(isMatch){
|
||||
if (obj instanceof JSONObject) {
|
||||
boolean isMatch = checkJsonObjCompliance((JSONObject) obj, matchObj);
|
||||
if (isMatch) {
|
||||
return isMatch;
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +97,7 @@ public class JsonStructUtils {
|
|||
|
||||
/**
|
||||
* 检查一个JSON对象的数据集合是否包含另一个对象(包含)
|
||||
*
|
||||
* @param sourceArray
|
||||
* @param matchObj
|
||||
* @return
|
||||
|
@ -103,14 +109,14 @@ public class JsonStructUtils {
|
|||
boolean isMatch = false;
|
||||
try {
|
||||
Set<String> matchKeys = matchObj.keySet();
|
||||
for(int sourceIndex = 0;sourceIndex < sourceArray.size();sourceIndex ++){
|
||||
for (int sourceIndex = 0; sourceIndex < sourceArray.size(); sourceIndex++) {
|
||||
JSONObject sourceObj = sourceArray.getJSONObject(sourceIndex);
|
||||
for (String key : matchKeys) {
|
||||
if (sourceObj.containsKey(key)) {
|
||||
Object sourceObjItem = sourceObj.get(key);
|
||||
Object matchObjItem = matchObj.get(key);
|
||||
isMatch = checkObjCompliance(sourceObjItem, matchObjItem);
|
||||
if(!isMatch){
|
||||
if (!isMatch) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -119,7 +125,7 @@ public class JsonStructUtils {
|
|||
}
|
||||
}
|
||||
|
||||
if(isMatch){
|
||||
if (isMatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -173,12 +179,12 @@ public class JsonStructUtils {
|
|||
public static void deepParseKeyByJsonObject(JSONObject jsonObject, List<String> keyList) {
|
||||
for (String key : jsonObject.keySet()) {
|
||||
Object obj = jsonObject.get(key);
|
||||
if(obj instanceof JSONArray) {
|
||||
if (obj instanceof JSONArray) {
|
||||
deepParseKeyByJsonArray((JSONArray) obj, keyList);
|
||||
}else if(obj instanceof JSONObject){
|
||||
deepParseKeyByJsonObject((JSONObject) obj,keyList);
|
||||
}else {
|
||||
if(!keyList.contains(key)){
|
||||
} else if (obj instanceof JSONObject) {
|
||||
deepParseKeyByJsonObject((JSONObject) obj, keyList);
|
||||
} else {
|
||||
if (!keyList.contains(key)) {
|
||||
keyList.add(key);
|
||||
}
|
||||
}
|
||||
|
@ -186,10 +192,10 @@ public class JsonStructUtils {
|
|||
}
|
||||
|
||||
public static void deepParseKeyByJsonArray(JSONArray jsonArray, List<String> keyList) {
|
||||
for (int i = 0; i < jsonArray.size(); i ++) {
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
Object itemObj = jsonArray.get(i);
|
||||
if(itemObj instanceof JSONObject){
|
||||
deepParseKeyByJsonObject((JSONObject)itemObj,keyList);
|
||||
if (itemObj instanceof JSONObject) {
|
||||
deepParseKeyByJsonObject((JSONObject) itemObj, keyList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,31 +210,31 @@ public class JsonStructUtils {
|
|||
JSONValidator matchValidator = JSONValidator.from(matchJson);
|
||||
String sourceType = sourceValidator.getType().name();
|
||||
String matchType = matchValidator.getType().name();
|
||||
if(StringUtils.equalsIgnoreCase(sourceType,"array")&&StringUtils.equalsIgnoreCase(matchType,"array")){
|
||||
if (StringUtils.equalsIgnoreCase(sourceType, "array") && StringUtils.equalsIgnoreCase(matchType, "array")) {
|
||||
isSourceJsonIsArray = true;
|
||||
isMatchJsonIsArray = true;
|
||||
}else if(StringUtils.equalsIgnoreCase(sourceType,"array")){
|
||||
} else if (StringUtils.equalsIgnoreCase(sourceType, "array")) {
|
||||
isSourceJsonIsArray = true;
|
||||
}else if(StringUtils.equalsIgnoreCase(matchType,"array")){
|
||||
} else if (StringUtils.equalsIgnoreCase(matchType, "array")) {
|
||||
isMatchJsonIsArray = true;
|
||||
}
|
||||
if(isSourceJsonIsArray && isMatchJsonIsArray){
|
||||
if (isSourceJsonIsArray && isMatchJsonIsArray) {
|
||||
JSONArray sourceArr = JSONArray.parseArray(sourceJson);
|
||||
JSONArray compArr = JSONArray.parseArray(matchJson);
|
||||
isMatch = checkJsonArrayCompliance(sourceArr,compArr);
|
||||
}else if(isSourceJsonIsArray && !isMatchJsonIsArray){
|
||||
isMatch = checkJsonArrayCompliance(sourceArr, compArr);
|
||||
} else if (isSourceJsonIsArray && !isMatchJsonIsArray) {
|
||||
JSONArray sourceArr = JSONArray.parseArray(sourceJson);
|
||||
JSONObject compObj = JSONObject.parseObject(matchJson);
|
||||
isMatch = checkJsonArrayContainsObj(sourceArr,compObj);
|
||||
}else if(!isSourceJsonIsArray && !isMatchJsonIsArray){
|
||||
isMatch = checkJsonArrayContainsObj(sourceArr, compObj);
|
||||
} else if (!isSourceJsonIsArray && !isMatchJsonIsArray) {
|
||||
JSONObject sourceObj = JSONObject.parseObject(sourceJson);
|
||||
JSONObject compObj = JSONObject.parseObject(matchJson);
|
||||
isMatch = checkJsonObjCompliance(sourceObj,compObj);
|
||||
}else {
|
||||
isMatch = checkJsonObjCompliance(sourceObj, compObj);
|
||||
} else {
|
||||
isMatch = false;
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return isMatch;
|
||||
|
|
|
@ -35,6 +35,10 @@ public class ServiceUtils {
|
|||
return getDefaultOrderByField(null, orders, "order");
|
||||
}
|
||||
|
||||
public static List<OrderRequest> getDefaultSortOrder(String prefix, List<OrderRequest> orders) {
|
||||
return getDefaultOrderByField(prefix, orders, "order");
|
||||
}
|
||||
|
||||
public static List<OrderRequest> getDefaultOrder(String prefix, List<OrderRequest> orders) {
|
||||
return getDefaultOrderByField(prefix, orders, "update_time");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import lombok.Data;
|
|||
public class CustomFieldItemDTO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String value;
|
||||
private Object value;
|
||||
private String type;
|
||||
private String customData;
|
||||
}
|
||||
|
|
|
@ -416,6 +416,9 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
|
||||
String customFieldsJson = this.getCustomFieldsJson(data);
|
||||
testCase.setCustomFields(customFieldsJson);
|
||||
if (StringUtils.isNotBlank(data.getMaintainer())) {
|
||||
testCase.setMaintainer(data.getMaintainer());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(data.getStepModel())
|
||||
&& StringUtils.equals(data.getStepModel(), TestCaseConstants.StepModel.TEXT.name())) {
|
||||
|
@ -466,6 +469,9 @@ public class TestCaseNoModelDataListener extends AnalysisEventListener<Map<Integ
|
|||
|
||||
String customFieldsJson = this.getCustomFieldsJson(data);
|
||||
testCase.setCustomFields(customFieldsJson);
|
||||
if (StringUtils.isNotBlank(data.getMaintainer())) {
|
||||
testCase.setMaintainer(data.getMaintainer());
|
||||
}
|
||||
|
||||
//将标签设置为前端可解析的格式
|
||||
String modifiedTags = modifyTagPattern(data);
|
||||
|
|
|
@ -61,6 +61,8 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
|||
private TestPlanLoadCaseService testPlanLoadCaseService;
|
||||
@Resource
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private TestReviewTestCaseService testReviewTestCaseService;
|
||||
|
||||
@Value("${jmeter.home}")
|
||||
private String jmeterHome;
|
||||
|
@ -128,6 +130,7 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
|||
initOnceOperate(testPlanApiCaseService::initOrderField, "init.sort.plan.api.case");
|
||||
initOnceOperate(testPlanScenarioCaseService::initOrderField, "init.sort.plan.api.scenario");
|
||||
initOnceOperate(testPlanLoadCaseService::initOrderField, "init.sort.plan.api.load");
|
||||
initOnceOperate(testReviewTestCaseService::initOrderField, "init.sort.review.test.case");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -134,7 +134,7 @@ public class NoticeService {
|
|||
public List<MessageDetail> searchMessageByTypeBySend(String type, String projectId) {
|
||||
try {
|
||||
String orgId = "";
|
||||
if (null == SessionUtils.getUser()) {
|
||||
if (StringUtils.isNotEmpty(projectId)) {
|
||||
Organization organization = extProjectMapper.getOrganizationByProjectId(projectId);
|
||||
orgId = organization.getId();
|
||||
} else {
|
||||
|
|
|
@ -48,7 +48,7 @@ public class JmeterFileController {
|
|||
@RequestParam("ratio") String ratio,
|
||||
@RequestParam("reportId") String reportId, @RequestParam("resourceIndex") int resourceIndex) {
|
||||
double[] ratios = Arrays.stream(ratio.split(",")).mapToDouble(Double::parseDouble).toArray();
|
||||
byte[] bytes = jmeterFileService.downloadZip(testId, ratios, reportId, resourceIndex);
|
||||
byte[] bytes = jmeterFileService.downloadZip(reportId, ratios, resourceIndex);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + testId + ".zip\"")
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.RunRequest;
|
||||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
import io.metersphere.base.domain.TestResourcePool;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
|
@ -21,15 +21,12 @@ import org.apache.commons.lang3.StringUtils;
|
|||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractEngine implements Engine {
|
||||
protected String JMETER_IMAGE;
|
||||
protected String HEAP;
|
||||
protected String GC_ALGO;
|
||||
private Long startTime;
|
||||
private String reportId;
|
||||
protected LoadTestWithBLOBs loadTest;
|
||||
protected LoadTestReportWithBLOBs loadTestReport;
|
||||
protected PerformanceTestService performanceTestService;
|
||||
protected Integer threadNum;
|
||||
protected List<TestResource> resourceList;
|
||||
|
@ -43,8 +40,6 @@ public abstract class AbstractEngine implements Engine {
|
|||
JMETER_IMAGE = CommonBeanFactory.getBean(JmeterProperties.class).getImage();
|
||||
HEAP = CommonBeanFactory.getBean(JmeterProperties.class).getHeap();
|
||||
GC_ALGO = CommonBeanFactory.getBean(JmeterProperties.class).getGcAlgo();
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.reportId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
protected void initApiConfig(RunRequest runRequest) {
|
||||
|
@ -81,16 +76,16 @@ public abstract class AbstractEngine implements Engine {
|
|||
}
|
||||
}
|
||||
|
||||
protected void init(LoadTestWithBLOBs loadTest) {
|
||||
if (loadTest == null) {
|
||||
protected void init(LoadTestReportWithBLOBs loadTestReport) {
|
||||
if (loadTestReport == null) {
|
||||
MSException.throwException("LoadTest is null.");
|
||||
}
|
||||
this.loadTest = loadTest;
|
||||
this.loadTestReport = loadTestReport;
|
||||
|
||||
this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class);
|
||||
|
||||
threadNum = getThreadNum(loadTest);
|
||||
String resourcePoolId = loadTest.getTestResourcePoolId();
|
||||
threadNum = getThreadNum(loadTestReport);
|
||||
String resourcePoolId = loadTestReport.getTestResourcePoolId();
|
||||
if (StringUtils.isBlank(resourcePoolId)) {
|
||||
MSException.throwException("Resource Pool ID is empty");
|
||||
}
|
||||
|
@ -127,16 +122,16 @@ public abstract class AbstractEngine implements Engine {
|
|||
}
|
||||
|
||||
protected Integer getRunningThreadNum() {
|
||||
List<LoadTestWithBLOBs> loadTests = performanceTestService.selectByTestResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
List<LoadTestReportWithBLOBs> loadTestReports = performanceTestService.selectReportsByTestResourcePoolId(loadTestReport.getTestResourcePoolId());
|
||||
// 使用当前资源池正在运行的测试占用的并发数
|
||||
return loadTests.stream()
|
||||
return loadTestReports.stream()
|
||||
.filter(t -> PerformanceTestStatus.Running.name().equals(t.getStatus()))
|
||||
.map(this::getThreadNum)
|
||||
.reduce(Integer::sum)
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
private Integer getThreadNum(LoadTestWithBLOBs t) {
|
||||
private Integer getThreadNum(LoadTestReportWithBLOBs t) {
|
||||
Integer s = 0;
|
||||
String loadConfiguration = t.getLoadConfiguration();
|
||||
JSONArray jsonArray = JSON.parseArray(loadConfiguration);
|
||||
|
@ -175,14 +170,4 @@ public abstract class AbstractEngine implements Engine {
|
|||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportId() {
|
||||
return reportId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
package io.metersphere.performance.engine;
|
||||
|
||||
public interface Engine {
|
||||
Long getStartTime();
|
||||
|
||||
String getReportId();
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
|
|
@ -6,10 +6,11 @@ import io.metersphere.Application;
|
|||
import io.metersphere.api.dto.RunRequest;
|
||||
import io.metersphere.base.domain.FileContent;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.TestResourcePool;
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
||||
import io.metersphere.commons.constants.ResourceStatusEnum;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -65,8 +66,8 @@ public class EngineFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public static Engine createEngine(LoadTestWithBLOBs loadTest) {
|
||||
String resourcePoolId = loadTest.getTestResourcePoolId();
|
||||
public static Engine createEngine(LoadTestReportWithBLOBs loadTestReport) {
|
||||
String resourcePoolId = loadTestReport.getTestResourcePoolId();
|
||||
if (StringUtils.isBlank(resourcePoolId)) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_id_is_null"));
|
||||
}
|
||||
|
@ -75,15 +76,18 @@ public class EngineFactory {
|
|||
if (resourcePool == null) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_id_is_null"));
|
||||
}
|
||||
if (ResourceStatusEnum.INVALID.name().equals(resourcePool.getStatus())) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_invalid"));
|
||||
}
|
||||
|
||||
final ResourcePoolTypeEnum type = ResourcePoolTypeEnum.valueOf(resourcePool.getType());
|
||||
|
||||
if (type == ResourcePoolTypeEnum.NODE) {
|
||||
return new DockerTestEngine(loadTest);
|
||||
return new DockerTestEngine(loadTestReport);
|
||||
}
|
||||
if (type == ResourcePoolTypeEnum.K8S) {
|
||||
try {
|
||||
return (Engine) ConstructorUtils.invokeConstructor(kubernetesTestEngineClass, loadTest);
|
||||
return (Engine) ConstructorUtils.invokeConstructor(kubernetesTestEngineClass, loadTestReport);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
return null;
|
||||
|
@ -102,10 +106,10 @@ public class EngineFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static EngineContext createContext(LoadTestWithBLOBs loadTest, double[] ratios, String reportId, int resourceIndex) {
|
||||
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId());
|
||||
public static EngineContext createContext(LoadTestReportWithBLOBs loadTestReport, double[] ratios, String reportId, int resourceIndex) {
|
||||
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTestReport.getTestId());
|
||||
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
|
||||
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId());
|
||||
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTestReport.getTestId());
|
||||
}
|
||||
|
||||
List<FileMetadata> jmxFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JMX.name())).collect(Collectors.toList());
|
||||
|
@ -113,17 +117,17 @@ public class EngineFactory {
|
|||
// 合并上传的jmx
|
||||
byte[] jmxBytes = mergeJmx(jmxFiles);
|
||||
final EngineContext engineContext = new EngineContext();
|
||||
engineContext.setTestId(loadTest.getId());
|
||||
engineContext.setTestName(loadTest.getName());
|
||||
engineContext.setNamespace(loadTest.getProjectId());
|
||||
engineContext.setTestId(loadTestReport.getTestId());
|
||||
engineContext.setTestName(loadTestReport.getName());
|
||||
engineContext.setNamespace(loadTestReport.getProjectId());
|
||||
engineContext.setFileType(FileType.JMX.name());
|
||||
engineContext.setResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
engineContext.setResourcePoolId(loadTestReport.getTestResourcePoolId());
|
||||
engineContext.setReportId(reportId);
|
||||
engineContext.setResourceIndex(resourceIndex);
|
||||
engineContext.setRatios(ratios);
|
||||
|
||||
if (StringUtils.isNotEmpty(loadTest.getLoadConfiguration())) {
|
||||
final JSONArray jsonArray = JSONObject.parseArray(loadTest.getLoadConfiguration());
|
||||
if (StringUtils.isNotEmpty(loadTestReport.getLoadConfiguration())) {
|
||||
final JSONArray jsonArray = JSONObject.parseArray(loadTestReport.getLoadConfiguration());
|
||||
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
if (jsonArray.get(i) instanceof List) {
|
||||
|
@ -160,8 +164,8 @@ public class EngineFactory {
|
|||
{"timeout":10,"statusCode":["302","301"],"params":[{"name":"param1","enable":true,"value":"0","edit":false}],"domains":[{"domain":"baidu.com","enable":true,"ip":"127.0.0.1","edit":false}]}
|
||||
*/
|
||||
Map<String, byte[]> testResourceFiles = new HashMap<>();
|
||||
byte[] props = getJMeterProperties(loadTest, engineContext);
|
||||
byte[] hosts = getDNSConfig(loadTest, engineContext);
|
||||
byte[] props = getJMeterProperties(loadTestReport, engineContext);
|
||||
byte[] hosts = getDNSConfig(loadTestReport, engineContext);
|
||||
// JMeter Properties
|
||||
testResourceFiles.put("ms.properties", props);
|
||||
// DNS
|
||||
|
@ -195,10 +199,10 @@ public class EngineFactory {
|
|||
return engineContext;
|
||||
}
|
||||
|
||||
private static byte[] getDNSConfig(LoadTestWithBLOBs loadTest, EngineContext engineContext) {
|
||||
private static byte[] getDNSConfig(LoadTestReportWithBLOBs loadTestReport, EngineContext engineContext) {
|
||||
StringBuilder dns = new StringBuilder("# DNS Config\n");
|
||||
if (StringUtils.isNotEmpty(loadTest.getAdvancedConfiguration())) {
|
||||
JSONObject advancedConfiguration = JSONObject.parseObject(loadTest.getAdvancedConfiguration());
|
||||
if (StringUtils.isNotEmpty(loadTestReport.getAdvancedConfiguration())) {
|
||||
JSONObject advancedConfiguration = JSONObject.parseObject(loadTestReport.getAdvancedConfiguration());
|
||||
engineContext.addProperties(advancedConfiguration);
|
||||
JSONArray domains = advancedConfiguration.getJSONArray("domains");
|
||||
if (domains != null) {
|
||||
|
@ -214,10 +218,10 @@ public class EngineFactory {
|
|||
return dns.toString().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static byte[] getJMeterProperties(LoadTestWithBLOBs loadTest, EngineContext engineContext) {
|
||||
private static byte[] getJMeterProperties(LoadTestReportWithBLOBs loadTestReportWithBLOBs, EngineContext engineContext) {
|
||||
StringBuilder props = new StringBuilder("# JMeter Properties\n");
|
||||
if (StringUtils.isNotEmpty(loadTest.getAdvancedConfiguration())) {
|
||||
JSONObject advancedConfiguration = JSONObject.parseObject(loadTest.getAdvancedConfiguration());
|
||||
if (StringUtils.isNotEmpty(loadTestReportWithBLOBs.getAdvancedConfiguration())) {
|
||||
JSONObject advancedConfiguration = JSONObject.parseObject(loadTestReportWithBLOBs.getAdvancedConfiguration());
|
||||
engineContext.addProperties(advancedConfiguration);
|
||||
JSONArray properties = advancedConfiguration.getJSONArray("properties");
|
||||
if (properties != null) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.performance.engine.docker;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
import io.metersphere.commons.constants.ResourceStatusEnum;
|
||||
|
@ -26,13 +27,13 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
private RestTemplate restTemplate;
|
||||
private RestTemplate restTemplateWithTimeOut;
|
||||
|
||||
public DockerTestEngine(LoadTestWithBLOBs loadTest) {
|
||||
this.init(loadTest);
|
||||
public DockerTestEngine(LoadTestReportWithBLOBs loadTestReport) {
|
||||
this.init(loadTestReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(LoadTestWithBLOBs loadTest) {
|
||||
super.init(loadTest);
|
||||
protected void init(LoadTestReportWithBLOBs loadTestReport) {
|
||||
super.init(loadTestReport);
|
||||
this.restTemplate = (RestTemplate) CommonBeanFactory.getBean("restTemplate");
|
||||
this.restTemplateWithTimeOut = (RestTemplate) CommonBeanFactory.getBean("restTemplateWithTimeOut");
|
||||
}
|
||||
|
@ -85,9 +86,9 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
env.put("RATIO", StringUtils.join(ratios, ","));
|
||||
env.put("RESOURCE_INDEX", "" + resourceIndex);
|
||||
env.put("METERSPHERE_URL", metersphereUrl);
|
||||
env.put("START_TIME", "" + this.getStartTime());
|
||||
env.put("TEST_ID", this.loadTest.getId());
|
||||
env.put("REPORT_ID", this.getReportId());
|
||||
env.put("START_TIME", "" + System.currentTimeMillis());
|
||||
env.put("TEST_ID", this.loadTestReport.getTestId());
|
||||
env.put("REPORT_ID", this.loadTestReport.getId());
|
||||
env.put("BOOTSTRAP_SERVERS", kafkaProperties.getBootstrapServers());
|
||||
env.put("LOG_TOPIC", kafkaProperties.getLog().getTopic());
|
||||
env.put("JMETER_REPORTS_TOPIC", kafkaProperties.getReport().getTopic());
|
||||
|
@ -95,7 +96,7 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
env.put("THREAD_NUM", "0");// 传入0表示不用修改线程数
|
||||
env.put("HEAP", HEAP);
|
||||
env.put("GC_ALGO", GC_ALGO);
|
||||
env.put("GRANULARITY", performanceTestService.getGranularity(this.getReportId()).toString());
|
||||
env.put("GRANULARITY", performanceTestService.getGranularity(this.loadTestReport.getId()).toString());
|
||||
env.put("BACKEND_LISTENER", resourcePool.getBackendListener().toString());
|
||||
|
||||
|
||||
|
@ -121,7 +122,7 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
|
||||
@Override
|
||||
public void stop() {
|
||||
String testId = loadTest.getId();
|
||||
String testId = loadTestReport.getTestId();
|
||||
this.resourceList.forEach(r -> {
|
||||
NodeDTO node = JSON.parseObject(r.getConfiguration(), NodeDTO.class);
|
||||
String ip = node.getIp();
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
package io.metersphere.performance.service;
|
||||
|
||||
|
||||
import com.alibaba.excel.util.CollectionUtils;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanLoadCase;
|
||||
import io.metersphere.base.mapper.LoadTestMapper;
|
||||
import io.metersphere.base.mapper.TestPlanLoadCaseMapper;
|
||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.performance.engine.EngineContext;
|
||||
import io.metersphere.performance.engine.EngineFactory;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -28,40 +23,18 @@ import java.util.zip.ZipOutputStream;
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class JmeterFileService {
|
||||
|
||||
@Resource
|
||||
private LoadTestMapper loadTestMapper;
|
||||
@Resource
|
||||
private ExtLoadTestReportMapper extLoadTestReportMapper;
|
||||
@Resource
|
||||
private TestPlanLoadCaseMapper testPlanLoadCaseMapper;
|
||||
private LoadTestReportMapper loadTestReportMapper;
|
||||
|
||||
public byte[] downloadZip(String testId, double[] ratios, String reportId, int resourceIndex) {
|
||||
public byte[] downloadZip(String reportId, double[] ratios, int resourceIndex) {
|
||||
try {
|
||||
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(testId);
|
||||
TestPlanLoadCase testPlanLoadCase = null;
|
||||
if (loadTest == null) {
|
||||
// 通过测试计划执行性能用例时,testId为测试计划性能用例表的主键ID,根据ID查询用例自身的压力配置
|
||||
testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testId);
|
||||
if (testPlanLoadCase != null) {
|
||||
loadTest = loadTestMapper.selectByPrimaryKey(testPlanLoadCase.getLoadCaseId());
|
||||
if (loadTest != null) {
|
||||
// 用例自身设置了资源池ID
|
||||
if (StringUtils.isNotBlank(testPlanLoadCase.getTestResourcePoolId())) {
|
||||
loadTest.setTestResourcePoolId(testPlanLoadCase.getTestResourcePoolId());
|
||||
}
|
||||
// 用例自身设置了压力配置
|
||||
if (StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
|
||||
loadTest.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EngineContext context = EngineFactory.createContext(loadTest, ratios, reportId, resourceIndex);
|
||||
if (testPlanLoadCase != null) {
|
||||
// ID
|
||||
context.setTestId(testPlanLoadCase.getId());
|
||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
if (loadTestReport == null) {
|
||||
MSException.throwException("测试报告不存在或还没产生");
|
||||
}
|
||||
EngineContext context = EngineFactory.createContext(loadTestReport, ratios, reportId, resourceIndex);
|
||||
return zipFilesToByteArray(context);
|
||||
} catch (MSException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
|
|
|
@ -97,14 +97,14 @@ public class PerformanceReportService {
|
|||
MSException.throwException("report id cannot be null");
|
||||
}
|
||||
|
||||
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId());
|
||||
|
||||
LogUtil.info("Delete report started, report ID: %s" + reportId);
|
||||
|
||||
if (loadTest != null) {
|
||||
try {
|
||||
final Engine engine = EngineFactory.createEngine(loadTest);
|
||||
final Engine engine = EngineFactory.createEngine(loadTestReport);
|
||||
if (engine == null) {
|
||||
MSException.throwException(String.format("Delete report fail. create engine fail,report ID:%s", reportId));
|
||||
}
|
||||
|
|
|
@ -313,6 +313,9 @@ public class PerformanceTestService {
|
|||
if (request.getUserId() != null) {
|
||||
loadTest.setUserId(request.getUserId());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(request.getProjectId())) {
|
||||
loadTest.setProjectId(request.getProjectId());
|
||||
}
|
||||
if (loadTest == null) {
|
||||
MSException.throwException(Translator.get("run_load_test_not_found") + request.getId());
|
||||
}
|
||||
|
@ -320,40 +323,12 @@ public class PerformanceTestService {
|
|||
if (StringUtils.equalsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) {
|
||||
MSException.throwException(Translator.get("load_test_is_running"));
|
||||
}
|
||||
String testResourcePoolId = loadTest.getTestResourcePoolId();
|
||||
TestResourcePool testResourcePool = testResourcePoolMapper.selectByPrimaryKey(testResourcePoolId);
|
||||
if (testResourcePool == null) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_not_exists"));
|
||||
}
|
||||
if (ResourceStatusEnum.INVALID.name().equals(testResourcePool.getStatus())) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_invalid"));
|
||||
}
|
||||
// check kafka
|
||||
checkKafka();
|
||||
|
||||
LogUtil.info("Load test started " + loadTest.getName());
|
||||
LoadTestWithBLOBs copyTest = new LoadTestWithBLOBs();
|
||||
BeanUtils.copyBean(copyTest, loadTest);
|
||||
// 如果是执行测试计划用例,把EngineFactory.createEngine参数对象的id 设置为测试计划用例id
|
||||
// 设置用例id目的是当 JmeterFileService 下载zip,拼装 jmx 文件时,如果用例自身带有压力配置,使用用例自身压力配置拼装 jmx
|
||||
String testPlanLoadId = request.getTestPlanLoadId();
|
||||
if (StringUtils.isNotBlank(testPlanLoadId)) {
|
||||
copyTest.setId(testPlanLoadId);
|
||||
// 设置本次报告中的压力配置信息
|
||||
TestPlanLoadCase testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testPlanLoadId);
|
||||
if (testPlanLoadCase != null && StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
|
||||
loadTest.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
|
||||
}
|
||||
}
|
||||
// engine type (NODE)
|
||||
final Engine engine = EngineFactory.createEngine(copyTest);
|
||||
if (engine == null) {
|
||||
MSException.throwException(String.format("Test cannot be run,test ID:%s", request.getId()));
|
||||
}
|
||||
|
||||
startEngine(loadTest, engine, request.getTriggerMode());
|
||||
|
||||
return engine.getReportId();
|
||||
return startEngine(loadTest, request);
|
||||
}
|
||||
|
||||
private void checkKafka() {
|
||||
|
@ -377,14 +352,16 @@ public class PerformanceTestService {
|
|||
}
|
||||
}
|
||||
|
||||
private void startEngine(LoadTestWithBLOBs loadTest, Engine engine, String triggerMode) {
|
||||
private String startEngine(LoadTestWithBLOBs loadTest, RunTestPlanRequest request) {
|
||||
|
||||
|
||||
LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs();
|
||||
testReport.setId(engine.getReportId());
|
||||
testReport.setCreateTime(engine.getStartTime());
|
||||
testReport.setUpdateTime(engine.getStartTime());
|
||||
testReport.setId(UUID.randomUUID().toString());
|
||||
testReport.setCreateTime(System.currentTimeMillis());
|
||||
testReport.setUpdateTime(System.currentTimeMillis());
|
||||
testReport.setTestId(loadTest.getId());
|
||||
testReport.setName(loadTest.getName());
|
||||
testReport.setTriggerMode(triggerMode);
|
||||
testReport.setTriggerMode(request.getTriggerMode());
|
||||
if (SessionUtils.getUser() == null) {
|
||||
testReport.setUserId(loadTest.getUserId());
|
||||
} else {
|
||||
|
@ -394,18 +371,36 @@ public class PerformanceTestService {
|
|||
LoadTestWithBLOBs updateTest = new LoadTestWithBLOBs();
|
||||
updateTest.setId(loadTest.getId());
|
||||
// 启动测试
|
||||
Engine engine = null;
|
||||
try {
|
||||
// 启动插入 report
|
||||
// 保存测试里的配置
|
||||
testReport.setTestResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
testReport.setLoadConfiguration(loadTest.getLoadConfiguration());
|
||||
|
||||
String testPlanLoadId = request.getTestPlanLoadId();
|
||||
if (StringUtils.isNotBlank(testPlanLoadId)) {
|
||||
// 设置本次报告中的压力配置信息
|
||||
TestPlanLoadCase testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testPlanLoadId);
|
||||
if (testPlanLoadCase != null && StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
|
||||
testReport.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
|
||||
}
|
||||
if (StringUtils.isNotBlank(testPlanLoadCase.getTestResourcePoolId())) {
|
||||
testReport.setTestResourcePoolId(testPlanLoadCase.getTestResourcePoolId());
|
||||
}
|
||||
}
|
||||
// 启动插入 report
|
||||
testReport.setAdvancedConfiguration(loadTest.getAdvancedConfiguration());
|
||||
testReport.setStatus(PerformanceTestStatus.Starting.name());
|
||||
testReport.setProjectId(loadTest.getProjectId());
|
||||
testReport.setTestResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
testReport.setTestName(loadTest.getName());
|
||||
loadTestReportMapper.insertSelective(testReport);
|
||||
|
||||
engine.start();
|
||||
// 启动正常修改状态 starting
|
||||
// engine
|
||||
engine = EngineFactory.createEngine(testReport);
|
||||
if (engine == null) {
|
||||
MSException.throwException(String.format("Test cannot be run,test ID:%s", loadTest.getId()));
|
||||
}
|
||||
|
||||
updateTest.setStatus(PerformanceTestStatus.Starting.name());
|
||||
loadTestMapper.updateByPrimaryKeySelective(updateTest);
|
||||
|
||||
|
@ -423,9 +418,14 @@ public class PerformanceTestService {
|
|||
reportResult.setReportKey(ReportKeys.ResultStatus.name());
|
||||
reportResult.setReportValue("Ready"); // 初始化一个 result_status, 这个值用在data-streaming中
|
||||
loadTestReportResultMapper.insertSelective(reportResult);
|
||||
// 启动测试
|
||||
engine.start();
|
||||
return testReport.getId();
|
||||
} catch (MSException e) {
|
||||
// 启动失败之后清理任务
|
||||
engine.stop();
|
||||
if (engine != null) {
|
||||
engine.stop();
|
||||
}
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
updateTest.setStatus(PerformanceTestStatus.Error.name());
|
||||
updateTest.setDescription(e.getMessage());
|
||||
|
@ -482,12 +482,6 @@ public class PerformanceTestService {
|
|||
return results;
|
||||
}
|
||||
|
||||
public List<LoadTestWithBLOBs> selectByTestResourcePoolId(String resourcePoolId) {
|
||||
LoadTestExample example = new LoadTestExample();
|
||||
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePoolId);
|
||||
return loadTestMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<DashboardTestDTO> dashboardTests(String workspaceId) {
|
||||
Instant oneYearAgo = Instant.now().plus(-365, ChronoUnit.DAYS);
|
||||
long startTimestamp = oneYearAgo.toEpochMilli();
|
||||
|
@ -572,9 +566,9 @@ public class PerformanceTestService {
|
|||
}
|
||||
|
||||
private void stopEngine(String reportId) {
|
||||
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId());
|
||||
final Engine engine = EngineFactory.createEngine(loadTest);
|
||||
final Engine engine = EngineFactory.createEngine(loadTestReport);
|
||||
if (engine == null) {
|
||||
MSException.throwException(String.format("Stop report fail. create engine fail,report ID:%s", reportId));
|
||||
}
|
||||
|
@ -832,13 +826,12 @@ public class PerformanceTestService {
|
|||
Integer granularity = CommonBeanFactory.getBean(JmeterProperties.class).getReport().getGranularity();
|
||||
try {
|
||||
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(report.getTestId());
|
||||
JSONObject advancedConfig = JSON.parseObject(loadTest.getAdvancedConfiguration());
|
||||
JSONObject advancedConfig = JSON.parseObject(report.getAdvancedConfiguration());
|
||||
if (advancedConfig.getInteger("granularity") != null) {
|
||||
return advancedConfig.getInteger("granularity") * 1000;// 单位是ms
|
||||
}
|
||||
AtomicReference<Integer> maxDuration = new AtomicReference<>(0);
|
||||
List<List<JSONObject>> pressureConfigLists = JSON.parseObject(loadTest.getLoadConfiguration(), new TypeReference<List<List<JSONObject>>>() {
|
||||
List<List<JSONObject>> pressureConfigLists = JSON.parseObject(report.getLoadConfiguration(), new TypeReference<List<List<JSONObject>>>() {
|
||||
});
|
||||
// 按照最长的执行时间来确定
|
||||
pressureConfigLists.forEach(pcList -> {
|
||||
|
@ -884,6 +877,7 @@ public class PerformanceTestService {
|
|||
|
||||
/**
|
||||
* 用例自定义排序
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void updateOrder(ResetOrderRequest request) {
|
||||
|
@ -893,4 +887,11 @@ public class PerformanceTestService {
|
|||
extLoadTestMapper::getLastOrder,
|
||||
loadTestMapper::updateByPrimaryKeySelective);
|
||||
}
|
||||
|
||||
public List<LoadTestReportWithBLOBs> selectReportsByTestResourcePoolId(String resourcePoolId) {
|
||||
LoadTestReportExample example = new LoadTestReportExample();
|
||||
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePoolId)
|
||||
.andStatusIn(Arrays.asList(PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name()));
|
||||
return loadTestReportMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package io.metersphere.reportstatistics.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import io.metersphere.base.domain.ReportStatistics;
|
||||
import io.metersphere.base.domain.ReportStatisticsWithBLOBs;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.reportstatistics.dto.ReportStatisticsSaveRequest;
|
||||
import io.metersphere.reportstatistics.service.ReportStatisticsService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/9/14 2:58 下午
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/history/report")
|
||||
public class HistoryReportController {
|
||||
|
||||
@Resource
|
||||
private ReportStatisticsService reportStatisticsService;
|
||||
|
||||
@PostMapping("/selectByParams")
|
||||
public List<ReportStatistics> selectByParams(@RequestBody ReportStatisticsSaveRequest request) {
|
||||
List<ReportStatistics> returnList = reportStatisticsService.selectByProjectIdAndReportType(request.getProjectId(),request.getReportType());
|
||||
LogUtil.info("报表查询结果:"+JSONArray.toJSONString(returnList));
|
||||
return returnList;
|
||||
}
|
||||
|
||||
@PostMapping("/saveReport")
|
||||
public ReportStatisticsWithBLOBs saveReport(@RequestBody ReportStatisticsSaveRequest request){
|
||||
ReportStatisticsWithBLOBs returnData = reportStatisticsService.saveByRequest(request);
|
||||
return returnData;
|
||||
}
|
||||
|
||||
@PostMapping("/updateReport")
|
||||
public ReportStatisticsWithBLOBs updateReport(@RequestBody ReportStatisticsSaveRequest request){
|
||||
ReportStatisticsWithBLOBs returnData = reportStatisticsService.updateByRequest(request);
|
||||
return returnData;
|
||||
}
|
||||
|
||||
@PostMapping("/deleteByParam")
|
||||
public int deleteById(@RequestBody ReportStatisticsSaveRequest request) {
|
||||
return reportStatisticsService.deleteById(request.getId());
|
||||
}
|
||||
|
||||
@PostMapping("/selectById")
|
||||
public ReportStatisticsWithBLOBs selectById(@RequestBody ReportStatisticsSaveRequest request) {
|
||||
return reportStatisticsService.selectById(request.getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.metersphere.reportstatistics.controller;
|
||||
|
||||
import io.metersphere.reportstatistics.dto.TestAnalysisChartRequest;
|
||||
import io.metersphere.reportstatistics.dto.TestAnalysisResult;
|
||||
import io.metersphere.reportstatistics.service.TestAnalysisService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/report/test/analysis")
|
||||
public class TestAnalysisController {
|
||||
|
||||
@Resource
|
||||
TestAnalysisService testAnalysisService;
|
||||
|
||||
@PostMapping("/getReport")
|
||||
public TestAnalysisResult getReport(@RequestBody TestAnalysisChartRequest request) {
|
||||
return testAnalysisService.getReport(request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.metersphere.reportstatistics.controller;
|
||||
|
||||
import io.metersphere.reportstatistics.dto.TestCaseCountRequest;
|
||||
import io.metersphere.reportstatistics.dto.TestCaseCountResponse;
|
||||
import io.metersphere.reportstatistics.service.TestCaseCountService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/report/test/case/count")
|
||||
public class TestCaseCountController {
|
||||
|
||||
@Resource
|
||||
TestCaseCountService testCaseCountService;
|
||||
|
||||
@PostMapping("/initDatas")
|
||||
public Map<String, List<Map<String,String>>> initDatas(@RequestBody TestCaseCountRequest request) {
|
||||
Map<String,List<Map<String, String>>> returnMap = testCaseCountService.getSelectFilterDatas(request.getProjectId());
|
||||
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
@PostMapping("/getReport")
|
||||
public TestCaseCountResponse getReport(@RequestBody TestCaseCountRequest request) {
|
||||
TestCaseCountResponse response = testCaseCountService.getReport(request);
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.reportstatistics.dto.charts.Series;
|
||||
import io.metersphere.reportstatistics.dto.charts.Title;
|
||||
import io.metersphere.reportstatistics.dto.charts.XAxis;
|
||||
import io.metersphere.reportstatistics.dto.charts.YAxis;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PieChartDTO {
|
||||
private JSONObject dataset;
|
||||
private JSONObject tooltip;
|
||||
private XAxis xAxis;
|
||||
private YAxis yAxis;
|
||||
private List<Series> series;
|
||||
private List<Title> title;
|
||||
private int width;
|
||||
|
||||
public PieChartDTO() {
|
||||
tooltip = new JSONObject();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import io.metersphere.base.domain.ReportStatisticsWithBLOBs;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/9/14 4:51 下午
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ReportStatisticsSaveRequest extends ReportStatisticsWithBLOBs {
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
public enum ReportStatisticsType {
|
||||
TEST_CASE_COUNT,TEST_CASE_ANALYSIS
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import io.metersphere.reportstatistics.dto.charts.Legend;
|
||||
import io.metersphere.reportstatistics.dto.charts.Series;
|
||||
import io.metersphere.reportstatistics.dto.charts.XAxis;
|
||||
import io.metersphere.reportstatistics.dto.charts.YAxis;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestAnalysisChartDTO {
|
||||
private Legend legend;
|
||||
private XAxis xAxis;
|
||||
private YAxis yAxis;
|
||||
private List<Series> series;
|
||||
|
||||
public TestAnalysisChartDTO() {
|
||||
}
|
||||
|
||||
public TestAnalysisChartDTO(Legend legend, XAxis xAxis, YAxis yAxis, List<Series> series) {
|
||||
this.legend = legend;
|
||||
this.xAxis = xAxis;
|
||||
this.yAxis = yAxis;
|
||||
this.series = series;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestAnalysisChartRequest {
|
||||
private boolean createCase;
|
||||
private boolean updateCase;
|
||||
private String order;
|
||||
private List<Long> times;
|
||||
private String startTime;
|
||||
private String endTime;
|
||||
private List<String> prioritys;
|
||||
private List<String> projects;
|
||||
private List<String> modules;
|
||||
private List<String> users;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestAnalysisChartResult {
|
||||
private String dateStr;
|
||||
private String countNum;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestAnalysisResult {
|
||||
private TestAnalysisChartDTO chartDTO;
|
||||
private List<TestAnalysisTableDTO> tableDTOs;
|
||||
|
||||
public TestAnalysisResult() {
|
||||
|
||||
}
|
||||
|
||||
public TestAnalysisResult(TestAnalysisChartDTO chartDTO, List<TestAnalysisTableDTO> tableDTOs) {
|
||||
this.chartDTO = chartDTO;
|
||||
this.tableDTOs = tableDTOs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestAnalysisTableDTO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String createCount;
|
||||
private String updateCount;
|
||||
private List<TestAnalysisTableDTO> children;
|
||||
|
||||
public TestAnalysisTableDTO() {
|
||||
|
||||
}
|
||||
|
||||
public TestAnalysisTableDTO(String name, String createCount, String updateCount, List<TestAnalysisTableDTO> children) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
this.name = name;
|
||||
this.createCount = createCount;
|
||||
this.updateCount = updateCount;
|
||||
this.children = children;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseCountChartResult {
|
||||
private String groupName;
|
||||
private long countNum;
|
||||
|
||||
public String getCountNumStr(){
|
||||
return String.valueOf(countNum);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseCountRequest {
|
||||
//x轴字段
|
||||
private String xaxis;
|
||||
//y轴字段
|
||||
private List<String> yaxis;
|
||||
|
||||
//搜索条件
|
||||
private String projectId;
|
||||
private String timeType;
|
||||
private TimeFilter timeFilter;
|
||||
private List<Long> times;
|
||||
private String order;
|
||||
|
||||
//起始时间
|
||||
private long startTime = 0;
|
||||
//结束时间
|
||||
private long endTime = 0;
|
||||
|
||||
//其余条件
|
||||
private String filterType;
|
||||
private List<Map<String,Object>> filters;
|
||||
|
||||
/**
|
||||
* 功能用例、接口用例、场景用例、性能用例的分组字段
|
||||
*/
|
||||
private String testCaseGroupColumn;
|
||||
private String apiCaseGroupColumn;
|
||||
private String scenarioCaseGroupColumn;
|
||||
private String loadCaseGroupColumn;
|
||||
|
||||
/**
|
||||
* filter整理后的查询数据
|
||||
* @return
|
||||
*/
|
||||
private Map<String,List<String>> filterSearchList;
|
||||
private Map<String,List<String>> apiFilterSearchList;
|
||||
private Map<String,List<String>> loadFilterSearchList;
|
||||
|
||||
public int getTimeRange(){
|
||||
if(timeFilter != null){
|
||||
return timeFilter.getTimeRange();
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String getTimeRangeUnit(){
|
||||
if(timeFilter != null){
|
||||
return timeFilter.getTimeRangeUnit();
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFilterSearchList(String key,List<String> values){
|
||||
if(this.filterSearchList == null){
|
||||
this.filterSearchList = new HashMap<>();
|
||||
}
|
||||
filterSearchList.put(key,values);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
class TimeFilter{
|
||||
private int timeRange;
|
||||
private String timeRangeUnit;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseCountResponse {
|
||||
private TestAnalysisChartDTO barChartDTO;
|
||||
private PieChartDTO pieChartDTO;
|
||||
private List<TestCaseCountTableDTO> tableDTOs;
|
||||
|
||||
public TestCaseCountResponse() {
|
||||
|
||||
}
|
||||
|
||||
public TestCaseCountResponse(TestAnalysisChartDTO chartDTO, PieChartDTO pieChartDTO, List<TestCaseCountTableDTO> tableDTOs) {
|
||||
this.pieChartDTO = pieChartDTO;
|
||||
this.barChartDTO = chartDTO;
|
||||
this.tableDTOs = tableDTOs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/9/8 5:36 下午
|
||||
*/
|
||||
public class TestCaseCountSummary {
|
||||
public String groupName;
|
||||
|
||||
public long testCaseCount = 0;
|
||||
public long apiCaseCount = 0;
|
||||
public long scenarioCaseCount = 0;
|
||||
public long loadCaseCount = 0;
|
||||
|
||||
public TestCaseCountSummary(String groupName) {
|
||||
this.groupName = groupName;
|
||||
}
|
||||
|
||||
public long getAllCount() {
|
||||
return this.testCaseCount + this.apiCaseCount + this.scenarioCaseCount + this.loadCaseCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.metersphere.reportstatistics.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseCountTableDTO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String allCount;
|
||||
private String testCaseCount;
|
||||
private String apiCaseCount;
|
||||
private String scenarioCaseCount;
|
||||
private String loadCaseCount;
|
||||
|
||||
private List<TestCaseCountTableDTO> children;
|
||||
|
||||
public TestCaseCountTableDTO(String name, long testCaseCount, long apiCaseCount, long scenarioCaseCount, long loadCaseCount) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
this.name = name;
|
||||
this.testCaseCount = String.valueOf(testCaseCount);
|
||||
this.apiCaseCount = String.valueOf(apiCaseCount);
|
||||
this.scenarioCaseCount = String.valueOf(scenarioCaseCount);
|
||||
this.loadCaseCount = String.valueOf(loadCaseCount);
|
||||
this.allCount = String.valueOf(testCaseCount+apiCaseCount+scenarioCaseCount+loadCaseCount);
|
||||
|
||||
children = new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Legend {
|
||||
private final String x = "center";
|
||||
private final String y = "bottom";
|
||||
private final String type = "scroll";
|
||||
private final List<Integer> padding = Arrays.asList(0, 40, 0, 0);
|
||||
private Map<String, Boolean> selected;
|
||||
private List<String> data;
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PieData {
|
||||
private String name;
|
||||
private long value;
|
||||
private JSONObject itemStyle;
|
||||
|
||||
public void setColor(String color){
|
||||
if(itemStyle == null){
|
||||
itemStyle = new JSONObject();
|
||||
}
|
||||
itemStyle.put("color",color);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Series {
|
||||
private String name;
|
||||
private List<Object> data;
|
||||
private String color = "#783887";
|
||||
private String type = "line";
|
||||
private String radius = "50";
|
||||
private String stack;
|
||||
private JSONObject encode;
|
||||
private List<String> center;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Title {
|
||||
private String name;
|
||||
private String subtext;
|
||||
private String left;
|
||||
private String top = "75%";
|
||||
private String textAlign = "center";
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class XAxis {
|
||||
private final String type = "category";
|
||||
private List<String> data;
|
||||
private String name;
|
||||
private Map<String,Integer> axisLabel = new HashMap<String,Integer>(){ {this.put("interval",0);this.put("rotate",30);}};
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.reportstatistics.dto.charts;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class YAxis {
|
||||
private String type;
|
||||
private List<String> data;
|
||||
private String name;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package io.metersphere.reportstatistics.service;
|
||||
|
||||
import io.metersphere.base.domain.ReportStatistics;
|
||||
import io.metersphere.base.domain.ReportStatisticsExample;
|
||||
import io.metersphere.base.domain.ReportStatisticsWithBLOBs;
|
||||
import io.metersphere.base.mapper.ReportStatisticsMapper;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.reportstatistics.dto.ReportStatisticsSaveRequest;
|
||||
import io.metersphere.reportstatistics.dto.ReportStatisticsType;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/9/14 4:50 下午
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ReportStatisticsService {
|
||||
@Resource
|
||||
private ReportStatisticsMapper reportStatisticsMapper;
|
||||
|
||||
public ReportStatisticsWithBLOBs saveByRequest(ReportStatisticsSaveRequest request) {
|
||||
ReportStatisticsWithBLOBs model = new ReportStatisticsWithBLOBs();
|
||||
model.setId(UUID.randomUUID().toString());
|
||||
String name = "用例分析报表";
|
||||
if(StringUtils.equalsIgnoreCase(ReportStatisticsType.TEST_CASE_COUNT.name(),request.getReportType())){
|
||||
name = "用例统计报表";
|
||||
model.setReportType(ReportStatisticsType.TEST_CASE_COUNT.name());
|
||||
}else {
|
||||
model.setReportType(ReportStatisticsType.TEST_CASE_ANALYSIS.name());
|
||||
}
|
||||
model.setName(name);
|
||||
model.setDataOption(request.getDataOption());
|
||||
model.setSelectOption(request.getSelectOption());
|
||||
model.setCreateTime(System.currentTimeMillis());
|
||||
model.setUpdateTime(System.currentTimeMillis());
|
||||
model.setProjectId(request.getProjectId());
|
||||
String userId = SessionUtils.getUserId();
|
||||
model.setCreateUser(userId);
|
||||
model.setUpdateUser(userId);
|
||||
|
||||
reportStatisticsMapper.insert(model);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public int deleteById(String id) {
|
||||
return reportStatisticsMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public List<ReportStatistics> selectByProjectIdAndReportType(String projectId, String reportType) {
|
||||
ReportStatisticsExample example = new ReportStatisticsExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andReportTypeEqualTo(reportType);
|
||||
example.setOrderByClause("create_time DESC");
|
||||
return reportStatisticsMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public ReportStatisticsWithBLOBs selectById(String id) {
|
||||
return reportStatisticsMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public ReportStatisticsWithBLOBs updateByRequest(ReportStatisticsSaveRequest request) {
|
||||
ReportStatisticsWithBLOBs updateModel = new ReportStatisticsWithBLOBs();
|
||||
updateModel.setId(request.getId());
|
||||
updateModel.setName(request.getName());
|
||||
updateModel.setUpdateTime(request.getUpdateTime());
|
||||
updateModel.setUpdateUser(SessionUtils.getUserId());
|
||||
reportStatisticsMapper.updateByPrimaryKeySelective(updateModel);
|
||||
return updateModel;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
package io.metersphere.reportstatistics.service;
|
||||
|
||||
import io.metersphere.base.mapper.ext.ExtTestAnalysisMapper;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.ProjectRequest;
|
||||
import io.metersphere.dto.ProjectDTO;
|
||||
import io.metersphere.reportstatistics.dto.*;
|
||||
import io.metersphere.reportstatistics.dto.charts.Legend;
|
||||
import io.metersphere.reportstatistics.dto.charts.Series;
|
||||
import io.metersphere.reportstatistics.dto.charts.XAxis;
|
||||
import io.metersphere.reportstatistics.dto.charts.YAxis;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestAnalysisService {
|
||||
@Resource
|
||||
private ExtTestAnalysisMapper extTestAnalysisMapper;
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
|
||||
private final String ADD = "新增用例";
|
||||
private final String UPDATE = "修改用例";
|
||||
|
||||
public TestAnalysisResult getReport(TestAnalysisChartRequest request) {
|
||||
if (CollectionUtils.isEmpty(request.getTimes())) {
|
||||
// 最近七天
|
||||
request.setTimes(Arrays.asList(System.currentTimeMillis() - 7 * 24 * 3600 * 1000L, System.currentTimeMillis()));
|
||||
}
|
||||
request.setStartTime(DateUtils.getDataStr(request.getTimes().get(0)));
|
||||
request.setEndTime(DateUtils.getDataStr(request.getTimes().get(1)));
|
||||
if (CollectionUtils.isEmpty(request.getProjects())) {
|
||||
// 获取当前组织空间下所有项目
|
||||
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||
ProjectRequest projectRequest = new ProjectRequest();
|
||||
projectRequest.setWorkspaceId(currentWorkspaceId);
|
||||
List<ProjectDTO> projectDTOS = projectService.getProjectList(projectRequest);
|
||||
if (CollectionUtils.isNotEmpty(projectDTOS)) {
|
||||
request.setProjects(projectDTOS.stream().map(ProjectDTO::getId).collect(Collectors.toList()));
|
||||
} else {
|
||||
request.setProjects(new LinkedList<String>(){{this.add(UUID.randomUUID().toString());}});
|
||||
}
|
||||
}
|
||||
TestAnalysisChartDTO dto = new TestAnalysisChartDTO();
|
||||
List<TestAnalysisTableDTO> dtos = new LinkedList<>();
|
||||
|
||||
List<Series> seriesList = new LinkedList<>();
|
||||
XAxis xAxis = new XAxis();
|
||||
|
||||
if (CollectionUtils.isEmpty(request.getUsers())) {
|
||||
// 组织charts格式数据
|
||||
Legend legend = new Legend();
|
||||
formatLegend(legend, null, request);
|
||||
dto.setLegend(legend);
|
||||
List<TestAnalysisChartResult> createResults = extTestAnalysisMapper.getCraeteCaseReport(request);
|
||||
// 获取修改的用例统计报表
|
||||
List<TestAnalysisChartResult> updateResults = extTestAnalysisMapper.getUpdateCaseReport(request);
|
||||
formatXaxisSeries(xAxis, seriesList, "", dto, createResults, updateResults);
|
||||
formatTable(dtos, createResults, updateResults);
|
||||
} else {
|
||||
List<String> users = request.getUsers();
|
||||
Legend legend = new Legend();
|
||||
formatLegend(legend, users, request);
|
||||
dto.setLegend(legend);
|
||||
|
||||
// 按用户展示
|
||||
boolean isFlag = true;
|
||||
for (String item : users) {
|
||||
request.setUsers(Arrays.asList(item));
|
||||
List<TestAnalysisChartResult> createResults = extTestAnalysisMapper.getCraeteCaseReport(request);
|
||||
// 获取修改的用例统计报表
|
||||
List<TestAnalysisChartResult> updateResults = extTestAnalysisMapper.getUpdateCaseReport(request);
|
||||
formatXaxisSeries(xAxis, seriesList, item + "-", dto, createResults, updateResults);
|
||||
|
||||
// 初始化列表总量,按天统计总量
|
||||
if (isFlag) {
|
||||
formatTable(dtos, createResults, updateResults);
|
||||
isFlag = false;
|
||||
}
|
||||
// 增加子项
|
||||
for (int j = 0; j < dtos.size(); j++) {
|
||||
TestAnalysisTableDTO childItem = new TestAnalysisTableDTO(item, createResults.get(j).getCountNum(), updateResults.get(j).getCountNum(), null);
|
||||
dtos.get(j).getChildren().add(childItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 每行总计
|
||||
dtos.forEach(item -> {
|
||||
if (CollectionUtils.isNotEmpty(item.getChildren())) {
|
||||
// table 总和计算
|
||||
List<Integer> collect = item.getChildren().stream().map(childItem -> Integer.valueOf(childItem.getCreateCount())).collect(Collectors.toList());
|
||||
// reduce求和
|
||||
Optional<Integer> createCount = collect.stream().reduce(Integer::sum);
|
||||
List<Integer> upCollect = item.getChildren().stream().map(childItem -> Integer.valueOf(childItem.getUpdateCount())).collect(Collectors.toList());
|
||||
// reduce求和
|
||||
Optional<Integer> updateCount = upCollect.stream().reduce(Integer::sum);
|
||||
item.setCreateCount(createCount.get().toString());
|
||||
item.setUpdateCount(updateCount.get().toString());
|
||||
}
|
||||
});
|
||||
// table 总和计算
|
||||
List<Integer> collect = dtos.stream().map(item -> Integer.valueOf(item.getCreateCount())).collect(Collectors.toList());
|
||||
// reduce求和
|
||||
Optional<Integer> createCount = collect.stream().reduce(Integer::sum);
|
||||
List<Integer> upCollect = dtos.stream().map(item -> Integer.valueOf(item.getUpdateCount())).collect(Collectors.toList());
|
||||
// reduce求和
|
||||
Optional<Integer> updateCount = upCollect.stream().reduce(Integer::sum);
|
||||
dtos.add(new TestAnalysisTableDTO("总计", createCount.get().toString(), updateCount.get().toString(), new LinkedList<>()));
|
||||
|
||||
TestAnalysisResult testAnalysisResult = new TestAnalysisResult();
|
||||
testAnalysisResult.setChartDTO(dto);
|
||||
testAnalysisResult.setTableDTOs(dtos);
|
||||
return testAnalysisResult;
|
||||
}
|
||||
|
||||
private void formatXaxisSeries(XAxis xAxis, List<Series> seriesList, String name, TestAnalysisChartDTO dto, List<TestAnalysisChartResult> createResults, List<TestAnalysisChartResult> updateResults) {
|
||||
if (CollectionUtils.isNotEmpty(createResults)) {
|
||||
xAxis.setData(createResults.stream().map(TestAnalysisChartResult::getDateStr).collect(Collectors.toList()));
|
||||
Series series = new Series();
|
||||
series.setName(name + ADD);
|
||||
series.setData(createResults.stream().map(TestAnalysisChartResult::getCountNum).collect(Collectors.toList()));
|
||||
seriesList.add(series);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateResults)) {
|
||||
xAxis.setData(updateResults.stream().map(TestAnalysisChartResult::getDateStr).collect(Collectors.toList()));
|
||||
Series series = new Series();
|
||||
series.setName(name + UPDATE);
|
||||
series.setColor("#B8741A");
|
||||
series.setData(updateResults.stream().map(TestAnalysisChartResult::getCountNum).collect(Collectors.toList()));
|
||||
seriesList.add(series);
|
||||
}
|
||||
dto.setXAxis(xAxis);
|
||||
dto.setYAxis(new YAxis());
|
||||
dto.setSeries(seriesList);
|
||||
}
|
||||
|
||||
private void formatLegend(Legend legend, List<String> datas, TestAnalysisChartRequest request) {
|
||||
Map<String, Boolean> selected = new LinkedHashMap<>();
|
||||
List<String> list = new LinkedList<>();
|
||||
if (CollectionUtils.isEmpty(datas)) {
|
||||
selected.put(ADD, request.isCreateCase());
|
||||
selected.put(UPDATE, request.isUpdateCase());
|
||||
list.add(ADD);
|
||||
list.add(UPDATE);
|
||||
} else {
|
||||
datas.forEach(item -> {
|
||||
selected.put(item + "-" + ADD, request.isCreateCase());
|
||||
selected.put(item + "-" + UPDATE, request.isUpdateCase());
|
||||
list.add(item + "-" + ADD);
|
||||
list.add(item + "-" + UPDATE);
|
||||
});
|
||||
}
|
||||
legend.setSelected(selected);
|
||||
legend.setData(list);
|
||||
}
|
||||
|
||||
private void formatTable(List<TestAnalysisTableDTO> dtos, List<TestAnalysisChartResult> createResults, List<TestAnalysisChartResult> updateResults) {
|
||||
for (int i = 0; i < createResults.size(); i++) {
|
||||
TestAnalysisTableDTO dto = new TestAnalysisTableDTO(createResults.get(i).getDateStr(), createResults.get(i).getCountNum(), updateResults.get(i).getCountNum(), new LinkedList<>());
|
||||
dtos.add(dto);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,775 @@
|
|||
package io.metersphere.reportstatistics.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.CustomField;
|
||||
import io.metersphere.base.domain.User;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseCountMapper;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||
import io.metersphere.dto.TestCaseTemplateDao;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.reportstatistics.dto.*;
|
||||
import io.metersphere.reportstatistics.dto.charts.*;
|
||||
import io.metersphere.service.TestCaseTemplateService;
|
||||
import io.metersphere.service.UserService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestCaseCountService {
|
||||
@Resource
|
||||
private ExtTestCaseCountMapper extTestCaseCountMapper;
|
||||
@Resource
|
||||
UserService userService;
|
||||
|
||||
public TestCaseCountResponse getReport(TestCaseCountRequest request) {
|
||||
request.setFilterType(request.getFilterType().toUpperCase(Locale.ROOT));
|
||||
|
||||
TestAnalysisChartDTO dto = new TestAnalysisChartDTO();
|
||||
PieChartDTO pieChartDTO = new PieChartDTO();
|
||||
List<TestCaseCountTableDTO> dtos = new LinkedList<>();
|
||||
|
||||
List<Series> seriesList = new LinkedList<>();
|
||||
XAxis xAxis = new XAxis();
|
||||
xAxis.setAxisLabel(new HashMap<String,Integer>(){ {this.put("interval",0);this.put("rotate",0);}});
|
||||
|
||||
// 组织charts格式数据
|
||||
Legend legend = new Legend();
|
||||
formatLegend(legend, request.getYaxis(), request);
|
||||
dto.setLegend(legend);
|
||||
//根据X轴(分组计算字段)来整理不同表对应的字段 注意:x轴维护人/查询条件有维护人时 不查接口和性能; x轴为用例等级/查询条件有用例等级的,不查性能
|
||||
|
||||
boolean yAxisSelectTestCase = false;
|
||||
boolean yAxisSelectApi = false;
|
||||
boolean yAxisSelectScenarioCase = false;
|
||||
boolean yAxisSelectLoad = false;
|
||||
|
||||
boolean selectApi = true;
|
||||
boolean selectLoad = true;
|
||||
|
||||
boolean parseUser = false;
|
||||
boolean parseStatus = false;
|
||||
|
||||
switch (request.getXaxis()) {
|
||||
case "creator":
|
||||
request.setTestCaseGroupColumn("create_user");
|
||||
request.setApiCaseGroupColumn("create_user_id");
|
||||
request.setScenarioCaseGroupColumn("create_user");
|
||||
request.setLoadCaseGroupColumn("create_user");
|
||||
parseUser = true;
|
||||
break;
|
||||
case "maintainer":
|
||||
request.setTestCaseGroupColumn("maintainer");
|
||||
request.setApiCaseGroupColumn("'无维护人'");
|
||||
request.setScenarioCaseGroupColumn("principal");
|
||||
request.setLoadCaseGroupColumn("'无维护人'");
|
||||
selectApi = false;
|
||||
selectLoad = false;
|
||||
parseUser = true;
|
||||
break;
|
||||
case "casetype":
|
||||
Map<String, String> caseDescMap = this.getCaseDescMap();
|
||||
request.setTestCaseGroupColumn("'" + caseDescMap.get("testCaseDesc") + "'");
|
||||
request.setApiCaseGroupColumn("'" + caseDescMap.get("apiCaseDesc") + "'");
|
||||
request.setScenarioCaseGroupColumn("'" + caseDescMap.get("scenarioCaseDesc") + "'");
|
||||
request.setLoadCaseGroupColumn("'" + caseDescMap.get("loadCaseDesc") + "'");
|
||||
break;
|
||||
case "casestatus":
|
||||
request.setTestCaseGroupColumn("status");
|
||||
request.setApiCaseGroupColumn("status");
|
||||
request.setScenarioCaseGroupColumn("status");
|
||||
request.setLoadCaseGroupColumn("status");
|
||||
selectApi = false;
|
||||
parseStatus = true;
|
||||
break;
|
||||
case "caselevel":
|
||||
request.setTestCaseGroupColumn("priority");
|
||||
request.setApiCaseGroupColumn("priority");
|
||||
request.setScenarioCaseGroupColumn("level");
|
||||
request.setLoadCaseGroupColumn("'无用例等级'");
|
||||
selectLoad = false;
|
||||
break;
|
||||
default:
|
||||
return new TestCaseCountResponse();
|
||||
}
|
||||
|
||||
//计算时间
|
||||
if (StringUtils.equalsIgnoreCase(request.getTimeType(), "dynamicTime")) {
|
||||
int dateCountType = 0;
|
||||
if (StringUtils.equalsIgnoreCase(request.getTimeRangeUnit(), "day")) {
|
||||
dateCountType = Calendar.DAY_OF_MONTH;
|
||||
} else if (StringUtils.equalsIgnoreCase(request.getTimeRangeUnit(), "month")) {
|
||||
dateCountType = Calendar.MONTH;
|
||||
} else if (StringUtils.equalsIgnoreCase(request.getTimeRangeUnit(), "year")) {
|
||||
dateCountType = Calendar.YEAR;
|
||||
}
|
||||
|
||||
if (dateCountType != 0 && request.getTimeRange() != 0) {
|
||||
long startTime = DateUtils.dateSum(new Date(), (0 - request.getTimeRange()), dateCountType).getTime();
|
||||
request.setStartTime(startTime);
|
||||
}
|
||||
|
||||
} else if (StringUtils.equalsIgnoreCase(request.getTimeType(), "fixedTime")) {
|
||||
if (CollectionUtils.isNotEmpty(request.getTimes()) && request.getTimes().size() == 2) {
|
||||
request.setStartTime(request.getTimes().get(0));
|
||||
request.setEndTime(request.getTimes().get(1));
|
||||
}
|
||||
}
|
||||
|
||||
//计算更多属性
|
||||
if (CollectionUtils.isNotEmpty(request.getFilters())) {
|
||||
for (Map<String, Object> filterMap : request.getFilters()) {
|
||||
String filterType = String.valueOf(filterMap.get("type"));
|
||||
|
||||
if (StringUtils.equalsAnyIgnoreCase(filterType, "casetype", "caselevel", "creator", "maintainer")) {
|
||||
Object valueObj = filterMap.get("values");
|
||||
if (valueObj instanceof List) {
|
||||
List<String> searchList = (List) valueObj;
|
||||
if(!searchList.isEmpty()){
|
||||
request.setFilterSearchList(filterType, searchList);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(filterType, "caselevel")) {
|
||||
selectLoad = false;
|
||||
}else if (StringUtils.equalsIgnoreCase(filterType, "maintainer")) {
|
||||
selectApi = false;
|
||||
selectLoad = false;
|
||||
}
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(filterType, "casestatus")){
|
||||
List<String> searchList = new ArrayList<>();
|
||||
Object valueObj = filterMap.get("values");
|
||||
if (valueObj instanceof List) {
|
||||
for (String statusStr : (List<String>) valueObj) {
|
||||
searchList.add(statusStr.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
//如果包含Running
|
||||
if(searchList.contains("RUNNING")){
|
||||
if(!searchList.contains("Starting")){
|
||||
searchList.add("STARTING");
|
||||
}
|
||||
if(!searchList.contains("Underway")){
|
||||
searchList.add("UNDERWAY");
|
||||
}
|
||||
}
|
||||
|
||||
if(searchList.contains("FINISHED")){
|
||||
if(!searchList.contains("Completed")){
|
||||
searchList.add("Completed");
|
||||
}
|
||||
}
|
||||
|
||||
if(!searchList.isEmpty()){
|
||||
request.setFilterSearchList(filterType, searchList);
|
||||
}
|
||||
selectApi = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取测试用例、接口用例、场景用例、性能用例的统计
|
||||
List<TestCaseCountChartResult> functionCaseCountResult = new ArrayList<>();
|
||||
List<TestCaseCountChartResult> apiCaseCountResult = new ArrayList<>();
|
||||
List<TestCaseCountChartResult> scenarioCaseCount = new ArrayList<>();
|
||||
List<TestCaseCountChartResult> loadCaseCount = new ArrayList<>();
|
||||
|
||||
List<String> moreOptionsAboutCaseType = new ArrayList<>();
|
||||
if (StringUtils.equalsIgnoreCase(request.getFilterType(), "And") && MapUtils.isNotEmpty(request.getFilterSearchList())) {
|
||||
if (request.getFilterSearchList().containsKey("maintainer")) {
|
||||
selectApi = false;
|
||||
}
|
||||
if (request.getFilterSearchList().containsKey("caselevel")) {
|
||||
selectLoad = false;
|
||||
}
|
||||
|
||||
if (request.getFilterSearchList().containsKey("casetype")) {
|
||||
//如果"且"查询,同时针对案例类型做过筛选,那么则分开批量查询
|
||||
List<String> selectCaseTypeList = request.getFilterSearchList().get("casetype");
|
||||
request.getFilterSearchList().remove("casetype");
|
||||
if (CollectionUtils.isNotEmpty(selectCaseTypeList)) {
|
||||
moreOptionsAboutCaseType.addAll(selectCaseTypeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
//没有选择的话默认搜索条件是所有类型的案例
|
||||
if(moreOptionsAboutCaseType.isEmpty()){
|
||||
moreOptionsAboutCaseType.add("testCase");
|
||||
moreOptionsAboutCaseType.add("apiCase");
|
||||
moreOptionsAboutCaseType.add("scenarioCase");
|
||||
moreOptionsAboutCaseType.add("loadCase");
|
||||
}
|
||||
|
||||
//解析Y轴,判断要查询的案例类型
|
||||
if(CollectionUtils.isNotEmpty(request.getYaxis())){
|
||||
|
||||
for (String selectType:request.getYaxis()) {
|
||||
if(moreOptionsAboutCaseType.contains(selectType)){
|
||||
if (StringUtils.equalsIgnoreCase(selectType, "testCase")) {
|
||||
yAxisSelectTestCase = true;
|
||||
} else if (StringUtils.equalsIgnoreCase(selectType, "apiCase")) {
|
||||
if(selectApi){
|
||||
yAxisSelectApi = true;
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(selectType, "scenarioCase")) {
|
||||
yAxisSelectScenarioCase = true;
|
||||
} else if (StringUtils.equalsIgnoreCase(selectType, "loadCase")) {
|
||||
if(selectLoad){
|
||||
yAxisSelectLoad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(yAxisSelectTestCase){
|
||||
functionCaseCountResult = extTestCaseCountMapper.getFunctionCaseCount(request);
|
||||
}
|
||||
if (yAxisSelectApi) {
|
||||
Map<String,List<String>> apiCaseFilterList = new HashMap<>();
|
||||
if(MapUtils.isNotEmpty(request.getFilterSearchList())){
|
||||
for (Map.Entry<String,List<String>> entry : request.getFilterSearchList().entrySet()) {
|
||||
String type = entry.getKey();
|
||||
if(!StringUtils.equalsAnyIgnoreCase(type,"maintainer","casestatus")){
|
||||
apiCaseFilterList.put(entry.getKey(),entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
request.setApiFilterSearchList(apiCaseFilterList);
|
||||
apiCaseCountResult = extTestCaseCountMapper.getApiCaseCount(request);
|
||||
}
|
||||
if(yAxisSelectScenarioCase){
|
||||
scenarioCaseCount = extTestCaseCountMapper.getScenarioCaseCount(request);
|
||||
}
|
||||
if (yAxisSelectLoad) {
|
||||
Map<String,List<String>> loadCaseFilterMap = new HashMap<>();
|
||||
if(MapUtils.isNotEmpty(request.getFilterSearchList())){
|
||||
for (Map.Entry<String,List<String>> entry : request.getFilterSearchList().entrySet()) {
|
||||
String type = entry.getKey();
|
||||
if(!StringUtils.equalsAnyIgnoreCase(type,"maintainer","caselevel")){
|
||||
loadCaseFilterMap.put(entry.getKey(),entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
request.setLoadFilterSearchList(loadCaseFilterMap);
|
||||
loadCaseCount = extTestCaseCountMapper.getLoadCaseCount(request);
|
||||
}
|
||||
|
||||
Map<String, TestCaseCountSummary> summaryMap = this.summaryCountResult(parseUser, parseStatus,request.getProjectId(),request.getOrder(),
|
||||
functionCaseCountResult, apiCaseCountResult, scenarioCaseCount, loadCaseCount);
|
||||
|
||||
formatXaxisSeries(xAxis, seriesList, dto, summaryMap);
|
||||
formatTable(dtos, summaryMap);
|
||||
|
||||
formatPieChart(pieChartDTO, request.getXaxis(), summaryMap,yAxisSelectTestCase,yAxisSelectApi,yAxisSelectScenarioCase,yAxisSelectLoad);
|
||||
|
||||
TestCaseCountResponse testCaseCountResult = new TestCaseCountResponse();
|
||||
testCaseCountResult.setBarChartDTO(dto);
|
||||
testCaseCountResult.setTableDTOs(dtos);
|
||||
testCaseCountResult.setPieChartDTO(pieChartDTO);
|
||||
return testCaseCountResult;
|
||||
}
|
||||
|
||||
private void formatPieChart(PieChartDTO pieChartDTO, String groupName, Map<String, TestCaseCountSummary> summaryMap,
|
||||
boolean selectTestCase, boolean selectApi, boolean selectScenarioCase, boolean selectLoad) {
|
||||
JSONArray titleArray = new JSONArray();
|
||||
titleArray.add("type");
|
||||
titleArray.add("count");
|
||||
titleArray.add(groupName);
|
||||
|
||||
List<Series> seriesArr = new ArrayList<>();
|
||||
List<Title> titles = new ArrayList<>();
|
||||
|
||||
int leftPx = 200;
|
||||
Map<String, String> caseDescMap = this.getCaseDescMap();
|
||||
for (TestCaseCountSummary summary : summaryMap.values()) {
|
||||
String leftPxStr = String.valueOf(leftPx);
|
||||
|
||||
List<Object> dataList = new ArrayList<>();
|
||||
|
||||
if(selectTestCase && summary.testCaseCount > 0){
|
||||
PieData pieData = new PieData();
|
||||
pieData.setName(caseDescMap.get("testCaseDesc"));
|
||||
pieData.setValue(summary.testCaseCount);
|
||||
pieData.setColor("#F38F1F");
|
||||
dataList.add(pieData);
|
||||
}
|
||||
|
||||
if(selectApi && summary.apiCaseCount > 0){
|
||||
PieData apicasePieData = new PieData();
|
||||
apicasePieData.setName(caseDescMap.get("apiCaseDesc"));
|
||||
apicasePieData.setValue(summary.apiCaseCount);
|
||||
apicasePieData.setColor("#6FD999");
|
||||
dataList.add(apicasePieData);
|
||||
}
|
||||
|
||||
if(selectScenarioCase && summary.scenarioCaseCount > 0){
|
||||
PieData scenarioPieData = new PieData();
|
||||
scenarioPieData.setName(caseDescMap.get("scenarioCaseDesc"));
|
||||
scenarioPieData.setValue(summary.scenarioCaseCount);
|
||||
scenarioPieData.setColor("#2884F3");
|
||||
dataList.add(scenarioPieData);
|
||||
}
|
||||
|
||||
if(selectLoad && summary.loadCaseCount > 0){
|
||||
PieData loadCasePieData = new PieData();
|
||||
loadCasePieData.setName(caseDescMap.get("loadCaseDesc"));
|
||||
loadCasePieData.setValue(summary.loadCaseCount);
|
||||
loadCasePieData.setColor("#F45E53");
|
||||
dataList.add(loadCasePieData);
|
||||
}
|
||||
|
||||
Series series = new Series();
|
||||
series.setType("pie");
|
||||
series.setRadius("50");
|
||||
series.setEncode(new JSONObject() {{
|
||||
this.put("itemName", "groupname");
|
||||
this.put("value", summary.groupName);
|
||||
}});
|
||||
seriesArr.add(series);
|
||||
|
||||
series.setData(dataList);
|
||||
series.setCenter(new ArrayList<String>() {{
|
||||
this.add(leftPxStr);
|
||||
this.add("50%");
|
||||
}});
|
||||
|
||||
Title title = new Title();
|
||||
title.setSubtext(summary.groupName);
|
||||
title.setLeft(leftPxStr);
|
||||
titles.add(title);
|
||||
|
||||
leftPx = leftPx + 350;
|
||||
}
|
||||
|
||||
pieChartDTO.setSeries(seriesArr);
|
||||
pieChartDTO.setTitle(titles);
|
||||
pieChartDTO.setWidth(leftPx);
|
||||
}
|
||||
|
||||
private Map<String, TestCaseCountSummary> summaryCountResult(boolean parseGroupNameToUserName, boolean parseGrouNameToCaseStatus, String projectId, String order,
|
||||
List<TestCaseCountChartResult> functionCaseCountResult, List<TestCaseCountChartResult> apiCaseCountResult, List<TestCaseCountChartResult> scenarioCaseCount, List<TestCaseCountChartResult> loadCaseCount) {
|
||||
Map<String, TestCaseCountSummary> summaryMap = new LinkedHashMap<>();
|
||||
|
||||
//groupName 解析对象
|
||||
Map<String, String> groupNameParseMap = new HashMap<>();
|
||||
if (parseGroupNameToUserName) {
|
||||
groupNameParseMap.putAll(this.getUserIdMap());
|
||||
}
|
||||
if (parseGrouNameToCaseStatus) {
|
||||
groupNameParseMap.putAll(this.getCaseStatusMap(projectId));
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(functionCaseCountResult)) {
|
||||
for (TestCaseCountChartResult result : functionCaseCountResult) {
|
||||
if(result.getGroupName() == null){
|
||||
result.setGroupName(groupNameParseMap.get("running"));
|
||||
}else {
|
||||
if (groupNameParseMap.containsKey(result.getGroupName().toLowerCase(Locale.ROOT))) {
|
||||
result.setGroupName(groupNameParseMap.get(result.getGroupName().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
|
||||
String groupName = result.getGroupName();
|
||||
if (StringUtils.isNotEmpty(groupName)) {
|
||||
TestCaseCountSummary summary = summaryMap.get(groupName);
|
||||
if (summary == null) {
|
||||
summary = new TestCaseCountSummary(groupName);
|
||||
}
|
||||
summary.testCaseCount = result.getCountNum();
|
||||
summaryMap.put(groupName, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(apiCaseCountResult)) {
|
||||
for (TestCaseCountChartResult result : apiCaseCountResult) {
|
||||
if(result.getGroupName() == null){
|
||||
result.setGroupName(groupNameParseMap.get("running"));
|
||||
}else {
|
||||
if (groupNameParseMap.containsKey(result.getGroupName().toLowerCase(Locale.ROOT))) {
|
||||
result.setGroupName(groupNameParseMap.get(result.getGroupName().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
String groupName = result.getGroupName();
|
||||
if (StringUtils.isNotEmpty(groupName)) {
|
||||
TestCaseCountSummary summary = summaryMap.get(groupName);
|
||||
if (summary == null) {
|
||||
summary = new TestCaseCountSummary(groupName);
|
||||
}
|
||||
summary.apiCaseCount = result.getCountNum();
|
||||
summaryMap.put(groupName, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(scenarioCaseCount)) {
|
||||
for (TestCaseCountChartResult result : scenarioCaseCount) {
|
||||
if(result.getGroupName() == null){
|
||||
result.setGroupName(groupNameParseMap.get("running"));
|
||||
}else {
|
||||
if (groupNameParseMap.containsKey(result.getGroupName().toLowerCase(Locale.ROOT))) {
|
||||
result.setGroupName(groupNameParseMap.get(result.getGroupName().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
String groupName = result.getGroupName();
|
||||
if (StringUtils.isNotEmpty(groupName)) {
|
||||
TestCaseCountSummary summary = summaryMap.get(groupName);
|
||||
if (summary == null) {
|
||||
summary = new TestCaseCountSummary(groupName);
|
||||
}
|
||||
summary.scenarioCaseCount = result.getCountNum();
|
||||
summaryMap.put(groupName, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(loadCaseCount)) {
|
||||
for (TestCaseCountChartResult result : loadCaseCount) {
|
||||
if(result.getGroupName() == null){
|
||||
result.setGroupName(groupNameParseMap.get("running"));
|
||||
}else {
|
||||
if (groupNameParseMap.containsKey(result.getGroupName().toLowerCase(Locale.ROOT))) {
|
||||
result.setGroupName(groupNameParseMap.get(result.getGroupName().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
String groupName = result.getGroupName();
|
||||
if (StringUtils.isNotEmpty(groupName)) {
|
||||
TestCaseCountSummary summary = summaryMap.get(groupName);
|
||||
if (summary == null) {
|
||||
summary = new TestCaseCountSummary(groupName);
|
||||
}
|
||||
summary.loadCaseCount = result.getCountNum();
|
||||
summaryMap.put(groupName, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, TestCaseCountSummary> returmMap = new LinkedHashMap<>();
|
||||
|
||||
if(StringUtils.equalsIgnoreCase(order,"desc")){
|
||||
TreeMap<Long,List<TestCaseCountSummary>> treeMap = new TreeMap<>();
|
||||
for (TestCaseCountSummary model : summaryMap.values()) {
|
||||
if(treeMap.containsKey(model.getAllCount())){
|
||||
treeMap.get(model.getAllCount()).add(model);
|
||||
}else {
|
||||
List<TestCaseCountSummary> list = new ArrayList<>();
|
||||
list.add(model);
|
||||
treeMap.put(model.getAllCount(),list);
|
||||
}
|
||||
}
|
||||
ArrayList<TestCaseCountSummary> sortedList = new ArrayList<>();
|
||||
for (List<TestCaseCountSummary> list : treeMap.values()) {
|
||||
sortedList.addAll(list);
|
||||
}
|
||||
|
||||
for (int i = sortedList.size(); i > 0; i --) {
|
||||
TestCaseCountSummary model = sortedList.get(i-1);
|
||||
returmMap.put(model.groupName,model);
|
||||
}
|
||||
}else if(StringUtils.equalsIgnoreCase(order,"asc")){
|
||||
TreeMap<Long,List<TestCaseCountSummary>> treeMap = new TreeMap<>();
|
||||
for (TestCaseCountSummary model : summaryMap.values()) {
|
||||
if(treeMap.containsKey(model.getAllCount())){
|
||||
treeMap.get(model.getAllCount()).add(model);
|
||||
}else {
|
||||
List<TestCaseCountSummary> list = new ArrayList<>();
|
||||
list.add(model);
|
||||
treeMap.put(model.getAllCount(),list);
|
||||
}
|
||||
}
|
||||
for (List<TestCaseCountSummary> list : treeMap.values()) {
|
||||
for (TestCaseCountSummary model : list ) {
|
||||
returmMap.put(model.groupName,model);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
returmMap = summaryMap;
|
||||
}
|
||||
|
||||
|
||||
return returmMap;
|
||||
}
|
||||
|
||||
private Map<String, String> getUserIdMap() {
|
||||
List<User> userList = userService.getUserList();
|
||||
Map<String, String> userIdMap = new HashMap<>();
|
||||
for (User model : userList) {
|
||||
userIdMap.put(model.getId(), model.getId() + "\n(" + model.getName() + ")");
|
||||
}
|
||||
return userIdMap;
|
||||
}
|
||||
|
||||
private Map<String, String> getCaseStatusMap(String projectId) {
|
||||
|
||||
Map<String, String> caseStatusMap = new HashMap<>();
|
||||
|
||||
TestCaseTemplateService testCaseTemplateService = CommonBeanFactory.getBean(TestCaseTemplateService.class);
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(projectId);
|
||||
|
||||
caseStatusMap.put("prepare", Translator.get("test_case_status_prepare"));
|
||||
caseStatusMap.put("error", Translator.get("test_case_status_error"));
|
||||
caseStatusMap.put("success", Translator.get("test_case_status_success"));
|
||||
caseStatusMap.put("trash", Translator.get("test_case_status_trash"));
|
||||
caseStatusMap.put("underway", Translator.get("test_case_status_running"));
|
||||
caseStatusMap.put("starting", Translator.get("test_case_status_running"));
|
||||
caseStatusMap.put("saved", Translator.get("test_case_status_saved"));
|
||||
caseStatusMap.put("running", Translator.get("test_case_status_running"));
|
||||
caseStatusMap.put("finished", Translator.get("test_case_status_finished"));
|
||||
caseStatusMap.put("completed", Translator.get("test_case_status_finished"));
|
||||
|
||||
if (testCaseTemplate != null && CollectionUtils.isNotEmpty(testCaseTemplate.getCustomFields())) {
|
||||
for (CustomField customField : testCaseTemplate.getCustomFields()) {
|
||||
if (StringUtils.equals(customField.getName(), "用例状态")) {
|
||||
JSONArray optionsArr = JSONArray.parseArray(customField.getOptions());
|
||||
for (int i = 0; i < optionsArr.size(); i++) {
|
||||
JSONObject jsonObject = optionsArr.getJSONObject(i);
|
||||
if (jsonObject.containsKey("value") && jsonObject.containsKey("text") &&
|
||||
!StringUtils.equalsAnyIgnoreCase(jsonObject.getString("value"), "Prepare", "Error", "Success", "Trash", "Underway", "Starting", "Saved")) {
|
||||
caseStatusMap.put(jsonObject.getString("value"), jsonObject.getString("text"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return caseStatusMap;
|
||||
}
|
||||
|
||||
|
||||
private void formatXaxisSeries(XAxis xAxis, List<Series> seriesList, TestAnalysisChartDTO dto,
|
||||
Map<String, TestCaseCountSummary> summaryMap) {
|
||||
List<String> xAxisDataList = new ArrayList<>();
|
||||
|
||||
List<Object> testCaseCountList = new ArrayList<>();
|
||||
List<Object> apiCaseCountList = new ArrayList<>();
|
||||
List<Object> scenarioCaseCountList = new ArrayList<>();
|
||||
List<Object> loadCaseCountList = new ArrayList<>();
|
||||
for (TestCaseCountSummary summary : summaryMap.values()) {
|
||||
xAxisDataList.add(summary.groupName);
|
||||
testCaseCountList.add(String.valueOf(summary.testCaseCount));
|
||||
apiCaseCountList.add(String.valueOf(summary.apiCaseCount));
|
||||
scenarioCaseCountList.add(String.valueOf(summary.scenarioCaseCount));
|
||||
loadCaseCountList.add(String.valueOf(summary.loadCaseCount));
|
||||
}
|
||||
xAxis.setData(xAxisDataList);
|
||||
|
||||
Map<String, String> caseDescMap = this.getCaseDescMap();
|
||||
|
||||
Series tetcaseSeries = new Series();
|
||||
tetcaseSeries.setName(caseDescMap.get("testCaseDesc"));
|
||||
tetcaseSeries.setColor("#F38F1F");
|
||||
tetcaseSeries.setRadius("20%");
|
||||
tetcaseSeries.setType("bar");
|
||||
tetcaseSeries.setStack("total");
|
||||
tetcaseSeries.setData(testCaseCountList);
|
||||
seriesList.add(tetcaseSeries);
|
||||
|
||||
Series apiSeries = new Series();
|
||||
apiSeries.setName(caseDescMap.get("apiCaseDesc"));
|
||||
apiSeries.setColor("#6FD999");
|
||||
apiSeries.setType("bar");
|
||||
apiSeries.setStack("total");
|
||||
apiSeries.setData(apiCaseCountList);
|
||||
seriesList.add(apiSeries);
|
||||
|
||||
Series scenarioSeries = new Series();
|
||||
scenarioSeries.setName(caseDescMap.get("scenarioCaseDesc"));
|
||||
scenarioSeries.setColor("#2884F3");
|
||||
scenarioSeries.setType("bar");
|
||||
scenarioSeries.setStack("total");
|
||||
scenarioSeries.setData(scenarioCaseCountList);
|
||||
seriesList.add(scenarioSeries);
|
||||
|
||||
Series loadSeries = new Series();
|
||||
loadSeries.setName(caseDescMap.get("loadCaseDesc"));
|
||||
loadSeries.setColor("#F45E53");
|
||||
loadSeries.setType("bar");
|
||||
loadSeries.setStack("total");
|
||||
loadSeries.setData(loadCaseCountList);
|
||||
seriesList.add(loadSeries);
|
||||
|
||||
dto.setXAxis(xAxis);
|
||||
dto.setYAxis(new YAxis());
|
||||
dto.setSeries(seriesList);
|
||||
}
|
||||
|
||||
private void formatLegend(Legend legend, List<String> datas, TestCaseCountRequest yrequest) {
|
||||
Map<String, Boolean> selected = new LinkedHashMap<>();
|
||||
List<String> list = new LinkedList<>();
|
||||
legend.setSelected(selected);
|
||||
legend.setData(datas);
|
||||
}
|
||||
|
||||
private void formatTable(List<TestCaseCountTableDTO> dtos, Map<String, TestCaseCountSummary> summaryMap) {
|
||||
for (TestCaseCountSummary summary : summaryMap.values()) {
|
||||
TestCaseCountTableDTO dto = new TestCaseCountTableDTO(summary.groupName, summary.testCaseCount, summary.apiCaseCount, summary.scenarioCaseCount, summary.loadCaseCount);
|
||||
dtos.add(dto);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getCaseDescMap() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("testCaseDesc", Translator.get("test_case"));
|
||||
map.put("apiCaseDesc", Translator.get("api_case"));
|
||||
map.put("scenarioCaseDesc", Translator.get("scenario_case"));
|
||||
map.put("loadCaseDesc", Translator.get("performance_case"));
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map<String, List<Map<String, String>>> getSelectFilterDatas(String projectId) {
|
||||
Map<String, List<Map<String, String>>> returnMap = new HashMap<>();
|
||||
|
||||
//组装用户
|
||||
QueryMemberRequest memberRequest = new QueryMemberRequest();
|
||||
memberRequest.setProjectId(projectId);
|
||||
List<User> userList = userService.getUserList();
|
||||
|
||||
List<Map<String, String>> returnUserList = new ArrayList<>();
|
||||
for (User user : userList) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("id", user.getId());
|
||||
map.put("label", user.getId() + "(" + user.getName() + ")");
|
||||
returnUserList.add(map);
|
||||
}
|
||||
|
||||
//组装用例等级和用例状态
|
||||
TestCaseTemplateService testCaseTemplateService = CommonBeanFactory.getBean(TestCaseTemplateService.class);
|
||||
TestCaseTemplateDao testCaseTemplate = testCaseTemplateService.getTemplate(projectId);
|
||||
|
||||
List<Map<String, String>> caseLevelList = new ArrayList<>();
|
||||
List<Map<String, String>> caseStatusList = new ArrayList<>();
|
||||
Map<String, String> statusMap1 = new HashMap<>();
|
||||
statusMap1.put("id", "Prepare");
|
||||
statusMap1.put("label", Translator.get("test_case_status_prepare"));
|
||||
|
||||
// Map<String, String> statusMap2 = new HashMap<>();
|
||||
// statusMap2.put("id", "Error");
|
||||
// statusMap2.put("label", Translator.get("test_case_status_error"));
|
||||
//
|
||||
// Map<String, String> statusMap3 = new HashMap<>();
|
||||
// statusMap3.put("id", "Success");
|
||||
// statusMap3.put("label", Translator.get("test_case_status_success"));
|
||||
|
||||
// Map<String, String> statusMap4 = new HashMap<>();
|
||||
// statusMap4.put("id", "Trash");
|
||||
// statusMap4.put("label", Translator.get("test_case_status_trash"));
|
||||
|
||||
// Map<String, String> statusMap5 = new HashMap<>();
|
||||
// statusMap5.put("id", "Underway");
|
||||
// statusMap5.put("label", Translator.get("test_case_status_running"));
|
||||
|
||||
// Map<String, String> statusMap6 = new HashMap<>();
|
||||
// statusMap6.put("id", "Starting");
|
||||
// statusMap6.put("label", Translator.get("test_case_status_running"));
|
||||
|
||||
Map<String, String> statusMap7 = new HashMap<>();
|
||||
statusMap7.put("id", "Saved");
|
||||
statusMap7.put("label", Translator.get("test_case_status_saved"));
|
||||
|
||||
Map<String, String> statusMap8 = new HashMap<>();
|
||||
statusMap8.put("id", "Running");
|
||||
statusMap8.put("label", Translator.get("test_case_status_running"));
|
||||
|
||||
Map<String, String> statusMap9 = new HashMap<>();
|
||||
statusMap9.put("id", "Finished");
|
||||
statusMap9.put("label", Translator.get("test_case_status_finished"));
|
||||
|
||||
caseStatusList.add(statusMap1);
|
||||
// caseStatusList.add(statusMap2);
|
||||
// caseStatusList.add(statusMap3);
|
||||
// caseStatusList.add(statusMap4);
|
||||
// caseStatusList.add(statusMap5);
|
||||
// caseStatusList.add(statusMap6);
|
||||
caseStatusList.add(statusMap7);
|
||||
caseStatusList.add(statusMap8);
|
||||
caseStatusList.add(statusMap9);
|
||||
|
||||
Map<String, String> levelMap1 = new HashMap<>();
|
||||
levelMap1.put("id", "P0");
|
||||
levelMap1.put("label", "P0");
|
||||
Map<String, String> levelMap2 = new HashMap<>();
|
||||
levelMap2.put("id", "P1");
|
||||
levelMap2.put("label", "P1");
|
||||
Map<String, String> levelMap3 = new HashMap<>();
|
||||
levelMap3.put("id", "P2");
|
||||
levelMap3.put("label", "P2");
|
||||
Map<String, String> levelMap4 = new HashMap<>();
|
||||
levelMap4.put("id", "P3");
|
||||
levelMap4.put("label", "P3");
|
||||
caseLevelList.add(levelMap1);
|
||||
caseLevelList.add(levelMap2);
|
||||
caseLevelList.add(levelMap3);
|
||||
caseLevelList.add(levelMap4);
|
||||
|
||||
|
||||
if (testCaseTemplate != null && CollectionUtils.isNotEmpty(testCaseTemplate.getCustomFields())) {
|
||||
for (CustomField customField : testCaseTemplate.getCustomFields()) {
|
||||
if (StringUtils.equals(customField.getName(), "用例状态")) {
|
||||
JSONArray optionsArr = JSONArray.parseArray(customField.getOptions());
|
||||
for (int i = 0; i < optionsArr.size(); i++) {
|
||||
JSONObject jsonObject = optionsArr.getJSONObject(i);
|
||||
if (jsonObject.containsKey("value") && jsonObject.containsKey("text")) {
|
||||
String value = jsonObject.getString("value");
|
||||
if(!StringUtils.equalsAnyIgnoreCase(value, "Prepare", "Error", "Success", "Trash", "Underway", "Starting", "Saved",
|
||||
"Completed","test_track.case.status_finished")){
|
||||
Map<String, String> statusMap = new HashMap<>();
|
||||
statusMap.put("id", jsonObject.getString("value"));
|
||||
statusMap.put("label", jsonObject.getString("text"));
|
||||
caseStatusList.add(statusMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(customField.getName(), "用例等级")) {
|
||||
JSONArray optionsArr = JSONArray.parseArray(customField.getOptions());
|
||||
for (int i = 0; i < optionsArr.size(); i++) {
|
||||
JSONObject jsonObject = optionsArr.getJSONObject(i);
|
||||
if (jsonObject.containsKey("value") && jsonObject.containsKey("text") &&
|
||||
!StringUtils.equalsAnyIgnoreCase(jsonObject.getString("value"), "P0", "P1", "P2", "P3")) {
|
||||
Map<String, String> levelMap = new HashMap<>();
|
||||
levelMap.put("id", jsonObject.getString("value"));
|
||||
levelMap.put("label", jsonObject.getString("text"));
|
||||
caseLevelList.add(levelMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> caseDescMap = this.getCaseDescMap();
|
||||
// 组装用例类型
|
||||
List<Map<String, String>> caseTypeList = new ArrayList<>();
|
||||
Map<String, String> caseTypeMap1 = new HashMap<>();
|
||||
caseTypeMap1.put("id", "testCase");
|
||||
caseTypeMap1.put("label", caseDescMap.get("testCaseDesc"));
|
||||
Map<String, String> caseTypeMap2 = new HashMap<>();
|
||||
caseTypeMap2.put("id", "apiCase");
|
||||
caseTypeMap2.put("label", caseDescMap.get("apiCaseDesc"));
|
||||
Map<String, String> caseTypeMap3 = new HashMap<>();
|
||||
caseTypeMap3.put("id", "scenarioCase");
|
||||
caseTypeMap3.put("label", caseDescMap.get("scenarioCaseDesc"));
|
||||
Map<String, String> caseTypeMap4 = new HashMap<>();
|
||||
caseTypeMap4.put("id", "loadCase");
|
||||
caseTypeMap4.put("label", caseDescMap.get("loadCaseDesc"));
|
||||
caseTypeList.add(caseTypeMap1);
|
||||
caseTypeList.add(caseTypeMap2);
|
||||
caseTypeList.add(caseTypeMap3);
|
||||
caseTypeList.add(caseTypeMap4);
|
||||
|
||||
returnMap.put("casetype", caseTypeList);
|
||||
returnMap.put("caselevel", caseLevelList);
|
||||
returnMap.put("casestatus", caseStatusList);
|
||||
returnMap.put("creator", returnUserList);
|
||||
returnMap.put("maintainer", returnUserList);
|
||||
return returnMap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.base.domain.TestPlanPrincipal;
|
||||
import io.metersphere.base.domain.TestPlanPrincipalExample;
|
||||
import io.metersphere.base.mapper.TestPlanPrincipalMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanPrincipalService {
|
||||
|
||||
@Resource
|
||||
private TestPlanPrincipalMapper testPlanPrincipalMapper;
|
||||
|
||||
|
||||
public void deleteTestPlanPrincipalByPlanId(String planId) {
|
||||
if (StringUtils.isBlank(planId)) {
|
||||
return;
|
||||
}
|
||||
TestPlanPrincipalExample example = new TestPlanPrincipalExample();
|
||||
example.createCriteria().andTestPlanIdEqualTo(planId);
|
||||
testPlanPrincipalMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public TestPlanPrincipal insert(TestPlanPrincipal testPlanPrincipal) {
|
||||
testPlanPrincipalMapper.insert(testPlanPrincipal);
|
||||
return testPlanPrincipal;
|
||||
}
|
||||
}
|
|
@ -5,10 +5,7 @@ import com.github.pagehelper.Page;
|
|||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest;
|
||||
import io.metersphere.api.service.ApiAutomationService;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.base.domain.TestPlan;
|
||||
import io.metersphere.base.domain.TestPlanWithBLOBs;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.constants.PermissionConstants;
|
||||
|
@ -107,8 +104,8 @@ public class TestPlanController {
|
|||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_PLAN_READ_EDIT)
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#testPlanDTO.id)", content = "#msClass.getLogDetails(#testPlanDTO.id)", msClass = TestPlanService.class)
|
||||
@SendNotice(taskType = NoticeConstants.TaskType.TEST_PLAN_TASK, event = NoticeConstants.Event.UPDATE, mailTemplate = "track/TestPlanEnd", subject = "测试计划通知")
|
||||
public TestPlan editTestPlan(@RequestBody TestPlanDTO testPlanDTO) {
|
||||
return testPlanService.editTestPlan(testPlanDTO);
|
||||
public TestPlan editTestPlan(@RequestBody AddTestPlanRequest testPlanDTO) {
|
||||
return testPlanService.editTestPlanWithRequest(testPlanDTO);
|
||||
}
|
||||
|
||||
@PostMapping("/edit/status/{planId}")
|
||||
|
@ -259,4 +256,9 @@ public class TestPlanController {
|
|||
public boolean haveExecCase(@PathVariable String id) {
|
||||
return testPlanService.haveExecCase(id);
|
||||
}
|
||||
|
||||
@GetMapping("/principal/{planId}")
|
||||
public List<User> getPlanPrincipal(@PathVariable String planId) {
|
||||
return testPlanService.getPlanPrincipal(planId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper;
|
|||
import io.metersphere.base.domain.LoadTest;
|
||||
import io.metersphere.base.domain.TestPlanLoadCase;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.constants.TriggerMode;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.ResetOrderRequest;
|
||||
|
@ -66,6 +67,11 @@ public class TestPlanLoadCaseController {
|
|||
@PostMapping("/run/batch")
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.EXECUTE, content = "#msClass.getRunLogDetails(#request.requests)", msClass = TestPlanLoadCaseService.class)
|
||||
public void runBatch(@RequestBody RunBatchTestPlanRequest request) {
|
||||
if (request.getRequests() != null) {
|
||||
for (RunTestPlanRequest req : request.getRequests()) {
|
||||
req.setTriggerMode(TriggerMode.BATCH.name());
|
||||
}
|
||||
}
|
||||
testPlanLoadCaseService.runBatch(request);
|
||||
}
|
||||
|
||||
|
@ -81,13 +87,13 @@ public class TestPlanLoadCaseController {
|
|||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.UPDATE, content = "#msClass.getLogDetails(#testPlanLoadCase.id)", msClass = TestPlanLoadCaseService.class)
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.UPDATE, content = "#msClass.getLogDetails(#testPlanLoadCase.id)", msClass = TestPlanLoadCaseService.class)
|
||||
public void update(@RequestBody TestPlanLoadCase testPlanLoadCase) {
|
||||
testPlanLoadCaseService.update(testPlanLoadCase);
|
||||
}
|
||||
|
||||
@PostMapping("/update/api")
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.UPDATE, content = "#msClass.getLogDetails(#testPlanLoadCase.id)", msClass = TestPlanLoadCaseService.class)
|
||||
@MsAuditLog(module = "track_test_plan", type = OperLogConstants.UPDATE, content = "#msClass.getLogDetails(#testPlanLoadCase.id)", msClass = TestPlanLoadCaseService.class)
|
||||
public void updateByApi(@RequestBody TestPlanLoadCase testPlanLoadCase) {
|
||||
testPlanLoadCaseService.updateByApi(testPlanLoadCase);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.base.domain.TestCaseReviewTestCase;
|
|||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.ResetOrderRequest;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||
import io.metersphere.track.request.testplancase.TestReviewCaseBatchRequest;
|
||||
|
@ -75,4 +76,9 @@ public class TestReviewTestCaseController {
|
|||
return testReviewTestCaseService.getTestCaseReviewDTOList(request);
|
||||
}
|
||||
|
||||
@PostMapping("/edit/order")
|
||||
public void orderCase(@RequestBody ResetOrderRequest request) {
|
||||
testReviewTestCaseService.updateOrder(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public class TestPlanDTO extends TestPlanWithBLOBs {
|
|||
private String projectName;
|
||||
private String userName;
|
||||
private List<String> projectIds;
|
||||
|
||||
private List<String> principals;
|
||||
/**
|
||||
* 定时任务ID
|
||||
*/
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jsoup.safety.Whitelist;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
@ -348,4 +349,13 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
.andIssuesIdEqualTo(id);
|
||||
testCaseIssuesMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
protected void addCustomFields(IssuesUpdateRequest issuesRequest, MultiValueMap<String, Object> paramMap) {
|
||||
List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields());
|
||||
customFields.forEach(item -> {
|
||||
if (StringUtils.isNotBlank(item.getCustomData())) {
|
||||
paramMap.add(item.getCustomData(), item.getValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
return issues;
|
||||
}
|
||||
|
||||
public void parseIssue(IssuesWithBLOBs item, JiraIssue jiraIssue) {
|
||||
public void parseIssue(IssuesWithBLOBs item, JiraIssue jiraIssue, String customFieldsStr) {
|
||||
String lastmodify = "";
|
||||
String status = "";
|
||||
JSONObject fields = jiraIssue.getFields();
|
||||
|
@ -89,9 +89,11 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
String description = fields.getString("description");
|
||||
|
||||
Parser parser = Parser.builder().build();
|
||||
Node document = parser.parse(description);
|
||||
HtmlRenderer renderer = HtmlRenderer.builder().build();
|
||||
description = renderer.render(document);
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
Node document = parser.parse(description);
|
||||
HtmlRenderer renderer = HtmlRenderer.builder().build();
|
||||
description = renderer.render(document);
|
||||
}
|
||||
|
||||
if (assignee != null) {
|
||||
lastmodify = assignee.getString("displayName");
|
||||
|
@ -103,6 +105,43 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
item.setDescription(description);
|
||||
item.setPlatformStatus(status);
|
||||
item.setPlatform(IssuesManagePlatform.Jira.toString());
|
||||
item.setCustomFields(parseIssueCustomField(customFieldsStr, jiraIssue));
|
||||
}
|
||||
|
||||
public String parseIssueCustomField(String customFieldsStr, JiraIssue jiraIssue) {
|
||||
List<CustomFieldItemDTO> customFields = getCustomFields(customFieldsStr);
|
||||
JSONObject fields = jiraIssue.getFields();
|
||||
|
||||
customFields.forEach(item -> {
|
||||
String fieldName = item.getCustomData();
|
||||
Object value = fields.get(fieldName);
|
||||
if (value != null) {
|
||||
if (value instanceof JSONObject) {
|
||||
if (!fieldName.equals("assignee") && !fieldName.equals("reporter")) { // 获取不到账号名
|
||||
item.setValue(((JSONObject)value).getString("id"));
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(item.getType()) &&
|
||||
StringUtils.equalsAny(item.getType(), "multipleSelect", "checkbox", "multipleMember")) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if (item.getValue() != null) {
|
||||
JSONArray attrs = (JSONArray) item.getValue();
|
||||
attrs.forEach(attr -> {
|
||||
if (attr instanceof JSONObject) {
|
||||
values.add(((JSONObject)attr).getString("id"));
|
||||
} else {
|
||||
values.add((String) attr);
|
||||
}
|
||||
});
|
||||
}
|
||||
item.setValue(values);
|
||||
} else {
|
||||
item.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return JSONObject.toJSONString(customFields);
|
||||
}
|
||||
|
||||
private String getStatus(JSONObject fields) {
|
||||
|
@ -253,7 +292,7 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
customFields.forEach(item -> {
|
||||
String fieldName = item.getCustomData();
|
||||
if (StringUtils.isNotBlank(fieldName)) {
|
||||
if (StringUtils.isNotBlank(item.getValue())) {
|
||||
if (item.getValue() != null) {
|
||||
if (StringUtils.isNotBlank(item.getType()) &&
|
||||
StringUtils.equalsAny(item.getType(), "select", "radio", "member")) {
|
||||
JSONObject param = new JSONObject();
|
||||
|
@ -266,8 +305,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
} else if (StringUtils.isNotBlank(item.getType()) &&
|
||||
StringUtils.equalsAny(item.getType(), "multipleSelect", "checkbox", "multipleMember")) {
|
||||
JSONArray attrs = new JSONArray();
|
||||
if (StringUtils.isNotBlank(item.getValue())) {
|
||||
JSONArray values = JSONObject.parseArray(item.getValue());
|
||||
if (item.getValue() != null) {
|
||||
JSONArray values = (JSONArray)item.getValue();
|
||||
values.forEach(v -> {
|
||||
JSONObject param = new JSONObject();
|
||||
param.put("id", v);
|
||||
|
@ -327,11 +366,12 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
setConfig();
|
||||
try {
|
||||
IssuesWithBLOBs issuesWithBLOBs = issuesMapper.selectByPrimaryKey(item.getId());
|
||||
parseIssue(item, jiraClientV2.getIssues(item.getId()));
|
||||
parseIssue(item, jiraClientV2.getIssues(item.getId()), issuesWithBLOBs.getCustomFields());
|
||||
String desc = htmlDesc2MsDesc(item.getDescription());
|
||||
// 保留之前上传的图片
|
||||
String images = getImages(issuesWithBLOBs.getDescription());
|
||||
item.setDescription(desc + "\n" + images);
|
||||
|
||||
issuesMapper.updateByPrimaryKeySelective(item);
|
||||
} catch (HttpClientErrorException e) {
|
||||
if (e.getRawStatusCode() == 404) {
|
||||
|
@ -339,6 +379,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
item.setPlatformStatus(IssuesStatus.DELETE.toString());
|
||||
issuesMapper.deleteByPrimaryKey(item.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public class TapdPlatform extends AbstractIssuePlatform {
|
|||
@Override
|
||||
public void addIssue(IssuesUpdateRequest issuesRequest) {
|
||||
|
||||
MultiValueMap<String, String> param = buildUpdateParam(issuesRequest);
|
||||
MultiValueMap<String, Object> param = buildUpdateParam(issuesRequest);
|
||||
TapdBug bug = tapdClient.addIssue(param);
|
||||
Map<String, String> statusMap = tapdClient.getStatusMap(getProjectId(this.projectId));
|
||||
issuesRequest.setPlatformStatus(statusMap.get(bug.getStatus()));
|
||||
|
@ -102,18 +102,16 @@ public class TapdPlatform extends AbstractIssuePlatform {
|
|||
|
||||
@Override
|
||||
public void updateIssue(IssuesUpdateRequest request) {
|
||||
MultiValueMap<String, String> param = buildUpdateParam(request);
|
||||
MultiValueMap<String, Object> param = buildUpdateParam(request);
|
||||
param.add("id", request.getId());
|
||||
handleIssueUpdate(request);
|
||||
tapdClient.updateIssue(param);
|
||||
}
|
||||
|
||||
private MultiValueMap<String, String> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
|
||||
private MultiValueMap<String, Object> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
|
||||
issuesRequest.setPlatform(IssuesManagePlatform.Tapd.toString());
|
||||
setConfig();
|
||||
|
||||
List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields());
|
||||
|
||||
String tapdId = getProjectId(issuesRequest.getProjectId());
|
||||
|
||||
if (StringUtils.isBlank(tapdId)) {
|
||||
|
@ -131,17 +129,14 @@ public class TapdPlatform extends AbstractIssuePlatform {
|
|||
reporter = SessionUtils.getUser().getName();
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
|
||||
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("title", issuesRequest.getTitle());
|
||||
paramMap.add("workspace_id", tapdId);
|
||||
paramMap.add("description", msDescription2Tapd(issuesRequest.getDescription()));
|
||||
paramMap.add("current_owner", usersStr);
|
||||
|
||||
customFields.forEach(item -> {
|
||||
if (StringUtils.isNotBlank(item.getCustomData())) {
|
||||
paramMap.add(item.getCustomData(), item.getValue());
|
||||
}
|
||||
});
|
||||
addCustomFields(issuesRequest, paramMap);
|
||||
|
||||
paramMap.add("reporter", reporter);
|
||||
return paramMap;
|
||||
}
|
||||
|
|
|
@ -204,7 +204,6 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
|
|||
private MultiValueMap<String, Object> buildUpdateParam(IssuesUpdateRequest issuesRequest) {
|
||||
issuesRequest.setPlatform(IssuesManagePlatform.Zentao.toString());
|
||||
|
||||
List<CustomFieldItemDTO> customFields = getCustomFields(issuesRequest.getCustomFields());
|
||||
zentaoClient.setConfig(getUserConfig());
|
||||
String projectId = getProjectId(issuesRequest.getProjectId());
|
||||
if (StringUtils.isBlank(projectId)) {
|
||||
|
@ -214,11 +213,7 @@ public class ZentaoPlatform extends AbstractIssuePlatform {
|
|||
paramMap.add("product", projectId);
|
||||
paramMap.add("title", issuesRequest.getTitle());
|
||||
|
||||
customFields.forEach(item -> {
|
||||
if (StringUtils.isNotBlank(item.getCustomData())) {
|
||||
paramMap.add(item.getCustomData(), item.getValue());
|
||||
}
|
||||
});
|
||||
addCustomFields(issuesRequest, paramMap);
|
||||
|
||||
String description = issuesRequest.getDescription();
|
||||
String zentaoSteps = description;
|
||||
|
|
|
@ -57,9 +57,9 @@ public class TapdClient extends BaseClient {
|
|||
return (TapdGetIssueResponse) getResultForObject(TapdGetIssueResponse.class, response);
|
||||
}
|
||||
|
||||
public TapdBug addIssue(MultiValueMap<String, String> paramMap) {
|
||||
public TapdBug addIssue(MultiValueMap<String, Object> paramMap) {
|
||||
String url = getBaseUrl() + "/bugs";
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(paramMap, getAuthHeader());
|
||||
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(paramMap, getAuthHeader());
|
||||
ResponseEntity<String> response = null;
|
||||
try {
|
||||
response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
|
||||
|
@ -70,7 +70,7 @@ public class TapdClient extends BaseClient {
|
|||
return ((AddTapdIssueResponse) getResultForObject(AddTapdIssueResponse.class, response)).getData().getBug();
|
||||
}
|
||||
|
||||
public TapdBug updateIssue(MultiValueMap<String, String> paramMap) {
|
||||
public TapdBug updateIssue(MultiValueMap<String, Object> paramMap) {
|
||||
// 带id为更新
|
||||
return addIssue(paramMap);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class ZentaoClient extends BaseClient {
|
|||
ResponseEntity<String> response = restTemplate.exchange(loginUrl + sessionId, HttpMethod.POST, requestEntity, String.class);
|
||||
getUserResponse = (GetUserResponse) getResultForObject(GetUserResponse.class, response);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("get result for object error," + e.getMessage());
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(e.getMessage());
|
||||
}
|
||||
GetUserResponse.User user = getUserResponse.getUser();
|
||||
|
|
|
@ -11,5 +11,12 @@ import java.util.List;
|
|||
public class TestCaseMinderEditRequest {
|
||||
private String projectId;
|
||||
private List<String> ids;
|
||||
List<TestCaseWithBLOBs> data;
|
||||
List<TestCaseMinderEditItem> data;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class TestCaseMinderEditItem extends TestCaseWithBLOBs {
|
||||
private String targetId;
|
||||
private String moveMode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,4 +10,5 @@ import java.util.List;
|
|||
@Setter
|
||||
public class AddTestPlanRequest extends TestPlanWithBLOBs {
|
||||
private List<String> projectIds;
|
||||
private List<String> principals;
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestCaseMapper testCaseMapper = sqlSession.getMapper(TestCaseMapper.class);
|
||||
testCases.forEach((value) -> {
|
||||
testCaseMapper.updateByPrimaryKey(value);
|
||||
testCaseMapper.updateByPrimaryKeySelective(value);
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
|
|
@ -294,9 +294,9 @@ public class TestCaseReviewService {
|
|||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestCaseReviewTestCaseMapper batchMapper = sqlSession.getMapper(TestCaseReviewTestCaseMapper.class);
|
||||
|
||||
Long nextOrder = ServiceUtils.getNextOrder(request.getReviewId(), extTestReviewCaseMapper::getLastOrder);
|
||||
if (!testCaseIds.isEmpty()) {
|
||||
testCaseIds.forEach(caseId -> {
|
||||
for (String caseId : testCaseIds) {
|
||||
TestCaseReviewTestCase caseReview = new TestCaseReviewTestCase();
|
||||
caseReview.setId(UUID.randomUUID().toString());
|
||||
caseReview.setReviewer(SessionUtils.getUser().getId());
|
||||
|
@ -306,8 +306,10 @@ public class TestCaseReviewService {
|
|||
caseReview.setUpdateTime(System.currentTimeMillis());
|
||||
caseReview.setReviewId(request.getReviewId());
|
||||
caseReview.setStatus(TestCaseReviewStatus.Prepare.name());
|
||||
caseReview.setOrder(nextOrder);
|
||||
batchMapper.insert(caseReview);
|
||||
});
|
||||
nextOrder += 5000;
|
||||
}
|
||||
}
|
||||
|
||||
sqlSession.flushStatements();
|
||||
|
|
|
@ -1427,7 +1427,7 @@ public class TestCaseService {
|
|||
}
|
||||
|
||||
public void minderEdit(TestCaseMinderEditRequest request) {
|
||||
List<TestCaseWithBLOBs> data = request.getData();
|
||||
List<TestCaseMinderEditRequest.TestCaseMinderEditItem> data = request.getData();
|
||||
if (CollectionUtils.isNotEmpty(data)) {
|
||||
List<String> editIds = data.stream()
|
||||
.filter(t -> StringUtils.isNotBlank(t.getId()) && t.getId().length() > 20)
|
||||
|
@ -1451,12 +1451,14 @@ public class TestCaseService {
|
|||
item.setId(UUID.randomUUID().toString());
|
||||
item.setMaintainer(SessionUtils.getUserId());
|
||||
addTestCase(item);
|
||||
changeOrder(item, request.getProjectId());
|
||||
} else {
|
||||
TestCaseWithBLOBs dbCase = finalTestCaseMap.get(item.getId());
|
||||
if (editCustomFieldsPriority(dbCase, item.getPriority())) {
|
||||
item.setCustomFields(dbCase.getCustomFields());
|
||||
}
|
||||
editTestCase(item);
|
||||
changeOrder(item, request.getProjectId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1468,6 +1470,17 @@ public class TestCaseService {
|
|||
}
|
||||
}
|
||||
|
||||
private void changeOrder(TestCaseMinderEditRequest.TestCaseMinderEditItem item, String projectId) {
|
||||
if (StringUtils.isNotBlank(item.getTargetId())) {
|
||||
ResetOrderRequest resetOrderRequest = new ResetOrderRequest();
|
||||
resetOrderRequest.setGroupId(projectId);
|
||||
resetOrderRequest.setMoveId(item.getId());
|
||||
resetOrderRequest.setTargetId(item.getTargetId());
|
||||
resetOrderRequest.setMoveMode(item.getMoveMode());
|
||||
updateOrder(resetOrderRequest);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 脑图编辑之后修改用例等级,同时修改自定义字段的用例等级
|
||||
*
|
||||
|
@ -1493,7 +1506,7 @@ public class TestCaseService {
|
|||
|
||||
public List<TestCase> getTestCaseByProjectId(String projectId) {
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId);
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andStatusNotEqualTo("Trash");
|
||||
return testCaseMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import io.metersphere.plugin.core.MsTestElement;
|
|||
import io.metersphere.service.IssueTemplateService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.service.TestPlanPrincipalService;
|
||||
import io.metersphere.track.Factory.ReportComponentFactory;
|
||||
import io.metersphere.track.domain.ReportComponent;
|
||||
import io.metersphere.track.dto.*;
|
||||
|
@ -183,6 +184,10 @@ public class TestPlanService {
|
|||
private PerformanceReportService performanceReportService;
|
||||
@Resource
|
||||
private MetricQueryService metricQueryService;
|
||||
@Resource
|
||||
private TestPlanPrincipalService testPlanPrincipalService;
|
||||
@Resource
|
||||
private TestPlanPrincipalMapper testPlanPrincipalMapper;
|
||||
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(20);
|
||||
|
||||
|
@ -194,6 +199,16 @@ public class TestPlanService {
|
|||
testPlan.setCreateTime(System.currentTimeMillis());
|
||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||
testPlan.setCreator(SessionUtils.getUser().getId());
|
||||
|
||||
String planId = testPlan.getId();
|
||||
List<String> principals = testPlan.getPrincipals();
|
||||
for (String principal : principals) {
|
||||
TestPlanPrincipal testPlanPrincipal = new TestPlanPrincipal();
|
||||
testPlanPrincipal.setTestPlanId(planId);
|
||||
testPlanPrincipal.setPrincipalId(principal);
|
||||
testPlanPrincipalService.insert(testPlanPrincipal);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(testPlan.getProjectId())) {
|
||||
testPlan.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
}
|
||||
|
@ -214,6 +229,22 @@ public class TestPlanService {
|
|||
return Optional.ofNullable(testPlanMapper.selectByPrimaryKey(testPlanId)).orElse(new TestPlanWithBLOBs());
|
||||
}
|
||||
|
||||
public TestPlan editTestPlanWithRequest(AddTestPlanRequest request) {
|
||||
List<String> principals = request.getPrincipals();
|
||||
if (!CollectionUtils.isEmpty(principals)) {
|
||||
if (StringUtils.isNotBlank(request.getId())) {
|
||||
testPlanPrincipalService.deleteTestPlanPrincipalByPlanId(request.getId());
|
||||
for (String principal : principals) {
|
||||
TestPlanPrincipal testPlanPrincipal = new TestPlanPrincipal();
|
||||
testPlanPrincipal.setTestPlanId(request.getId());
|
||||
testPlanPrincipal.setPrincipalId(principal);
|
||||
testPlanPrincipalService.insert(testPlanPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.editTestPlan(request);
|
||||
}
|
||||
|
||||
public TestPlan editTestPlan(TestPlanWithBLOBs testPlan) {
|
||||
checkTestPlanExist(testPlan);
|
||||
TestPlan res = testPlanMapper.selectByPrimaryKey(testPlan.getId()); // 先查一次库
|
||||
|
@ -317,7 +348,7 @@ public class TestPlanService {
|
|||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria()
|
||||
.andNameEqualTo(testPlan.getName())
|
||||
.andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||
.andProjectIdEqualTo(testPlan.getProjectId())
|
||||
.andIdNotEqualTo(testPlan.getId());
|
||||
if (testPlanMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("plan_name_already_exists"));
|
||||
|
@ -326,6 +357,7 @@ public class TestPlanService {
|
|||
}
|
||||
|
||||
public int deleteTestPlan(String planId) {
|
||||
testPlanPrincipalService.deleteTestPlanPrincipalByPlanId(planId);
|
||||
deleteTestCaseByPlanId(planId);
|
||||
testPlanApiCaseService.deleteByPlanId(planId);
|
||||
testPlanScenarioCaseService.deleteByPlanId(planId);
|
||||
|
@ -1243,7 +1275,6 @@ public class TestPlanService {
|
|||
targetPlan.setWorkspaceId(testPlan.getWorkspaceId());
|
||||
targetPlan.setDescription(testPlan.getDescription());
|
||||
targetPlan.setStage(testPlan.getStage());
|
||||
targetPlan.setPrincipal(testPlan.getPrincipal());
|
||||
targetPlan.setTags(testPlan.getTags());
|
||||
targetPlan.setProjectId(testPlan.getProjectId());
|
||||
testPlan.setAutomaticStatusUpdate(testPlan.getAutomaticStatusUpdate());
|
||||
|
@ -1253,11 +1284,26 @@ public class TestPlanService {
|
|||
targetPlan.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanMapper.insert(targetPlan);
|
||||
|
||||
copyPlanPrincipal(targetPlanId, planId);
|
||||
copyPlanCase(sourcePlanId, targetPlanId);
|
||||
|
||||
return targetPlan;
|
||||
}
|
||||
|
||||
private void copyPlanPrincipal(String targetPlanId, String sourcePlanId) {
|
||||
TestPlanPrincipalExample example = new TestPlanPrincipalExample();
|
||||
example.createCriteria().andTestPlanIdEqualTo(sourcePlanId);
|
||||
List<TestPlanPrincipal> testPlanPrincipals = testPlanPrincipalMapper.selectByExample(example);
|
||||
if (!CollectionUtils.isEmpty(testPlanPrincipals)) {
|
||||
for (TestPlanPrincipal tpp : testPlanPrincipals) {
|
||||
TestPlanPrincipal testPlanPrincipal = new TestPlanPrincipal();
|
||||
testPlanPrincipal.setPrincipalId(tpp.getPrincipalId());
|
||||
testPlanPrincipal.setTestPlanId(targetPlanId);
|
||||
testPlanPrincipalMapper.insert(testPlanPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void copyPlanCase(String sourcePlanId, String targetPlanId) {
|
||||
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||
|
@ -1992,4 +2038,21 @@ public class TestPlanService {
|
|||
List<TestPlanLoadCase> testPlanLoadCases = testPlanLoadCaseMapper.selectByExample(loadCaseExample);
|
||||
return !CollectionUtils.isEmpty(testPlanLoadCases);
|
||||
}
|
||||
|
||||
public List<User> getPlanPrincipal(String planId) {
|
||||
List<User> result = new ArrayList<>();
|
||||
if (StringUtils.isBlank(planId)) {
|
||||
return result;
|
||||
}
|
||||
TestPlanPrincipalExample example = new TestPlanPrincipalExample();
|
||||
example.createCriteria().andTestPlanIdEqualTo(planId);
|
||||
List<TestPlanPrincipal> testPlanPrincipals = testPlanPrincipalMapper.selectByExample(example);
|
||||
List<String> userIds = testPlanPrincipals.stream().map(TestPlanPrincipal::getPrincipalId).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(userIds)) {
|
||||
return result;
|
||||
}
|
||||
UserExample userExample = new UserExample();
|
||||
userExample.createCriteria().andIdIn(userIds);
|
||||
return userMapper.selectByExample(userExample);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue