From 07b500331d4b614b91295c17a95c2f014c039b4a Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 11 Jan 2021 18:14:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89TCP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/request/MsTestElement.java | 13 ++ .../request/sampler/MsHTTPSamplerProxy.java | 17 +- .../request/sampler/MsTCPSampler.java | 32 +++ .../api/automation/scenario/ApiComponent.vue | 2 +- .../scenario/ApiScenarioComponent.vue | 2 +- .../components/case/ApiCaseItem.vue | 2 +- .../complete/EditCompleteTCPApi.vue | 5 +- .../components/debug/DebugTcpPage.vue | 34 ++-- .../environment/EnvironmentSelect.vue | 119 +++++++++++ .../components/sampler/tcp-sampler/index.js | 2 + ...sParameters.vue => TcpBasisParameters.vue} | 187 ++++++++++-------- .../components/runtest/RunTestHTTPPage.vue | 77 +------- .../components/runtest/RunTestTCPPage.vue | 51 +---- .../api/definition/model/ApiTestModel.js | 2 + frontend/src/i18n/en-US.js | 3 + frontend/src/i18n/zh-CN.js | 3 + frontend/src/i18n/zh-TW.js | 5 +- 17 files changed, 334 insertions(+), 222 deletions(-) create mode 100644 frontend/src/business/components/api/definition/components/environment/EnvironmentSelect.vue rename frontend/src/business/components/api/definition/components/request/tcp/{BasisParameters.vue => TcpBasisParameters.vue} (63%) 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 d5e6ee61b7..48364c9b74 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 @@ -1,5 +1,6 @@ package io.metersphere.api.dto.definition.request; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.annotation.JsonSubTypes; @@ -22,8 +23,11 @@ import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler; import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.definition.request.timer.MsConstantTimer; import io.metersphere.api.dto.scenario.KeyValue; +import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.service.ApiDefinitionService; +import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; import lombok.Data; @@ -153,6 +157,15 @@ public abstract class MsTestElement { } return arguments; } + + protected EnvironmentConfig getEnvironmentConfig(String environmentId) { + ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); + ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId); + if (environment != null && environment.getConfig() != null) { + return JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class); + } + return 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..3cf81c2363 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 @@ -1,6 +1,5 @@ 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; @@ -8,10 +7,6 @@ import io.metersphere.api.dto.definition.request.ParameterConfig; import io.metersphere.api.dto.definition.request.dns.MsDNSCacheManager; import io.metersphere.api.dto.scenario.Body; 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 io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ScriptEngineUtils; import lombok.Data; @@ -35,6 +30,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; + + @Data @EqualsAndHashCode(callSuper = true) @JSONType(typeName = "HTTPSamplerProxy") @@ -108,13 +105,9 @@ public class MsHTTPSamplerProxy extends MsTestElement { sampler.setFollowRedirects(this.isFollowRedirects()); sampler.setUseKeepAlive(true); sampler.setDoMultipart(this.isDoMultipartPost()); - if (useEnvironment != null) { - ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); - ApiTestEnvironmentWithBLOBs environment = environmentService.get(useEnvironment); - if (environment != null && environment.getConfig() != null) { - config.setConfig(JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class)); - } - } + + config.setConfig(getEnvironmentConfig(useEnvironment)); + // 添加环境中的公共变量 Arguments arguments = this.addArguments(config); if (arguments != null) { 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..6f2d22b8ba 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,12 +1,19 @@ 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; +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; @@ -15,6 +22,7 @@ import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.ListedHashTree; import java.util.List; +import java.util.regex.Matcher; @Data @EqualsAndHashCode(callSuper = true) @@ -50,6 +58,10 @@ public class MsTCPSampler extends MsTestElement { private String request; @JSONField(ordinal = 34) private Object requestResult; + @JSONField(ordinal = 35) + private List parameters; + @JSONField(ordinal = 36) + private String useEnvironment; public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { if (!this.isEnable()) { @@ -58,6 +70,9 @@ 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(), samplerHashTree); @@ -68,6 +83,13 @@ public class MsTCPSampler extends MsTestElement { } } + private void parseEnvironment(EnvironmentConfig config) { + if (config != null && config.getTcpConfig() != null) { + this.server = config.getTcpConfig().getServer(); + this.port = config.getTcpConfig().getPort(); + } + } + private TCPSampler tcpSampler() { TCPSampler tcpSampler = new TCPSampler(); tcpSampler.setName(this.getName()); @@ -89,6 +111,16 @@ public class MsTCPSampler extends MsTestElement { 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 ConfigTestElement tcpConfig() { ConfigTestElement configTestElement = new ConfigTestElement(); configTestElement.setEnabled(true); diff --git a/frontend/src/business/components/api/automation/scenario/ApiComponent.vue b/frontend/src/business/components/api/automation/scenario/ApiComponent.vue index 7390d6edd0..9361031ecd 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiComponent.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiComponent.vue @@ -79,7 +79,7 @@ + + diff --git a/frontend/src/business/components/api/definition/components/jmeter/components/sampler/tcp-sampler/index.js b/frontend/src/business/components/api/definition/components/jmeter/components/sampler/tcp-sampler/index.js index 4d437674b5..4a3dda46c0 100644 --- a/frontend/src/business/components/api/definition/components/jmeter/components/sampler/tcp-sampler/index.js +++ b/frontend/src/business/components/api/definition/components/jmeter/components/sampler/tcp-sampler/index.js @@ -31,6 +31,8 @@ export default class TCPSampler extends Sampler { this.username = options.username; this.password = options.password; + + this.parameters = []; this.hashTree = []; } } diff --git a/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/tcp/TcpBasisParameters.vue similarity index 63% rename from frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue rename to frontend/src/business/components/api/definition/components/request/tcp/TcpBasisParameters.vue index bd408af00d..4a762f5173 100644 --- a/frontend/src/business/components/api/definition/components/request/tcp/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/tcp/TcpBasisParameters.vue @@ -4,89 +4,93 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + + + + + - - - - - + +
+ +
+
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- -
- -
-
@@ -133,10 +137,15 @@ import {API_STATUS} from "../../../model/JsonData"; import TCPSampler from "../../jmeter/components/sampler/tcp-sampler"; import {getCurrentProjectID, getUUID} from "@/common/js/utils"; + import MsApiVariable from "../../ApiVariable"; + import MsInstructionsIcon from "../../../../../common/components/MsInstructionsIcon"; + export default { - name: "MsDatabaseConfig", + name: "TcpBasisParameters", components: { + MsInstructionsIcon, + MsApiVariable, MsApiScenarioVariables, MsCodeEdit, MsJsr233Processor, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiKeyValue, ApiEnvironmentConfig @@ -152,7 +161,7 @@ }, data() { return { - activeName: "assertions", + activeName: "parameters", classes: TCPSampler.CLASSES, isReloadData: false, options: API_STATUS, @@ -166,6 +175,10 @@ }, created() { this.currentProjectId = getCurrentProjectID(); + if (!this.request.parameters) { + this.$set(this.request, 'parameters', []); + this.request.parameters = []; + } this.getEnvironments(); }, methods: { @@ -275,7 +288,7 @@ }, environmentConfigClose() { this.getEnvironments(); - }, + } } } @@ -317,4 +330,18 @@ /deep/ .el-form-item { margin-bottom: 15px; } + + /deep/ .instructions-icon { + font-size: 14px !important; + } + + .request-tabs { + margin: 20px; + min-height: 200px; + } + + .other-config { + padding: 15px; + } + diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue index b2fa12af0b..016378d2e0 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue @@ -15,23 +15,7 @@ - - - - {{ $t('api_test.environment.environment_config') }} - - - + @@ -77,8 +61,6 @@ :currentApi="api" ref="caseList"/> - - @@ -91,20 +73,19 @@ import {downloadFile, getUUID, getCurrentProjectID} from "@/common/js/utils"; import MsApiCaseList from "../case/ApiCaseList"; import MsContainer from "../../../../common/components/MsContainer"; - import {parseEnvironment} from "../../model/EnvironmentModel"; - import ApiEnvironmentConfig from "../environment/ApiEnvironmentConfig"; import MsRequestResultTail from "../response/RequestResultTail"; import MsRun from "../Run"; import {REQ_METHOD} from "../../model/JsonData"; + import EnvironmentSelect from "../environment/EnvironmentSelect"; export default { name: "RunTestHTTPPage", components: { + EnvironmentSelect, MsApiRequestForm, MsApiCaseList, MsContainer, MsRequestResultTail, - ApiEnvironmentConfig, MsRun }, data() { @@ -118,7 +99,6 @@ refreshSign: "", responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []}, reqOptions: REQ_METHOD, - environments: [], rules: { method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}], path: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}], @@ -230,50 +210,7 @@ this.api.request = this.currentRequest; } }, - getEnvironments() { - if (this.projectId) { - this.$get('/api/environment/list/' + this.projectId, response => { - this.environments = response.data; - this.environments.forEach(environment => { - parseEnvironment(environment); - }); - let hasEnvironment = false; - for (let i in this.environments) { - if (this.environments[i].id === this.api.environmentId) { - this.api.environmentId = this.environments[i].id; - hasEnvironment = true; - break; - } - } - if (!hasEnvironment) { - this.api.environmentId = ''; - this.api.environment = undefined; - } - }); - } else { - this.api.environmentId = ''; - this.api.environment = undefined; - } - }, - openEnvironmentConfig() { - if (!this.projectId) { - this.$error(this.$t('api_test.select_project')); - return; - } - this.$refs.environmentConfig.open(this.projectId); - }, - environmentChange(value) { - for (let i in this.environments) { - if (this.environments[i].id === value) { - this.api.environmentId = value; - this.api.request.useEnvironment = value; - break; - } - } - }, - environmentConfigClose() { - this.getEnvironments(); - }, + refresh() { this.$emit('refresh'); }, @@ -292,7 +229,6 @@ this.api = this.apiData; this.api.protocol = this.currentProtocol; this.currentRequest = this.api.request; - this.getEnvironments(); this.getResult(); } } @@ -303,11 +239,6 @@ width: 350px; } - .environment-button { - margin-left: 20px; - padding: 7px; - } - .tip { padding: 3px 5px; font-size: 16px; diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue index 687083ad33..2326af16c1 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue @@ -16,6 +16,10 @@ +

{{$t('test_track.plan_view.base_info')}}

+ + {{$t('api_test.definition.request.run_env')}}: +

{{$t('api_test.definition.request.req_param')}}

@@ -32,8 +36,7 @@ - - + @@ -47,22 +50,21 @@ import MsApiCaseList from "../case/ApiCaseList"; import MsContainer from "../../../../common/components/MsContainer"; import MsBottomContainer from "../BottomContainer"; - import {parseEnvironment} from "../../model/EnvironmentModel"; - import ApiEnvironmentConfig from "../environment/ApiEnvironmentConfig"; import MsRequestResultTail from "../response/RequestResultTail"; import MsRun from "../Run"; - import MsBasisParameters from "../request/tcp/BasisParameters"; + import MsBasisParameters from "../request/tcp/TcpBasisParameters"; import {REQ_METHOD} from "../../model/JsonData"; + import EnvironmentSelect from "../environment/EnvironmentSelect"; export default { name: "RunTestTCPPage", components: { + EnvironmentSelect, MsApiRequestForm, MsApiCaseList, MsContainer, MsBottomContainer, MsRequestResultTail, - ApiEnvironmentConfig, MsRun, MsBasisParameters }, @@ -85,6 +87,7 @@ }, runData: [], reportId: "", + projectId: "" } }, props: {apiData: {}, currentProtocol: String,}, @@ -180,40 +183,6 @@ this.api.request = this.currentRequest; } }, - getEnvironments() { - this.$get('/api/environment/list/' + getCurrentProjectID(), response => { - this.environments = response.data; - this.environments.forEach(environment => { - parseEnvironment(environment); - }); - let hasEnvironment = false; - for (let i in this.environments) { - if (this.environments[i].id === this.api.environmentId) { - this.api.environment = this.environments[i]; - hasEnvironment = true; - break; - } - } - if (!hasEnvironment) { - this.api.environmentId = ''; - this.api.environment = undefined; - } - }); - }, - openEnvironmentConfig() { - this.$refs.environmentConfig.open(getCurrentProjectID()); - }, - environmentChange(value) { - for (let i in this.environments) { - if (this.environments[i].id === value) { - this.api.request.useEnvironment = this.environments[i].id; - break; - } - } - }, - environmentConfigClose() { - this.getEnvironments(); - }, getResult() { let url = "/api/definition/report/getReport/" + this.api.id; this.$get(url, response => { @@ -228,7 +197,7 @@ this.api = this.apiData; this.api.protocol = this.currentProtocol; this.currentRequest = this.api.request; - this.getEnvironments(); + this.projectId = getCurrentProjectID(); this.getResult(); } } diff --git a/frontend/src/business/components/api/definition/model/ApiTestModel.js b/frontend/src/business/components/api/definition/model/ApiTestModel.js index f6ef40f9f2..4932b1e301 100644 --- a/frontend/src/business/components/api/definition/model/ApiTestModel.js +++ b/frontend/src/business/components/api/definition/model/ApiTestModel.js @@ -596,9 +596,11 @@ export class TCPRequest extends Request { super(RequestFactory.TYPES.TCP, options); this.useEnvironment = options.useEnvironment; this.debugReport = undefined; + this.parameters = []; //设置TCPConfig的属性 this.set(new TCPConfig(options)); + this.sets({parameters: KeyValue}, options); this.request = options.request; } diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index d7e9bb243d..e7fcb90cfa 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -564,6 +564,9 @@ export default { update_info: 'Update', batch_edit: "Batch edit", path_valid_info: "The request path is invalid", + other_config: "Other Config", + message_template: "Message Template", + tcp_parameter_tip: "The request parameters can be referenced in the request template ${XXX}", } }, automation: { diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 7aa1dfeb64..48e9ece9c8 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -563,6 +563,9 @@ export default { update_info: '更新', batch_edit: "批量编辑", path_valid_info: "请求路径无效", + other_config: "其他设置", + message_template: "报文模版", + tcp_parameter_tip: "请求参数可以在请求模版通过${xxx}引用", } }, automation: { diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 8a4e0202bd..de03c316c4 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -563,6 +563,9 @@ export default { update_info: '更新', batch_edit: "批量編輯", path_valid_info: "請求路徑無效", + other_config: "其他設置", + message_template: "報文模版", + tcp_parameter_tip: "請求參數可以在請求模版通過${xxx}引用", } }, automation: { @@ -1434,7 +1437,7 @@ export default { }, variables: { cvs_info: "只能上傳CSV文件", - end: "结束", + end: "結束", start: "開始", increment: "增量", counter_info: "000產生至少3位數字。user_000輸出形式為user_nnn",