From caf9444db42ded3531ef3436636687135fc3b347 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Mon, 30 Mar 2020 17:31:39 +0800 Subject: [PATCH 1/3] advanced config --- .../io/metersphere/engine/EngineContext.java | 4 + .../io/metersphere/engine/EngineFactory.java | 11 +- .../xml/reader/jmx/JmeterDocumentParser.java | 249 +++++++++++++++++- .../java/io/metersphere/JmxFileParseTest.java | 110 +++++++- 4 files changed, 370 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/io/metersphere/engine/EngineContext.java b/backend/src/main/java/io/metersphere/engine/EngineContext.java index 23001bec39..55232516cc 100644 --- a/backend/src/main/java/io/metersphere/engine/EngineContext.java +++ b/backend/src/main/java/io/metersphere/engine/EngineContext.java @@ -42,6 +42,10 @@ public class EngineContext { this.properties.put(key, value); } + public void addProperties(Map props) { + this.properties.putAll(props); + } + public Object getProperty(String key) { return this.properties.get(key); } diff --git a/backend/src/main/java/io/metersphere/engine/EngineFactory.java b/backend/src/main/java/io/metersphere/engine/EngineFactory.java index b202317d60..e6bfbaff71 100644 --- a/backend/src/main/java/io/metersphere/engine/EngineFactory.java +++ b/backend/src/main/java/io/metersphere/engine/EngineFactory.java @@ -77,7 +77,7 @@ public class EngineFactory { engineContext.setThreadNum(threadNum); engineContext.setResourcePoolId(loadTest.getTestResourcePoolId()); - if (!StringUtils.isEmpty(loadTest.getLoadConfiguration())) { + if (StringUtils.isNotEmpty(loadTest.getLoadConfiguration())) { final JSONArray jsonArray = JSONObject.parseArray(loadTest.getLoadConfiguration()); for (int i = 0; i < jsonArray.size(); i++) { @@ -85,6 +85,13 @@ public class EngineFactory { engineContext.addProperty(jsonObject.getString("key"), jsonObject.get("value")); } } + /* + {"timeout":10,"statusCode":["302","301"],"params":[{"name":"param1","enable":true,"value":"0","edit":false}],"domains":[{"domain":"baidu.com","enable":true,"ip":"127.0.0.1","edit":false}]} + */ + if (StringUtils.isNotEmpty(loadTest.getAdvancedConfiguration())) { + JSONObject advancedConfiguration = JSONObject.parseObject(loadTest.getAdvancedConfiguration()); + engineContext.addProperties(advancedConfiguration); + } final EngineSourceParser engineSourceParser = EngineSourceParserFactory.createEngineSourceParser(engineContext.getFileType()); @@ -95,6 +102,8 @@ public class EngineFactory { try (ByteArrayInputStream source = new ByteArrayInputStream(fileContent.getFile())) { String content = engineSourceParser.parse(engineContext, source); engineContext.setContent(content); + } catch (Exception e) { + MSException.throwException(e); } if (CollectionUtils.isNotEmpty(csvFiles)) { diff --git a/backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java b/backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java index cccc050a7a..6a271d4e38 100644 --- a/backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java +++ b/backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java @@ -1,10 +1,12 @@ package io.metersphere.parse.xml.reader.jmx; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.config.KafkaProperties; import io.metersphere.engine.EngineContext; import io.metersphere.parse.xml.reader.DocumentParser; -import org.junit.platform.commons.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -16,6 +18,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.StringWriter; +import java.util.List; public class JmeterDocumentParser implements DocumentParser { private final static String HASH_TREE_ELEMENT = "hashTree"; @@ -26,7 +29,9 @@ public class JmeterDocumentParser implements DocumentParser { private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer"; private final static String THREAD_GROUP = "ThreadGroup"; private final static String BACKEND_LISTENER = "BackendListener"; - + private final static String CONFIG_TEST_ELEMENT = "ConfigTestElement"; + private final static String DNS_CACHE_MANAGER = "DNSCacheManager"; + private final static String ARGUMENTS = "Arguments"; private EngineContext context; @Override @@ -79,6 +84,9 @@ public class JmeterDocumentParser implements DocumentParser { parseHashTree(ele); } else if (nodeNameEquals(ele, TEST_PLAN)) { processTearDownTestPlan(ele); + processCheckoutConfigTestElement(ele); + processCheckoutDnsCacheManager(ele); + processCheckoutArguments(ele); } else if (nodeNameEquals(ele, CONCURRENCY_THREAD_GROUP)) { processConcurrencyThreadGroup(ele); processCheckoutTimer(ele); @@ -93,12 +101,249 @@ public class JmeterDocumentParser implements DocumentParser { processCheckoutBackendListener(ele); } else if (nodeNameEquals(ele, BACKEND_LISTENER)) { processBackendListener(ele); + } else if (nodeNameEquals(ele, CONFIG_TEST_ELEMENT)) { + processConfigTestElement(ele); + } else if (nodeNameEquals(ele, DNS_CACHE_MANAGER)) { + processDnsCacheManager(ele); + } else if (nodeNameEquals(ele, ARGUMENTS)) { + processArguments(ele); } } } } } + private void processCheckoutArguments(Element ele) { + Node hashTree = ele.getNextSibling(); + while (!(hashTree instanceof Element)) { + hashTree = hashTree.getNextSibling(); + } + + NodeList childNodes = hashTree.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (nodeNameEquals(item, ARGUMENTS)) { + // 已经存在不再添加 + return; + } + } + /* + + + + BASE_URL_1 + rddev2.fit2cloud.com + = + + + + */ + + Document document = ele.getOwnerDocument(); + Element element = document.createElement(ARGUMENTS); + element.setAttribute("guiclass", "ArgumentsPanel"); + element.setAttribute("testclass", "Arguments"); + element.setAttribute("testname", "User Defined Variables"); + element.setAttribute("enabled", "true"); + Element collectionProp = document.createElement(COLLECTION_PROP); + collectionProp.setAttribute("name", "Arguments.arguments"); + element.appendChild(collectionProp); + hashTree.appendChild(element); + // 空的 hashTree + hashTree.appendChild(document.createElement(HASH_TREE_ELEMENT)); + } + + private void processCheckoutDnsCacheManager(Element ele) { + Node hashTree = ele.getNextSibling(); + while (!(hashTree instanceof Element)) { + hashTree = hashTree.getNextSibling(); + } + + NodeList childNodes = hashTree.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (nodeNameEquals(item, DNS_CACHE_MANAGER)) { + // 已经存在不再添加 + return; + } + } + /* + + + + + baiud.com + 172.16.10.187 + + + true + true + + */ + + Document document = ele.getOwnerDocument(); + Element element = document.createElement(DNS_CACHE_MANAGER); + element.setAttribute("guiclass", "DNSCachePanel"); + element.setAttribute("testclass", "DNSCacheManager"); + element.setAttribute("testname", "DNS Cache Manager"); + element.setAttribute("enabled", "true"); + Element collectionProp = document.createElement(COLLECTION_PROP); + collectionProp.setAttribute("name", "DNSCacheManager.servers"); + element.appendChild(collectionProp); + + Element collectionProp2 = document.createElement(COLLECTION_PROP); + collectionProp2.setAttribute("name", "DNSCacheManager.hosts"); + element.appendChild(collectionProp2); + + element.appendChild(createBoolProp(document, "DNSCacheManager.clearEachIteration", true)); + element.appendChild(createBoolProp(document, "DNSCacheManager.isCustomResolver", true)); + + hashTree.appendChild(element); + // 空的 hashTree + hashTree.appendChild(document.createElement(HASH_TREE_ELEMENT)); + } + + private void processCheckoutConfigTestElement(Element ele) { + Node hashTree = ele.getNextSibling(); + while (!(hashTree instanceof Element)) { + hashTree = hashTree.getNextSibling(); + } + + NodeList childNodes = hashTree.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (nodeNameEquals(item, CONFIG_TEST_ELEMENT)) { + // 已经存在不再添加 + return; + } + } +/* + + + + + + + + + + true + true + 6 + 30000 + + + */ + Document document = ele.getOwnerDocument(); + Element element = document.createElement(CONFIG_TEST_ELEMENT); + element.setAttribute("guiclass", "HttpDefaultsGui"); + element.setAttribute("testclass", "ConfigTestElement"); + element.setAttribute("testname", "HTTP Request Defaults"); + element.setAttribute("enabled", "true"); + Element elementProp = document.createElement("elementProp"); + elementProp.setAttribute("name", "HTTPsampler.Arguments"); + elementProp.setAttribute("elementType", "Arguments"); + elementProp.setAttribute("guiclass", "HTTPArgumentsPanel"); + elementProp.setAttribute("testclass", "Arguments"); + elementProp.setAttribute("enabled", "true"); + Element collectionProp = document.createElement(COLLECTION_PROP); + collectionProp.setAttribute("name", "Arguments.arguments"); + elementProp.appendChild(collectionProp); + element.appendChild(elementProp); + element.appendChild(createStringProp(document, "HTTPSampler.domain", "")); + element.appendChild(createStringProp(document, "HTTPSampler.port", "")); + element.appendChild(createStringProp(document, "HTTPSampler.protocol", "")); + element.appendChild(createStringProp(document, "HTTPSampler.contentEncoding", "")); + element.appendChild(createStringProp(document, "HTTPSampler.path", "")); + element.appendChild(createStringProp(document, "HTTPSampler.concurrentPool", "6")); + element.appendChild(createStringProp(document, "HTTPSampler.connect_timeout", "")); + element.appendChild(createStringProp(document, "HTTPSampler.response_timeout", "")); + element.appendChild(createBoolProp(document, "HTTPSampler.image_parser", true)); + element.appendChild(createBoolProp(document, "HTTPSampler.concurrentDwn", true)); + hashTree.appendChild(element); + // 空的 hashTree + hashTree.appendChild(document.createElement(HASH_TREE_ELEMENT)); + } + + private void processArguments(Element ele) { + NodeList childNodes = ele.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, "collectionProp")) { + removeChildren(item); + Document document = item.getOwnerDocument(); + Object params = context.getProperty("params"); + if (params instanceof List) { + for (Object p : (List) params) { + JSONObject jsonObject = JSON.parseObject(p.toString()); + if (!jsonObject.getBooleanValue("enable")) { + continue; + } + Element elementProp = document.createElement("elementProp"); + elementProp.setAttribute("name", jsonObject.getString("name")); + elementProp.setAttribute("elementType", "Argument"); + elementProp.appendChild(createStringProp(document, "Argument.name", jsonObject.getString("name"))); + elementProp.appendChild(createStringProp(document, "Argument.value", jsonObject.getString("value"))); + elementProp.appendChild(createStringProp(document, "Argument.metadata", "=")); + item.appendChild(elementProp); + } + } + } + } + + } + + private void processDnsCacheManager(Element ele) { + + NodeList childNodes = ele.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, "collectionProp") + && org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.hosts")) { + + removeChildren(item); + Document document = item.getOwnerDocument(); + Object domains = context.getProperty("domains"); + if (domains instanceof List) { + for (Object d : (List) domains) { + JSONObject jsonObject = JSON.parseObject(d.toString()); + if (!jsonObject.getBooleanValue("enable")) { + continue; + } + Element elementProp = document.createElement("elementProp"); + elementProp.setAttribute("name", jsonObject.getString("domain")); + elementProp.setAttribute("elementType", "StaticHost"); + elementProp.appendChild(createStringProp(document, "StaticHost.Name", jsonObject.getString("domain"))); + elementProp.appendChild(createStringProp(document, "StaticHost.Address", jsonObject.getString("ip"))); + item.appendChild(elementProp); + } + } + } + + if (item instanceof Element && nodeNameEquals(item, "boolProp") + && org.apache.commons.lang3.StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.isCustomResolver")) { + item.getFirstChild().setNodeValue("true"); + } + } + + } + + private void processConfigTestElement(Element ele) { + + NodeList childNodes = ele.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, STRING_PROP) + && StringUtils.equals(((Element) item).getAttribute("name"), "HTTPSampler.connect_timeout")) { + if (context.getProperty("timeout") != null) { + removeChildren(item); + item.appendChild(ele.getOwnerDocument().createTextNode(context.getProperty("timeout").toString())); + } + } + } + } + + private void processTearDownTestPlan(Element ele) { /*true*/ Document document = ele.getOwnerDocument(); diff --git a/backend/src/test/java/io/metersphere/JmxFileParseTest.java b/backend/src/test/java/io/metersphere/JmxFileParseTest.java index 1d2eaaded8..e09209270c 100644 --- a/backend/src/test/java/io/metersphere/JmxFileParseTest.java +++ b/backend/src/test/java/io/metersphere/JmxFileParseTest.java @@ -1,8 +1,8 @@ package io.metersphere; import io.metersphere.config.KafkaProperties; +import org.apache.commons.lang3.StringUtils; import org.junit.Test; -import org.junit.platform.commons.util.StringUtils; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @@ -33,6 +33,9 @@ public class JmxFileParseTest { private final static String VARIABLE_THROUGHPUT_TIMER = "kg.apc.jmeter.timers.VariableThroughputTimer"; private final static String BACKEND_LISTENER = "BackendListener"; private final static String THREAD_GROUP = "ThreadGroup"; + private final static String CONFIG_TEST_ELEMENT = "ConfigTestElement"; + private final static String DNS_CACHE_MANAGER = "DNSCacheManager"; + private final static String ARGUMENTS = "Arguments"; @Resource private KafkaProperties kafkaProperties; @@ -110,12 +113,117 @@ public class JmxFileParseTest { } else if (nodeNameEquals(ele, BACKEND_LISTENER)) { processBackendListener(ele); + } else if (nodeNameEquals(ele, CONFIG_TEST_ELEMENT)) { + processConfigTestElement(ele); + } else if (nodeNameEquals(ele, DNS_CACHE_MANAGER)) { + processDnsCacheManager(ele); + } else if (nodeNameEquals(ele, ARGUMENTS)) { + processArguments(ele); } } } } } + private void processArguments(Element ele) { + /* + + + + BASE_URL_1 + rddev2.fit2cloud.com + = + + + + */ + NodeList childNodes = ele.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, "collectionProp")) { + removeChildren(item); + Document document = item.getOwnerDocument(); + Element elementProp = document.createElement("elementProp"); + elementProp.setAttribute("name", ""); + elementProp.setAttribute("elementType", ""); + elementProp.appendChild(createStringProp(document, "Argument.name", "")); + elementProp.appendChild(createStringProp(document, "Argument.value", "")); + elementProp.appendChild(createStringProp(document, "Argument.metadata", "=")); + item.appendChild(elementProp); + } + } + + } + + private void processDnsCacheManager(Element ele) { + /* + + + + + baiud.com + 172.16.10.187 + + + true + true + + */ + NodeList childNodes = ele.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, "collectionProp") + && StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.hosts")) { + Node childNode = item.getFirstChild(); + // todo 绑定域名 多个 + while (!(childNode instanceof Element)) { + childNode = childNode.getNextSibling(); + } + Element elementProp = ((Element) childNode); + elementProp.setAttribute("name", "baidu.com"); + elementProp.setAttribute("elementType", "StaticHost"); + removeChildren(elementProp); + elementProp.appendChild(createStringProp(ele.getOwnerDocument(), "StaticHost.Name", "")); + elementProp.appendChild(createStringProp(ele.getOwnerDocument(), "StaticHost.Address", "")); + } + + if (item instanceof Element && nodeNameEquals(item, "boolProp") + && StringUtils.equals(((Element) item).getAttribute("name"), "DNSCacheManager.isCustomResolver")) { + item.getFirstChild().setNodeValue("true"); + } + } + + } + + private void processConfigTestElement(Element ele) { + /* + + + + + + + + + + true + true + 6 + 30000 + + + */ + NodeList childNodes = ele.getChildNodes(); + for (int i = 0, size = childNodes.getLength(); i < size; i++) { + Node item = childNodes.item(i); + if (item instanceof Element && nodeNameEquals(item, STRING_PROP) + && StringUtils.equals(((Element) item).getAttribute("name"), "HTTPSampler.connect_timeout")) { + + item.getFirstChild().setNodeValue("30000"); + } + } + } + private void processTearDownTestPlan(Element ele) { /*true*/ Document document = ele.getOwnerDocument(); From c2daa8090e094864363f631a7d1486ab1fe07e38 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Mon, 30 Mar 2020 18:24:23 +0800 Subject: [PATCH 2/3] bug fix --- .../performance/plan/components/PerformanceBasicConfig.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/business/components/performance/plan/components/PerformanceBasicConfig.vue b/frontend/src/business/components/performance/plan/components/PerformanceBasicConfig.vue index 006501cf40..5148b1e882 100644 --- a/frontend/src/business/components/performance/plan/components/PerformanceBasicConfig.vue +++ b/frontend/src/business/components/performance/plan/components/PerformanceBasicConfig.vue @@ -167,7 +167,9 @@ this.tableData.splice(index, 1); // let i = this.uploadList.indexOf(file); - this.uploadList.splice(i, 1); + if (i > -1) { + this.uploadList.splice(i, 1); + } }, handleExceed() { this.$message.error(this.$t('load_test.delete_file')); From 780507604099151e7d7e3a092eb1f38c3b437095 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Mon, 30 Mar 2020 18:35:14 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=8D=E8=83=BD=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/io/metersphere/service/LoadTestService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/service/LoadTestService.java b/backend/src/main/java/io/metersphere/service/LoadTestService.java index a9396f4dd8..31e45c0289 100644 --- a/backend/src/main/java/io/metersphere/service/LoadTestService.java +++ b/backend/src/main/java/io/metersphere/service/LoadTestService.java @@ -167,7 +167,7 @@ public class LoadTestService { MSException.throwException(Translator.get("run_load_test_not_found") + request.getId()); } if (TestStatus.Running.name().equals(loadTest.getStatus())) { - MSException.throwException(Translator.get("load_test_is_running") + request.getId()); + MSException.throwException(Translator.get("load_test_is_running")); } LogUtil.info("Load test started " + loadTest.getName());