From 93d57b7d1fa34c43abdc2128002379a6bf274f80 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Mon, 11 Jan 2021 18:50:12 +0800 Subject: [PATCH 01/11] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E5=A4=8D=E6=B5=8B=E8=AF=95=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=EF=BC=8C=E6=8C=89=E7=85=A7=E5=9C=BA=E6=99=AF=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/request/MsScenario.java | 2 ++ .../definition/request/ParameterConfig.java | 4 +++ .../request/sampler/MsDubboSampler.java | 21 ++++------- .../request/sampler/MsHTTPSamplerProxy.java | 4 +++ .../request/sampler/MsJDBCSampler.java | 7 ++-- .../request/sampler/MsTCPSampler.java | 9 +++-- .../api/jmeter/ScenarioResult.java | 2 +- .../io/metersphere/api/jmeter/TestResult.java | 36 +++++++++++++++++-- .../api/service/ApiAutomationService.java | 6 ++-- .../api/service/ApiScenarioReportService.java | 24 +++++++------ 10 files changed, 78 insertions(+), 37 deletions(-) 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 5d576dece2..d76439cb5f 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 @@ -58,6 +58,8 @@ public class MsScenario extends MsTestElement { if (!this.isEnable()) { return; } + config.setStep(this.name); + config.setEnableCookieShare(enableCookieShare); if (StringUtils.isNotEmpty(environmentId)) { ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java index 9f790cc7a9..6f75a54fb6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/ParameterConfig.java @@ -14,5 +14,9 @@ public class ParameterConfig { private List variables; // 公共Cookie private boolean enableCookieShare; + // 步骤 + private String step; + + private final String stepType = "STEP_GROUP"; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java index 432d3e73e8..5ed1ae4cdd 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java @@ -15,6 +15,7 @@ import io.metersphere.api.dto.scenario.KeyValue; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.config.ConfigTestElement; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -64,7 +65,7 @@ public class MsDubboSampler extends MsTestElement { this.getRefElement(this); } - final HashTree testPlanTree = tree.add(dubboSample()); + final HashTree testPlanTree = tree.add(dubboSample(config)); if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { el.toHashTree(testPlanTree, el.getHashTree(), config); @@ -72,9 +73,12 @@ public class MsDubboSampler extends MsTestElement { } } - private DubboSample dubboSample() { + private DubboSample dubboSample(ParameterConfig config) { DubboSample sampler = new DubboSample(); sampler.setName(this.getName()); + if (config != null && StringUtils.isNotEmpty(config.getStep())) { + sampler.setName(this.getName() + "<->" + config.getStep()); + } sampler.setProperty(TestElement.TEST_CLASS, DubboSample.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DubboSampleGui")); @@ -97,19 +101,6 @@ public class MsDubboSampler extends MsTestElement { return sampler; } - - private ConfigTestElement dubboConfig() { - ConfigTestElement configTestElement = new ConfigTestElement(); - configTestElement.setEnabled(true); - configTestElement.setName(this.getName()); - configTestElement.setProperty(TestElement.TEST_CLASS, ConfigTestElement.class.getName()); - configTestElement.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DubboDefaultConfigGui")); - configTestElement.addConfigElement(configCenter(this.getConfigCenter())); - configTestElement.addConfigElement(registryCenter(this.getRegistryCenter())); - configTestElement.addConfigElement(consumerAndService(this.getConsumerAndService())); - return configTestElement; - } - private ConfigTestElement configCenter(MsConfigCenter configCenter) { ConfigTestElement configTestElement = new ConfigTestElement(); if (configCenter != null && configCenter.getProtocol() != null && configCenter.getUsername() != null && configCenter.getPassword() != null) { 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 967bedb446..b8e22b101b 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 @@ -99,6 +99,10 @@ public class MsHTTPSamplerProxy extends MsTestElement { HTTPSamplerProxy sampler = new HTTPSamplerProxy(); sampler.setEnabled(true); sampler.setName(this.getName()); + if (config != null && StringUtils.isNotEmpty(config.getStep())) { + sampler.setName(this.getName() + "<->" + config.getStep()); + } + sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("HttpTestSampleGui")); sampler.setMethod(this.getMethod()); 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 d9b3ecd4ae..f4a97f1405 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 @@ -64,7 +64,7 @@ public class MsJDBCSampler extends MsTestElement { if (this.dataSource == null) { MSException.throwException("数据源为空无法执行"); } - final HashTree samplerHashTree = tree.add(jdbcSampler()); + final HashTree samplerHashTree = tree.add(jdbcSampler(config)); tree.add(jdbcDataSource()); tree.add(arguments(this.getName() + " Variables", this.getVariables())); if (CollectionUtils.isNotEmpty(hashTree)) { @@ -102,9 +102,12 @@ public class MsJDBCSampler extends MsTestElement { return arguments; } - private JDBCSampler jdbcSampler() { + private JDBCSampler jdbcSampler(ParameterConfig config) { JDBCSampler sampler = new JDBCSampler(); sampler.setName(this.getName()); + if (config != null && StringUtils.isNotEmpty(config.getStep())) { + sampler.setName(this.getName() + "<->" + config.getStep()); + } sampler.setProperty(TestElement.TEST_CLASS, JDBCSampler.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); // request.getDataSource() 是ID,需要转换为Name 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 25515a8f03..b575bd9b57 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 @@ -7,6 +7,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.config.ConfigTestElement; import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; import org.apache.jmeter.save.SaveService; @@ -59,7 +60,7 @@ public class MsTCPSampler extends MsTestElement { this.getRefElement(this); } final HashTree samplerHashTree = new ListedHashTree(); - samplerHashTree.add(tcpConfig()); + samplerHashTree.add(tcpConfig(config)); tree.set(tcpSampler(), samplerHashTree); if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { @@ -89,10 +90,14 @@ public class MsTCPSampler extends MsTestElement { return tcpSampler; } - private ConfigTestElement tcpConfig() { + private ConfigTestElement tcpConfig(ParameterConfig config) { ConfigTestElement configTestElement = new ConfigTestElement(); configTestElement.setEnabled(true); configTestElement.setName(this.getName()); + if (config != null && StringUtils.isNotEmpty(config.getStep())) { + configTestElement.setName(this.getName() + "<->" + config.getStep()); + } + configTestElement.setProperty(TestElement.TEST_CLASS, ConfigTestElement.class.getName()); configTestElement.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TCPConfigGui")); configTestElement.setProperty(TCPSampler.CLASSNAME, this.getClassname()); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java b/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java index d64805c4e5..e9ec0a7599 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/ScenarioResult.java @@ -22,7 +22,7 @@ public class ScenarioResult { private int passAssertions = 0; - private final List requestResults = new ArrayList<>(); + private List requestResults = new ArrayList<>(); public void addResponseTime(long time) { this.responseTime += time; 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 246ef6e82f..b66d4212c0 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -1,9 +1,11 @@ package io.metersphere.api.jmeter; +import io.metersphere.commons.utils.BeanUtils; import lombok.Data; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.*; @Data public class TestResult { @@ -38,5 +40,33 @@ public class TestResult { this.passAssertions += count; } - + public void addScenario(ScenarioResult result) { + Map> requestResultMap = new LinkedHashMap<>(); + if (result != null && CollectionUtils.isNotEmpty(result.getRequestResults())) { + result.getRequestResults().forEach(item -> { + if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf("<->") != -1) { + String array[] = item.getName().split("<->"); + item.setName(array[0]); + if (requestResultMap.containsKey(array[1])) { + requestResultMap.get(array[1]).add(item); + } else { + List requestResults = new LinkedList<>(); + requestResults.add(item); + requestResultMap.put(array[1], requestResults); + } + } + }); + } + if (!requestResultMap.isEmpty()) { + requestResultMap.forEach((k, v) -> { + ScenarioResult scenarioResult = new ScenarioResult(); + BeanUtils.copyBean(scenarioResult, result); + scenarioResult.setName(k); + scenarioResult.setRequestResults(v); + scenarios.add(scenarioResult); + }); + } else { + scenarios.add(result); + } + } } 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 7aab0f9c7b..10a92ada82 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -368,14 +368,12 @@ public class ApiAutomationService { // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), - new TypeReference>() { - }); + new TypeReference>() {}); scenario.setHashTree(elements); } if (StringUtils.isNotEmpty(element.getString("variables"))) { LinkedList variables = mapper.readValue(element.getString("variables"), - new TypeReference>() { - }); + new TypeReference>() {}); scenario.setVariables(variables); } group.setEnableCookieShare(scenario.isEnableCookieShare()); 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 be7594f5ac..8313835e75 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -3,7 +3,9 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.QueryAPIReportRequest; -import io.metersphere.api.dto.automation.*; +import io.metersphere.api.dto.automation.APIScenarioReportResult; +import io.metersphere.api.dto.automation.ExecuteType; +import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.api.jmeter.ScenarioResult; import io.metersphere.api.jmeter.TestResult; @@ -26,7 +28,6 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -136,10 +137,12 @@ public class ApiScenarioReportService { // 报告详情内容 ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); TestResult newResult = createTestResult(result.getTestId(), scenarioResult); - List scenarioResults = new ArrayList(); - scenarioResult.setName(report.getScenarioName()); - scenarioResults.add(scenarioResult); - newResult.setScenarios(scenarioResults); +// List scenarioResults = new ArrayList(); +// scenarioResult.setName(report.getScenarioName()); +// scenarioResults.add(scenarioResult); +// newResult.setScenarios(scenarioResults); + newResult.addScenario(scenarioResult); + detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); detail.setReportId(report.getId()); detail.setProjectId(report.getProjectId()); @@ -158,10 +161,11 @@ public class ApiScenarioReportService { // 报告详情内容 ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); TestResult newResult = createTestResult(result.getTestId(), item); - List scenarioResults = new ArrayList(); - item.setName(report.getScenarioName()); - scenarioResults.add(item); - newResult.setScenarios(scenarioResults); +// List scenarioResults = new ArrayList(); +// item.setName(report.getScenarioName()); +// scenarioResults.add(item); +// newResult.setScenarios(scenarioResults); + newResult.addScenario(item); detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); detail.setReportId(report.getId()); detail.setProjectId(report.getProjectId()); From e451248e255cc6820db4195bdd8ddb0db2ff4890 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Tue, 12 Jan 2021 09:33:44 +0800 Subject: [PATCH 02/11] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=86=B2=E7=AA=81=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/request/sampler/MsTCPSampler.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 6c26aa89e3..b545bc405e 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 @@ -1,15 +1,11 @@ package io.metersphere.api.dto.definition.request.sampler; -import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; -import io.metersphere.api.service.ApiTestEnvironmentService; -import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; -import io.metersphere.commons.utils.CommonBeanFactory; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -74,8 +70,8 @@ public class MsTCPSampler extends MsTestElement { config.setConfig(getEnvironmentConfig(useEnvironment)); parseEnvironment(config.getConfig()); final HashTree samplerHashTree = new ListedHashTree(); - samplerHashTree.add(tcpConfig(config)); - tree.set(tcpSampler(), samplerHashTree); + samplerHashTree.add(tcpConfig()); + tree.set(tcpSampler(config), samplerHashTree); if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { el.toHashTree(samplerHashTree, el.getHashTree(), config); @@ -90,9 +86,13 @@ public class MsTCPSampler extends MsTestElement { } } - private TCPSampler tcpSampler() { + private TCPSampler tcpSampler(ParameterConfig config) { TCPSampler tcpSampler = new TCPSampler(); tcpSampler.setName(this.getName()); + if (config != null && StringUtils.isNotEmpty(config.getStep())) { + tcpSampler.setName(this.getName() + "<->" + config.getStep()); + } + tcpSampler.setProperty(TestElement.TEST_CLASS, TCPSampler.class.getName()); tcpSampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TCPSamplerGui")); tcpSampler.setClassname(this.getClassname()); From 86b19b68fc395d88995a80ab73e81bccc783ae61 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Tue, 12 Jan 2021 11:16:46 +0800 Subject: [PATCH 03/11] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=8A=A5=E5=91=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/jmeter/TestResult.java | 18 ++++++++++------ .../api/service/ApiAutomationService.java | 1 + .../api/automation/report/ApiReportDetail.vue | 21 ++++++++++++------- .../report/components/ScenarioResult.vue | 2 +- .../api/definition/components/ApiVariable.vue | 2 +- .../definition/components/body/ApiBody.vue | 19 +++++++---------- .../common/json-schema/JsonSchemaEditor.vue | 4 ++-- 7 files changed, 39 insertions(+), 28 deletions(-) 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 b66d4212c0..925ff066c2 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -40,20 +40,26 @@ public class TestResult { this.passAssertions += count; } + private static final String separator = "<->"; + public void addScenario(ScenarioResult result) { Map> requestResultMap = new LinkedHashMap<>(); if (result != null && CollectionUtils.isNotEmpty(result.getRequestResults())) { result.getRequestResults().forEach(item -> { - if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf("<->") != -1) { - String array[] = item.getName().split("<->"); - item.setName(array[0]); - if (requestResultMap.containsKey(array[1])) { - requestResultMap.get(array[1]).add(item); + if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(separator) != -1) { + String array[] = item.getName().split(separator); + String scenarioName = array[array.length - 1]; + item.setName(item.getName().replace(separator + scenarioName, "")); + if (requestResultMap.containsKey(scenarioName)) { + requestResultMap.get(scenarioName).add(item); } else { List requestResults = new LinkedList<>(); requestResults.add(item); - requestResultMap.put(array[1], requestResults); + requestResultMap.put(scenarioName, 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 10a92ada82..3e33bdc4d4 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -441,6 +441,7 @@ public class ApiAutomationService { ParameterConfig config = new ParameterConfig(); config.setConfig(envConfig); HashTree hashTree = request.getTestElement().generateHashTree(config); + // 调用执行方法 createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId()); diff --git a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue index 9711a728ac..ed6453e2a0 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue @@ -9,14 +9,21 @@
- + + + + + + + + + + + +
- - - - - -
diff --git a/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue b/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue index a380bdca36..664507e874 100644 --- a/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue +++ b/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue @@ -1,5 +1,5 @@ @@ -26,6 +29,7 @@ import {hasLicense} from '@/common/js/utils'; const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); const display = requireComponent.keys().length > 0 ? requireComponent("./display/Display.vue") : {}; +const auth = requireComponent.keys().length > 0 ? requireComponent("./auth/Auth.vue") : {}; export default { name: "SystemParameterSetting", @@ -33,7 +37,8 @@ export default { BaseSetting, EmailSetting, LdapSetting, - "MsDisplay": display.default + "MsDisplay": display.default, + "MsAuth": auth.default, }, data() { return { diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index 7d43154a7c..3d96d7c61b 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit 7d43154a7c19732407a8e9ace8a7d1ea13c91f36 +Subproject commit 3d96d7c61bc50f32f18311d23f447663e02d7d44 diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 46b74f7012..40dc7b1b66 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1458,6 +1458,8 @@ export default { add_file: "Add file", delimiter: "Delimiter", format: "Output format", + }, + auth_source: { + delete_prompt:'This operation will delete the authentication source, do you want to continue? ' } - }; diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 9f7ebec1d7..8902b8eb9d 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -1458,5 +1458,8 @@ export default { add_file: "添加文件", delimiter: "分隔符", format: "输出格式", + }, + auth_source: { + delete_prompt: '此操作会删除认证源,是否继续?' } }; diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index e16fea582f..1b8cf470fa 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -1458,5 +1458,8 @@ export default { add_file: "添加文件", delimiter: "分隔符", format: "輸出格式", + }, + auth_source: { + delete_prompt: '此操作會刪除認證源,是否繼續? ' } }; From 67a9e1588e5cd91f82075c84440ebed66fa624fa Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Tue, 12 Jan 2021 15:12:10 +0800 Subject: [PATCH 07/11] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/db/migration/V64__auth_source.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 backend/src/main/resources/db/migration/V64__auth_source.sql diff --git a/backend/src/main/resources/db/migration/V64__auth_source.sql b/backend/src/main/resources/db/migration/V64__auth_source.sql new file mode 100644 index 0000000000..9145d8d099 --- /dev/null +++ b/backend/src/main/resources/db/migration/V64__auth_source.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS `auth_source` ( + `id` varchar(50) NOT NULL, + `configuration` text NOT NULL, + `status` varchar(64) NOT NULL, + `create_time` bigint(13) NOT NULL, + `update_time` bigint(13) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `name` varchar(60) DEFAULT NULL, + `type` varchar(30) DEFAULT NULL, + PRIMARY KEY (`id`) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; + From 4cef65d9f88585515166220ca6ebe14673bc208c Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 12 Jan 2021 15:22:08 +0800 Subject: [PATCH 08/11] =?UTF-8?q?feat(=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95?= =?UTF-8?q?):=20=E6=B5=8B=E8=AF=95=E5=88=97=E8=A1=A8=E6=B7=BB=E5=8A=A0ID?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/base/domain/LoadTest.java | 2 + .../base/domain/LoadTestExample.java | 60 +++++++++++++++++++ .../base/domain/LoadTestWithBLOBs.java | 2 + .../base/mapper/LoadTestMapper.xml | 52 ++++++++++++---- .../base/mapper/ext/ExtLoadTestMapper.java | 2 + .../base/mapper/ext/ExtLoadTestMapper.xml | 3 + .../service/PerformanceTestService.java | 11 ++++ .../db/migration/V65__init_load_test_num.sql | 51 ++++++++++++++++ .../performance/test/PerformanceTestList.vue | 6 ++ 9 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V65__init_load_test_num.sql diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTest.java b/backend/src/main/java/io/metersphere/base/domain/LoadTest.java index f0fb9694c1..b62e751a3f 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTest.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTest.java @@ -23,5 +23,7 @@ public class LoadTest implements Serializable { private String userId; + private Integer num; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestExample.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestExample.java index 27c7a4496f..9907f4b785 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTestExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestExample.java @@ -713,6 +713,66 @@ public class LoadTestExample { addCriterion("user_id not between", value1, value2, "userId"); return (Criteria) this; } + + public Criteria andNumIsNull() { + addCriterion("num is null"); + return (Criteria) this; + } + + public Criteria andNumIsNotNull() { + addCriterion("num is not null"); + return (Criteria) this; + } + + public Criteria andNumEqualTo(Integer value) { + addCriterion("num =", value, "num"); + return (Criteria) this; + } + + public Criteria andNumNotEqualTo(Integer value) { + addCriterion("num <>", value, "num"); + return (Criteria) this; + } + + public Criteria andNumGreaterThan(Integer value) { + addCriterion("num >", value, "num"); + return (Criteria) this; + } + + public Criteria andNumGreaterThanOrEqualTo(Integer value) { + addCriterion("num >=", value, "num"); + return (Criteria) this; + } + + public Criteria andNumLessThan(Integer value) { + addCriterion("num <", value, "num"); + return (Criteria) this; + } + + public Criteria andNumLessThanOrEqualTo(Integer value) { + addCriterion("num <=", value, "num"); + return (Criteria) this; + } + + public Criteria andNumIn(List values) { + addCriterion("num in", values, "num"); + return (Criteria) this; + } + + public Criteria andNumNotIn(List values) { + addCriterion("num not in", values, "num"); + return (Criteria) this; + } + + public Criteria andNumBetween(Integer value1, Integer value2) { + addCriterion("num between", value1, value2, "num"); + return (Criteria) this; + } + + public Criteria andNumNotBetween(Integer value1, Integer value2) { + addCriterion("num not between", value1, value2, "num"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestWithBLOBs.java index ed7c0c698c..5e3c4b20b3 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTestWithBLOBs.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestWithBLOBs.java @@ -13,5 +13,7 @@ public class LoadTestWithBLOBs extends LoadTest implements Serializable { private String advancedConfiguration; + private String schedule; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/LoadTestMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/LoadTestMapper.xml index b6c45ec1d3..af5478f5bb 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/LoadTestMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/LoadTestMapper.xml @@ -11,10 +11,12 @@ + + @@ -76,10 +78,10 @@ id, project_id, `name`, description, create_time, update_time, `status`, test_resource_pool_id, - user_id + user_id, num - load_configuration, advanced_configuration + load_configuration, advanced_configuration, schedule @@ -250,12 +264,18 @@ user_id = #{record.userId,jdbcType=VARCHAR}, + + num = #{record.num,jdbcType=INTEGER}, + load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR}, advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR}, + + schedule = #{record.schedule,jdbcType=LONGVARCHAR}, + @@ -272,8 +292,10 @@ `status` = #{record.status,jdbcType=VARCHAR}, test_resource_pool_id = #{record.testResourcePoolId,jdbcType=VARCHAR}, user_id = #{record.userId,jdbcType=VARCHAR}, + num = #{record.num,jdbcType=INTEGER}, load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR}, - advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR} + advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR}, + schedule = #{record.schedule,jdbcType=LONGVARCHAR} @@ -288,7 +310,8 @@ update_time = #{record.updateTime,jdbcType=BIGINT}, `status` = #{record.status,jdbcType=VARCHAR}, test_resource_pool_id = #{record.testResourcePoolId,jdbcType=VARCHAR}, - user_id = #{record.userId,jdbcType=VARCHAR} + user_id = #{record.userId,jdbcType=VARCHAR}, + num = #{record.num,jdbcType=INTEGER} @@ -320,12 +343,18 @@ user_id = #{userId,jdbcType=VARCHAR}, + + num = #{num,jdbcType=INTEGER}, + load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR}, advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR}, + + schedule = #{schedule,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} @@ -339,8 +368,10 @@ `status` = #{status,jdbcType=VARCHAR}, test_resource_pool_id = #{testResourcePoolId,jdbcType=VARCHAR}, user_id = #{userId,jdbcType=VARCHAR}, + num = #{num,jdbcType=INTEGER}, load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR}, - advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR} + advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR}, + schedule = #{schedule,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} @@ -352,7 +383,8 @@ update_time = #{updateTime,jdbcType=BIGINT}, `status` = #{status,jdbcType=VARCHAR}, test_resource_pool_id = #{testResourcePoolId,jdbcType=VARCHAR}, - user_id = #{userId,jdbcType=VARCHAR} + user_id = #{userId,jdbcType=VARCHAR}, + num = #{num,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.java index 8a90bf5e7e..9ea652a93f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.java @@ -14,4 +14,6 @@ public interface ExtLoadTestMapper { List getLoadTestByProjectId(String projectId); int checkLoadTestOwner(@Param("testId") String testId, @Param("workspaceIds") Set workspaceIds); + + LoadTest getNextNum(@Param("projectId") String projectId); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml index 6e5806ac28..0282187863 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml @@ -128,4 +128,7 @@ + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java index 6827045fb2..a3d6a4d9a6 100644 --- a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java +++ b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java @@ -160,6 +160,7 @@ public class PerformanceTestService { loadTest.setLoadConfiguration(request.getLoadConfiguration()); loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration()); loadTest.setStatus(PerformanceTestStatus.Saved.name()); + loadTest.setNum(getNextNum(request.getProjectId())); loadTestMapper.insert(loadTest); return loadTest; } @@ -396,6 +397,7 @@ public class PerformanceTestService { copy.setUpdateTime(System.currentTimeMillis()); copy.setStatus(APITestStatus.Saved.name()); copy.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId()); + copy.setNum(getNextNum(copy.getProjectId())); loadTestMapper.insert(copy); // copy test file LoadTestFileExample loadTestFileExample = new LoadTestFileExample(); @@ -499,4 +501,13 @@ public class PerformanceTestService { List loadTests = loadTestMapper.selectByExample(loadTestExample); return Optional.ofNullable(loadTests).orElse(new ArrayList<>()); } + + private int getNextNum(String projectId) { + LoadTest loadTest = extLoadTestMapper.getNextNum(projectId); + if (loadTest == null) { + return 100001; + } else { + return Optional.of(loadTest.getNum() + 1).orElse(100001); + } + } } diff --git a/backend/src/main/resources/db/migration/V65__init_load_test_num.sql b/backend/src/main/resources/db/migration/V65__init_load_test_num.sql new file mode 100644 index 0000000000..ad6c223dc8 --- /dev/null +++ b/backend/src/main/resources/db/migration/V65__init_load_test_num.sql @@ -0,0 +1,51 @@ +alter table load_test add num int null; + +DROP PROCEDURE IF EXISTS test_cursor; +DELIMITER // +CREATE PROCEDURE test_cursor() +BEGIN + DECLARE projectId VARCHAR(64); + DECLARE loadTestId VARCHAR(64); + DECLARE num INT; + DECLARE done INT DEFAULT 0; + DECLARE cursor1 CURSOR FOR (SELECT DISTINCT project_id + FROM load_test + WHERE num IS NULL); + DECLARE cursor2 CURSOR FOR (SELECT id + FROM load_test + WHERE project_id = projectId + ORDER BY create_time); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cursor1; + outer_loop: + LOOP + FETCH cursor1 INTO projectId; + IF done + THEN + LEAVE outer_loop; + END IF; + SET num = 100001; + OPEN cursor2; + inner_loop: + LOOP + FETCH cursor2 INTO loadTestId; + IF done + THEN + LEAVE inner_loop; + END IF; + UPDATE load_test + SET num = num + WHERE id = loadTestId; + SET num = num + 1; + END LOOP; + SET done = 0; + CLOSE cursor2; + END LOOP; + CLOSE cursor1; +END // +DELIMITER ; + +CALL test_cursor(); +DROP PROCEDURE IF EXISTS test_cursor; + diff --git a/frontend/src/business/components/performance/test/PerformanceTestList.vue b/frontend/src/business/components/performance/test/PerformanceTestList.vue index 80d3210f0d..0b3af35206 100644 --- a/frontend/src/business/components/performance/test/PerformanceTestList.vue +++ b/frontend/src/business/components/performance/test/PerformanceTestList.vue @@ -13,6 +13,12 @@ @filter-change="filter" @row-click="link" > + + Date: Tue, 12 Jan 2021 15:39:20 +0800 Subject: [PATCH 09/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=99=AE?= =?UTF-8?q?=E9=80=9A=E7=94=A8=E6=88=B7=E6=9F=A5=E8=AF=A2=E6=89=80=E6=9C=89?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=88=97=E8=A1=A8=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1090 --- .../main/java/io/metersphere/controller/RoleController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/io/metersphere/controller/RoleController.java b/backend/src/main/java/io/metersphere/controller/RoleController.java index 2faf7a3947..b1a40877f1 100644 --- a/backend/src/main/java/io/metersphere/controller/RoleController.java +++ b/backend/src/main/java/io/metersphere/controller/RoleController.java @@ -1,7 +1,9 @@ package io.metersphere.controller; import io.metersphere.base.domain.Role; +import io.metersphere.commons.constants.RoleConstants; import io.metersphere.service.RoleService; +import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -23,6 +25,7 @@ public class RoleController { } @GetMapping("/all") + @RequiresRoles(RoleConstants.ADMIN) public List getAllRole() { return roleService.getAllRole(); } From 30b3f83725e1cc51b99a17c111f1769654372933 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 12 Jan 2021 15:41:14 +0800 Subject: [PATCH 10/11] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92?= =?UTF-8?q?):=20=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E5=B1=95=E7=A4=BAID=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/ext/ExtTestPlanLoadCaseMapper.xml | 1 + .../track/dto/TestPlanLoadCaseDTO.java | 1 + .../comonents/load/TestPlanLoadCaseList.vue | 24 ++++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml index fb99116be3..ace3c621e2 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanLoadCaseMapper.xml @@ -18,6 +18,7 @@ tplc.test_plan_id, tplc.load_case_id, lt.status, + lt.num, tplc.status as caseStatus, lt.name as caseName, tplc.load_report_id, diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java index 6dcfd166ab..1d8cb09a13 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanLoadCaseDTO.java @@ -11,4 +11,5 @@ public class TestPlanLoadCaseDTO extends TestPlanLoadCase { private String caseName; private String projectName; private String caseStatus; + private String num; } diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue index 11ea445db5..5f9dc9a788 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue @@ -24,7 +24,7 @@ - + {{ scope.row.createTime | timestampFormatDate }} - - - - - - - - + + + + + + + + @@ -268,7 +270,7 @@ export default { this.initTable(); }).catch(() => { //todo 用例出错 - this.$post('/test/plan/load/case/update', {id: loadCase.id, status: "error"},() => { + this.$post('/test/plan/load/case/update', {id: loadCase.id, status: "error"}, () => { this.initTable(); }); this.$notify.error({ From a46f3cfbba6c76f26c2410ce18515a537d942282 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Tue, 12 Jan 2021 15:53:12 +0800 Subject: [PATCH 11/11] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA)?= =?UTF-8?q?:=20=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8BXMIND=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=EF=BC=8C=E9=87=8D=E5=A4=8D=E5=86=85=E5=AE=B9=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/service/TestCaseService.java | 56 +++++++++++++++---- .../io/metersphere/xmind/XmindCaseParser.java | 29 ++++++++-- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index 9237735195..5666e3285b 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -39,7 +39,7 @@ import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; +import org.apache.commons.collections.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -119,7 +119,7 @@ public class TestCaseService { return testCaseMapper.updateByPrimaryKeySelective(testCase); } - private void checkTestCaseExist(TestCaseWithBLOBs testCase) { + public TestCaseWithBLOBs checkTestCaseExist(TestCaseWithBLOBs testCase) { // 全部字段值相同才判断为用例存在 if (testCase != null) { @@ -152,17 +152,22 @@ public class TestCaseService { List caseList = testCaseMapper.selectByExampleWithBLOBs(example); // 如果上边字段全部相同,去检查 steps 和 remark + boolean isExt = false; if (!CollectionUtils.isEmpty(caseList)) { - caseList.forEach(tc -> { + for (TestCaseWithBLOBs tc : caseList) { String steps = tc.getSteps(); String remark = tc.getRemark(); if (StringUtils.equals(steps, testCase.getSteps()) && StringUtils.equals(remark, testCase.getRemark())) { - MSException.throwException(Translator.get("test_case_already_exists")); + // MSException.throwException(Translator.get("test_case_already_exists")); + isExt = true; } - }); + } + } + if (isExt) { + return caseList.get(0); } - } + return null; } public int deleteTestCase(String testCaseId) { @@ -260,7 +265,9 @@ public class TestCaseService { try { XmindCaseParser xmindParser = new XmindCaseParser(this, userId, projectId, testCaseNames); errList = xmindParser.parse(multipartFile); - if (xmindParser.getNodePaths().isEmpty() && xmindParser.getTestCase().isEmpty()) { + if (CollectionUtils.isEmpty(xmindParser.getNodePaths()) + && CollectionUtils.isEmpty(xmindParser.getTestCase()) + && CollectionUtils.isEmpty(xmindParser.getUpdateTestCase())) { if (errList == null) { errList = new ArrayList<>(); } @@ -269,15 +276,18 @@ public class TestCaseService { excelResponse.setErrList(errList); } if (errList.isEmpty()) { - if (!xmindParser.getNodePaths().isEmpty()) { + if (CollectionUtils.isNotEmpty(xmindParser.getNodePaths())) { testCaseNodeService.createNodes(xmindParser.getNodePaths(), projectId); } - if (!xmindParser.getTestCase().isEmpty()) { + if (CollectionUtils.isNotEmpty(xmindParser.getTestCase())) { Collections.reverse(xmindParser.getTestCase()); this.saveImportData(xmindParser.getTestCase(), projectId); - xmindParser.clear(); + } + if (CollectionUtils.isNotEmpty(xmindParser.getUpdateTestCase())) { + this.updateImportData(xmindParser.getUpdateTestCase(), projectId); } } + xmindParser.clear(); } catch (Exception e) { LogUtil.error(e.getMessage(), e); MSException.throwException(e.getMessage()); @@ -313,7 +323,6 @@ public class TestCaseService { } public void saveImportData(List testCases, String projectId) { - Map nodePathMap = testCaseNodeService.createNodeByTestCases(testCases, projectId); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class); @@ -335,6 +344,27 @@ public class TestCaseService { sqlSession.flushStatements(); } + public void updateImportData(List testCases, String projectId) { + Map nodePathMap = testCaseNodeService.createNodeByTestCases(testCases, projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class); + if (!testCases.isEmpty()) { + AtomicInteger sort = new AtomicInteger(); + AtomicInteger num = new AtomicInteger(); + num.set(getNextNum(projectId) + testCases.size()); + testCases.forEach(testcase -> { + testcase.setUpdateTime(System.currentTimeMillis()); + testcase.setNodeId(nodePathMap.get(testcase.getNodePath())); + testcase.setSort(sort.getAndIncrement()); + testcase.setNum(num.decrementAndGet()); + testcase.setReviewStatus(TestCaseReviewStatus.Prepare.name()); + mapper.updateByPrimaryKeySelective(testcase); + }); + } + sqlSession.flushStatements(); + } + + public void testCaseTemplateExport(HttpServletResponse response) { try { EasyExcelExporter easyExcelExporter = new EasyExcelExporter(new TestCaseExcelDataFactory().getExcelDataByLocal()); @@ -572,7 +602,9 @@ public class TestCaseService { public boolean exist(TestCaseWithBLOBs testCaseWithBLOBs) { try { - checkTestCaseExist(testCaseWithBLOBs); + TestCaseWithBLOBs caseWithBLOBs = checkTestCaseExist(testCaseWithBLOBs); + if (caseWithBLOBs != null) + return true; } catch (MSException e) { return true; } diff --git a/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java b/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java index 939b8f3730..1dab92a9f8 100644 --- a/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java +++ b/backend/src/main/java/io/metersphere/xmind/XmindCaseParser.java @@ -44,6 +44,11 @@ public class XmindCaseParser { * 转换后的案例信息 */ private List testCases; + /** + * 需要更新的用例 + */ + private List updateTestCases; + /** * 案例详情重写了hashCode方法去重用 */ @@ -59,6 +64,7 @@ public class XmindCaseParser { this.projectId = projectId; this.testCaseNames = testCaseNames; testCases = new LinkedList<>(); + updateTestCases = new LinkedList<>(); compartDatas = new ArrayList<>(); process = new DetailUtil(); nodePaths = new ArrayList<>(); @@ -71,6 +77,7 @@ public class XmindCaseParser { public void clear() { compartDatas.clear(); testCases.clear(); + updateTestCases.clear(); testCaseNames.clear(); nodePaths.clear(); } @@ -79,6 +86,10 @@ public class XmindCaseParser { return this.testCases; } + public List getUpdateTestCase() { + return this.updateTestCases; + } + public List getNodePaths() { return this.nodePaths; } @@ -112,7 +123,7 @@ public class XmindCaseParser { /** * 验证用例的合规性 */ - private void validate(TestCaseWithBLOBs data) { + private boolean validate(TestCaseWithBLOBs data) { String nodePath = data.getNodePath(); if (!nodePath.startsWith("/")) { nodePath = "/" + nodePath; @@ -149,9 +160,13 @@ public class XmindCaseParser { } if (testCaseNames.contains(data.getName())) { - boolean dbExist = testCaseService.exist(data); - if (dbExist) { - process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + data.getName()); + TestCaseWithBLOBs bloBs = testCaseService.checkTestCaseExist(data); + if (bloBs != null) { + // process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + data.getName()); + // 记录需要变更的用例 + BeanUtils.copyBean(bloBs, data, "id"); + updateTestCases.add(bloBs); + return false; } } else { testCaseNames.add(data.getName()); @@ -172,6 +187,7 @@ public class XmindCaseParser { process.add(Translator.get("test_case_already_exists_excel"), nodePath + "/" + compartData.getName()); } compartDatas.add(compartData); + return true; } /** @@ -299,9 +315,10 @@ public class XmindCaseParser { } testCase.setRemark(rc.toString()); testCase.setSteps(this.getSteps(steps)); - testCases.add(testCase); // 校验合规性 - validate(testCase); + if (validate(testCase)) { + testCases.add(testCase); + } } /**