diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index 78b90cec9f..82e2ec81e8 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -314,11 +314,7 @@ public class APITestController { apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber); //统计 失败 成功 以及总数 -// List api_allExecuteResult = apiReportService.countByProjectIdGroupByExecuteResult(projectId); List allExecuteResult = apiScenarioReportService.countByProjectIdGroupByExecuteResult(projectId); -// List allExecuteResult = new ArrayList<>(); -// allExecuteResult.addAll(api_allExecuteResult); -// allExecuteResult.addAll(scene_allExecuteResult); apiCountResult.countScheduleExecute(allExecuteResult); long allCount = apiCountResult.getExecutedCount(); diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index 2ce942c37f..254a6083c9 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -6,8 +6,6 @@ import io.metersphere.api.dto.APIReportResult; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.automation.ApiScenarioRequest; import io.metersphere.api.dto.automation.ReferenceDTO; -import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest; -import io.metersphere.api.dto.datacount.response.TaskInfoResult; import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest; @@ -216,4 +214,6 @@ public class ApiDefinitionController { public String preview(@RequestBody String jsonSchema) { return JSONSchemaGenerator.getJson(jsonSchema); } + + } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java index 8c28f72bbc..7566659b14 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java @@ -33,4 +33,6 @@ public class ApiBatchRequest extends ApiDefinitionWithBLOBs { private List unSelectIds; + private String moduleId; + } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java index de6e1b6356..19515769ad 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java @@ -95,7 +95,7 @@ public class MsScenario extends MsTestElement { } // 场景变量和环境变量 tree.add(arguments(config)); - this.addCsvDataSet(tree, variables); + //this.addCsvDataSet(tree, variables); this.addCounter(tree, variables); this.addRandom(tree, variables); if (CollectionUtils.isNotEmpty(hashTree)) { diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java index 69d573f617..7052e1df60 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java @@ -100,6 +100,8 @@ public abstract class MsTestElement { private String refType; @JSONField(ordinal = 10) private LinkedList hashTree; + @JSONField(ordinal = 11) + private boolean customizeReq; private MsTestElement parent; @@ -192,15 +194,16 @@ public abstract class MsTestElement { csvDataSet.setEnabled(true); csvDataSet.setProperty(TestElement.TEST_CLASS, CSVDataSet.class.getName()); csvDataSet.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); - csvDataSet.setName(item.getName()); - csvDataSet.setProperty("fileEncoding", item.getEncoding()); - csvDataSet.setProperty("variableNames", item.getName()); + csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName()); + csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding()); if (CollectionUtils.isNotEmpty(item.getFiles())) { csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName()); } csvDataSet.setIgnoreFirstLine(false); + csvDataSet.setRecycle(true); + csvDataSet.setProperty("recycle", true); csvDataSet.setProperty("delimiter", item.getDelimiter()); - csvDataSet.setComment(item.getDescription()); + csvDataSet.setComment(StringUtils.isEmpty(item.getDescription()) ? "" : item.getDescription()); tree.add(csvDataSet); }); } @@ -222,7 +225,7 @@ public abstract class MsTestElement { counterConfig.setVarName(item.getName()); counterConfig.setIncrement(item.getIncrement()); counterConfig.setFormat(item.getValue()); - counterConfig.setComment(item.getDescription()); + counterConfig.setComment(StringUtils.isEmpty(item.getDescription()) ? "" : item.getDescription()); tree.add(counterConfig); }); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertionJSR223.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertionJSR223.java index 110741291c..1b523ed774 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertionJSR223.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertionJSR223.java @@ -13,13 +13,13 @@ public class MsAssertionJSR223 extends MsAssertionType { private String desc; private String name; private String script; - private String language; + private String scriptLanguage; public MsAssertionJSR223() { setType(MsAssertionType.JSR223); } public boolean isValid() { - return StringUtils.isNotBlank(script) && StringUtils.isNotBlank(language); + return StringUtils.isNotBlank(script) && StringUtils.isNotBlank(scriptLanguage); } } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java index 842e0acab8..032e6fe607 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java @@ -6,6 +6,7 @@ import io.metersphere.api.dto.definition.request.ParameterConfig; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.assertions.*; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -89,7 +90,7 @@ public class MsAssertions extends MsTestElement { private JSONPathAssertion jsonPathAssertion(MsAssertionJsonPath assertionJsonPath) { JSONPathAssertion assertion = new JSONPathAssertion(); assertion.setEnabled(true); - assertion.setName(assertionJsonPath.getDescription()); + assertion.setName(StringUtils.isEmpty(assertionJsonPath.getDescription()) ? "JSONPathAssertion" : assertionJsonPath.getDescription()); assertion.setProperty(TestElement.TEST_CLASS, JSONPathAssertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPathAssertionGui")); assertion.setJsonPath(assertionJsonPath.getExpression()); @@ -104,7 +105,7 @@ public class MsAssertions extends MsTestElement { private XPath2Assertion xPath2Assertion(MsAssertionXPath2 assertionXPath2) { XPath2Assertion assertion = new XPath2Assertion(); assertion.setEnabled(true); - assertion.setName(assertionXPath2.getExpression()); + assertion.setName(StringUtils.isEmpty(assertionXPath2.getExpression()) ? "XPath2Assertion" : assertionXPath2.getExpression()); assertion.setProperty(TestElement.TEST_CLASS, XPath2Assertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2AssertionGui")); assertion.setXPathString(assertionXPath2.getExpression()); @@ -125,11 +126,11 @@ public class MsAssertions extends MsTestElement { private JSR223Assertion jsr223Assertion(MsAssertionJSR223 assertionJSR223) { JSR223Assertion assertion = new JSR223Assertion(); assertion.setEnabled(true); - assertion.setName(assertionJSR223.getDesc()); + assertion.setName(StringUtils.isEmpty(assertionJSR223.getDesc()) ? "JSR223Assertion" : assertionJSR223.getDesc()); assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); assertion.setProperty("cacheKey", "true"); - assertion.setProperty("scriptLanguage", assertionJSR223.getLanguage()); + assertion.setProperty("scriptLanguage", assertionJSR223.getScriptLanguage()); assertion.setProperty("script", assertionJSR223.getScript()); return assertion; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java index 61a22081cf..acbfa04709 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java @@ -42,10 +42,10 @@ public class MsIfController extends MsTestElement { private IfController ifController() { IfController ifController = new IfController(); ifController.setEnabled(true); - ifController.setName(this.getLabelName()); - ifController.setCondition(this.getCondition()); + ifController.setName(StringUtils.isEmpty(this.getName()) ? "IfController" : this.getName()); ifController.setProperty(TestElement.TEST_CLASS, IfController.class.getName()); ifController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("IfControllerPanel")); + ifController.setCondition(this.getCondition()); ifController.setEvaluateAll(false); ifController.setUseExpression(true); return ifController; @@ -79,13 +79,13 @@ public class MsIfController extends MsTestElement { } if (StringUtils.equals(operator, "is empty")) { - variable = "empty(" + variable + ")"; + variable = "!empty(" + variable + ")"; operator = ""; value = ""; } if (StringUtils.equals(operator, "is not empty")) { - variable = "!empty(" + variable + ")"; + variable = "empty(" + variable + ")"; operator = ""; value = ""; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java index e82c9b07bb..3d05319d2b 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java @@ -123,13 +123,13 @@ public class MsLoopController extends MsTestElement { } if (StringUtils.equals(operator, "is empty")) { - variable = "empty(" + variable + ")"; + variable = "!empty(" + variable + ")"; operator = ""; value = ""; } if (StringUtils.equals(operator, "is not empty")) { - variable = "!empty(" + variable + ")"; + variable = "empty(" + variable + ")"; operator = ""; value = ""; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java index 295890e786..28a78a6e4c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java @@ -57,7 +57,7 @@ public class MsExtract extends MsTestElement { if (Optional.ofNullable(extract).orElse(extract).length() > 0) { JSR223PostProcessor shell = new JSR223PostProcessor(); shell.setEnabled(true); - shell.setName(this.getName()); + shell.setName(StringUtils.isEmpty(this.getName()) ? "JSR223PostProcessor" : this.getName()); shell.setProperty(TestElement.TEST_CLASS, JSR223PostProcessor.class.getName()); shell.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); shell.setProperty("script", "io.metersphere.api.jmeter.JMeterVars.addVars(prev.hashCode(),vars," + "\"" + extract.toString() + "\"" + ");"); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index 702d3326a4..4e35756c1a 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -207,14 +207,17 @@ public class MsHTTPSamplerProxy extends MsTestElement { } final HashTree httpSamplerTree = tree.add(sampler); + + // 注意顺序,放在config前面,会优先于环境的请求头生效 + if (CollectionUtils.isNotEmpty(this.headers)) { + setHeader(httpSamplerTree, this.headers); + } + // 通用请求Headers if (config != null && config.getConfig() != null && config.getConfig().getHttpConfig() != null && CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) { setHeader(httpSamplerTree, config.getConfig().getHttpConfig().getHeaders()); } - if (CollectionUtils.isNotEmpty(this.headers)) { - setHeader(httpSamplerTree, this.headers); - } //判断是否要开启DNS if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null @@ -287,6 +290,9 @@ public class MsHTTPSamplerProxy extends MsTestElement { Arguments arguments = new Arguments(); list.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> { HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), StringUtils.isNotEmpty(keyValue.getValue()) && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue()); + if (keyValue.getValue() == null) { + httpArgument.setValue(""); + } httpArgument.setAlwaysEncoded(keyValue.isEncode()); if (StringUtils.isNotBlank(keyValue.getContentType())) { httpArgument.setContentType(keyValue.getContentType()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index 3eb20a8b99..dcd0bb5f19 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -96,7 +96,7 @@ public class MsJDBCSampler extends MsTestElement { private Arguments arguments(String name, List variables) { Arguments arguments = new Arguments(); - if (!variables.isEmpty()) { + if (CollectionUtils.isNotEmpty(variables)) { arguments.setEnabled(true); arguments.setName(name); arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java index 50c790534b..0e0031ace9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java @@ -12,6 +12,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Arguments; import org.apache.jmeter.config.ConfigTestElement; import org.apache.jmeter.modifiers.UserParameters; import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; @@ -79,6 +80,13 @@ public class MsTCPSampler extends MsTestElement { } config.setConfig(getEnvironmentConfig(useEnvironment)); parseEnvironment(config.getConfig()); + + // 添加环境中的公共变量 + Arguments arguments = this.addArguments(config); + if (arguments != null) { + tree.add(this.addArguments(config)); + } + final HashTree samplerHashTree = new ListedHashTree(); samplerHashTree.add(tcpConfig()); tree.set(tcpSampler(config), samplerHashTree); @@ -94,7 +102,7 @@ public class MsTCPSampler extends MsTestElement { } private void parseEnvironment(EnvironmentConfig config) { - if (config != null && config.getTcpConfig() != null) { + if (!isCustomizeReq() && config != null && config.getTcpConfig() != null) { this.server = config.getTcpConfig().getServer(); this.port = config.getTcpConfig().getPort(); } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 262036e359..3923ea49e6 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -2,6 +2,7 @@ package io.metersphere.api.jmeter; import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.service.*; +import io.metersphere.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiScenarioReport; import io.metersphere.base.domain.ApiTestReport; import io.metersphere.commons.constants.*; @@ -177,10 +178,17 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl } else if (StringUtils.equals(this.runMode, ApiRunMode.JENKINS.name())) { apiDefinitionService.addResult(testResult); apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.DEFINITION.name()); - apiTestService.changeStatus(testId, APITestStatus.Completed); - report = apiReportService.getRunningReport(testResult.getTestId()); - apiReportService.complete(testResult, report); + + } else if (StringUtils.equals(this.runMode, ApiRunMode.JENKINS_API_PLAN.name())) { + apiDefinitionService.addResult(testResult); apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name()); + ApiDefinitionExecResult result = new ApiDefinitionExecResult(); + result = apiDefinitionService.getResultByJenkins(debugReportId, ApiRunMode.API_PLAN.name()); + report = new ApiTestReport(); + report.setStatus(result.getStatus()); + report.setId(result.getId()); + report.setTriggerMode(ApiRunMode.API.name()); + report.setName(apiDefinitionService.getApiCaseInfo(testId).getName()); } else if (StringUtils.equalsAny(this.runMode, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name())) { apiDefinitionService.addResult(testResult); @@ -264,9 +272,15 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl 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 paramMap = new HashMap<>(); paramMap.put("testName", report.getName()); paramMap.put("id", report.getId()); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java index c8914871e7..77cdebca8b 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -60,6 +60,18 @@ public class TestResult { item.getSubRequestResults().forEach(subItem -> { subItem.setName(item.getName()); }); + } else { + if (requestResultMap.containsKey(result.getName())) { + requestResultMap.get(result.getName()).add(item); + } else { + List requestResults = new LinkedList<>(); + requestResults.add(item); + requestResultMap.put(result.getName(), requestResults); + } + item.getSubRequestResults().forEach(subItem -> { + subItem.setName(item.getName()); + }); + } }); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index f9d1779d31..2decf1ba4a 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -117,6 +117,15 @@ public class ApiAutomationService { if (setDefultOrders) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); } + if (StringUtils.isNotEmpty(request.getExecuteStatus())) { + Map> statusFilter = new HashMap<>(); + List list = new ArrayList<>(); + list.add("Prepare"); + list.add("Underway"); + list.add("Completed"); + statusFilter.put("status", list); + request.setFilters(statusFilter); + } if (checkThisWeekData) { if (request.isSelectThisWeedData()) { Map weekFirstTimeAndLastTime = DateUtils.getWeedFirstTimeAndLastTime(new Date()); @@ -387,7 +396,7 @@ public class ApiAutomationService { try { boolean isFirst = true; for (ApiScenarioWithBLOBs item : apiScenarios) { - if (item.getStepTotal() == 0) { + if (item.getStepTotal() == null || item.getStepTotal() == 0) { // 只有一个场景且没有测试步骤,则提示 if (apiScenarios.size() == 1) { MSException.throwException((item.getName() + "," + Translator.get("automation_exec_info"))); @@ -464,6 +473,8 @@ public class ApiAutomationService { ids = this.getAllScenarioIdsByFontedSelect( request.getModuleIds(), request.getName(), request.getProjectId(), request.getFilters(), request.getUnSelectIds()); } + //检查是否有正在执行中的情景 + this.checkScenarioIsRunnng(ids); List apiScenarios = extApiScenarioMapper.selectIds(ids); String runMode = ApiRunMode.SCENARIO.name(); @@ -480,6 +491,15 @@ public class ApiAutomationService { return request.getId(); } + public void checkScenarioIsRunnng(List ids) { + List lastReportStatusByIds = apiReportService.selectLastReportByIds(ids); + for (ApiScenarioReport report : lastReportStatusByIds) { + if (StringUtils.equals(report.getStatus(), APITestStatus.Running.name())) { + MSException.throwException(report.getName() + " Is Running!"); + } + } + } + /** * 获取前台查询条件查询的所有(未经分页筛选)数据ID * @@ -722,7 +742,9 @@ public class ApiAutomationService { apiScenarios.forEach(item -> { JSONObject object = JSONObject.parseObject(item.getScenarioDefinition()); object.put("environmentId", request.getEnvironmentId()); - item.setScenarioDefinition(JSONObject.toJSONString(object)); + if (object != null) { + item.setScenarioDefinition(JSONObject.toJSONString(object)); + } apiScenarioMapper.updateByPrimaryKeySelective(item); }); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 390043a1ff..66143cb04d 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -82,6 +82,8 @@ public class ApiDefinitionService { private ExtSwaggerUrlScheduleMapper extSwaggerUrlScheduleMapper; @Resource private ScheduleMapper scheduleMapper; + @Resource + private ApiTestCaseMapper apiTestCaseMapper; private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); @@ -348,7 +350,8 @@ public class ApiDefinitionService { private String setImportHashTree(ApiDefinitionWithBLOBs apiDefinition) { String request = apiDefinition.getRequest(); MsHTTPSamplerProxy msHTTPSamplerProxy = JSONObject.parseObject(request, MsHTTPSamplerProxy.class); - msHTTPSamplerProxy.setHashTree(null); + msHTTPSamplerProxy.setId(apiDefinition.getId()); + msHTTPSamplerProxy.setHashTree(new LinkedList<>()); apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy)); return request; } @@ -468,6 +471,14 @@ public class ApiDefinitionService { return buildAPIReportResult(result); } + public ApiDefinitionExecResult getResultByJenkins(String testId, String type) { + return extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(testId, type); + } + + public ApiTestCaseWithBLOBs getApiCaseInfo(String apiCaseId) { + return apiTestCaseMapper.selectByPrimaryKey(apiCaseId); + } + public ApiDefinitionImport apiTestImport(MultipartFile file, ApiTestImportRequest request) { ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 6c945f5d2e..7469f8a987 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -415,4 +415,12 @@ public class ApiScenarioReportService { public List countByProjectIdGroupByExecuteResult(String projectId) { return extApiScenarioReportMapper.countByProjectIdGroupByExecuteResult(projectId); } + + public List selectLastReportByIds(List ids) { + if(!ids.isEmpty()){ + return extApiScenarioReportMapper.selectLastReportByIds(ids); + }else { + return new ArrayList<>(0); + } + } } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index f612b84f64..6ccaf75c36 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -473,7 +473,7 @@ public class ApiTestCaseService { String runMode = ApiRunMode.JENKINS.name(); */ // 调用执行方法 - jMeterService.runDefinition(request.getReportId(), jmeterHashTree, request.getReportId(), request.getRunMode()); + jMeterService.runDefinition(request.getCaseId(), jmeterHashTree, request.getReportId(), request.getRunMode()); } catch (Exception ex) { LogUtil.error(ex.getMessage()); diff --git a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java index 0e0d55f483..0033018d34 100644 --- a/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java +++ b/backend/src/main/java/io/metersphere/api/service/HistoricalDataUpgradeService.java @@ -171,12 +171,16 @@ public class HistoricalDataUpgradeService { element = new MsJDBCSampler(); SqlRequest request1 = (SqlRequest) request; BeanUtils.copyBean(element, request1); + EnvironmentDTO dto = environmentDTOMap.get(request1.getDataSource()); if (dto != null) { ((MsJDBCSampler) element).setEnvironmentId(dto.getEnvironmentId()); ((MsJDBCSampler) element).setDataSourceId(dto.getDatabaseConfig().getId()); ((MsJDBCSampler) element).setDataSource(dto.getDatabaseConfig()); } + if (CollectionUtils.isEmpty(request1.getVariables())) { + ((MsJDBCSampler) element).setVariables(new ArrayList<>()); + } element.setType("JDBCSampler"); } if (request instanceof TCPRequest) { diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index 415d22029b..7dce263d4f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -304,7 +304,7 @@ diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java index 425ec646de..8fd7e161be 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java @@ -3,6 +3,7 @@ package io.metersphere.base.mapper.ext; import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.datacount.ApiDataCountResult; +import io.metersphere.base.domain.ApiScenarioReport; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -20,4 +21,6 @@ public interface ExtApiScenarioReportMapper { long countByProjectIdAndCreateAndByScheduleInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp); List countByProjectIdGroupByExecuteResult(String projectId); + + List selectLastReportByIds(@Param("scenarioIdList") List ids); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml index 8acd2c9948..5a552d03e3 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml @@ -194,4 +194,26 @@ WHERE acr.project_id = #{projectId} AND ar.trigger_mode = 'SCHEDULE' GROUP BY groupField; + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml index fb5e0b81ba..c1676447e5 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml @@ -4,10 +4,12 @@ @@ -393,4 +393,8 @@ border-left: 4px solid #783887; margin: 0px 0px 10px; } + .ms-transform { + transform: rotate(-180deg); + transition: 0ms; + } diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 1257af30cd..13a512d91e 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -293,12 +293,12 @@ export default { }; this.result = this.$request(config).then(response => { const content = response.data; - const blob = new Blob([content]); + const blob = new Blob([content], {type: "application/octet-stream"}); if ("download" in document.createElement("a")) { // 非IE下载 // chrome/firefox let aTag = document.createElement('a'); - aTag.download = this.reportId + ".jtl"; + aTag.download = this.reportId + ".zip"; aTag.href = URL.createObjectURL(blob); aTag.click(); URL.revokeObjectURL(aTag.href) diff --git a/frontend/src/business/components/performance/report/PerformanceTestReport.vue b/frontend/src/business/components/performance/report/PerformanceTestReport.vue index 8034e345ea..8e46a0708d 100644 --- a/frontend/src/business/components/performance/report/PerformanceTestReport.vue +++ b/frontend/src/business/components/performance/report/PerformanceTestReport.vue @@ -93,13 +93,15 @@ import MsTablePagination from "../../common/pagination/TablePagination"; import MsContainer from "../../common/components/MsContainer"; import MsMainContainer from "../../common/components/MsMainContainer"; import MsPerformanceReportStatus from "./PerformanceReportStatus"; -import {_filter, _sort, getCurrentProjectID} from "../../../../common/js/utils"; +import {getCurrentProjectID} from "../../../../common/js/utils"; import MsTableOperatorButton from "../../common/components/MsTableOperatorButton"; import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem"; import {REPORT_CONFIGS} from "../../common/components/search/search-components"; import MsTableHeader from "../../common/components/MsTableHeader"; import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent"; import ShowMoreBtn from "../../track/case/components/ShowMoreBtn"; +import {_filter, _sort} from "@/common/js/tableUtils"; + export default { name: "PerformanceTestReport", diff --git a/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue b/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue index ee34766b45..234783b9d2 100644 --- a/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue +++ b/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue @@ -14,11 +14,11 @@ + :disabled="true" + :placeholder="$t('load_test.input_thread_num')" + v-model="threadGroup.threadNumber" + :min="1" + size="mini"/>
@@ -31,72 +31,72 @@
+ :disabled="true" + v-model="threadGroup.duration" + :min="1" + @change="calculateChart(threadGroup)" + size="mini"/>
  + :disabled="true " + v-model="threadGroup.rpsLimit" + @change="calculateChart(threadGroup)" + :min="1" + size="mini"/>
