Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
4f3af764d5
|
@ -71,7 +71,6 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
|
|
||||||
// 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id
|
// 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id
|
||||||
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
|
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
|
||||||
|
|
||||||
queue.forEach(result -> {
|
queue.forEach(result -> {
|
||||||
// 线程名称: <场景名> <场景Index>-<请求Index>, 例如:Scenario 2-1
|
// 线程名称: <场景名> <场景Index>-<请求Index>, 例如:Scenario 2-1
|
||||||
String scenarioName = StringUtils.substringBeforeLast(result.getThreadName(), THREAD_SPLIT);
|
String scenarioName = StringUtils.substringBeforeLast(result.getThreadName(), THREAD_SPLIT);
|
||||||
|
@ -154,6 +153,21 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
responseResult.setResponseTime(result.getTime());
|
responseResult.setResponseTime(result.getTime());
|
||||||
responseResult.setResponseMessage(result.getResponseMessage());
|
responseResult.setResponseMessage(result.getResponseMessage());
|
||||||
|
|
||||||
|
if (JMeterVars.get(result.hashCode()) != null) {
|
||||||
|
List<String> vars = new LinkedList<>();
|
||||||
|
JMeterVars.get(result.hashCode()).entrySet().parallelStream().reduce(vars, (first, second) -> {
|
||||||
|
first.add(second.getKey() + ":" + second.getValue());
|
||||||
|
return first;
|
||||||
|
}, (first, second) -> {
|
||||||
|
if (first == second) {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
first.addAll(second);
|
||||||
|
return first;
|
||||||
|
});
|
||||||
|
responseResult.setVars(StringUtils.join(vars, "\n"));
|
||||||
|
JMeterVars.remove(result.hashCode());
|
||||||
|
}
|
||||||
for (AssertionResult assertionResult : result.getAssertionResults()) {
|
for (AssertionResult assertionResult : result.getAssertionResults()) {
|
||||||
ResponseAssertionResult responseAssertionResult = getResponseAssertionResult(assertionResult);
|
ResponseAssertionResult responseAssertionResult = getResponseAssertionResult(assertionResult);
|
||||||
if (responseAssertionResult.isPass()) {
|
if (responseAssertionResult.isPass()) {
|
||||||
|
|
|
@ -41,8 +41,8 @@ public class JMeterService {
|
||||||
try {
|
try {
|
||||||
Object scriptWrapper = SaveService.loadElement(is);
|
Object scriptWrapper = SaveService.loadElement(is);
|
||||||
HashTree testPlan = getHashTree(scriptWrapper);
|
HashTree testPlan = getHashTree(scriptWrapper);
|
||||||
|
JMeterVars.addJSR223PostProcessor(testPlan);
|
||||||
addBackendListener(testId, debugReportId, testPlan);
|
addBackendListener(testId, debugReportId, testPlan);
|
||||||
|
|
||||||
LocalRunner runner = new LocalRunner(testPlan);
|
LocalRunner runner = new LocalRunner(testPlan);
|
||||||
runner.run();
|
runner.run();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package io.metersphere.api.jmeter;
|
||||||
|
|
||||||
|
import org.apache.jmeter.extractor.JSR223PostProcessor;
|
||||||
|
import org.apache.jmeter.extractor.RegexExtractor;
|
||||||
|
import org.apache.jmeter.extractor.XPath2Extractor;
|
||||||
|
import org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor;
|
||||||
|
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||||
|
import org.apache.jmeter.threads.JMeterVariables;
|
||||||
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class JMeterVars {
|
||||||
|
|
||||||
|
private JMeterVars() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据和线程变量保持一致
|
||||||
|
private static Map<Integer, JMeterVariables> variables = new HashMap<>();
|
||||||
|
|
||||||
|
// 线程执行过程调用提取变量值
|
||||||
|
public static void addVars(Integer testId, JMeterVariables vars, String extract) {
|
||||||
|
JMeterVariables vs = new JMeterVariables();
|
||||||
|
if (!StringUtils.isEmpty(extract) && vars != null) {
|
||||||
|
List<String> extracts = Arrays.asList(extract.split(";"));
|
||||||
|
Optional.ofNullable(extracts).orElse(new ArrayList<>()).forEach(item -> {
|
||||||
|
vs.put(item, vars.get(item) == null ? "" : vars.get(item));
|
||||||
|
});
|
||||||
|
vs.remove("TESTSTART.MS"); // 标示变量移除
|
||||||
|
}
|
||||||
|
variables.put(testId, vs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归处理所有请求,对有提取变量的增加后置脚本
|
||||||
|
public static void addJSR223PostProcessor(HashTree tree) {
|
||||||
|
for (Object key : tree.keySet()) {
|
||||||
|
HashTree node = tree.get(key);
|
||||||
|
if (key instanceof HTTPSamplerProxy) {
|
||||||
|
StringJoiner extract = new StringJoiner(";");
|
||||||
|
for (Object child : node.keySet()) {
|
||||||
|
if (child instanceof RegexExtractor) {
|
||||||
|
RegexExtractor regexExtractor = (RegexExtractor) child;
|
||||||
|
extract.add(regexExtractor.getRefName());
|
||||||
|
} else if (child instanceof XPath2Extractor) {
|
||||||
|
XPath2Extractor regexExtractor = (XPath2Extractor) child;
|
||||||
|
extract.add(regexExtractor.getRefName());
|
||||||
|
} else if (child instanceof JSONPostProcessor) {
|
||||||
|
JSONPostProcessor regexExtractor = (JSONPostProcessor) child;
|
||||||
|
extract.add(regexExtractor.getRefNames());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Optional.ofNullable(extract).orElse(extract).length() > 0) {
|
||||||
|
JSR223PostProcessor shell = new JSR223PostProcessor();
|
||||||
|
shell.setEnabled(true);
|
||||||
|
shell.setProperty("script", "io.metersphere.api.jmeter.JMeterVars.addVars(prev.hashCode(),vars," + "\"" + extract.toString() + "\"" + ");");
|
||||||
|
node.add(shell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node != null) {
|
||||||
|
addJSR223PostProcessor(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JMeterVariables get(Integer key) {
|
||||||
|
return variables.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove(Integer key) {
|
||||||
|
variables.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ public class ResponseResult {
|
||||||
|
|
||||||
private String body;
|
private String body;
|
||||||
|
|
||||||
|
private String vars;
|
||||||
|
|
||||||
private final List<ResponseAssertionResult> assertions = new ArrayList<>();
|
private final List<ResponseAssertionResult> assertions = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
</template>
|
</template>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane">
|
||||||
|
<pre>{{response.vars}}</pre>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-collapse-transition>
|
</el-collapse-transition>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue