diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..dac72e3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + io.metersphere + metersphere-plugin-ParallelController + 1.0.0 + + + UTF-8 + 1.8 + ${pom.basedir}/src/main/resources + + + + + io.metersphere + metersphere-plugin-core + 1.0.1 + provided + + + com.blazemeter + jmeter-parallel + 0.11 + + + org.apache.commons + commons-collections4 + 4.4 + provided + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.5 + + + ${custom.lib-path}/xml/assembly.xml + + + + + make-assembly + package + + single + + + + + + + + \ No newline at end of file diff --git a/src/main/java/io/metersphere/plugin/parallel/UiScriptApiImpl.java b/src/main/java/io/metersphere/plugin/parallel/UiScriptApiImpl.java new file mode 100644 index 0000000..b752773 --- /dev/null +++ b/src/main/java/io/metersphere/plugin/parallel/UiScriptApiImpl.java @@ -0,0 +1,54 @@ +package io.metersphere.plugin.parallel; + +import io.metersphere.plugin.core.api.UiScriptApi; +import io.metersphere.plugin.core.ui.PluginResource; +import io.metersphere.plugin.core.ui.UiScript; +import io.metersphere.plugin.core.utils.LogUtil; + +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; + +public class UiScriptApiImpl extends UiScriptApi { + /** + * 企业版插件增加 这个方法 + * + * @return 是否是企业版插件 + */ + public boolean xpack() { + return false; + } + + @Override + public PluginResource init() { + LogUtil.info("开始初始化脚本内容 "); + List uiScripts = new LinkedList<>(); + String scriptString = getJson("/json/ui_parallel.json"); + UiScript script = new UiScript("parallel_controller", "并行控制器", "io.metersphere.plugin.parallel.controller.MsParallelController", scriptString); + script.setJmeterClazz("GenericController"); + + // 添加可选参数 + script.setFormOption(getJson("/json/ui_form.json")); + + uiScripts.add(script); + LogUtil.info("初始化脚本内容结束 "); + return new PluginResource("parallel-v1.0.0", uiScripts); + } + + @Override + public String customMethod(String req) { + LogUtil.info("Parallel Controller 自定义方法"); + return null; + } + + public String getJson(String path) { + try { + InputStream in = UiScriptApiImpl.class.getResourceAsStream(path); + String json = org.apache.commons.io.IOUtils.toString(in); + return json; + } catch (Exception ex) { + LogUtil.error(ex.getMessage()); + } + return null; + } +} diff --git a/src/main/java/io/metersphere/plugin/parallel/controller/MsParallelController.java b/src/main/java/io/metersphere/plugin/parallel/controller/MsParallelController.java new file mode 100644 index 0000000..d909425 --- /dev/null +++ b/src/main/java/io/metersphere/plugin/parallel/controller/MsParallelController.java @@ -0,0 +1,82 @@ +package io.metersphere.plugin.parallel.controller; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import io.metersphere.plugin.core.MsParameter; +import io.metersphere.plugin.core.MsTestElement; +import io.metersphere.plugin.core.utils.LogUtil; +import io.metersphere.plugin.parallel.utils.ElementUtil; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.collections.CollectionUtils; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; +import com.blazemeter.jmeter.controller.ParallelSampler; + +import java.util.LinkedList; +import java.util.List; +@Data +@EqualsAndHashCode(callSuper = true) +public class MsParallelController extends MsTestElement { + public MsParallelController() { + + } + private String clazzName = "io.metersphere.plugin.parallel.controller.MsParallelController"; + + @JSONField(ordinal = 21) + private Boolean limitMaxThread; + @JSONField(ordinal = 22) + private String maxThreads; + + @Override + public void toHashTree(HashTree tree, List hashTree, MsParameter config) { + LogUtil.info("===========开始转换MsDummySampler =================="); + if (!this.isEnable()) { + return; + } + ParallelSampler initParallelSampler = initParallelSampler(); + if (initParallelSampler != null) { + final HashTree groupTree = tree.add(initParallelSampler()); + if (CollectionUtils.isNotEmpty(hashTree)) { + hashTree.forEach(el -> { + // 给所有孩子加一个父亲标志 + el.setParent(this); + el.toHashTree(groupTree, el.getHashTree(), config); + }); + } + } + else { + LogUtil.error("Connect Sampler 生成失败"); + throw new RuntimeException("Connect Sampler生成失败"); + } + } + + public ParallelSampler initParallelSampler() { + try { + ParallelSampler parallelSampler = new ParallelSampler(); + // base 执行时需要的参数 + parallelSampler.setProperty("MS-ID", this.getId()); + String indexPath = this.getIndex(); + parallelSampler.setProperty("MS-RESOURCE-ID", this.getResourceId() + "_" + ElementUtil.getFullIndexPath(this.getParent(), indexPath)); + List id_names = new LinkedList<>(); + ElementUtil.getScenarioSet(this, id_names); + parallelSampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); + + parallelSampler.setEnabled(this.isEnable()); + parallelSampler.setName(this.getName()); + parallelSampler.setProperty(TestElement.GUI_CLASS, "com.blazemeter.jmeter.controller.ParallelControllerGui"); + parallelSampler.setProperty(TestElement.TEST_CLASS, "com.blazemeter.jmeter.controller.ParallelSampler"); + + parallelSampler.setProperty("PARENT_SAMPLE", false); + parallelSampler.setProperty("LIMIT_MAX_THREAD_NUMBER", this.getLimitMaxThread()); + if (this.getLimitMaxThread() != null && this.getLimitMaxThread()) { + parallelSampler.setProperty("MAX_THREAD_NUMBER", this.getMaxThreads()); + } + + return parallelSampler; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/io/metersphere/plugin/parallel/utils/ElementUtil.java b/src/main/java/io/metersphere/plugin/parallel/utils/ElementUtil.java new file mode 100644 index 0000000..8bf010a --- /dev/null +++ b/src/main/java/io/metersphere/plugin/parallel/utils/ElementUtil.java @@ -0,0 +1,26 @@ +package io.metersphere.plugin.parallel.utils; + +import io.metersphere.plugin.core.MsTestElement; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +public class ElementUtil { + public static void getScenarioSet(MsTestElement element, List id_names) { + if (StringUtils.equals(element.getType(), "scenario")) { + id_names.add(element.getResourceId() + "_" + element.getName()); + } + if (element.getParent() == null) { + return; + } + getScenarioSet(element.getParent(), id_names); + } + + public static String getFullIndexPath(MsTestElement element, String path) { + if (element == null || element.getParent() == null) { + return path; + } + path = element.getIndex() + "_" + path; + return getFullIndexPath(element.getParent(), path); + } +} diff --git a/src/main/resources/json/ui_form.json b/src/main/resources/json/ui_form.json new file mode 100644 index 0000000..3c55deb --- /dev/null +++ b/src/main/resources/json/ui_form.json @@ -0,0 +1,11 @@ +{ + "form": { + "inline": false, + "labelPosition": "left", + "size": "mini", + "labelWidth": "200px", + "hideRequiredAsterisk": false, + "showMessage": true, + "inlineMessage": false + } +} \ No newline at end of file diff --git a/src/main/resources/json/ui_parallel.json b/src/main/resources/json/ui_parallel.json new file mode 100644 index 0000000..4869f7c --- /dev/null +++ b/src/main/resources/json/ui_parallel.json @@ -0,0 +1,33 @@ +[ + { + "type": "switch", + "field": "limitMaxThread", + "title": "Limit max thread number", + "info": "", + "_fc_drag_tag": "switch", + "hidden": false, + "display": true, + "value": false, + "props": { + "activeText": "", + "inactiveText": "" + }, + "control": [ + { + "value": true, + "rule": [ + { + "type": "inputNumber", + "field": "maxThreads", + "title": "Max threads", + "info": "", + "_fc_drag_tag": "inputNumber", + "hidden": false, + "display": true, + "value": 5 + } + ] + } + ] + } +] \ No newline at end of file diff --git a/src/main/resources/metersphere-plugin-ParallelController-1.0.0-jar-with-all-dependencies b/src/main/resources/metersphere-plugin-ParallelController-1.0.0-jar-with-all-dependencies new file mode 100644 index 0000000..7816134 --- /dev/null +++ b/src/main/resources/metersphere-plugin-ParallelController-1.0.0-jar-with-all-dependencies @@ -0,0 +1 @@ +io.metersphere.plugin.parallel.UiScriptApiImpl \ No newline at end of file diff --git a/src/main/resources/xml/assembly.xml b/src/main/resources/xml/assembly.xml new file mode 100644 index 0000000..7af2ea3 --- /dev/null +++ b/src/main/resources/xml/assembly.xml @@ -0,0 +1,26 @@ + + jar-with-all-dependencies + + jar + + false + + + / + true + true + runtime + false + + + / + true + system + false + + + + \ No newline at end of file