refactor: 性能测试重构

This commit is contained in:
Captain.B 2021-09-23 16:54:43 +08:00 committed by 刘瑞斌
parent fbfab6b1f3
commit b13884016f
9 changed files with 103 additions and 140 deletions

View File

@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.RunRequest; import io.metersphere.api.dto.RunRequest;
import io.metersphere.base.domain.LoadTestWithBLOBs; import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.domain.TestResource; import io.metersphere.base.domain.TestResource;
import io.metersphere.base.domain.TestResourcePool; import io.metersphere.base.domain.TestResourcePool;
import io.metersphere.commons.constants.PerformanceTestStatus; import io.metersphere.commons.constants.PerformanceTestStatus;
@ -21,15 +21,12 @@ import org.apache.commons.lang3.StringUtils;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID;
public abstract class AbstractEngine implements Engine { public abstract class AbstractEngine implements Engine {
protected String JMETER_IMAGE; protected String JMETER_IMAGE;
protected String HEAP; protected String HEAP;
protected String GC_ALGO; protected String GC_ALGO;
private Long startTime; protected LoadTestReportWithBLOBs loadTestReport;
private String reportId;
protected LoadTestWithBLOBs loadTest;
protected PerformanceTestService performanceTestService; protected PerformanceTestService performanceTestService;
protected Integer threadNum; protected Integer threadNum;
protected List<TestResource> resourceList; protected List<TestResource> resourceList;
@ -43,8 +40,6 @@ public abstract class AbstractEngine implements Engine {
JMETER_IMAGE = CommonBeanFactory.getBean(JmeterProperties.class).getImage(); JMETER_IMAGE = CommonBeanFactory.getBean(JmeterProperties.class).getImage();
HEAP = CommonBeanFactory.getBean(JmeterProperties.class).getHeap(); HEAP = CommonBeanFactory.getBean(JmeterProperties.class).getHeap();
GC_ALGO = CommonBeanFactory.getBean(JmeterProperties.class).getGcAlgo(); GC_ALGO = CommonBeanFactory.getBean(JmeterProperties.class).getGcAlgo();
this.startTime = System.currentTimeMillis();
this.reportId = UUID.randomUUID().toString();
} }
protected void initApiConfig(RunRequest runRequest) { protected void initApiConfig(RunRequest runRequest) {
@ -81,16 +76,16 @@ public abstract class AbstractEngine implements Engine {
} }
} }
protected void init(LoadTestWithBLOBs loadTest) { protected void init(LoadTestReportWithBLOBs loadTestReport) {
if (loadTest == null) { if (loadTestReport == null) {
MSException.throwException("LoadTest is null."); MSException.throwException("LoadTest is null.");
} }
this.loadTest = loadTest; this.loadTestReport = loadTestReport;
this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class); this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class);
threadNum = getThreadNum(loadTest); threadNum = getThreadNum(loadTestReport);
String resourcePoolId = loadTest.getTestResourcePoolId(); String resourcePoolId = loadTestReport.getTestResourcePoolId();
if (StringUtils.isBlank(resourcePoolId)) { if (StringUtils.isBlank(resourcePoolId)) {
MSException.throwException("Resource Pool ID is empty"); MSException.throwException("Resource Pool ID is empty");
} }
@ -127,16 +122,16 @@ public abstract class AbstractEngine implements Engine {
} }
protected Integer getRunningThreadNum() { protected Integer getRunningThreadNum() {
List<LoadTestWithBLOBs> loadTests = performanceTestService.selectByTestResourcePoolId(loadTest.getTestResourcePoolId()); List<LoadTestReportWithBLOBs> loadTestReports = performanceTestService.selectReportsByTestResourcePoolId(loadTestReport.getTestResourcePoolId());
// 使用当前资源池正在运行的测试占用的并发数 // 使用当前资源池正在运行的测试占用的并发数
return loadTests.stream() return loadTestReports.stream()
.filter(t -> PerformanceTestStatus.Running.name().equals(t.getStatus())) .filter(t -> PerformanceTestStatus.Running.name().equals(t.getStatus()))
.map(this::getThreadNum) .map(this::getThreadNum)
.reduce(Integer::sum) .reduce(Integer::sum)
.orElse(0); .orElse(0);
} }
private Integer getThreadNum(LoadTestWithBLOBs t) { private Integer getThreadNum(LoadTestReportWithBLOBs t) {
Integer s = 0; Integer s = 0;
String loadConfiguration = t.getLoadConfiguration(); String loadConfiguration = t.getLoadConfiguration();
JSONArray jsonArray = JSON.parseArray(loadConfiguration); JSONArray jsonArray = JSON.parseArray(loadConfiguration);
@ -175,14 +170,4 @@ public abstract class AbstractEngine implements Engine {
} }
return s; return s;
} }
@Override
public Long getStartTime() {
return startTime;
}
@Override
public String getReportId() {
return reportId;
}
} }

