refactor: 性能测试重构
This commit is contained in:
parent
fbfab6b1f3
commit
b13884016f
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 fail,report ID:%s", reportId));
|
MSException.throwException(String.format("Delete report fail. create engine fail,report ID:%s", reportId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 run,test 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 run,test 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 fail,report ID:%s", reportId));
|
MSException.throwException(String.format("Stop report fail. create engine fail,report 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
|
|
@ -0,0 +1,2 @@
|
||||||
|
CREATE INDEX load_test_report_test_resource_pool_id_index
|
||||||
|
ON load_test_report (test_resource_pool_id);
|
Loading…
Reference in New Issue