From d6f285a1d478ea41e4b53c9ca405897fe282b5bf Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Thu, 26 Mar 2020 13:40:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/request/TestRequest.java | 15 +++++-- .../io/metersphere/engine/AbstractEngine.java | 6 +-- .../java/io/metersphere/engine/Engine.java | 3 -- .../io/metersphere/engine/EngineFactory.java | 4 +- .../engine/docker/DockerTestEngine.java | 45 +++++++++++++------ .../kubernetes/KubernetesTestEngine.java | 31 +++++++++++-- .../metersphere/service/LoadTestService.java | 11 +---- 7 files changed, 77 insertions(+), 38 deletions(-) diff --git a/backend/src/main/java/io/metersphere/controller/request/TestRequest.java b/backend/src/main/java/io/metersphere/controller/request/TestRequest.java index bb4cdcbbf0..94c0214ab1 100644 --- a/backend/src/main/java/io/metersphere/controller/request/TestRequest.java +++ b/backend/src/main/java/io/metersphere/controller/request/TestRequest.java @@ -2,9 +2,10 @@ package io.metersphere.controller.request; public class TestRequest { - int size; - String fileString; - String testId; + private int size; + private String fileString; + private String testId; + private String image; public int getSize() { return size; @@ -29,4 +30,12 @@ public class TestRequest { public void setTestId(String testId) { this.testId = testId; } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } } diff --git a/backend/src/main/java/io/metersphere/engine/AbstractEngine.java b/backend/src/main/java/io/metersphere/engine/AbstractEngine.java index 3596b135ab..26a4219639 100644 --- a/backend/src/main/java/io/metersphere/engine/AbstractEngine.java +++ b/backend/src/main/java/io/metersphere/engine/AbstractEngine.java @@ -19,6 +19,8 @@ import org.apache.commons.lang3.StringUtils; import java.util.List; public abstract class AbstractEngine implements Engine { + public static final String JMETER_IMAGE = "jmeter-master:0.0.2"; + protected LoadTestWithBLOBs loadTest; protected LoadTestService loadTestService; protected Integer threadNum; @@ -32,8 +34,7 @@ public abstract class AbstractEngine implements Engine { testResourceService = CommonBeanFactory.getBean(TestResourceService.class); } - @Override - public boolean init(LoadTestWithBLOBs loadTest) { + protected void init(LoadTestWithBLOBs loadTest) { if (loadTest == null) { MSException.throwException("LoadTest is null."); } @@ -57,7 +58,6 @@ public abstract class AbstractEngine implements Engine { if (CollectionUtils.isEmpty(this.resourceList)) { MSException.throwException("Test Resource is empty"); } - return true; } protected Integer getRunningThreadNum() { diff --git a/backend/src/main/java/io/metersphere/engine/Engine.java b/backend/src/main/java/io/metersphere/engine/Engine.java index d352472d42..1bb05f0e79 100644 --- a/backend/src/main/java/io/metersphere/engine/Engine.java +++ b/backend/src/main/java/io/metersphere/engine/Engine.java @@ -1,9 +1,6 @@ package io.metersphere.engine; -import io.metersphere.base.domain.LoadTestWithBLOBs; - public interface Engine { - boolean init(LoadTestWithBLOBs loadTest); void start(); diff --git a/backend/src/main/java/io/metersphere/engine/EngineFactory.java b/backend/src/main/java/io/metersphere/engine/EngineFactory.java index 6d522e696b..b202317d60 100644 --- a/backend/src/main/java/io/metersphere/engine/EngineFactory.java +++ b/backend/src/main/java/io/metersphere/engine/EngineFactory.java @@ -47,9 +47,9 @@ public class EngineFactory { switch (type) { case NODE: - return new DockerTestEngine(); + return new DockerTestEngine(loadTest); case K8S: - return new KubernetesTestEngine(); + return new KubernetesTestEngine(loadTest); } return null; } diff --git a/backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java b/backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java index 016009543a..a025001c02 100644 --- a/backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java +++ b/backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java @@ -2,6 +2,7 @@ package io.metersphere.engine.docker; import com.alibaba.fastjson.JSON; import io.metersphere.base.domain.LoadTestWithBLOBs; +import io.metersphere.base.domain.TestResource; import io.metersphere.commons.constants.ResourceStatusEnum; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; @@ -10,6 +11,7 @@ import io.metersphere.dto.NodeDTO; import io.metersphere.engine.AbstractEngine; import io.metersphere.engine.EngineContext; import io.metersphere.engine.EngineFactory; +import io.metersphere.engine.kubernetes.registry.RegistryService; import org.apache.commons.lang3.StringUtils; import org.springframework.web.client.RestTemplate; @@ -18,22 +20,27 @@ import java.util.List; import java.util.stream.Collectors; public class DockerTestEngine extends AbstractEngine { + private static final String BASE_URL = "http://%s:%d"; private RestTemplate restTemplate; + private RegistryService registryService; + public DockerTestEngine(LoadTestWithBLOBs loadTest) { + this.init(loadTest); + } @Override - public boolean init(LoadTestWithBLOBs loadTest) { + protected void init(LoadTestWithBLOBs loadTest) { super.init(loadTest); this.restTemplate = CommonBeanFactory.getBean(RestTemplate.class); + this.registryService = CommonBeanFactory.getBean(RegistryService.class); // todo 初始化操作 - return true; } @Override public void start() { Integer runningSumThreadNum = getRunningThreadNum(); - Integer totalThreadNum = resourceList.stream() + int totalThreadNum = resourceList.stream() .filter(r -> ResourceStatusEnum.VALID.name().equals(r.getStatus())) .map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency()) .reduce(Integer::sum) @@ -46,34 +53,40 @@ public class DockerTestEngine extends AbstractEngine { .map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency()) .collect(Collectors.toList()); - resourceRatio.forEach(ratio -> { + for (int i = 0, size = resourceList.size(); i < size; i++) { + int ratio = resourceRatio.get(i); double realThreadNum = ((double) ratio / totalThreadNum) * threadNum; - runTest(Math.round(realThreadNum)); - }); + runTest(resourceList.get(i), Math.round(realThreadNum)); + } } - private void runTest(long realThreadNum) { + private void runTest(TestResource resource, long realThreadNum) { // todo 运行测试 EngineContext context = null; try { context = EngineFactory.createContext(loadTest, realThreadNum); } catch (Exception e) { - e.printStackTrace(); + MSException.throwException(e); } + String configuration = resource.getConfiguration(); + NodeDTO node = JSON.parseObject(configuration, NodeDTO.class); + String nodeIp = node.getIp(); + Integer port = node.getPort(); String testId = context.getTestId(); String content = context.getContent(); - String uri = "http://localhost:8082/jmeter/container/start"; + String uri = String.format(BASE_URL + "/jmeter/container/start", nodeIp, port); TestRequest testRequest = new TestRequest(); testRequest.setSize(1); testRequest.setTestId(testId); testRequest.setFileString(content); + testRequest.setImage(registryService.getRegistry() + JMETER_IMAGE); // todo 判断测试状态 - String taskStatusUri = "http://localhost:8082/jmeter/task/status/" + testId; + String taskStatusUri = String.format(BASE_URL + "/jmeter/task/status/" + testId, nodeIp, port); List containerList = restTemplate.getForObject(taskStatusUri, List.class); for (int i = 0; i < containerList.size(); i++) { HashMap h = (HashMap) containerList.get(i); @@ -88,12 +101,16 @@ public class DockerTestEngine extends AbstractEngine { @Override public void stop() { // TODO 停止运行测试 -// RestTemplate restTemplate = new RestTemplate(); - String testId = loadTest.getId(); + this.resourceList.forEach(r -> { + NodeDTO node = JSON.parseObject(r.getConfiguration(), NodeDTO.class); + String ip = node.getIp(); + Integer port = node.getPort(); + + String uri = String.format(BASE_URL + "/jmeter/container/stop/" + testId, ip, port); + restTemplate.postForObject(uri, "", String.class); + }); - String uri = "http://localhost:8082/jmeter/container/stop/" + testId; - restTemplate.postForObject(uri, "", String.class); } } diff --git a/backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java b/backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java index bab390e1fd..69f154816a 100644 --- a/backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java +++ b/backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java @@ -24,11 +24,14 @@ public class KubernetesTestEngine extends AbstractEngine { private RegistryService registryService; + public KubernetesTestEngine(LoadTestWithBLOBs loadTest) { + this.init(loadTest); + } + @Override - public boolean init(LoadTestWithBLOBs loadTest) { + public void init(LoadTestWithBLOBs loadTest) { super.init(loadTest); this.registryService = CommonBeanFactory.getBean(RegistryService.class); - return true; } @@ -89,7 +92,7 @@ public class KubernetesTestEngine extends AbstractEngine { }}); jmeter.setSpec(new JmeterSpec() {{ setReplicas(1); - setImage(registryService.getRegistry() + "jmeter-master:0.0.2"); + setImage(registryService.getRegistry() + JMETER_IMAGE); }}); LogUtil.info("Load test started. " + context.getTestId()); kubernetesProvider.applyCustomResource(jmeter); @@ -100,6 +103,28 @@ public class KubernetesTestEngine extends AbstractEngine { @Override public void stop() { + resourceList.forEach(r -> { + try { + EngineContext context = EngineFactory.createContext(loadTest, threadNum); + String configuration = r.getConfiguration(); + ClientCredential clientCredential = JSON.parseObject(configuration, ClientCredential.class); + KubernetesProvider provider = new KubernetesProvider(JSON.toJSONString(clientCredential)); + provider.confirmNamespace(context.getNamespace()); + Jmeter jmeter = new Jmeter(); + jmeter.setMetadata(new ObjectMeta() {{ + setName(context.getTestId()); + setNamespace(context.getNamespace()); + }}); + jmeter.setSpec(new JmeterSpec() {{ + setReplicas(1); + setImage(registryService.getRegistry() + JMETER_IMAGE); + }}); + provider.deleteCustomResource(jmeter); + } catch (Exception e) { + MSException.throwException(e); + } + + }); } } diff --git a/backend/src/main/java/io/metersphere/service/LoadTestService.java b/backend/src/main/java/io/metersphere/service/LoadTestService.java index 0a6e7369b9..1cdce5e7fb 100644 --- a/backend/src/main/java/io/metersphere/service/LoadTestService.java +++ b/backend/src/main/java/io/metersphere/service/LoadTestService.java @@ -174,16 +174,7 @@ public class LoadTestService { MSException.throwException(String.format("Test cannot be run,test ID:%s", request.getId())); } - boolean init = true; - try { - init = engine.init(loadTest); - } catch (Exception e) { - MSException.throwException(e); - } - if (!init) { - MSException.throwException(Translator.get("run_load_test_file_init_error") + request.getId()); - } - + // 启动测试 engine.start(); // 标记running状态 loadTest.setStatus(TestStatus.Running.name());