From 9c310d767807351ff697a6f907b8811a003999aa Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 20 Jan 2021 20:27:12 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20TCP=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../processors/pre/MsJSR223PreProcessor.java | 17 +- .../request/sampler/MsTCPSampler.java | 39 +++-- .../common/Jsr233ProcessorContent.vue | 162 ++++++++++++++++++ .../scenario/component/Jsr233Processor.vue | 140 ++------------- .../request/tcp/TcpBasisParameters.vue | 13 ++ 5 files changed, 223 insertions(+), 148 deletions(-) create mode 100644 frontend/src/business/components/api/automation/scenario/common/Jsr233ProcessorContent.vue diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java index 9f76eab72b..3afbe1ac13 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/pre/MsJSR223PreProcessor.java @@ -32,6 +32,15 @@ public class MsJSR223PreProcessor extends MsTestElement { if (!this.isEnable()) { return; } + final HashTree jsr223PreTree = tree.add(getJSR223PreProcessor()); + if (CollectionUtils.isNotEmpty(hashTree)) { + hashTree.forEach(el -> { + el.toHashTree(jsr223PreTree, el.getHashTree(), config); + }); + } + } + + public JSR223PreProcessor getJSR223PreProcessor() { JSR223PreProcessor processor = new JSR223PreProcessor(); processor.setEnabled(true); if (StringUtils.isNotEmpty(this.getName())) { @@ -44,13 +53,7 @@ public class MsJSR223PreProcessor extends MsTestElement { processor.setProperty("cacheKey", "true"); processor.setProperty("scriptLanguage", this.getScriptLanguage()); processor.setProperty("script", this.getScript()); - - final HashTree jsr223PreTree = tree.add(processor); - if (CollectionUtils.isNotEmpty(hashTree)) { - hashTree.forEach(el -> { - el.toHashTree(jsr223PreTree, el.getHashTree(), config); - }); - } + return processor; } } 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 e2209f1842..d2d10d6f28 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 @@ -4,6 +4,7 @@ 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.definition.request.processors.pre.MsJSR223PreProcessor; import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import lombok.Data; @@ -11,14 +12,18 @@ 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.modifiers.UserParameters; import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; +import org.apache.jmeter.testelement.property.CollectionProperty; +import org.apache.jmeter.testelement.property.StringProperty; import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.ListedHashTree; +import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; +import java.util.Random; @Data @EqualsAndHashCode(callSuper = true) @@ -58,6 +63,8 @@ public class MsTCPSampler extends MsTestElement { private List parameters; @JSONField(ordinal = 36) private String useEnvironment; + @JSONField(ordinal = 37) + private MsJSR223PreProcessor tcpPreProcessor; @Override public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { @@ -67,12 +74,13 @@ public class MsTCPSampler extends MsTestElement { if (this.getReferenced() != null && this.getReferenced().equals("REF")) { this.getRefElement(this); } - parseParameters(); config.setConfig(getEnvironmentConfig(useEnvironment)); parseEnvironment(config.getConfig()); final HashTree samplerHashTree = new ListedHashTree(); samplerHashTree.add(tcpConfig()); tree.set(tcpSampler(config), samplerHashTree); + setUserParameters(samplerHashTree); + samplerHashTree.add(tcpPreProcessor.getJSR223PreProcessor()); if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { el.toHashTree(samplerHashTree, el.getHashTree(), config); @@ -108,18 +116,27 @@ public class MsTCPSampler extends MsTestElement { tcpSampler.setRequestData(this.getRequest()); tcpSampler.setProperty(ConfigTestElement.USERNAME, this.getUsername()); tcpSampler.setProperty(ConfigTestElement.PASSWORD, this.getPassword()); - return tcpSampler; } - private void parseParameters() { - if (CollectionUtils.isNotEmpty(parameters)) { - parameters.forEach(item -> { - if (item.isEnable() && StringUtils.isNotBlank(item.getValue())) { - request = request.replaceAll("\\$\\{" + item.getName() + "\\}", Matcher.quoteReplacement(item.getValue())); - } - }); - } + private void setUserParameters(HashTree tree) { + UserParameters userParameters = new UserParameters(); + userParameters.setEnabled(true); + userParameters.setName(this.getName() + "UserParameters"); + userParameters.setPerIteration(false); + userParameters.setProperty(TestElement.TEST_CLASS, UserParameters.class.getName()); + userParameters.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("UserParametersGui")); + List names = new ArrayList<>(); + List threadValues = new ArrayList<>(); + this.parameters.forEach(item -> { + names.add(new StringProperty(new Integer(new Random().nextInt(1000000)).toString(), item.getName())); + threadValues.add(new StringProperty(new Integer(new Random().nextInt(1000000)).toString(), item.getValue())); + }); + userParameters.setNames(new CollectionProperty(UserParameters.NAMES, names)); + List collectionPropertyList = new ArrayList<>(); + collectionPropertyList.add(new CollectionProperty(new Integer(new Random().nextInt(1000000)).toString(), threadValues)); + userParameters.setThreadLists(new CollectionProperty(UserParameters.THREAD_VALUES, collectionPropertyList)); + tree.add(userParameters); } private ConfigTestElement tcpConfig() { diff --git a/frontend/src/business/components/api/automation/scenario/common/Jsr233ProcessorContent.vue b/frontend/src/business/components/api/automation/scenario/common/Jsr233ProcessorContent.vue new file mode 100644 index 0000000000..a011d76e48 --- /dev/null +++ b/frontend/src/business/components/api/automation/scenario/common/Jsr233ProcessorContent.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/frontend/src/business/components/api/automation/scenario/component/Jsr233Processor.vue b/frontend/src/business/components/api/automation/scenario/component/Jsr233Processor.vue index d85a83cf73..9678914202 100644 --- a/frontend/src/business/components/api/automation/scenario/component/Jsr233Processor.vue +++ b/frontend/src/business/components/api/automation/scenario/component/Jsr233Processor.vue @@ -2,35 +2,18 @@ - - -
- {{$t('commons.reference_documentation')}} - -
-
-
- - - - - - -
{{$t('api_test.request.processor.code_template')}}
-
- {{template.title}} -
-
-
+ + +
@@ -39,61 +22,11 @@ import MsInstructionsIcon from "../../../../common/components/MsInstructionsIcon"; import MsDropdown from "../../../../common/components/MsDropdown"; import ApiBaseComponent from "../common/ApiBaseComponent"; + import Jsr233ProcessorContent from "../common/Jsr233ProcessorContent"; export default { name: "MsJsr233Processor", - components: {ApiBaseComponent, MsDropdown, MsInstructionsIcon, MsCodeEdit}, - data() { - return { - jsr223ProcessorData: {}, - codeTemplates: [ - { - title: this.$t('api_test.request.processor.code_template_get_variable'), - value: 'vars.get("variable_name")', - }, - { - title: this.$t('api_test.request.processor.code_template_set_variable'), - value: 'vars.put("variable_name", "variable_value")', - }, - { - title: this.$t('api_test.request.processor.code_template_get_global_variable'), - value: 'props.get("variable_name")', - }, - { - title: this.$t('api_test.request.processor.code_template_set_global_variable'), - value: 'props.put("variable_name", "variable_value")', - }, - { - title: this.$t('api_test.request.processor.code_template_get_response_header'), - value: 'prev.getResponseHeaders()', - disabled: this.isPreProcessor - }, - { - title: this.$t('api_test.request.processor.code_template_get_response_code'), - value: 'prev.getResponseCode()', - disabled: this.isPreProcessor - }, - { - title: this.$t('api_test.request.processor.code_template_get_response_result'), - value: 'prev.getResponseDataAsString()', - disabled: this.isPreProcessor - } - ], - isCodeEditAlive: true, - languages: [ - 'beanshell', "python", "groovy", "javascript" - ], - codeEditModeMap: { - beanshell: 'java', - python: 'python', - groovy: 'java', - javascript: 'javascript', - } - } - }, - created() { - this.jsr223ProcessorData = this.jsr223Processor; - }, + components: {Jsr233ProcessorContent, ApiBaseComponent, MsDropdown, MsInstructionsIcon, MsCodeEdit}, props: { draggable: { type: Boolean, @@ -117,71 +50,18 @@ backgroundColor: String, node: {}, }, - watch: { - jsr223Processor() { - this.reload(); - } - } - , methods: { - addTemplate(template) { - if (!this.jsr223ProcessorData.script) { - this.jsr223ProcessorData.script = ""; - } - this.jsr223ProcessorData.script += template.value; - if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') { - this.jsr223ProcessorData.script += ';'; - } - this.reload(); - }, remove() { this.$emit('remove', this.jsr223ProcessorData, this.node); }, copyRow() { this.$emit('copyRow', this.jsr223ProcessorData, this.node); }, - reload() { - this.isCodeEditAlive = false; - this.$nextTick(() => (this.isCodeEditAlive = true)); - }, - languageChange(language) { - this.jsr223ProcessorData.scriptLanguage = language; - }, } } From cf9e24f069b76a19fd6ae6e4bbcc29cf7dbe03e8 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Thu, 21 Jan 2021 10:32:03 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20json=E7=BB=93=E6=9E=9C=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/definition/components/response/ResponseResult.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/components/api/definition/components/response/ResponseResult.vue b/frontend/src/business/components/api/definition/components/response/ResponseResult.vue index c6f64ebdcc..83ed95ee60 100644 --- a/frontend/src/business/components/api/definition/components/response/ResponseResult.vue +++ b/frontend/src/business/components/api/definition/components/response/ResponseResult.vue @@ -101,10 +101,10 @@ this.mode = mode; }, setBodyType() { - if (!this.response.headers) { + if (!this.response.responseResult.headers) { return; } - if (this.response.headers.indexOf("Content-Type: application/json") > 0) { + if (this.response.responseResult.headers.indexOf("Content-Type: application/json") > 0) { if (this.$refs.modeDropdown) { this.$refs.modeDropdown.handleCommand(BODY_FORMAT.JSON); this.msCodeReload(); From 141a526e1d452ec84ed516f4cb2ee57130305da3 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Thu, 21 Jan 2021 10:55:37 +0800 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=E5=90=AF=E5=8A=A8=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=97=B6=E6=A3=80=E6=9F=A5=E5=BD=93=E5=89=8D=E7=AB=99?= =?UTF-8?q?=E7=82=B9=E9=85=8D=E7=BD=AE=E6=98=AF=E5=90=A6=E5=8F=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/utils/UrlTestUtils.java | 20 +++++++++++++++++++ .../engine/docker/DockerTestEngine.java | 9 +++++++++ backend/src/main/java/io/metersphere/xpack | 2 +- .../resources/i18n/messages_en_US.properties | 2 +- .../resources/i18n/messages_zh_CN.properties | 2 +- .../resources/i18n/messages_zh_TW.properties | 2 +- 6 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java diff --git a/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java new file mode 100644 index 0000000000..d536cf484d --- /dev/null +++ b/backend/src/main/java/io/metersphere/commons/utils/UrlTestUtils.java @@ -0,0 +1,20 @@ +package io.metersphere.commons.utils; + +import java.net.URL; +import java.net.URLConnection; + +public class UrlTestUtils { + + public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { + try { + URL url = new URL(urlString); + URLConnection co = url.openConnection(); + co.setConnectTimeout(timeOutMillSeconds); + co.connect(); + return true; + } catch (Exception e) { + LogUtil.error(e); + return false; + } + } +} diff --git a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java index c58107318f..abcfa543c8 100644 --- a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java +++ b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java @@ -6,6 +6,7 @@ import io.metersphere.base.domain.TestResource; import io.metersphere.commons.constants.ResourceStatusEnum; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; +import io.metersphere.commons.utils.UrlTestUtils; import io.metersphere.config.JmeterProperties; import io.metersphere.config.KafkaProperties; import io.metersphere.controller.ResultHolder; @@ -15,6 +16,7 @@ import io.metersphere.i18n.Translator; import io.metersphere.performance.engine.AbstractEngine; import io.metersphere.performance.engine.request.StartTestRequest; import io.metersphere.service.SystemParameterService; +import org.apache.commons.lang3.StringUtils; import org.springframework.web.client.RestTemplate; import java.util.HashMap; @@ -77,6 +79,12 @@ public class DockerTestEngine extends AbstractEngine { metersphereUrl = baseInfo.getUrl(); } + // docker 不能从 localhost 中下载文件 + if (StringUtils.contains(metersphereUrl, "http://localhost") + || !UrlTestUtils.testUrlWithTimeOut(metersphereUrl, 1000)) { + MSException.throwException(Translator.get("run_load_test_file_init_error")); + } + Map env = new HashMap<>(); env.put("RATIO", "" + ratio); env.put("RESOURCE_INDEX", "" + resourceIndex); @@ -123,4 +131,5 @@ public class DockerTestEngine extends AbstractEngine { } }); } + } diff --git a/backend/src/main/java/io/metersphere/xpack b/backend/src/main/java/io/metersphere/xpack index 7f7808c6f0..132f406fac 160000 --- a/backend/src/main/java/io/metersphere/xpack +++ b/backend/src/main/java/io/metersphere/xpack @@ -1 +1 @@ -Subproject commit 7f7808c6f0457dd2df6b19a1622558f3f8122646 +Subproject commit 132f406fac7fb4d841210343eb98c09f78317f18 diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index 1a5222966c..63a9f26f1e 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -34,7 +34,7 @@ edit_load_test_not_found=Cannot edit test, test not found= run_load_test_not_found=Cannot run test, test not found= run_load_test_file_not_found=Unable to run test, unable to get test file meta information, test ID= run_load_test_file_content_not_found=Cannot run test, cannot get test file content, test ID= -run_load_test_file_init_error=Failed to run test, failed to initialize run environment, test ID= +run_load_test_file_init_error=Failed to run test, please check current end point configuration load_test_is_running=Load test is running, please wait. load_test_kafka_invalid=Kafka is not available, please check the configuration cannot_edit_load_test_running=Cannot modify the running test diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 2d077f1e49..d42e0b0162 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -34,7 +34,7 @@ edit_load_test_not_found=无法编辑测试,未找到测试: run_load_test_not_found=无法运行测试,未找到测试: run_load_test_file_not_found=无法运行测试,无法获取测试文件元信息,测试ID: run_load_test_file_content_not_found=无法运行测试,无法获取测试文件内容,测试ID: -run_load_test_file_init_error=无法运行测试,初始化运行环境失败,测试ID: +run_load_test_file_init_error=无法运行测试,请检查当前站点配置 load_test_is_running=测试正在运行, 请等待 load_test_kafka_invalid=Kafka 不可用,请检查配置 cannot_edit_load_test_running=不能修改正在运行的测试 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 7314bdecaa..5c2666354b 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -34,7 +34,7 @@ edit_load_test_not_found=無法編輯測試,未找到測試: run_load_test_not_found=無法運行測試,未找到測試: run_load_test_file_not_found=無法運行測試,無法獲取測試文件元信息,測試ID: run_load_test_file_content_not_found=無法運行測試,無法獲取測試文件內容,測試ID: -run_load_test_file_init_error=無法運行測試,初始化運行環境失敗,測試ID: +run_load_test_file_init_error=無法運行測試,請檢查當前站點配置 load_test_is_running=測試正在運行, 請等待 load_test_kafka_invalid=Kafka 不可用,請檢查配置 cannot_edit_load_test_running=不能修改正在運行的測試