feat(性能测试): 支持自动停止

This commit is contained in:
Captain.B 2021-04-06 13:22:38 +08:00 committed by 刘瑞斌
parent 7b5c15a565
commit 71c3e92332
2 changed files with 69 additions and 11 deletions

View File

@ -40,8 +40,8 @@ public class JmeterDocumentParser implements DocumentParser {
private final static String ARGUMENTS = "Arguments"; private final static String ARGUMENTS = "Arguments";
private final static String RESPONSE_ASSERTION = "ResponseAssertion"; private final static String RESPONSE_ASSERTION = "ResponseAssertion";
private final static String CSV_DATA_SET = "CSVDataSet"; private final static String CSV_DATA_SET = "CSVDataSet";
private final static String THREAD_GROUP_AUTO_STOP = "io.metersphere.jmeter.reporters.ThreadGroupAutoStop";
private EngineContext context; private EngineContext context;
private boolean containsIterationThread = false;
@Override @Override
public String parse(EngineContext context, Document document) throws Exception { public String parse(EngineContext context, Document document) throws Exception {
@ -98,6 +98,7 @@ public class JmeterDocumentParser implements DocumentParser {
processCheckoutResponseAssertion(ele); processCheckoutResponseAssertion(ele);
processCheckoutSerializeThreadgroups(ele); processCheckoutSerializeThreadgroups(ele);
processCheckoutBackendListener(ele); processCheckoutBackendListener(ele);
processCheckoutAutoStopListener(ele);
} else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) { } else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) {
processThreadGroupName(ele); processThreadGroupName(ele);
processCheckoutTimer(ele); processCheckoutTimer(ele);
@ -113,7 +114,6 @@ public class JmeterDocumentParser implements DocumentParser {
} }
if ("ITERATION".equals(o)) { if ("ITERATION".equals(o)) {
processIterationThreadGroup(ele); processIterationThreadGroup(ele);
this.containsIterationThread = true; // 包括按照迭代次数的线程组
} }
} else { } else {
processThreadGroup(ele); processThreadGroup(ele);
@ -134,6 +134,8 @@ public class JmeterDocumentParser implements DocumentParser {
processResponseAssertion(ele); processResponseAssertion(ele);
} else if (nodeNameEquals(ele, CSV_DATA_SET)) { } else if (nodeNameEquals(ele, CSV_DATA_SET)) {
processCsvDataSet(ele); processCsvDataSet(ele);
} else if (nodeNameEquals(ele, THREAD_GROUP_AUTO_STOP)) {
processAutoStopListener(ele);
} }
// 处理http上传的附件 // 处理http上传的附件
if (isHTTPFileArg(ele)) { if (isHTTPFileArg(ele)) {
@ -144,6 +146,46 @@ public class JmeterDocumentParser implements DocumentParser {
} }
} }
private void processAutoStopListener(Element autoStopListener) {
Object autoStopDelays = context.getProperty("autoStopDelay");
String autoStopDelay = "30";
if (autoStopDelays instanceof List) {
Object o = ((List<?>) autoStopDelays).get(0);
autoStopDelay = o.toString();
}
Document document = autoStopListener.getOwnerDocument();
// 清空child
removeChildren(autoStopListener);
autoStopListener.appendChild(createStringProp(document, "delay_seconds", autoStopDelay));
}
private void processCheckoutAutoStopListener(Element element) {
Object autoStops = context.getProperty("autoStop");
String autoStop = "false";
if (autoStops instanceof List) {
Object o = ((List<?>) autoStops).get(0);
autoStop = o.toString();
}
if (!BooleanUtils.toBoolean(autoStop)) {
return;
}
Document document = element.getOwnerDocument();
Node listenerParent = element.getNextSibling();
while (!(listenerParent instanceof Element)) {
listenerParent = listenerParent.getNextSibling();
}
// add class name
Element autoStopListener = document.createElement(THREAD_GROUP_AUTO_STOP);
autoStopListener.setAttribute("guiclass", "io.metersphere.jmeter.reporters.ThreadGroupAutoStopGui");
autoStopListener.setAttribute("testclass", "io.metersphere.jmeter.reporters.ThreadGroupAutoStop");
autoStopListener.setAttribute("testname", "MeterSphere - AutoStop Listener");
autoStopListener.setAttribute("enabled", "true");
listenerParent.appendChild(autoStopListener);
listenerParent.appendChild(document.createElement(HASH_TREE_ELEMENT));
}
private void processCheckoutSerializeThreadgroups(Element element) { private void processCheckoutSerializeThreadgroups(Element element) {
Object serializeThreadGroups = context.getProperty("serializeThreadGroups"); Object serializeThreadGroups = context.getProperty("serializeThreadGroups");
String serializeThreadGroup = "false"; String serializeThreadGroup = "false";
@ -548,15 +590,6 @@ public class JmeterDocumentParser implements DocumentParser {
} }
private void processBackendListener(Element backendListener) { private void processBackendListener(Element backendListener) {
String duration = "0";
Object expectedDurations = context.getProperty("expectedDuration");
if (expectedDurations instanceof List) {
Object o = ((List<?>) expectedDurations).get(0);// 预计执行时间已经计算好
duration = o.toString() + "000"; // 转成 ms
}
if (this.containsIterationThread) {
duration = Integer.MAX_VALUE + ""; // 如果包含了按照迭代次数的线程组预计执行时间很长
}
KafkaProperties kafkaProperties = CommonBeanFactory.getBean(KafkaProperties.class); KafkaProperties kafkaProperties = CommonBeanFactory.getBean(KafkaProperties.class);
Document document = backendListener.getOwnerDocument(); Document document = backendListener.getOwnerDocument();
// 清空child // 清空child

View File

@ -16,6 +16,19 @@
<el-form-item :label="$t('load_test.serialize_threadgroups')"> <el-form-item :label="$t('load_test.serialize_threadgroups')">
<el-switch v-model="serializeThreadGroups"/> <el-switch v-model="serializeThreadGroups"/>
</el-form-item> </el-form-item>
<br>
<el-form-item :label="$t('自动停止开启')">
<el-switch v-model="autoStop"/>
</el-form-item>
<el-form-item :label="$t('到达执行时间')">
<el-input-number
:disabled="isReadOnly || !autoStop"
v-model="autoStopDelay"
:min="1"
:max="9999"
size="mini"/>
</el-form-item>
<el-form-item :label="$t('秒后停止测试')"/>
</el-form> </el-form>
</el-col> </el-col>
</el-row> </el-row>
@ -181,6 +194,8 @@ import {findThreadGroup} from "@/business/components/performance/test/model/Thre
const HANDLER = "handler"; const HANDLER = "handler";
const THREAD_GROUP_TYPE = "tgType"; const THREAD_GROUP_TYPE = "tgType";
const SERIALIZE_THREAD_GROUPS = "serializeThreadGroups"; const SERIALIZE_THREAD_GROUPS = "serializeThreadGroups";
const AUTO_STOP = "autoStop";
const AUTO_STOP_DELAY = "autoStopDelay";
const TARGET_LEVEL = "TargetLevel"; const TARGET_LEVEL = "TargetLevel";
const RAMP_UP = "RampUp"; const RAMP_UP = "RampUp";
const ITERATE_RAMP_UP = "iterateRampUpTime"; const ITERATE_RAMP_UP = "iterateRampUpTime";
@ -236,6 +251,8 @@ export default {
resourcePoolResourceLength: 1, resourcePoolResourceLength: 1,
maxThreadNumbers: 5000, maxThreadNumbers: 5000,
serializeThreadGroups: false, serializeThreadGroups: false,
autoStop: false,
autoStopDelay: 30,
} }
}, },
mounted() { mounted() {
@ -325,6 +342,12 @@ export default {
case SERIALIZE_THREAD_GROUPS: case SERIALIZE_THREAD_GROUPS:
this.serializeThreadGroups = item.value;// 线 this.serializeThreadGroups = item.value;// 线
break; break;
case AUTO_STOP:
this.autoStop = item.value;// 线
break;
case AUTO_STOP_DELAY:
this.autoStopDelay = item.value;// 线
break;
default: default:
break; break;
} }
@ -670,6 +693,8 @@ export default {
{key: DELETED, value: this.threadGroups[i].deleted}, {key: DELETED, value: this.threadGroups[i].deleted},
{key: THREAD_GROUP_TYPE, value: this.threadGroups[i].tgType}, {key: THREAD_GROUP_TYPE, value: this.threadGroups[i].tgType},
{key: SERIALIZE_THREAD_GROUPS, value: this.serializeThreadGroups}, {key: SERIALIZE_THREAD_GROUPS, value: this.serializeThreadGroups},
{key: AUTO_STOP, value: this.autoStop},
{key: AUTO_STOP_DELAY, value: this.autoStopDelay},
]); ]);
} }