启动测试

This commit is contained in:
Captain.B 2020-03-26 13:40:54 +08:00
parent 4cc73c172c
commit d6f285a1d4
7 changed files with 77 additions and 38 deletions

View File

@ -2,9 +2,10 @@ package io.metersphere.controller.request;
public class TestRequest { public class TestRequest {
int size; private int size;
String fileString; private String fileString;
String testId; private String testId;
private String image;
public int getSize() { public int getSize() {
return size; return size;
@ -29,4 +30,12 @@ public class TestRequest {
public void setTestId(String testId) { public void setTestId(String testId) {
this.testId = testId; this.testId = testId;
} }
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
} }

View File

@ -19,6 +19,8 @@ import org.apache.commons.lang3.StringUtils;
import java.util.List; import java.util.List;
public abstract class AbstractEngine implements Engine { public abstract class AbstractEngine implements Engine {
public static final String JMETER_IMAGE = "jmeter-master:0.0.2";
protected LoadTestWithBLOBs loadTest; protected LoadTestWithBLOBs loadTest;
protected LoadTestService loadTestService; protected LoadTestService loadTestService;
protected Integer threadNum; protected Integer threadNum;
@ -32,8 +34,7 @@ public abstract class AbstractEngine implements Engine {
testResourceService = CommonBeanFactory.getBean(TestResourceService.class); testResourceService = CommonBeanFactory.getBean(TestResourceService.class);
} }
@Override protected void init(LoadTestWithBLOBs loadTest) {
public boolean init(LoadTestWithBLOBs loadTest) {
if (loadTest == null) { if (loadTest == null) {
MSException.throwException("LoadTest is null."); MSException.throwException("LoadTest is null.");
} }
@ -57,7 +58,6 @@ public abstract class AbstractEngine implements Engine {
if (CollectionUtils.isEmpty(this.resourceList)) { if (CollectionUtils.isEmpty(this.resourceList)) {
MSException.throwException("Test Resource is empty"); MSException.throwException("Test Resource is empty");
} }
return true;
} }
protected Integer getRunningThreadNum() { protected Integer getRunningThreadNum() {

View File

@ -1,9 +1,6 @@
package io.metersphere.engine; package io.metersphere.engine;
import io.metersphere.base.domain.LoadTestWithBLOBs;
public interface Engine { public interface Engine {
boolean init(LoadTestWithBLOBs loadTest);
void start(); void start();

View File

@ -47,9 +47,9 @@ public class EngineFactory {
switch (type) { switch (type) {
case NODE: case NODE:
return new DockerTestEngine(); return new DockerTestEngine(loadTest);
case K8S: case K8S:
return new KubernetesTestEngine(); return new KubernetesTestEngine(loadTest);
} }
return null; return null;
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.engine.docker;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.base.domain.LoadTestWithBLOBs; import io.metersphere.base.domain.LoadTestWithBLOBs;
import io.metersphere.base.domain.TestResource;
import io.metersphere.commons.constants.ResourceStatusEnum; import io.metersphere.commons.constants.ResourceStatusEnum;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
@ -10,6 +11,7 @@ import io.metersphere.dto.NodeDTO;
import io.metersphere.engine.AbstractEngine; import io.metersphere.engine.AbstractEngine;
import io.metersphere.engine.EngineContext; import io.metersphere.engine.EngineContext;
import io.metersphere.engine.EngineFactory; import io.metersphere.engine.EngineFactory;
import io.metersphere.engine.kubernetes.registry.RegistryService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@ -18,22 +20,27 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class DockerTestEngine extends AbstractEngine { public class DockerTestEngine extends AbstractEngine {
private static final String BASE_URL = "http://%s:%d";
private RestTemplate restTemplate; private RestTemplate restTemplate;
private RegistryService registryService;
public DockerTestEngine(LoadTestWithBLOBs loadTest) {
this.init(loadTest);
}
@Override @Override
public boolean init(LoadTestWithBLOBs loadTest) { protected void init(LoadTestWithBLOBs loadTest) {
super.init(loadTest); super.init(loadTest);
this.restTemplate = CommonBeanFactory.getBean(RestTemplate.class); this.restTemplate = CommonBeanFactory.getBean(RestTemplate.class);
this.registryService = CommonBeanFactory.getBean(RegistryService.class);
// todo 初始化操作 // todo 初始化操作
return true;
} }
@Override @Override
public void start() { public void start() {
Integer runningSumThreadNum = getRunningThreadNum(); Integer runningSumThreadNum = getRunningThreadNum();
Integer totalThreadNum = resourceList.stream() int totalThreadNum = resourceList.stream()
.filter(r -> ResourceStatusEnum.VALID.name().equals(r.getStatus())) .filter(r -> ResourceStatusEnum.VALID.name().equals(r.getStatus()))
.map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency()) .map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency())
.reduce(Integer::sum) .reduce(Integer::sum)
@ -46,34 +53,40 @@ public class DockerTestEngine extends AbstractEngine {
.map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency()) .map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency())
.collect(Collectors.toList()); .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; 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 运行测试 // todo 运行测试
EngineContext context = null; EngineContext context = null;
try { try {
context = EngineFactory.createContext(loadTest, realThreadNum); context = EngineFactory.createContext(loadTest, realThreadNum);
} catch (Exception e) { } 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 testId = context.getTestId();
String content = context.getContent(); 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 testRequest = new TestRequest();
testRequest.setSize(1); testRequest.setSize(1);
testRequest.setTestId(testId); testRequest.setTestId(testId);
testRequest.setFileString(content); testRequest.setFileString(content);
testRequest.setImage(registryService.getRegistry() + JMETER_IMAGE);
// todo 判断测试状态 // 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); List containerList = restTemplate.getForObject(taskStatusUri, List.class);
for (int i = 0; i < containerList.size(); i++) { for (int i = 0; i < containerList.size(); i++) {
HashMap h = (HashMap) containerList.get(i); HashMap h = (HashMap) containerList.get(i);
@ -88,12 +101,16 @@ public class DockerTestEngine extends AbstractEngine {
@Override @Override
public void stop() { public void stop() {
// TODO 停止运行测试 // TODO 停止运行测试
// RestTemplate restTemplate = new RestTemplate();
String testId = loadTest.getId(); 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);
} }
} }

View File

@ -24,11 +24,14 @@ public class KubernetesTestEngine extends AbstractEngine {
private RegistryService registryService; private RegistryService registryService;
public KubernetesTestEngine(LoadTestWithBLOBs loadTest) {
this.init(loadTest);
}
@Override @Override
public boolean init(LoadTestWithBLOBs loadTest) { public void init(LoadTestWithBLOBs loadTest) {
super.init(loadTest); super.init(loadTest);
this.registryService = CommonBeanFactory.getBean(RegistryService.class); this.registryService = CommonBeanFactory.getBean(RegistryService.class);
return true;
} }
@ -89,7 +92,7 @@ public class KubernetesTestEngine extends AbstractEngine {
}}); }});
jmeter.setSpec(new JmeterSpec() {{ jmeter.setSpec(new JmeterSpec() {{
setReplicas(1); setReplicas(1);
setImage(registryService.getRegistry() + "jmeter-master:0.0.2"); setImage(registryService.getRegistry() + JMETER_IMAGE);
}}); }});
LogUtil.info("Load test started. " + context.getTestId()); LogUtil.info("Load test started. " + context.getTestId());
kubernetesProvider.applyCustomResource(jmeter); kubernetesProvider.applyCustomResource(jmeter);
@ -100,6 +103,28 @@ public class KubernetesTestEngine extends AbstractEngine {
@Override @Override
public void stop() { 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);
}
});
} }
} }

View File

@ -174,16 +174,7 @@ public class LoadTestService {
MSException.throwException(String.format("Test cannot be runtest ID%s", request.getId())); MSException.throwException(String.format("Test cannot be runtest 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(); engine.start();
// 标记running状态 // 标记running状态
loadTest.setStatus(TestStatus.Running.name()); loadTest.setStatus(TestStatus.Running.name());