View File

@ -1,10 +1,6 @@
package io.metersphere.performance.engine; package io.metersphere.performance.engine;
public interface Engine { public interface Engine {
Long getStartTime();
String getReportId();
void start(); void start();
void stop(); void stop();

View File

@ -6,10 +6,11 @@ import io.metersphere.Application;
import io.metersphere.api.dto.RunRequest; import io.metersphere.api.dto.RunRequest;
import io.metersphere.base.domain.FileContent; import io.metersphere.base.domain.FileContent;
import io.metersphere.base.domain.FileMetadata; import io.metersphere.base.domain.FileMetadata;
import io.metersphere.base.domain.LoadTestWithBLOBs; import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.domain.TestResourcePool; import io.metersphere.base.domain.TestResourcePool;
import io.metersphere.commons.constants.FileType; import io.metersphere.commons.constants.FileType;
import io.metersphere.commons.constants.ResourcePoolTypeEnum; import io.metersphere.commons.constants.ResourcePoolTypeEnum;
import io.metersphere.commons.constants.ResourceStatusEnum;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
@ -65,8 +66,8 @@ public class EngineFactory {
} }
} }
public static Engine createEngine(LoadTestWithBLOBs loadTest) { public static Engine createEngine(LoadTestReportWithBLOBs loadTestReport) {
String resourcePoolId = loadTest.getTestResourcePoolId(); String resourcePoolId = loadTestReport.getTestResourcePoolId();
if (StringUtils.isBlank(resourcePoolId)) { if (StringUtils.isBlank(resourcePoolId)) {
MSException.throwException(Translator.get("test_resource_pool_id_is_null")); MSException.throwException(Translator.get("test_resource_pool_id_is_null"));
} }
@ -75,15 +76,18 @@ public class EngineFactory {
if (resourcePool == null) { if (resourcePool == null) {
MSException.throwException(Translator.get("test_resource_pool_id_is_null")); MSException.throwException(Translator.get("test_resource_pool_id_is_null"));
} }
if (ResourceStatusEnum.INVALID.name().equals(resourcePool.getStatus())) {
MSException.throwException(Translator.get("test_resource_pool_invalid"));
}
final ResourcePoolTypeEnum type = ResourcePoolTypeEnum.valueOf(resourcePool.getType()); final ResourcePoolTypeEnum type = ResourcePoolTypeEnum.valueOf(resourcePool.getType());
if (type == ResourcePoolTypeEnum.NODE) { if (type == ResourcePoolTypeEnum.NODE) {
return new DockerTestEngine(loadTest); return new DockerTestEngine(loadTestReport);
} }
if (type == ResourcePoolTypeEnum.K8S) { if (type == ResourcePoolTypeEnum.K8S) {
try { try {
return (Engine) ConstructorUtils.invokeConstructor(kubernetesTestEngineClass, loadTest); return (Engine) ConstructorUtils.invokeConstructor(kubernetesTestEngineClass, loadTestReport);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
return null; return null;
@ -102,10 +106,10 @@ public class EngineFactory {
return null; return null;
} }
public static EngineContext createContext(LoadTestWithBLOBs loadTest, double[] ratios, String reportId, int resourceIndex) { public static EngineContext createContext(LoadTestReportWithBLOBs loadTestReport, double[] ratios, String reportId, int resourceIndex) {
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId()); final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTestReport.getTestId());
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) { if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId()); MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTestReport.getTestId());
} }
List<FileMetadata> jmxFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JMX.name())).collect(Collectors.toList()); List<FileMetadata> jmxFiles = fileMetadataList.stream().filter(f -> StringUtils.equalsIgnoreCase(f.getType(), FileType.JMX.name())).collect(Collectors.toList());
@ -113,17 +117,17 @@ public class EngineFactory {
// 合并上传的jmx // 合并上传的jmx
byte[] jmxBytes = mergeJmx(jmxFiles); byte[] jmxBytes = mergeJmx(jmxFiles);
final EngineContext engineContext = new EngineContext(); final EngineContext engineContext = new EngineContext();
engineContext.setTestId(loadTest.getId()); engineContext.setTestId(loadTestReport.getTestId());
engineContext.setTestName(loadTest.getName()); engineContext.setTestName(loadTestReport.getName());
engineContext.setNamespace(loadTest.getProjectId()); engineContext.setNamespace(loadTestReport.getProjectId());
engineContext.setFileType(FileType.JMX.name()); engineContext.setFileType(FileType.JMX.name());
engineContext.setResourcePoolId(loadTest.getTestResourcePoolId()); engineContext.setResourcePoolId(loadTestReport.getTestResourcePoolId());
engineContext.setReportId(reportId); engineContext.setReportId(reportId);
engineContext.setResourceIndex(resourceIndex); engineContext.setResourceIndex(resourceIndex);
engineContext.setRatios(ratios); engineContext.setRatios(ratios);
if (StringUtils.isNotEmpty(loadTest.getLoadConfiguration())) { if (StringUtils.isNotEmpty(loadTestReport.getLoadConfiguration())) {
final JSONArray jsonArray = JSONObject.parseArray(loadTest.getLoadConfiguration()); final JSONArray jsonArray = JSONObject.parseArray(loadTestReport.getLoadConfiguration());
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
if (jsonArray.get(i) instanceof List) { if (jsonArray.get(i) instanceof List) {
@ -160,8 +164,8 @@ public class EngineFactory {
{"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}]} {"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}]}
*/ */
Map<String, byte[]> testResourceFiles = new HashMap<>(); Map<String, byte[]> testResourceFiles = new HashMap<>();
byte[] props = getJMeterProperties(loadTest, engineContext); byte[] props = getJMeterProperties(loadTestReport, engineContext);
byte[] hosts = getDNSConfig(loadTest, engineContext); byte[] hosts = getDNSConfig(loadTestReport, engineContext);
// JMeter Properties // JMeter Properties
testResourceFiles.put("ms.properties", props); testResourceFiles.put("ms.properties", props);
// DNS // DNS
@ -195,10 +199,10 @@ public class EngineFactory {
return engineContext; return engineContext;
} }
private static byte[] getDNSConfig(LoadTestWithBLOBs loadTest, EngineContext engineContext) { private static byte[] getDNSConfig(LoadTestReportWithBLOBs loadTestReport, EngineContext engineContext) {
StringBuilder dns = new StringBuilder("# DNS Config\n"); StringBuilder dns = new StringBuilder("# DNS Config\n");
if (StringUtils.isNotEmpty(loadTest.getAdvancedConfiguration())) { if (StringUtils.isNotEmpty(loadTestReport.getAdvancedConfiguration())) {
JSONObject advancedConfiguration = JSONObject.parseObject(loadTest.getAdvancedConfiguration()); JSONObject advancedConfiguration = JSONObject.parseObject(loadTestReport.getAdvancedConfiguration());
engineContext.addProperties(advancedConfiguration); engineContext.addProperties(advancedConfiguration);
JSONArray domains = advancedConfiguration.getJSONArray("domains"); JSONArray domains = advancedConfiguration.getJSONArray("domains");
if (domains != null) { if (domains != null) {
@ -214,10 +218,10 @@ public class EngineFactory {
return dns.toString().getBytes(StandardCharsets.UTF_8); return dns.toString().getBytes(StandardCharsets.UTF_8);
} }
private static byte[] getJMeterProperties(LoadTestWithBLOBs loadTest, EngineContext engineContext) { private static byte[] getJMeterProperties(LoadTestReportWithBLOBs loadTestReportWithBLOBs, EngineContext engineContext) {
StringBuilder props = new StringBuilder("# JMeter Properties\n"); StringBuilder props = new StringBuilder("# JMeter Properties\n");
if (StringUtils.isNotEmpty(loadTest.getAdvancedConfiguration())) { if (StringUtils.isNotEmpty(loadTestReportWithBLOBs.getAdvancedConfiguration())) {
JSONObject advancedConfiguration = JSONObject.parseObject(loadTest.getAdvancedConfiguration()); JSONObject advancedConfiguration = JSONObject.parseObject(loadTestReportWithBLOBs.getAdvancedConfiguration());
engineContext.addProperties(advancedConfiguration); engineContext.addProperties(advancedConfiguration);
JSONArray properties = advancedConfiguration.getJSONArray("properties"); JSONArray properties = advancedConfiguration.getJSONArray("properties");
if (properties != null) { if (properties != null) {

View File

@ -1,6 +1,7 @@
package io.metersphere.performance.engine.docker; package io.metersphere.performance.engine.docker;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.domain.LoadTestWithBLOBs; import io.metersphere.base.domain.LoadTestWithBLOBs;
import io.metersphere.base.domain.TestResource; import io.metersphere.base.domain.TestResource;
import io.metersphere.commons.constants.ResourceStatusEnum; import io.metersphere.commons.constants.ResourceStatusEnum;
@ -26,13 +27,13 @@ public class DockerTestEngine extends AbstractEngine {
private RestTemplate restTemplate; private RestTemplate restTemplate;
private RestTemplate restTemplateWithTimeOut; private RestTemplate restTemplateWithTimeOut;
public DockerTestEngine(LoadTestWithBLOBs loadTest) { public DockerTestEngine(LoadTestReportWithBLOBs loadTestReport) {
this.init(loadTest); this.init(loadTestReport);
} }
@Override @Override
protected void init(LoadTestWithBLOBs loadTest) { protected void init(LoadTestReportWithBLOBs loadTestReport) {
super.init(loadTest); super.init(loadTestReport);
this.restTemplate = (RestTemplate) CommonBeanFactory.getBean("restTemplate"); this.restTemplate = (RestTemplate) CommonBeanFactory.getBean("restTemplate");
this.restTemplateWithTimeOut = (RestTemplate) CommonBeanFactory.getBean("restTemplateWithTimeOut"); this.restTemplateWithTimeOut = (RestTemplate) CommonBeanFactory.getBean("restTemplateWithTimeOut");
} }
@ -85,9 +86,9 @@ public class DockerTestEngine extends AbstractEngine {
env.put("RATIO", StringUtils.join(ratios, ",")); env.put("RATIO", StringUtils.join(ratios, ","));
env.put("RESOURCE_INDEX", "" + resourceIndex); env.put("RESOURCE_INDEX", "" + resourceIndex);
env.put("METERSPHERE_URL", metersphereUrl); env.put("METERSPHERE_URL", metersphereUrl);
env.put("START_TIME", "" + this.getStartTime()); env.put("START_TIME", "" + System.currentTimeMillis());
env.put("TEST_ID", this.loadTest.getId()); env.put("TEST_ID", this.loadTestReport.getTestId());
env.put("REPORT_ID", this.getReportId()); env.put("REPORT_ID", this.loadTestReport.getId());
env.put("BOOTSTRAP_SERVERS", kafkaProperties.getBootstrapServers()); env.put("BOOTSTRAP_SERVERS", kafkaProperties.getBootstrapServers());
env.put("LOG_TOPIC", kafkaProperties.getLog().getTopic()); env.put("LOG_TOPIC", kafkaProperties.getLog().getTopic());
env.put("JMETER_REPORTS_TOPIC", kafkaProperties.getReport().getTopic()); env.put("JMETER_REPORTS_TOPIC", kafkaProperties.getReport().getTopic());
@ -95,7 +96,7 @@ public class DockerTestEngine extends AbstractEngine {
env.put("THREAD_NUM", "0");// 传入0表示不用修改线程数 env.put("THREAD_NUM", "0");// 传入0表示不用修改线程数
env.put("HEAP", HEAP); env.put("HEAP", HEAP);
env.put("GC_ALGO", GC_ALGO); env.put("GC_ALGO", GC_ALGO);
env.put("GRANULARITY", performanceTestService.getGranularity(this.getReportId()).toString()); env.put("GRANULARITY", performanceTestService.getGranularity(this.loadTestReport.getId()).toString());
env.put("BACKEND_LISTENER", resourcePool.getBackendListener().toString()); env.put("BACKEND_LISTENER", resourcePool.getBackendListener().toString());
@ -121,7 +122,7 @@ public class DockerTestEngine extends AbstractEngine {
@Override @Override
public void stop() { public void stop() {
String testId = loadTest.getId(); String testId = loadTestReport.getTestId();
this.resourceList.forEach(r -> { this.resourceList.forEach(r -> {
NodeDTO node = JSON.parseObject(r.getConfiguration(), NodeDTO.class); NodeDTO node = JSON.parseObject(r.getConfiguration(), NodeDTO.class);
String ip = node.getIp(); String ip = node.getIp();

View File

@ -3,16 +3,13 @@ package io.metersphere.performance.service;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import io.metersphere.base.domain.LoadTestReportWithBLOBs; import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.domain.LoadTestWithBLOBs;
import io.metersphere.base.domain.TestPlanLoadCase;
import io.metersphere.base.mapper.LoadTestMapper; import io.metersphere.base.mapper.LoadTestMapper;
import io.metersphere.base.mapper.TestPlanLoadCaseMapper; import io.metersphere.base.mapper.LoadTestReportMapper;
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper; import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.performance.engine.EngineContext; import io.metersphere.performance.engine.EngineContext;
import io.metersphere.performance.engine.EngineFactory; import io.metersphere.performance.engine.EngineFactory;
import org.codehaus.plexus.util.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -34,34 +31,13 @@ public class JmeterFileService {
@Resource @Resource
private ExtLoadTestReportMapper extLoadTestReportMapper; private ExtLoadTestReportMapper extLoadTestReportMapper;
@Resource @Resource
private TestPlanLoadCaseMapper testPlanLoadCaseMapper; private LoadTestReportMapper loadTestReportMapper;
public byte[] downloadZip(String testId, double[] ratios, String reportId, int resourceIndex) { public byte[] downloadZip(String testId, double[] ratios, String reportId, int resourceIndex) {
try { try {
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(testId); LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
TestPlanLoadCase testPlanLoadCase = null;
if (loadTest == null) { EngineContext context = EngineFactory.createContext(loadTestReport, ratios, reportId, resourceIndex);
// 通过测试计划执行性能用例时testId为测试计划性能用例表的主键ID根据ID查询用例自身的压力配置
testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testId);
if (testPlanLoadCase != null) {
loadTest = loadTestMapper.selectByPrimaryKey(testPlanLoadCase.getLoadCaseId());
if (loadTest != null) {
// 用例自身设置了资源池ID
if (StringUtils.isNotBlank(testPlanLoadCase.getTestResourcePoolId())) {
loadTest.setTestResourcePoolId(testPlanLoadCase.getTestResourcePoolId());
}
// 用例自身设置了压力配置
if (StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
loadTest.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
}
}
}
}
EngineContext context = EngineFactory.createContext(loadTest, ratios, reportId, resourceIndex);
if (testPlanLoadCase != null) {
// ID
context.setTestId(testPlanLoadCase.getId());
}
return zipFilesToByteArray(context); return zipFilesToByteArray(context);
} catch (MSException e) { } catch (MSException e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);

View File

@ -97,14 +97,14 @@ public class PerformanceReportService {
MSException.throwException("report id cannot be null"); MSException.throwException("report id cannot be null");
} }
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId); LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId()); LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId());
LogUtil.info("Delete report started, report ID: %s" + reportId); LogUtil.info("Delete report started, report ID: %s" + reportId);
if (loadTest != null) { if (loadTest != null) {
try { try {
final Engine engine = EngineFactory.createEngine(loadTest); final Engine engine = EngineFactory.createEngine(loadTestReport);
if (engine == null) { if (engine == null) {
MSException.throwException(String.format("Delete report fail. create engine failreport ID%s", reportId)); MSException.throwException(String.format("Delete report fail. create engine failreport ID%s", reportId));
} }

View File

@ -313,7 +313,7 @@ public class PerformanceTestService {
if (request.getUserId() != null) { if (request.getUserId() != null) {
loadTest.setUserId(request.getUserId()); loadTest.setUserId(request.getUserId());
} }
if(StringUtils.isNotEmpty(request.getProjectId())){ if (StringUtils.isNotEmpty(request.getProjectId())) {
loadTest.setProjectId(request.getProjectId()); loadTest.setProjectId(request.getProjectId());
} }
if (loadTest == null) { if (loadTest == null) {
@ -323,40 +323,12 @@ public class PerformanceTestService {
if (StringUtils.equalsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) { if (StringUtils.equalsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) {
MSException.throwException(Translator.get("load_test_is_running")); MSException.throwException(Translator.get("load_test_is_running"));
} }
String testResourcePoolId = loadTest.getTestResourcePoolId();
TestResourcePool testResourcePool = testResourcePoolMapper.selectByPrimaryKey(testResourcePoolId);
if (testResourcePool == null) {
MSException.throwException(Translator.get("test_resource_pool_not_exists"));
}
if (ResourceStatusEnum.INVALID.name().equals(testResourcePool.getStatus())) {
MSException.throwException(Translator.get("test_resource_pool_invalid"));
}
// check kafka // check kafka
checkKafka(); checkKafka();
LogUtil.info("Load test started " + loadTest.getName()); LogUtil.info("Load test started " + loadTest.getName());
LoadTestWithBLOBs copyTest = new LoadTestWithBLOBs();
BeanUtils.copyBean(copyTest, loadTest);
// 如果是执行测试计划用例把EngineFactory.createEngine参数对象的id 设置为测试计划用例id
// 设置用例id目的是当 JmeterFileService 下载zip拼装 jmx 文件时如果用例自身带有压力配置使用用例自身压力配置拼装 jmx
String testPlanLoadId = request.getTestPlanLoadId();
if (StringUtils.isNotBlank(testPlanLoadId)) {
copyTest.setId(testPlanLoadId);
// 设置本次报告中的压力配置信息
TestPlanLoadCase testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testPlanLoadId);
if (testPlanLoadCase != null && StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
loadTest.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
}
}
// engine type (NODE)
final Engine engine = EngineFactory.createEngine(copyTest);
if (engine == null) {
MSException.throwException(String.format("Test cannot be runtest ID%s", request.getId()));
}
startEngine(loadTest, engine, request.getTriggerMode()); return startEngine(loadTest, request);
return engine.getReportId();
} }
private void checkKafka() { private void checkKafka() {
@ -380,14 +352,16 @@ public class PerformanceTestService {
} }
} }
private void startEngine(LoadTestWithBLOBs loadTest, Engine engine, String triggerMode) { private String startEngine(LoadTestWithBLOBs loadTest, RunTestPlanRequest request) {
LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs(); LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs();
testReport.setId(engine.getReportId()); testReport.setId(UUID.randomUUID().toString());
testReport.setCreateTime(engine.getStartTime()); testReport.setCreateTime(System.currentTimeMillis());
testReport.setUpdateTime(engine.getStartTime()); testReport.setUpdateTime(System.currentTimeMillis());
testReport.setTestId(loadTest.getId()); testReport.setTestId(loadTest.getId());
testReport.setName(loadTest.getName()); testReport.setName(loadTest.getName());
testReport.setTriggerMode(triggerMode); testReport.setTriggerMode(request.getTriggerMode());
if (SessionUtils.getUser() == null) { if (SessionUtils.getUser() == null) {
testReport.setUserId(loadTest.getUserId()); testReport.setUserId(loadTest.getUserId());
} else { } else {
@ -397,18 +371,36 @@ public class PerformanceTestService {
LoadTestWithBLOBs updateTest = new LoadTestWithBLOBs(); LoadTestWithBLOBs updateTest = new LoadTestWithBLOBs();
updateTest.setId(loadTest.getId()); updateTest.setId(loadTest.getId());
// 启动测试 // 启动测试
Engine engine = null;
try { try {
// 启动插入 report // 保存测试里的配置
testReport.setTestResourcePoolId(loadTest.getTestResourcePoolId());
testReport.setLoadConfiguration(loadTest.getLoadConfiguration()); testReport.setLoadConfiguration(loadTest.getLoadConfiguration());
String testPlanLoadId = request.getTestPlanLoadId();
if (StringUtils.isNotBlank(testPlanLoadId)) {
// 设置本次报告中的压力配置信息
TestPlanLoadCase testPlanLoadCase = testPlanLoadCaseMapper.selectByPrimaryKey(testPlanLoadId);
if (testPlanLoadCase != null && StringUtils.isNotBlank(testPlanLoadCase.getLoadConfiguration())) {
testReport.setLoadConfiguration(testPlanLoadCase.getLoadConfiguration());
}
if (StringUtils.isNotBlank(testPlanLoadCase.getTestResourcePoolId())) {
testReport.setTestResourcePoolId(testPlanLoadCase.getTestResourcePoolId());
}
}
// 启动插入 report
testReport.setAdvancedConfiguration(loadTest.getAdvancedConfiguration()); testReport.setAdvancedConfiguration(loadTest.getAdvancedConfiguration());
testReport.setStatus(PerformanceTestStatus.Starting.name()); testReport.setStatus(PerformanceTestStatus.Starting.name());
testReport.setProjectId(loadTest.getProjectId()); testReport.setProjectId(loadTest.getProjectId());
testReport.setTestResourcePoolId(loadTest.getTestResourcePoolId());
testReport.setTestName(loadTest.getName()); testReport.setTestName(loadTest.getName());
loadTestReportMapper.insertSelective(testReport); loadTestReportMapper.insertSelective(testReport);
engine.start(); // engine
// 启动正常修改状态 starting engine = EngineFactory.createEngine(testReport);
if (engine == null) {
MSException.throwException(String.format("Test cannot be runtest ID%s", loadTest.getId()));
}
updateTest.setStatus(PerformanceTestStatus.Starting.name()); updateTest.setStatus(PerformanceTestStatus.Starting.name());
loadTestMapper.updateByPrimaryKeySelective(updateTest); loadTestMapper.updateByPrimaryKeySelective(updateTest);
@ -426,9 +418,14 @@ public class PerformanceTestService {
reportResult.setReportKey(ReportKeys.ResultStatus.name()); reportResult.setReportKey(ReportKeys.ResultStatus.name());
reportResult.setReportValue("Ready"); // 初始化一个 result_status, 这个值用在data-streaming中 reportResult.setReportValue("Ready"); // 初始化一个 result_status, 这个值用在data-streaming中
loadTestReportResultMapper.insertSelective(reportResult); loadTestReportResultMapper.insertSelective(reportResult);
// 启动测试
engine.start();
return testReport.getId();
} catch (MSException e) { } catch (MSException e) {
// 启动失败之后清理任务 // 启动失败之后清理任务
engine.stop(); if (engine != null) {
engine.stop();
}
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
updateTest.setStatus(PerformanceTestStatus.Error.name()); updateTest.setStatus(PerformanceTestStatus.Error.name());
updateTest.setDescription(e.getMessage()); updateTest.setDescription(e.getMessage());
@ -485,12 +482,6 @@ public class PerformanceTestService {
return results; return results;
} }
public List<LoadTestWithBLOBs> selectByTestResourcePoolId(String resourcePoolId) {
LoadTestExample example = new LoadTestExample();
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePoolId);
return loadTestMapper.selectByExampleWithBLOBs(example);
}
public List<DashboardTestDTO> dashboardTests(String workspaceId) { public List<DashboardTestDTO> dashboardTests(String workspaceId) {
Instant oneYearAgo = Instant.now().plus(-365, ChronoUnit.DAYS); Instant oneYearAgo = Instant.now().plus(-365, ChronoUnit.DAYS);
long startTimestamp = oneYearAgo.toEpochMilli(); long startTimestamp = oneYearAgo.toEpochMilli();
@ -575,9 +566,9 @@ public class PerformanceTestService {
} }
private void stopEngine(String reportId) { private void stopEngine(String reportId) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId); LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId()); LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(loadTestReport.getTestId());
final Engine engine = EngineFactory.createEngine(loadTest); final Engine engine = EngineFactory.createEngine(loadTestReport);
if (engine == null) { if (engine == null) {
MSException.throwException(String.format("Stop report fail. create engine failreport ID%s", reportId)); MSException.throwException(String.format("Stop report fail. create engine failreport ID%s", reportId));
} }
@ -887,6 +878,7 @@ public class PerformanceTestService {
/** /**
* 用例自定义排序 * 用例自定义排序
*
* @param request * @param request
*/ */
public void updateOrder(ResetOrderRequest request) { public void updateOrder(ResetOrderRequest request) {
@ -896,4 +888,11 @@ public class PerformanceTestService {
extLoadTestMapper::getLastOrder, extLoadTestMapper::getLastOrder,
loadTestMapper::updateByPrimaryKeySelective); loadTestMapper::updateByPrimaryKeySelective);
} }
public List<LoadTestReportWithBLOBs> selectReportsByTestResourcePoolId(String resourcePoolId) {
LoadTestReportExample example = new LoadTestReportExample();
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePoolId)
.andStatusIn(Arrays.asList(PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name()));
return loadTestReportMapper.selectByExampleWithBLOBs(example);
}
} }

@ -1 +1 @@
Subproject commit ae9b3772eebbfd3ce389c4d5c028eca8ef9687b8 Subproject commit 48820dfc4405c8733483f546b73f354854e033a4

View File

@ -0,0 +1,2 @@
CREATE INDEX load_test_report_test_resource_pool_id_index
ON load_test_report (test_resource_pool_id);