+ :disabled="true" + :min="1" + :max="threadGroup.duration" + v-model="threadGroup.rampUpTime" + @change="calculateChart(threadGroup)" + size="mini"/> + :disabled="true" + :min="1" + :max="Math.min(threadGroup.threadNumber, threadGroup.rampUpTime)" + v-model="threadGroup.step" + @change="calculateChart(threadGroup)" + size="mini"/>
+ :disabled="true" + v-model="threadGroup.iterateNum" + :min="1" + @change="calculateChart(threadGroup)" + size="mini"/>
  + :disabled="true || !threadGroup.rpsLimitEnable" + v-model="threadGroup.rpsLimit" + @change="calculateChart(threadGroup)" + :min="1" + size="mini"/>
+ :disabled="true" + :min="1" + v-model="threadGroup.iterateRampUp" + @change="calculateChart(threadGroup)" + size="mini"/>
@@ -129,11 +129,11 @@ const ITERATE_RAMP_UP = "iterateRampUpTime"; const hexToRgba = function (hex, opacity) { return 'rgba(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5)) + ',' - + parseInt('0x' + hex.slice(5, 7)) + ',' + opacity + ')'; + + parseInt('0x' + hex.slice(5, 7)) + ',' + opacity + ')'; } const hexToRgb = function (hex) { return 'rgb(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5)) - + ',' + parseInt('0x' + hex.slice(5, 7)) + ')'; + + ',' + parseInt('0x' + hex.slice(5, 7)) + ')'; } export default { @@ -469,11 +469,12 @@ export default { }, }, watch: { - 'report.testId': { + report: { handler() { this.getJmxContent(); }, - } + deep: true + }, } } diff --git a/frontend/src/business/components/performance/test/PerformanceTestList.vue b/frontend/src/business/components/performance/test/PerformanceTestList.vue index 0b3af35206..5090c4a609 100644 --- a/frontend/src/business/components/performance/test/PerformanceTestList.vue +++ b/frontend/src/business/components/performance/test/PerformanceTestList.vue @@ -89,11 +89,12 @@ import MsContainer from "../../common/components/MsContainer"; import MsMainContainer from "../../common/components/MsMainContainer"; import MsPerformanceTestStatus from "./PerformanceTestStatus"; import MsTableOperators from "../../common/components/MsTableOperators"; -import {_filter, _sort, getCurrentProjectID} from "@/common/js/utils"; +import {getCurrentProjectID} from "@/common/js/utils"; import MsTableHeader from "../../common/components/MsTableHeader"; import {TEST_CONFIGS} from "../../common/components/search/search-components"; import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent"; import {WORKSPACE_ID} from "@/common/js/constants"; +import {_filter, _sort} from "@/common/js/tableUtils"; export default { components: { diff --git a/frontend/src/business/components/performance/test/components/PerformanceAdvancedConfig.vue b/frontend/src/business/components/performance/test/components/PerformanceAdvancedConfig.vue index 023fa1bad2..6c6348bc68 100644 --- a/frontend/src/business/components/performance/test/components/PerformanceAdvancedConfig.vue +++ b/frontend/src/business/components/performance/test/components/PerformanceAdvancedConfig.vue @@ -128,7 +128,7 @@ export default { components: {MsTableOperatorButton}, data() { return { - timeout: 2000, + timeout: 60000, responseTimeout: null, statusCode: [], domains: [], diff --git a/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue b/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue index 44dfbfb158..f26c83f681 100644 --- a/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue +++ b/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue @@ -10,8 +10,9 @@ @@ -506,7 +507,6 @@ .member-size { text-decoration: underline; - cursor: pointer; } .select-width { diff --git a/frontend/src/business/components/settings/personal/PersonSetting.vue b/frontend/src/business/components/settings/personal/PersonSetting.vue index 79ce46bc13..6bbf92a0f3 100644 --- a/frontend/src/business/components/settings/personal/PersonSetting.vue +++ b/frontend/src/business/components/settings/personal/PersonSetting.vue @@ -114,9 +114,7 @@ export default { } ], phone: [ - {required: true, message: this.$t('user.input_phone'), trigger: 'blur'}, { - required: false, pattern: PHONE_REGEX, message: this.$t('member.mobile_number_format_is_incorrect'), trigger: 'blur' diff --git a/frontend/src/business/components/settings/project/MsProject.vue b/frontend/src/business/components/settings/project/MsProject.vue index ac1bc85cc5..1f111a35cc 100644 --- a/frontend/src/business/components/settings/project/MsProject.vue +++ b/frontend/src/business/components/settings/project/MsProject.vue @@ -92,33 +92,35 @@