feat: TCP优化

This commit is contained in:
chenjianxing 2021-01-20 20:27:12 +08:00
parent 3a342b915d
commit 9c310d7678
5 changed files with 223 additions and 148 deletions

View File

@ -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;
}
}

View File

@ -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<KeyValue> parameters;
@JSONField(ordinal = 36)
private String useEnvironment;
@JSONField(ordinal = 37)
private MsJSR223PreProcessor tcpPreProcessor;
@Override
public void toHashTree(HashTree tree, List<MsTestElement> 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<StringProperty> names = new ArrayList<>();
List<StringProperty> 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<CollectionProperty> 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() {

View File

@ -0,0 +1,162 @@
<template>
<div>
<el-row style="margin:0px 10px 10px">
<el-col>
<div class="document-url">
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor"
type="primary">{{$t('commons.reference_documentation')}}
</el-link>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="20" class="script-content">
<ms-code-edit v-if="isCodeEditAlive" :mode="codeEditModeMap[jsr223ProcessorData.scriptLanguage]"
:read-only="isReadOnly"
:data.sync="jsr223ProcessorData.script" theme="eclipse" :modes="['java','python']"
ref="codeEdit"/>
</el-col>
<el-col :span="4" class="script-index">
<ms-dropdown :default-command="jsr223ProcessorData.scriptLanguage" :commands="languages" @command="languageChange"/>
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import MsCodeEdit from "../../../definition/components/MsCodeEdit";
import MsDropdown from "../../../../common/components/MsDropdown";
export default {
name: "Jsr233ProcessorContent",
components: {MsDropdown, 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;
},
props: {
isReadOnly: {
type: Boolean,
default:
false
},
jsr223Processor: {
type: Object,
},
isPreProcessor: {
type: Boolean,
default:
false
},
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();
},
reload() {
this.isCodeEditAlive = false;
this.$nextTick(() => (this.isCodeEditAlive = true));
},
languageChange(language) {
this.jsr223ProcessorData.scriptLanguage = language;
},
}
}
</script>
<style scoped>
.ace_editor {
border-radius: 5px;
}
.script-content {
height: calc(100vh - 570px);
}
.script-index {
padding: 0 20px;
}
.template-title {
margin-bottom: 5px;
font-weight: bold;
font-size: 15px;
}
.document-url {
margin-top: 10px;
}
.instructions-icon {
margin-left: 5px;
}
.ms-dropdown {
margin-bottom: 20px;
}
</style>

View File

@ -2,35 +2,18 @@
<api-base-component
@copy="copyRow"
@remove="remove"
:data="jsr223ProcessorData"
:data="jsr223Processor"
:draggable="draggable"
:color="color"
:background-color="backgroundColor"
:title="title">
<el-row style="margin:0px 10px 10px">
<el-col>
<div class="document-url">
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor"
type="primary">{{$t('commons.reference_documentation')}}
</el-link>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="20" class="script-content">
<ms-code-edit v-if="isCodeEditAlive" :mode="codeEditModeMap[jsr223ProcessorData.scriptLanguage]"
:read-only="isReadOnly"
:data.sync="jsr223ProcessorData.script" theme="eclipse" :modes="['java','python']"
ref="codeEdit"/>
</el-col>
<el-col :span="4" class="script-index">
<ms-dropdown :default-command="jsr223ProcessorData.scriptLanguage" :commands="languages" @command="languageChange"/>
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
</div>
</el-col>
</el-row>
<jsr233-processor-content
:jsr223-processor="jsr223Processor"
:is-pre-processor="isPreProcessor"
:node="node"
:is-read-only="isReadOnly"/>
</api-base-component>
</template>
@ -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;
},
}
}
</script>
<style scoped>
.ace_editor {
border-radius: 5px;
}
.script-content {
height: calc(100vh - 570px);
}
.script-index {
padding: 0 20px;
}
.template-title {
margin-bottom: 5px;
font-weight: bold;
font-size: 15px;
}
.document-url {
margin-top: 10px;
}
.instructions-icon {
margin-left: 5px;
}
.ms-dropdown {
margin-bottom: 20px;
}
/deep/ .el-divider {
margin-bottom: 10px;
}

View File

@ -23,6 +23,13 @@
</div>
</el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.pre_script')" name="script">
<jsr233-processor-content
:jsr223-processor="request.tcpPreProcessor"
:is-pre-processor="true"
:is-read-only="isReadOnly"/>
</el-tab-pane>
<el-tab-pane :label="$t('api_test.definition.request.other_config')" name="other" class="other-config">
<el-row>
<el-col :span="8">
@ -138,11 +145,14 @@
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
import MsApiVariable from "../../ApiVariable";
import MsInstructionsIcon from "../../../../../common/components/MsInstructionsIcon";
import Jsr233ProcessorContent from "../../../../automation/scenario/common/Jsr233ProcessorContent";
import JSR223PreProcessor from "../../jmeter/components/pre-processors/jsr223-pre-processor";
export default {
name: "TcpBasisParameters",
components: {
Jsr233ProcessorContent,
MsInstructionsIcon,
MsApiVariable,
MsApiScenarioVariables,
@ -178,6 +188,9 @@
this.$set(this.request, 'parameters', []);
this.request.parameters = [];
}
if (!this.request.tcpPreProcessor) {
this.$set(this.request, 'tcpPreProcessor', new JSR223PreProcessor())
}
this.getEnvironments();
},
methods: {