feat(接口测试): 支持 k8s 执行
This commit is contained in:
parent
e30207a72f
commit
240cdbddf4
|
@ -8,6 +8,7 @@ import lombok.Setter;
|
||||||
@Setter
|
@Setter
|
||||||
public class RunRequest {
|
public class RunRequest {
|
||||||
private String testId;
|
private String testId;
|
||||||
|
private String poolId;
|
||||||
// api / case 或有这个属性值
|
// api / case 或有这个属性值
|
||||||
private String reportId;
|
private String reportId;
|
||||||
private String url;
|
private String url;
|
||||||
|
|
|
@ -7,13 +7,20 @@ import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||||
import io.metersphere.api.service.ApiScenarioReportService;
|
import io.metersphere.api.service.ApiScenarioReportService;
|
||||||
import io.metersphere.base.domain.JarConfig;
|
import io.metersphere.base.domain.JarConfig;
|
||||||
import io.metersphere.base.domain.TestResource;
|
import io.metersphere.base.domain.TestResource;
|
||||||
|
import io.metersphere.base.domain.TestResourcePool;
|
||||||
|
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
|
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.*;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.CompressUtils;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.config.JmeterProperties;
|
import io.metersphere.config.JmeterProperties;
|
||||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||||
import io.metersphere.dto.NodeDTO;
|
import io.metersphere.dto.NodeDTO;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
|
import io.metersphere.performance.engine.Engine;
|
||||||
|
import io.metersphere.performance.engine.EngineFactory;
|
||||||
import io.metersphere.service.JarConfigService;
|
import io.metersphere.service.JarConfigService;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
@ -54,6 +61,8 @@ public class JMeterService {
|
||||||
ResourcePoolCalculation resourcePoolCalculation;
|
ResourcePoolCalculation resourcePoolCalculation;
|
||||||
@Resource
|
@Resource
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
@Resource
|
||||||
|
private TestResourcePoolMapper testResourcePoolMapper;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
@ -311,42 +320,48 @@ public class JMeterService {
|
||||||
public void runTest(String testId, String reportId, String runMode, String testPlanScenarioId, RunModeConfig config) {
|
public void runTest(String testId, String reportId, String runMode, String testPlanScenarioId, RunModeConfig config) {
|
||||||
// 获取可以执行的资源池
|
// 获取可以执行的资源池
|
||||||
String resourcePoolId = config.getResourcePoolId();
|
String resourcePoolId = config.getResourcePoolId();
|
||||||
TestResource testResource = resourcePoolCalculation.getPool(resourcePoolId);
|
|
||||||
|
|
||||||
String configuration = testResource.getConfiguration();
|
|
||||||
NodeDTO node = JSON.parseObject(configuration, NodeDTO.class);
|
|
||||||
String nodeIp = node.getIp();
|
|
||||||
Integer port = node.getPort();
|
|
||||||
|
|
||||||
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
|
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo();
|
||||||
// 占位符
|
RunRequest runRequest = new RunRequest();
|
||||||
String metersphereUrl = "http://localhost:8081";
|
runRequest.setTestId(testId);
|
||||||
if (baseInfo != null) {
|
if (ApiRunMode.API_PLAN.name().equals(runMode)) {
|
||||||
metersphereUrl = baseInfo.getUrl();
|
runRequest.setReportId(reportId);
|
||||||
}
|
}
|
||||||
try {
|
runRequest.setPoolId(resourcePoolId);
|
||||||
RunRequest runRequest = new RunRequest();
|
// 占位符
|
||||||
runRequest.setTestId(testId);
|
String platformUrl = "http://localhost:8081";
|
||||||
if (ApiRunMode.API_PLAN.name().equals(runMode)) {
|
if (baseInfo != null) {
|
||||||
runRequest.setReportId(reportId);
|
platformUrl = baseInfo.getUrl();
|
||||||
|
}
|
||||||
|
platformUrl += "/api/jmeter/download?testId=" + testId + "&reportId=" + reportId + "&testPlanScenarioId" + "&runMode=" + runMode;
|
||||||
|
if (StringUtils.isNotEmpty(testPlanScenarioId)) {
|
||||||
|
platformUrl += "=" + testPlanScenarioId;
|
||||||
|
}
|
||||||
|
runRequest.setUrl(platformUrl);
|
||||||
|
runRequest.setRunMode(runMode);
|
||||||
|
// 如果是K8S调用
|
||||||
|
TestResourcePool pool = testResourcePoolMapper.selectByPrimaryKey(resourcePoolId);
|
||||||
|
if (pool != null && pool.getApi() && pool.getType().equals(ResourcePoolTypeEnum.K8S.name())) {
|
||||||
|
final Engine engine = EngineFactory.createApiEngine(runRequest);
|
||||||
|
engine.start();
|
||||||
|
} else {
|
||||||
|
TestResource testResource = resourcePoolCalculation.getPool(resourcePoolId);
|
||||||
|
String configuration = testResource.getConfiguration();
|
||||||
|
NodeDTO node = JSON.parseObject(configuration, NodeDTO.class);
|
||||||
|
String nodeIp = node.getIp();
|
||||||
|
Integer port = node.getPort();
|
||||||
|
try {
|
||||||
|
String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port);
|
||||||
|
ResponseEntity<String> result = restTemplate.postForEntity(uri, runRequest, String.class);
|
||||||
|
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) {
|
||||||
|
// 清理零时报告
|
||||||
|
ApiScenarioReportService apiScenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
|
||||||
|
apiScenarioReportService.delete(reportId);
|
||||||
|
MSException.throwException("执行失败:" + result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
MSException.throwException(e.getMessage());
|
||||||
}
|
}
|
||||||
metersphereUrl += "/api/jmeter/download?testId=" + testId + "&reportId=" + reportId + "&testPlanScenarioId" + "&runMode=" + runMode;
|
|
||||||
if (StringUtils.isNotEmpty(testPlanScenarioId)) {
|
|
||||||
metersphereUrl += "=" + testPlanScenarioId;
|
|
||||||
}
|
|
||||||
runRequest.setUrl(metersphereUrl);
|
|
||||||
runRequest.setRunMode(runMode);
|
|
||||||
String uri = String.format(BASE_URL + "/jmeter/api/start", nodeIp, port);
|
|
||||||
ResponseEntity<String> result = restTemplate.postForEntity(uri, runRequest, String.class);
|
|
||||||
if (result == null || !StringUtils.equals("SUCCESS", result.getBody())) {
|
|
||||||
// 清理零时报告
|
|
||||||
ApiScenarioReportService apiScenarioReportService = CommonBeanFactory.getBean(ApiScenarioReportService.class);
|
|
||||||
apiScenarioReportService.delete(reportId);
|
|
||||||
MSException.throwException("执行失败:" + result);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
MSException.throwException(e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.performance.engine;
|
||||||
import com.alibaba.fastjson.JSON;
|
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.base.domain.LoadTestWithBLOBs;
|
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||||
import io.metersphere.base.domain.TestResource;
|
import io.metersphere.base.domain.TestResource;
|
||||||
import io.metersphere.base.domain.TestResourcePool;
|
import io.metersphere.base.domain.TestResourcePool;
|
||||||
|
@ -32,7 +33,6 @@ public abstract class AbstractEngine implements Engine {
|
||||||
protected PerformanceTestService performanceTestService;
|
protected PerformanceTestService performanceTestService;
|
||||||
protected Integer threadNum;
|
protected Integer threadNum;
|
||||||
protected List<TestResource> resourceList;
|
protected List<TestResource> resourceList;
|
||||||
|
|
||||||
private final TestResourcePoolService testResourcePoolService;
|
private final TestResourcePoolService testResourcePoolService;
|
||||||
private final TestResourceService testResourceService;
|
private final TestResourceService testResourceService;
|
||||||
|
|
||||||
|
@ -45,7 +45,39 @@ public abstract class AbstractEngine implements Engine {
|
||||||
this.startTime = System.currentTimeMillis();
|
this.startTime = System.currentTimeMillis();
|
||||||
this.reportId = UUID.randomUUID().toString();
|
this.reportId = UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
protected void initApiConfig(RunRequest runRequest) {
|
||||||
|
String resourcePoolId = runRequest.getPoolId();
|
||||||
|
TestResourcePool resourcePool = testResourcePoolService.getResourcePool(resourcePoolId);
|
||||||
|
if (resourcePool == null || StringUtils.equals(resourcePool.getStatus(), ResourceStatusEnum.DELETE.name())) {
|
||||||
|
MSException.throwException("Resource Pool is empty");
|
||||||
|
}
|
||||||
|
if (!ResourcePoolTypeEnum.K8S.name().equals(resourcePool.getType())
|
||||||
|
&& !ResourcePoolTypeEnum.NODE.name().equals(resourcePool.getType())) {
|
||||||
|
MSException.throwException("Invalid Resource Pool type.");
|
||||||
|
}
|
||||||
|
if (!StringUtils.equals(resourcePool.getStatus(), ResourceStatusEnum.VALID.name())) {
|
||||||
|
MSException.throwException("Resource Pool Status is not VALID");
|
||||||
|
}
|
||||||
|
// image
|
||||||
|
String image = resourcePool.getImage();
|
||||||
|
if (StringUtils.isNotEmpty(image)) {
|
||||||
|
JMETER_IMAGE = image;
|
||||||
|
}
|
||||||
|
// heap
|
||||||
|
String heap = resourcePool.getHeap();
|
||||||
|
if (StringUtils.isNotEmpty(heap)) {
|
||||||
|
HEAP = heap;
|
||||||
|
}
|
||||||
|
// gc_algo
|
||||||
|
String gcAlgo = resourcePool.getGcAlgo();
|
||||||
|
if (StringUtils.isNotEmpty(gcAlgo)) {
|
||||||
|
GC_ALGO = gcAlgo;
|
||||||
|
}
|
||||||
|
this.resourceList = testResourceService.getResourcesByPoolId(resourcePool.getId());
|
||||||
|
if (CollectionUtils.isEmpty(this.resourceList)) {
|
||||||
|
MSException.throwException("Test Resource is empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
protected void init(LoadTestWithBLOBs loadTest) {
|
protected void init(LoadTestWithBLOBs loadTest) {
|
||||||
if (loadTest == null) {
|
if (loadTest == null) {
|
||||||
MSException.throwException("LoadTest is null.");
|
MSException.throwException("LoadTest is null.");
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.performance.engine;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.Application;
|
import io.metersphere.Application;
|
||||||
|
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.LoadTestWithBLOBs;
|
||||||
|
@ -88,6 +89,15 @@ public class EngineFactory {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Engine createApiEngine(RunRequest runRequest) {
|
||||||
|
try {
|
||||||
|
return (Engine) ConstructorUtils.invokeConstructor(kubernetesTestEngineClass, runRequest);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static EngineContext createContext(LoadTestWithBLOBs loadTest, double[] ratios, String reportId, int resourceIndex) {
|
public static EngineContext createContext(LoadTestWithBLOBs loadTest, double[] ratios, String reportId, int resourceIndex) {
|
||||||
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId());
|
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId());
|
||||||
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
|
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
|
||||||
|
|
Loading…
Reference in New Issue