feat(接口测试): 支持场景接口用例批量执行选择环境
--story=1004209 --user=赵勇 3.case列表和场景列表批量执行支持选择环境 和测试计划保持一致 https://www.tapd.cn/55049933/s/1088817
This commit is contained in:
parent
63e59be1d2
commit
8b48633d0a
|
@ -381,5 +381,10 @@ public class ApiAutomationController {
|
|||
public void saveFollows(@PathVariable String scenarioId, @RequestBody List<String> follows) {
|
||||
apiAutomationService.saveFollows(scenarioId, follows);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/env")
|
||||
public List<String> getEnvProjects(@RequestBody RunScenarioRequest request) {
|
||||
return apiAutomationService.getProjects(request);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,9 @@ public class ApiJmeterFileController {
|
|||
}
|
||||
|
||||
@GetMapping("download")
|
||||
public ResponseEntity<byte[]> downloadJmeterFiles(@RequestParam("testId") String testId, @RequestParam("reportId") String reportId, @RequestParam("runMode") String runMode, @RequestParam("reportType") String reportType) {
|
||||
byte[] bytes = apiJmeterFileService.downloadJmeterFiles(runMode, testId, reportId, reportType);
|
||||
public ResponseEntity<byte[]> downloadJmeterFiles(@RequestParam("testId") String testId, @RequestParam("reportId") String reportId,
|
||||
@RequestParam("runMode") String runMode, @RequestParam("reportType") String reportType, @RequestParam("queueId") String queueId) {
|
||||
byte[] bytes = apiJmeterFileService.downloadJmeterFiles(runMode, testId, reportId, reportType, queueId);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + reportId + "_" + testId + ".zip\"")
|
||||
|
|
|
@ -6,6 +6,8 @@ import io.metersphere.api.dto.ApiCaseEditRequest;
|
|||
import io.metersphere.api.dto.ApiCaseRunRequest;
|
||||
import io.metersphere.api.dto.DeleteCheckResult;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.exec.api.ApiCaseExecuteService;
|
||||
import io.metersphere.api.exec.api.ApiExecuteService;
|
||||
import io.metersphere.api.service.ApiTestCaseService;
|
||||
import io.metersphere.base.domain.ApiTestCase;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
|
@ -36,6 +38,10 @@ public class ApiTestCaseController {
|
|||
private ApiTestCaseService apiTestCaseService;
|
||||
@Resource
|
||||
private TestPlanApiCaseService testPlanApiCaseService;
|
||||
@Resource
|
||||
private ApiCaseExecuteService apiCaseExecuteService;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
|
||||
@PostMapping("/list")
|
||||
public List<ApiTestCaseResult> list(@RequestBody ApiTestCaseRequest request) {
|
||||
|
@ -194,13 +200,13 @@ public class ApiTestCaseController {
|
|||
@MsAuditLog(module = "api_definition_case", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class)
|
||||
public void batchRun(@RequestBody ApiCaseRunRequest request) {
|
||||
request.setTriggerMode(ReportTriggerMode.BATCH.name());
|
||||
apiTestCaseService.batchRun(request);
|
||||
apiCaseExecuteService.run(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/jenkins/run")
|
||||
@MsAuditLog(module = "api_definition_case", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class)
|
||||
public MsExecResponseDTO jenkinsRun(@RequestBody RunCaseRequest request) {
|
||||
return apiTestCaseService.jenkinsRun(request);
|
||||
return apiExecuteService.jenkinsRun(request);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/jenkins/exec/result/{id}")
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.api.dto;
|
|||
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -17,5 +18,6 @@ public class ApiCaseRunRequest {
|
|||
private List<OrderRequest> orders;
|
||||
private String projectId;
|
||||
private String environmentId;
|
||||
private RunModeConfigDTO config;
|
||||
private ApiTestCaseRequest condition;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
package io.metersphere.api.exec.api;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
|
||||
import io.metersphere.api.dto.ApiCaseRunRequest;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.TriggerMode;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ApiCaseExecuteService {
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
private ApiScenarioSerialService apiScenarioSerialService;
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
@Resource
|
||||
private ApiCaseParallelExecuteService apiCaseParallelExecuteService;
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private EnvironmentGroupProjectService environmentGroupProjectService;
|
||||
|
||||
/**
|
||||
* 测试计划case执行
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
|
||||
List<String> ids = request.getPlanIds();
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
if (request.getConfig() == null) {
|
||||
request.setConfig(new RunModeConfigDTO());
|
||||
}
|
||||
if (StringUtils.equals("GROUP", request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
|
||||
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
|
||||
}
|
||||
LoggerUtil.debug("开始查询测试计划用例");
|
||||
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
example.setOrderByClause("`order` DESC");
|
||||
List<TestPlanApiCase> planApiCases = testPlanApiCaseMapper.selectByExample(example);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||
request.setTriggerMode(ApiRunMode.API_PLAN.name());
|
||||
}
|
||||
|
||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||
Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>();
|
||||
//记录案例线程结果以及执行失败的案例ID
|
||||
Map<String, String> executeThreadIdMap = new HashMap<>();
|
||||
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
||||
planApiCases.forEach(testPlanApiCase -> {
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, batchMapper);
|
||||
executeQueue.put(testPlanApiCase.getId(), report);
|
||||
executeThreadIdMap.put(testPlanApiCase.getId(), report.getId());
|
||||
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
LoggerUtil.debug("开始生成测试计划队列");
|
||||
String reportType = request.getConfig().getReportType();
|
||||
String poolId = request.getConfig().getResourcePoolId();
|
||||
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
|
||||
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap());
|
||||
|
||||
//如果是测试计划生成报告的执行,则更新执行信息、执行线程信息。
|
||||
if (TestPlanReportExecuteCatch.containsReport(request.getPlanReportId())) {
|
||||
if (!executeThreadIdMap.isEmpty()) {
|
||||
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(request.getPlanReportId(), executeThreadIdMap, null, null);
|
||||
}
|
||||
}
|
||||
// 开始选择执行模式
|
||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
LoggerUtil.debug("开始串行执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
apiScenarioSerialService.serial(deQueue, deQueue.getQueue());
|
||||
}
|
||||
} else {
|
||||
LoggerUtil.debug("开始并发执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), deQueue, runMode);
|
||||
}
|
||||
}
|
||||
return responseDTOS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口定义case执行
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public List<MsExecResponseDTO> run(ApiCaseRunRequest request) {
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("进入执行方法,接收到参数:" + JSON.toJSONString(request));
|
||||
}
|
||||
if (request.getConfig() == null) {
|
||||
request.setConfig(new RunModeConfigDTO());
|
||||
}
|
||||
|
||||
if (StringUtils.equals("GROUP", request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
|
||||
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
|
||||
}
|
||||
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiTestCaseMapper.selectIdsByQuery((ApiTestCaseRequest) query));
|
||||
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
List<ApiTestCaseWithBLOBs> list = apiTestCaseMapper.selectByExampleWithBLOBs(example);
|
||||
LoggerUtil.debug("查询到执行数据:" + list.size());
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||
request.setTriggerMode(ApiRunMode.DEFINITION.name());
|
||||
}
|
||||
|
||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||
Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>();
|
||||
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
||||
list.forEach(caseWithBLOBs -> {
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null, request.getConfig());
|
||||
report.setStatus(status);
|
||||
batchMapper.insert(report);
|
||||
executeQueue.put(caseWithBLOBs.getId(), report);
|
||||
responseDTOS.add(new MsExecResponseDTO(caseWithBLOBs.getId(), report.getId(), request.getTriggerMode()));
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
String reportType = request.getConfig().getReportType();
|
||||
String poolId = request.getConfig().getResourcePoolId();
|
||||
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig().getEnvMap());
|
||||
// 开始选择执行模式
|
||||
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
LoggerUtil.debug("开始串行执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
apiScenarioSerialService.serial(deQueue, deQueue.getQueue());
|
||||
}
|
||||
} else {
|
||||
LoggerUtil.debug("开始并发执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
apiCaseParallelExecuteService.parallel(executeQueue, request.getConfig(), deQueue, ApiRunMode.DEFINITION.name());
|
||||
}
|
||||
}
|
||||
return responseDTOS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package io.metersphere.api.exec.api;
|
||||
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class ApiCaseParallelExecuteService {
|
||||
@Resource
|
||||
private ApiScenarioSerialService apiScenarioSerialService;
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
|
||||
public void parallel(Map<String, ApiDefinitionExecResult> executeQueue, RunModeConfigDTO config, DBTestQueue executionQueue, String runMode) {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
Thread.currentThread().setName("API-CASE-THREAD");
|
||||
for (String testId : executeQueue.keySet()) {
|
||||
ApiDefinitionExecResult result = executeQueue.get(testId);
|
||||
String reportId = result.getId();
|
||||
HashTree hashTree = null;
|
||||
if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
|
||||
hashTree = apiScenarioSerialService.generateHashTree(testId, executionQueue.getRunMode(), config.getEnvMap());
|
||||
}
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree);
|
||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()));
|
||||
runRequest.setPoolId(config.getResourcePoolId());
|
||||
runRequest.setReportType(executionQueue.getReportType());
|
||||
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
||||
runRequest.setQueueId(executionQueue.getId());
|
||||
if (executionQueue.getQueue() != null) {
|
||||
runRequest.setPlatformUrl(executionQueue.getQueue().getId());
|
||||
}
|
||||
jMeterService.run(runRequest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("并发执行用例失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.metersphere.api.dto.ApiCaseRunRequest;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.RunCaseRequest;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.ElementUtil;
|
||||
|
@ -30,19 +28,14 @@ import io.metersphere.commons.constants.ApiRunMode;
|
|||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.apache.jorphan.collections.ListedHashTree;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -56,10 +49,6 @@ public class ApiExecuteService {
|
|||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
@Resource
|
||||
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
||||
|
@ -69,68 +58,45 @@ public class ApiExecuteService {
|
|||
private ApiTestEnvironmentService environmentService;
|
||||
@Resource
|
||||
private TcpApiParamService tcpApiParamService;
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
|
||||
public List<MsExecResponseDTO> run(ApiCaseRunRequest request) {
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("进入执行方法,接收到参数:" + JSON.toJSONString(request));
|
||||
public MsExecResponseDTO jenkinsRun(RunCaseRequest request) {
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
||||
if (request.getBloBs() == null) {
|
||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId());
|
||||
if (caseWithBLOBs == null) {
|
||||
return null;
|
||||
}
|
||||
request.setBloBs(caseWithBLOBs);
|
||||
} else {
|
||||
caseWithBLOBs = request.getBloBs();
|
||||
}
|
||||
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiTestCaseMapper.selectIdsByQuery((ApiTestCaseRequest) query));
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
List<ApiTestCaseWithBLOBs> list = apiTestCaseMapper.selectByExampleWithBLOBs(example);
|
||||
|
||||
LoggerUtil.debug("查询到执行数据:" + list.size());
|
||||
|
||||
ApiTestCaseMapper sqlSessionMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
|
||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
List<RunCaseRequest> executeQueue = new LinkedList<>();
|
||||
for (ApiTestCaseWithBLOBs caseWithBLOBs : list) {
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null);
|
||||
report.setName(caseWithBLOBs.getName());
|
||||
report.setTriggerMode(request.getTriggerMode());
|
||||
caseWithBLOBs.setLastResultId(report.getId());
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
caseWithBLOBs.setStatus(APITestStatus.Running.name());
|
||||
sqlSessionMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
|
||||
// 执行对象
|
||||
RunCaseRequest runCaseRequest = new RunCaseRequest();
|
||||
runCaseRequest.setRunMode(ApiRunMode.DEFINITION.name());
|
||||
runCaseRequest.setCaseId(caseWithBLOBs.getId());
|
||||
runCaseRequest.setReportId(report.getId());
|
||||
runCaseRequest.setEnvironmentId(request.getEnvironmentId());
|
||||
runCaseRequest.setBloBs(caseWithBLOBs);
|
||||
runCaseRequest.setReport(report);
|
||||
|
||||
batchMapper.insert(report);
|
||||
executeQueue.add(runCaseRequest);
|
||||
if (caseWithBLOBs == null) {
|
||||
return null;
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
if (StringUtils.isBlank(request.getEnvironmentId())) {
|
||||
request.setEnvironmentId(extApiTestCaseMapper.getApiCaseEnvironment(request.getCaseId()));
|
||||
}
|
||||
//提前生成报告
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.add(caseWithBLOBs.getId(), APITestStatus.Running.name(), request.getReportId());
|
||||
report.setName(caseWithBLOBs.getName());
|
||||
report.setTriggerMode(ApiRunMode.JENKINS.name());
|
||||
report.setType(ApiRunMode.JENKINS.name());
|
||||
apiDefinitionExecResultMapper.insert(report);
|
||||
//更新接口案例的最后执行状态等信息
|
||||
caseWithBLOBs.setLastResultId(report.getId());
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
caseWithBLOBs.setStatus(APITestStatus.Running.name());
|
||||
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
request.setReport(report);
|
||||
|
||||
LoggerUtil.info("生成执行队列:" + executeQueue.size());
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("生成执行队列:" + JSON.toJSONString(executeQueue));
|
||||
if (StringUtils.isEmpty(request.getRunMode())) {
|
||||
request.setRunMode(ApiRunMode.DEFINITION.name());
|
||||
}
|
||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||
for (RunCaseRequest runCaseRequest : executeQueue) {
|
||||
responseDTOS.add(exec(runCaseRequest));
|
||||
}
|
||||
return responseDTOS;
|
||||
return this.exec(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单条执行
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public MsExecResponseDTO exec(RunCaseRequest request) {
|
||||
ApiTestCaseWithBLOBs testCaseWithBLOBs = request.getBloBs();
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
package io.metersphere.api.exec.api;
|
||||
|
||||
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
|
||||
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.service.ApiExecutionQueueService;
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResult;
|
||||
import io.metersphere.base.domain.TestPlanApiCase;
|
||||
import io.metersphere.base.domain.TestPlanApiCaseExample;
|
||||
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiCaseMapper;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.TriggerMode;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanApiExecuteService {
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
private ApiScenarioSerialService apiScenarioSerialService;
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
|
||||
public List<MsExecResponseDTO> run(BatchRunDefinitionRequest request) {
|
||||
List<String> ids = request.getPlanIds();
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
LoggerUtil.debug("开始查询测试计划用例");
|
||||
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
example.setOrderByClause("`order` DESC");
|
||||
List<TestPlanApiCase> planApiCases = testPlanApiCaseMapper.selectByExample(example);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
|
||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||
request.setTriggerMode(ApiRunMode.API_PLAN.name());
|
||||
}
|
||||
|
||||
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
|
||||
Map<TestPlanApiCase, ApiDefinitionExecResult> executeQueue = new HashMap<>();
|
||||
//记录案例线程结果以及执行失败的案例ID
|
||||
Map<String, String> executeThreadIdMap = new HashMap<>();
|
||||
String status = request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
|
||||
planApiCases.forEach(testPlanApiCase -> {
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, batchMapper);
|
||||
executeQueue.put(testPlanApiCase, report);
|
||||
executeThreadIdMap.put(testPlanApiCase.getId(), report.getId());
|
||||
responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode()));
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
LoggerUtil.debug("开始生成测试计划队列");
|
||||
String reportType = request.getConfig() != null ? request.getConfig().getReportType() : null;
|
||||
String poolId = request.getConfig() != null ? request.getConfig().getResourcePoolId() : null;
|
||||
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
|
||||
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode);
|
||||
|
||||
//如果是测试计划生成报告的执行,则更新执行信息、执行线程信息。
|
||||
if (TestPlanReportExecuteCatch.containsReport(request.getPlanReportId())) {
|
||||
if (!executeThreadIdMap.isEmpty()) {
|
||||
TestPlanReportExecuteCatch.updateTestPlanThreadInfo(request.getPlanReportId(), executeThreadIdMap, null, null);
|
||||
}
|
||||
}
|
||||
// 开始选择执行模式
|
||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
LoggerUtil.debug("开始串行执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
apiScenarioSerialService.serial(deQueue, deQueue.getQueue());
|
||||
}
|
||||
} else {
|
||||
LoggerUtil.debug("开始并发执行");
|
||||
if (deQueue != null && deQueue.getQueue() != null) {
|
||||
parallel(executeQueue, request, deQueue);
|
||||
}
|
||||
}
|
||||
return responseDTOS;
|
||||
}
|
||||
|
||||
private void parallel(Map<TestPlanApiCase, ApiDefinitionExecResult> executeQueue, BatchRunDefinitionRequest request, DBTestQueue executionQueue) {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
Thread.currentThread().setName("测试计划入列线程");
|
||||
for (TestPlanApiCase testPlanApiCase : executeQueue.keySet()) {
|
||||
ApiDefinitionExecResult result = executeQueue.get(testPlanApiCase);
|
||||
String reportId = result.getId();
|
||||
HashTree hashTree = null;
|
||||
if (request.getConfig() == null || !GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) {
|
||||
hashTree = apiScenarioSerialService.generateHashTree(testPlanApiCase.getId());
|
||||
}
|
||||
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testPlanApiCase.getId(), reportId, runMode, hashTree);
|
||||
if (request.getConfig() != null) {
|
||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
|
||||
runRequest.setPoolId(request.getConfig().getResourcePoolId());
|
||||
}
|
||||
runRequest.setTestPlanReportId(request.getPlanReportId());
|
||||
runRequest.setReportType(executionQueue.getReportType());
|
||||
runRequest.setTestPlanReportId(request.getPlanReportId());
|
||||
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
|
||||
runRequest.setQueueId(executionQueue.getId());
|
||||
jMeterService.run(runRequest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("并发执行测试计划用例失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
}
|
|
@ -4,7 +4,11 @@ import io.metersphere.base.domain.ApiExecutionQueue;
|
|||
import io.metersphere.base.domain.ApiExecutionQueueDetail;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class DBTestQueue extends ApiExecutionQueue {
|
||||
private ApiExecutionQueueDetail queue;
|
||||
private Map<String, String> detailMap = new HashMap<>();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import io.metersphere.commons.utils.SessionUtils;
|
|||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||
import io.metersphere.track.service.TestPlanScenarioCaseService;
|
||||
|
@ -98,6 +99,14 @@ public class ApiScenarioExecuteService {
|
|||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||
request.setTriggerMode(ReportTriggerMode.MANUAL.name());
|
||||
}
|
||||
if (request.getConfig() == null) {
|
||||
request.setConfig(new RunModeConfigDTO());
|
||||
}
|
||||
|
||||
if (StringUtils.equals("GROUP", request.getConfig().getEnvironmentType()) && StringUtils.isNotEmpty(request.getConfig().getEnvironmentGroupId())) {
|
||||
request.getConfig().setEnvMap(environmentGroupProjectService.getEnvMap(request.getConfig().getEnvironmentGroupId()));
|
||||
}
|
||||
|
||||
// 生成集成报告
|
||||
String serialReportId = null;
|
||||
LoggerUtil.info("Scenario run-执行脚本装载-根据条件查询所有场景 ");
|
||||
|
@ -156,8 +165,7 @@ public class ApiScenarioExecuteService {
|
|||
// 开始执行
|
||||
if (executeQueue != null && executeQueue.size() > 0) {
|
||||
String reportType = request.getConfig().getReportType();
|
||||
|
||||
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), serialReportId, reportType, request.getRunMode());
|
||||
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), serialReportId, reportType, request.getRunMode(), request.getConfig().getEnvMap());
|
||||
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
if (StringUtils.isNotEmpty(serialReportId)) {
|
||||
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig() != null ? request.getConfig().getReportType() : null);
|
||||
|
@ -181,7 +189,7 @@ public class ApiScenarioExecuteService {
|
|||
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
|
||||
}
|
||||
} else {
|
||||
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS, executionQueue.getId());
|
||||
apiScenarioParallelService.parallel(executeQueue, request, serialReportId, responseDTOS, executionQueue);
|
||||
}
|
||||
}
|
||||
return responseDTOS;
|
||||
|
@ -309,6 +317,9 @@ public class ApiScenarioExecuteService {
|
|||
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
|
||||
runModeDataDTO.setTestId(item.getId());
|
||||
runModeDataDTO.setPlanEnvMap(new HashMap<>());
|
||||
if (request.getConfig().getEnvMap() != null) {
|
||||
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
|
||||
}
|
||||
runModeDataDTO.setReport(report);
|
||||
runModeDataDTO.setReportId(report.getId());
|
||||
executeQueue.put(report.getId(), runModeDataDTO);
|
||||
|
@ -317,9 +328,10 @@ public class ApiScenarioExecuteService {
|
|||
try {
|
||||
RunModeDataDTO runModeDataDTO = new RunModeDataDTO(report, item.getId());
|
||||
if (request.getConfig() != null && !request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
|
||||
HashTree hashTree = GenerateHashTreeUtil.generateHashTree(item, StringUtils.isNotEmpty(serialReportId) ? serialReportId + "-" + i : reportId, new HashMap<>(), request.getConfig().getReportType());
|
||||
HashTree hashTree = GenerateHashTreeUtil.generateHashTree(item, StringUtils.isNotEmpty(serialReportId) ? serialReportId + "-" + i : reportId, request.getConfig().getEnvMap(), request.getConfig().getReportType());
|
||||
runModeDataDTO.setHashTree(hashTree);
|
||||
}
|
||||
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
|
||||
executeQueue.put(report.getId(), runModeDataDTO);
|
||||
} catch (Exception ex) {
|
||||
scenarioIds.remove(item.getId());
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import io.metersphere.api.dto.RunModeDataDTO;
|
||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||
import io.metersphere.api.exec.queue.DBTestQueue;
|
||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
|
@ -30,7 +31,7 @@ public class ApiScenarioParallelService {
|
|||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
|
||||
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS, String queueId) {
|
||||
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, List<MsExecResponseDTO> responseDTOS, DBTestQueue executionQueue) {
|
||||
if (StringUtils.isEmpty(serialReportId)) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
|
||||
|
@ -49,13 +50,14 @@ public class ApiScenarioParallelService {
|
|||
for (String reportId : executeQueue.keySet()) {
|
||||
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(executeQueue.get(reportId).getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), executeQueue.get(reportId).getHashTree());
|
||||
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
|
||||
runRequest.setQueueId(queueId);
|
||||
runRequest.setQueueId(executionQueue.getId());
|
||||
if (request.getConfig() != null) {
|
||||
runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()));
|
||||
runRequest.setPoolId(request.getConfig().getResourcePoolId());
|
||||
}
|
||||
runRequest.setTestPlanReportId(request.getTestPlanReportId());
|
||||
runRequest.setHashTree(executeQueue.get(reportId).getHashTree());
|
||||
runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId));
|
||||
if (LoggerUtil.getLogger().isDebugEnabled()) {
|
||||
LoggerUtil.debug("Scenario run-开始并发执行:" + JSON.toJSONString(request));
|
||||
}
|
||||
|
|
|
@ -100,7 +100,11 @@ public class ApiScenarioSerialService {
|
|||
}
|
||||
hashTree = GenerateHashTreeUtil.generateHashTree(scenario, queue.getReportId(), planEnvMap, executionQueue.getReportType());
|
||||
} else {
|
||||
hashTree = generateHashTree(queue.getTestId());
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
if (StringUtils.isNotEmpty(queue.getEvnMap())) {
|
||||
map = JSON.parseObject(queue.getEvnMap(), Map.class);
|
||||
}
|
||||
hashTree = generateHashTree(queue.getTestId(), queue.getType(), map);
|
||||
}
|
||||
// 更新环境变量
|
||||
this.initEnv(hashTree);
|
||||
|
@ -116,6 +120,9 @@ public class ApiScenarioSerialService {
|
|||
runRequest.setRunType(RunModeConstants.SERIAL.toString());
|
||||
runRequest.setQueueId(executionQueue.getId());
|
||||
runRequest.setPoolId(executionQueue.getPoolId());
|
||||
if (queue != null) {
|
||||
runRequest.setPlatformUrl(queue.getId());
|
||||
}
|
||||
// 开始执行
|
||||
jMeterService.run(runRequest);
|
||||
} catch (Exception e) {
|
||||
|
@ -145,25 +152,36 @@ public class ApiScenarioSerialService {
|
|||
hashTreeUtil.mergeParamDataMap(null, envParamsMap);
|
||||
}
|
||||
|
||||
public HashTree generateHashTree(String testId) {
|
||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||
if (apiCase != null) {
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
||||
public HashTree generateHashTree(String testId, String type, Map<String, String> envMap) {
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
||||
String envId = null;
|
||||
if (StringUtils.equals(type, ApiRunMode.DEFINITION.name())) {
|
||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(testId);
|
||||
} else {
|
||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(testId);
|
||||
if (apiCase != null) {
|
||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(apiCase.getApiCaseId());
|
||||
envId = apiCase.getEnvironmentId();
|
||||
}
|
||||
}
|
||||
if (envMap != null && envMap.containsKey(caseWithBLOBs.getProjectId())) {
|
||||
envId = envMap.get(caseWithBLOBs.getProjectId());
|
||||
}
|
||||
if (caseWithBLOBs != null) {
|
||||
HashTree jmeterHashTree = new HashTree();
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
if (caseWithBLOBs != null) {
|
||||
try {
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(caseWithBLOBs.getName());
|
||||
group.setName(caseWithBLOBs.getName());
|
||||
MsTestElement testElement = parse(caseWithBLOBs, testId);
|
||||
group.setHashTree(new LinkedList<>());
|
||||
group.getHashTree().add(testElement);
|
||||
testPlan.getHashTree().add(group);
|
||||
} catch (Exception ex) {
|
||||
MSException.throwException(ex.getMessage());
|
||||
}
|
||||
try {
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(caseWithBLOBs.getName());
|
||||
group.setName(caseWithBLOBs.getName());
|
||||
|
||||
MsTestElement testElement = parse(caseWithBLOBs, testId, envId);
|
||||
group.setHashTree(new LinkedList<>());
|
||||
group.getHashTree().add(testElement);
|
||||
testPlan.getHashTree().add(group);
|
||||
} catch (Exception ex) {
|
||||
MSException.throwException(ex.getMessage());
|
||||
}
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||
return jmeterHashTree;
|
||||
|
@ -171,7 +189,7 @@ public class ApiScenarioSerialService {
|
|||
return null;
|
||||
}
|
||||
|
||||
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId) {
|
||||
private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId, String envId) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
try {
|
||||
|
@ -186,31 +204,38 @@ public class ApiScenarioSerialService {
|
|||
});
|
||||
list.addAll(elements);
|
||||
}
|
||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(planId);
|
||||
if (element.getString("type").equals("HTTPSamplerProxy")) {
|
||||
MsHTTPSamplerProxy httpSamplerProxy = JSON.parseObject(api, MsHTTPSamplerProxy.class);
|
||||
httpSamplerProxy.setHashTree(list);
|
||||
httpSamplerProxy.setName(planId);
|
||||
httpSamplerProxy.setUseEnvironment(apiCase.getEnvironmentId());
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
httpSamplerProxy.setUseEnvironment(envId);
|
||||
}
|
||||
return httpSamplerProxy;
|
||||
}
|
||||
if (element.getString("type").equals("TCPSampler")) {
|
||||
MsTCPSampler msTCPSampler = JSON.parseObject(api, MsTCPSampler.class);
|
||||
msTCPSampler.setUseEnvironment(apiCase.getEnvironmentId());
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
msTCPSampler.setUseEnvironment(envId);
|
||||
}
|
||||
msTCPSampler.setHashTree(list);
|
||||
msTCPSampler.setName(planId);
|
||||
return msTCPSampler;
|
||||
}
|
||||
if (element.getString("type").equals("DubboSampler")) {
|
||||
MsDubboSampler dubboSampler = JSON.parseObject(api, MsDubboSampler.class);
|
||||
dubboSampler.setUseEnvironment(apiCase.getEnvironmentId());
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
dubboSampler.setUseEnvironment(envId);
|
||||
}
|
||||
dubboSampler.setHashTree(list);
|
||||
dubboSampler.setName(planId);
|
||||
return dubboSampler;
|
||||
}
|
||||
if (element.getString("type").equals("JDBCSampler")) {
|
||||
MsJDBCSampler jDBCSampler = JSON.parseObject(api, MsJDBCSampler.class);
|
||||
jDBCSampler.setUseEnvironment(apiCase.getEnvironmentId());
|
||||
if (StringUtils.isNotEmpty(envId)) {
|
||||
jDBCSampler.setUseEnvironment(envId);
|
||||
}
|
||||
jDBCSampler.setHashTree(list);
|
||||
jDBCSampler.setName(planId);
|
||||
return jDBCSampler;
|
||||
|
|
|
@ -10,13 +10,14 @@ import io.metersphere.commons.constants.ApiRunMode;
|
|||
import io.metersphere.commons.constants.TriggerMode;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.dto.RunModeConfigDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ApiDefinitionExecResultUtil {
|
||||
public static ApiDefinitionExecResult initBase(String resourceId, String status, String reportId) {
|
||||
public static ApiDefinitionExecResult initBase(String resourceId, String status, String reportId, RunModeConfigDTO config) {
|
||||
ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult();
|
||||
if (StringUtils.isEmpty(reportId)) {
|
||||
apiResult.setId(UUID.randomUUID().toString());
|
||||
|
@ -28,6 +29,9 @@ public class ApiDefinitionExecResultUtil {
|
|||
apiResult.setEndTime(System.currentTimeMillis());
|
||||
apiResult.setTriggerMode(TriggerMode.BATCH.name());
|
||||
apiResult.setActuator("LOCAL");
|
||||
if (config != null && GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) {
|
||||
apiResult.setActuator(config.getResourcePoolId());
|
||||
}
|
||||
apiResult.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||
apiResult.setResourceId(resourceId);
|
||||
apiResult.setStartTime(System.currentTimeMillis());
|
||||
|
|
|
@ -107,11 +107,15 @@ public class JMeterService {
|
|||
if (baseInfo != null) {
|
||||
platformUrl = baseInfo.getUrl();
|
||||
}
|
||||
// 临时存放
|
||||
String queueDetailId = request.getPlatformUrl();
|
||||
|
||||
platformUrl += "/api/jmeter/download?testId="
|
||||
+ request.getTestId()
|
||||
+ "&reportId=" + request.getReportId()
|
||||
+ "&runMode=" + request.getRunMode()
|
||||
+ "&reportType=" + request.getReportType();
|
||||
+ "&reportType=" + request.getReportType()
|
||||
+ "&queueId=" + queueDetailId;
|
||||
|
||||
request.setPlatformUrl(platformUrl);
|
||||
request.setKafkaConfig(KafkaConfig.getKafka());
|
||||
|
|
|
@ -1899,4 +1899,20 @@ public class ApiAutomationService {
|
|||
public List<MsExecResponseDTO> run(RunScenarioRequest request) {
|
||||
return apiScenarioExecuteService.run(request);
|
||||
}
|
||||
|
||||
public List<String> getProjects(RunScenarioRequest request) {
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiScenarioMapper.selectIdsByQuery(query));
|
||||
List<String> ids = request.getIds();
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(example);
|
||||
List<String> strings = new LinkedList<>();
|
||||
apiScenarios.forEach(item -> {
|
||||
if (!strings.contains(item.getProjectId())) {
|
||||
strings.add(item.getProjectId());
|
||||
}
|
||||
});
|
||||
return strings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,43 +90,47 @@ public class ApiDefinitionExecResultService {
|
|||
}
|
||||
|
||||
private void sendNotice(ApiDefinitionExecResult result) {
|
||||
String resourceId = result.getResourceId();
|
||||
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(resourceId);
|
||||
// 接口定义直接执行不发通知
|
||||
if (apiTestCaseWithBLOBs == null) {
|
||||
return;
|
||||
}
|
||||
BeanMap beanMap = new BeanMap(apiTestCaseWithBLOBs);
|
||||
try {
|
||||
String resourceId = result.getResourceId();
|
||||
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(resourceId);
|
||||
// 接口定义直接执行不发通知
|
||||
if (apiTestCaseWithBLOBs == null) {
|
||||
return;
|
||||
}
|
||||
BeanMap beanMap = new BeanMap(apiTestCaseWithBLOBs);
|
||||
|
||||
String event;
|
||||
String status;
|
||||
if (StringUtils.equals(result.getStatus(), "success")) {
|
||||
event = NoticeConstants.Event.EXECUTE_SUCCESSFUL;
|
||||
status = "成功";
|
||||
} else {
|
||||
event = NoticeConstants.Event.EXECUTE_FAILED;
|
||||
status = "失败";
|
||||
}
|
||||
String event;
|
||||
String status;
|
||||
if (StringUtils.equals(result.getStatus(), "success")) {
|
||||
event = NoticeConstants.Event.EXECUTE_SUCCESSFUL;
|
||||
status = "成功";
|
||||
} else {
|
||||
event = NoticeConstants.Event.EXECUTE_FAILED;
|
||||
status = "失败";
|
||||
}
|
||||
|
||||
Map paramMap = new HashMap<>(beanMap);
|
||||
paramMap.put("operator", SessionUtils.getUser().getName());
|
||||
paramMap.put("status", result.getStatus());
|
||||
String context = "${operator}执行接口用例" + status + ": ${name}";
|
||||
NoticeModel noticeModel = NoticeModel.builder()
|
||||
.operator(SessionUtils.getUserId())
|
||||
.context(context)
|
||||
.subject("接口用例通知")
|
||||
.successMailTemplate("api/CaseResultSuccess")
|
||||
.failedMailTemplate("api/CaseResultFailed")
|
||||
.paramMap(paramMap)
|
||||
.event(event)
|
||||
.build();
|
||||
Map paramMap = new HashMap<>(beanMap);
|
||||
paramMap.put("operator", SessionUtils.getUser().getName());
|
||||
paramMap.put("status", result.getStatus());
|
||||
String context = "${operator}执行接口用例" + status + ": ${name}";
|
||||
NoticeModel noticeModel = NoticeModel.builder()
|
||||
.operator(SessionUtils.getUserId())
|
||||
.context(context)
|
||||
.subject("接口用例通知")
|
||||
.successMailTemplate("api/CaseResultSuccess")
|
||||
.failedMailTemplate("api/CaseResultFailed")
|
||||
.paramMap(paramMap)
|
||||
.event(event)
|
||||
.build();
|
||||
|
||||
String taskType = NoticeConstants.TaskType.API_DEFINITION_TASK;
|
||||
if (StringUtils.equals(ReportTriggerMode.API.name(), result.getTriggerMode())) {
|
||||
noticeSendService.send(ReportTriggerMode.API.name(), taskType, noticeModel);
|
||||
} else {
|
||||
noticeSendService.send(taskType, noticeModel);
|
||||
String taskType = NoticeConstants.TaskType.API_DEFINITION_TASK;
|
||||
if (StringUtils.equals(ReportTriggerMode.API.name(), result.getTriggerMode())) {
|
||||
noticeSendService.send(ReportTriggerMode.API.name(), taskType, noticeModel);
|
||||
} else {
|
||||
noticeSendService.send(taskType, noticeModel);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ import org.mybatis.spring.SqlSessionUtils;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
@ -50,7 +48,7 @@ public class ApiExecutionQueueService {
|
|||
@Resource
|
||||
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
|
||||
|
||||
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode) {
|
||||
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, Map<String, String> envMap) {
|
||||
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
|
||||
executionQueue.setId(UUID.randomUUID().toString());
|
||||
executionQueue.setCreateTime(System.currentTimeMillis());
|
||||
|
@ -61,19 +59,25 @@ public class ApiExecutionQueueService {
|
|||
queueMapper.insert(executionQueue);
|
||||
DBTestQueue resQueue = new DBTestQueue();
|
||||
BeanUtils.copyBean(resQueue, executionQueue);
|
||||
Map<String, String> detailMap = new HashMap<>();
|
||||
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiExecutionQueueDetailMapper batchMapper = sqlSession.getMapper(ApiExecutionQueueDetailMapper.class);
|
||||
if (StringUtils.equals(type, ApiRunMode.API_PLAN.name())) {
|
||||
if (StringUtils.equalsAny(type, ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name())) {
|
||||
final int[] sort = {0};
|
||||
Map<TestPlanApiCase, ApiDefinitionExecResult> runMap = (Map<TestPlanApiCase, ApiDefinitionExecResult>) runObj;
|
||||
Map<String, ApiDefinitionExecResult> runMap = (Map<String, ApiDefinitionExecResult>) runObj;
|
||||
if (envMap == null) {
|
||||
envMap = new LinkedHashMap<>();
|
||||
}
|
||||
String envStr = JSON.toJSONString(envMap);
|
||||
runMap.forEach((k, v) -> {
|
||||
ApiExecutionQueueDetail queue = detail(v.getId(), k.getId(), type, sort[0], executionQueue.getId(), null);
|
||||
ApiExecutionQueueDetail queue = detail(v.getId(), k, type, sort[0], executionQueue.getId(), envStr);
|
||||
if (sort[0] == 0) {
|
||||
resQueue.setQueue(queue);
|
||||
}
|
||||
sort[0]++;
|
||||
batchMapper.insert(queue);
|
||||
detailMap.put(k, queue.getId());
|
||||
});
|
||||
} else {
|
||||
Map<String, RunModeDataDTO> runMap = (Map<String, RunModeDataDTO>) runObj;
|
||||
|
@ -86,12 +90,14 @@ public class ApiExecutionQueueService {
|
|||
}
|
||||
sort[0]++;
|
||||
batchMapper.insert(queue);
|
||||
detailMap.put(k, queue.getId());
|
||||
});
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
if (sqlSession != null && sqlSessionFactory != null) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
resQueue.setDetailMap(detailMap);
|
||||
return resQueue;
|
||||
}
|
||||
|
||||
|
@ -117,7 +123,7 @@ public class ApiExecutionQueueService {
|
|||
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
|
||||
example.setOrderByClause("sort asc");
|
||||
example.createCriteria().andQueueIdEqualTo(id);
|
||||
List<ApiExecutionQueueDetail> queues = executionQueueDetailMapper.selectByExample(example);
|
||||
List<ApiExecutionQueueDetail> queues = executionQueueDetailMapper.selectByExampleWithBLOBs(example);
|
||||
if (CollectionUtils.isNotEmpty(queues)) {
|
||||
List<ApiExecutionQueueDetail> list = queues.stream().filter(item -> StringUtils.equals(item.getTestId(), testId)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
|
|
|
@ -6,10 +6,8 @@ import io.metersphere.api.dto.definition.request.MsTestPlan;
|
|||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
|
||||
import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.JarConfig;
|
||||
import io.metersphere.base.domain.Plugin;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
|
@ -43,6 +41,9 @@ public class ApiJmeterFileService {
|
|||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
@Resource
|
||||
private ApiScenarioMapper apiScenarioMapper;
|
||||
@Resource
|
||||
private ApiExecutionQueueDetailMapper executionQueueDetailMapper;
|
||||
|
||||
@Resource
|
||||
private EnvironmentGroupProjectService environmentGroupProjectService;
|
||||
|
||||
|
@ -58,7 +59,7 @@ public class ApiJmeterFileService {
|
|||
return listBytesToZip(files);
|
||||
}
|
||||
|
||||
public byte[] downloadJmeterFiles(String runMode, String remoteTestId, String reportId, String reportType) {
|
||||
public byte[] downloadJmeterFiles(String runMode, String remoteTestId, String reportId, String reportType, String queueId) {
|
||||
Map<String, String> planEnvMap = new HashMap<>();
|
||||
ApiScenarioWithBLOBs scenario = null;
|
||||
if (StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
||||
|
@ -76,9 +77,14 @@ public class ApiJmeterFileService {
|
|||
scenario = apiScenarioMapper.selectByPrimaryKey(planApiScenario.getApiScenarioId());
|
||||
}
|
||||
}
|
||||
ApiExecutionQueueDetail detail = executionQueueDetailMapper.selectByPrimaryKey(queueId);
|
||||
Map<String, String> envMap = new LinkedHashMap<>();
|
||||
if (detail != null && StringUtils.isNotEmpty(detail.getEvnMap())) {
|
||||
envMap = JSON.parseObject(detail.getEvnMap(), Map.class);
|
||||
}
|
||||
HashTree hashTree;
|
||||
if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
|
||||
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId);
|
||||
hashTree = apiScenarioSerialService.generateHashTree(remoteTestId, runMode, envMap);
|
||||
} else {
|
||||
if (scenario == null) {
|
||||
scenario = apiScenarioMapper.selectByPrimaryKey(remoteTestId);
|
||||
|
@ -86,7 +92,9 @@ public class ApiJmeterFileService {
|
|||
if (scenario == null) {
|
||||
MSException.throwException("未找到执行场景。");
|
||||
}
|
||||
if (!StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
||||
if (envMap != null && !envMap.isEmpty()) {
|
||||
planEnvMap = envMap;
|
||||
} else if (!StringUtils.equalsAny(runMode, ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
|
||||
String envType = scenario.getEnvironmentType();
|
||||
String envJson = scenario.getEnvironmentJson();
|
||||
String envGroupId = scenario.getEnvironmentGroupId();
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.metersphere.api.dto.ApiCaseEditRequest;
|
||||
import io.metersphere.api.dto.ApiCaseRunRequest;
|
||||
import io.metersphere.api.dto.DeleteCheckResult;
|
||||
import io.metersphere.api.dto.JmxInfoDTO;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
|
@ -16,20 +15,16 @@ import io.metersphere.api.dto.definition.request.MsTestPlan;
|
|||
import io.metersphere.api.dto.definition.request.MsThreadGroup;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.exec.api.ApiExecuteService;
|
||||
import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.*;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.MsTestElementConstants;
|
||||
import io.metersphere.commons.constants.TestPlanStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.controller.request.ResetOrderRequest;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.log.utils.ReflexObjectUtil;
|
||||
import io.metersphere.log.vo.DetailColumn;
|
||||
|
@ -83,8 +78,6 @@ public class ApiTestCaseService {
|
|||
@Resource
|
||||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
@Resource
|
||||
private ApiExecuteService apiCaseExecuteService;
|
||||
@Resource
|
||||
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
|
||||
@Resource
|
||||
private EsbApiParamService esbApiParamService;
|
||||
|
@ -744,47 +737,6 @@ public class ApiTestCaseService {
|
|||
return ids;
|
||||
}
|
||||
|
||||
public void batchRun(ApiCaseRunRequest request) {
|
||||
apiCaseExecuteService.run(request);
|
||||
}
|
||||
|
||||
public MsExecResponseDTO jenkinsRun(RunCaseRequest request) {
|
||||
ApiTestCaseWithBLOBs caseWithBLOBs = null;
|
||||
if (request.getBloBs() == null) {
|
||||
caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getCaseId());
|
||||
if (caseWithBLOBs == null) {
|
||||
return null;
|
||||
}
|
||||
request.setBloBs(caseWithBLOBs);
|
||||
} else {
|
||||
caseWithBLOBs = request.getBloBs();
|
||||
}
|
||||
if (caseWithBLOBs == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isBlank(request.getEnvironmentId())) {
|
||||
request.setEnvironmentId(extApiTestCaseMapper.getApiCaseEnvironment(request.getCaseId()));
|
||||
}
|
||||
//提前生成报告
|
||||
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.add(caseWithBLOBs.getId(), APITestStatus.Running.name(), request.getReportId());
|
||||
report.setName(caseWithBLOBs.getName());
|
||||
report.setTriggerMode(ApiRunMode.JENKINS.name());
|
||||
report.setType(ApiRunMode.JENKINS.name());
|
||||
apiDefinitionExecResultMapper.insert(report);
|
||||
//更新接口案例的最后执行状态等信息
|
||||
caseWithBLOBs.setLastResultId(report.getId());
|
||||
caseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
caseWithBLOBs.setStatus(APITestStatus.Running.name());
|
||||
apiTestCaseMapper.updateByPrimaryKey(caseWithBLOBs);
|
||||
request.setReport(report);
|
||||
|
||||
if (StringUtils.isEmpty(request.getRunMode())) {
|
||||
request.setRunMode(ApiRunMode.DEFINITION.name());
|
||||
}
|
||||
|
||||
return apiCaseExecuteService.exec(request);
|
||||
}
|
||||
|
||||
public String getExecResult(String id) {
|
||||
String status = extApiDefinitionExecResultMapper.selectExecResult(id);
|
||||
return status;
|
||||
|
|
|
@ -9,7 +9,7 @@ import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
|||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.BatchRunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.api.exec.api.TestPlanApiExecuteService;
|
||||
import io.metersphere.api.exec.api.ApiCaseExecuteService;
|
||||
import io.metersphere.api.service.ApiDefinitionExecResultService;
|
||||
import io.metersphere.api.service.ApiTestCaseService;
|
||||
import io.metersphere.base.domain.*;
|
||||
|
@ -60,7 +60,7 @@ public class TestPlanApiCaseService {
|
|||
@Resource
|
||||
ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private TestPlanApiExecuteService testPlanApiCaseExecuteService;
|
||||
private ApiCaseExecuteService testPlanApiCaseExecuteService;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
|
|
|
@ -141,9 +141,9 @@
|
|||
<div v-if="row.environmentMap">
|
||||
<span v-for="(k, v, index) in row.environmentMap" :key="index">
|
||||
<span v-if="index===0">
|
||||
<span class="project-name" :title="v">{{v}}</span>:
|
||||
<span class="project-name" :title="v">{{ v }}</span>:
|
||||
<el-tag type="success" size="mini" effect="plain">
|
||||
<span class="project-env">{{k}}</span>
|
||||
<span class="project-env">{{ k }}</span>
|
||||
</el-tag>
|
||||
<br/>
|
||||
</span>
|
||||
|
@ -152,8 +152,8 @@
|
|||
width="350"
|
||||
trigger="click">
|
||||
<div v-for="(k, v, index) in row.environmentMap" :key="index">
|
||||
<span class="plan-case-env">{{v}}:
|
||||
<el-tag type="success" size="mini" effect="plain">{{k}}</el-tag><br/>
|
||||
<span class="plan-case-env">{{ v }}:
|
||||
<el-tag type="success" size="mini" effect="plain">{{ k }}</el-tag><br/>
|
||||
</span>
|
||||
</div>
|
||||
<el-link v-if="index === 1" slot="reference" type="info" :underline="false" icon="el-icon-more"/>
|
||||
|
@ -266,7 +266,7 @@
|
|||
<batch-edit ref="batchEdit" @batchEdit="batchEdit" :typeArr="typeArr" :value-arr="valueArr"
|
||||
:dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||
<batch-move @refresh="search" @moveSave="moveSave" ref="testBatchMove"/>
|
||||
<ms-run-mode @handleRunBatch="handleRunBatch" ref="runMode"/>
|
||||
<ms-run-mode @handleRunBatch="handleRunBatch" :request="runRequest" ref="runMode"/>
|
||||
<ms-run :debug="true" :environment="projectEnvMap" @runRefresh="runRefresh" :reportId="reportId" :saved="true"
|
||||
:environment-type="environmentType" :environment-group-id="envGroupId"
|
||||
:run-data="debugData" ref="runTest"/>
|
||||
|
@ -533,7 +533,8 @@ export default {
|
|||
graphData: {},
|
||||
environmentType: "",
|
||||
envGroupId: "",
|
||||
apiscenariofilters:{},
|
||||
apiscenariofilters: {},
|
||||
runRequest: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -832,6 +833,14 @@ export default {
|
|||
param.condition = this.condition;
|
||||
},
|
||||
handleBatchExecute() {
|
||||
let run = {};
|
||||
run.id = getUUID();
|
||||
//按照列表排序
|
||||
let ids = this.orderBySelectRows();
|
||||
run.ids = ids;
|
||||
run.projectId = this.projectId;
|
||||
run.condition = this.condition;
|
||||
this.runRequest = run;
|
||||
this.$refs.runMode.open();
|
||||
|
||||
},
|
||||
|
@ -1249,7 +1258,7 @@ export default {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.project-env{
|
||||
.project-env {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -2,9 +2,22 @@
|
|||
<el-dialog
|
||||
destroy-on-close
|
||||
:title="$t('load_test.runtime_config')"
|
||||
width="450px"
|
||||
width="550px"
|
||||
:visible.sync="runModeVisible"
|
||||
>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span class="ms-mode-span">{{ $t("commons.environment") }}:</span>
|
||||
<env-popover :project-ids="projectIds"
|
||||
:placement="'bottom-start'"
|
||||
:project-list="projectList"
|
||||
:project-env-map="projectEnvListMap"
|
||||
:environment-type.sync="runConfig.environmentType"
|
||||
:group-id="runConfig.environmentGroupId"
|
||||
@setEnvGroup="setEnvGroup"
|
||||
@setProjectEnvMap="setProjectEnvMap"
|
||||
@showPopover="showPopover"
|
||||
ref="envPopover" class="env-popover"/>
|
||||
</div>
|
||||
<div>
|
||||
<span class="ms-mode-span">{{ $t("run_mode.title") }}:</span>
|
||||
<el-radio-group v-model="runConfig.mode" @change="changeMode">
|
||||
|
@ -58,27 +71,39 @@
|
|||
|
||||
<script>
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import {ENV_TYPE} from "@/common/js/constants";
|
||||
import {strMapToObj} from "@/common/js/utils";
|
||||
import EnvPopover from "@/business/components/api/automation/scenario/EnvPopover";
|
||||
|
||||
export default {
|
||||
name: "RunMode",
|
||||
components: {MsDialogFooter},
|
||||
components: {MsDialogFooter, EnvPopover},
|
||||
data() {
|
||||
return {
|
||||
runModeVisible: false,
|
||||
testType: null,
|
||||
resourcePools: [],
|
||||
runConfig: {
|
||||
reportName: "",
|
||||
mode: "serial",
|
||||
reportType: "iddReport",
|
||||
reportName: "",
|
||||
onSampleError: false,
|
||||
runWithinResourcePool: false,
|
||||
resourcePoolId: null,
|
||||
envMap: new Map(),
|
||||
environmentGroupId: "",
|
||||
environmentType: ENV_TYPE.JSON
|
||||
},
|
||||
projectEnvListMap: {},
|
||||
projectList: [],
|
||||
projectIds: new Set(),
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
'runConfig.runWithinResourcePool'(){
|
||||
if(!this.runConfig.runWithinResourcePool){
|
||||
props: ['request'],
|
||||
|
||||
watch: {
|
||||
'runConfig.runWithinResourcePool'() {
|
||||
if (!this.runConfig.runWithinResourcePool) {
|
||||
this.runConfig = {
|
||||
mode: this.runConfig.mode,
|
||||
reportType: "iddReport",
|
||||
|
@ -93,6 +118,7 @@ export default {
|
|||
open() {
|
||||
this.runModeVisible = true;
|
||||
this.getResourcePools();
|
||||
this.getWsProjects();
|
||||
},
|
||||
changeMode() {
|
||||
this.runConfig.runWithinResourcePool = false;
|
||||
|
@ -110,6 +136,11 @@ export default {
|
|||
};
|
||||
this.runModeVisible = false;
|
||||
},
|
||||
getWsProjects() {
|
||||
this.$get("/project/listAll", res => {
|
||||
this.projectList = res.data;
|
||||
})
|
||||
},
|
||||
handleRunBatch() {
|
||||
if (this.runConfig.mode === 'serial' && this.runConfig.reportType === 'setReport' && this.runConfig.reportName.trim() === "") {
|
||||
this.$warning(this.$t('commons.input_name'));
|
||||
|
@ -123,6 +154,25 @@ export default {
|
|||
this.resourcePools = response.data;
|
||||
});
|
||||
},
|
||||
setEnvGroup(id) {
|
||||
this.runConfig.environmentGroupId = id;
|
||||
},
|
||||
setProjectEnvMap(projectEnvMap) {
|
||||
this.runConfig.envMap = strMapToObj(projectEnvMap);
|
||||
},
|
||||
showPopover() {
|
||||
this.projectIds.clear();
|
||||
let url = "/api/automation/env";
|
||||
this.$post(url, this.request, res => {
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
for (let d in data) {
|
||||
this.projectIds.add(data[d]);
|
||||
}
|
||||
}
|
||||
this.$refs.envPopover.openEnvSelect();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
destroy-on-close
|
||||
:title="$t('load_test.runtime_config')"
|
||||
width="550px"
|
||||
:visible.sync="runModeVisible"
|
||||
>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span class="ms-mode-span">{{ $t("commons.environment") }}:</span>
|
||||
<env-popover :project-ids="projectIds"
|
||||
:placement="'bottom-start'"
|
||||
:project-list="projectList"
|
||||
:project-env-map="projectEnvListMap"
|
||||
:environment-type.sync="runConfig.environmentType"
|
||||
:group-id="runConfig.environmentGroupId"
|
||||
@setEnvGroup="setEnvGroup"
|
||||
@setProjectEnvMap="setProjectEnvMap"
|
||||
@showPopover="showPopover"
|
||||
ref="envPopover" class="env-popover"/>
|
||||
</div>
|
||||
<div>
|
||||
<span class="ms-mode-span">{{ $t("run_mode.title") }}:</span>
|
||||
<el-radio-group v-model="runConfig.mode" @change="changeMode">
|
||||
<el-radio label="serial">{{ $t("run_mode.serial") }}</el-radio>
|
||||
<el-radio label="parallel">{{ $t("run_mode.parallel") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="ms-mode-div" v-if="runConfig.mode === 'serial'">
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<span class="ms-mode-span">{{ $t("run_mode.other_config") }}:</span>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<div>
|
||||
<el-checkbox v-model="runConfig.onSampleError">{{ $t("api_test.fail_to_stop") }}</el-checkbox>
|
||||
</div>
|
||||
<div style="padding-top: 10px">
|
||||
<el-checkbox v-model="runConfig.runWithinResourcePool" style="padding-right: 10px;">
|
||||
{{ $t('run_mode.run_with_resource_pool') }}
|
||||
</el-checkbox>
|
||||
<el-select :disabled="!runConfig.runWithinResourcePool" v-model="runConfig.resourcePoolId" size="mini">
|
||||
<el-option
|
||||
v-for="item in resourcePools"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="ms-mode-div" v-if="runConfig.mode === 'parallel'">
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<span class="ms-mode-span">{{ $t("run_mode.other_config") }}:</span>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-checkbox v-model="runConfig.runWithinResourcePool" style="padding-right: 10px;">
|
||||
{{ $t('run_mode.run_with_resource_pool') }}
|
||||
</el-checkbox>
|
||||
<el-select :disabled="!runConfig.runWithinResourcePool" v-model="runConfig.resourcePoolId" size="mini">
|
||||
<el-option
|
||||
v-for="item in resourcePools"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:disabled="!item.api"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer @cancel="close" @confirm="handleRunBatch"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import EnvPopover from "@/business/components/api/automation/scenario/EnvPopover";
|
||||
import {strMapToObj} from "@/common/js/utils";
|
||||
import {ENV_TYPE} from "@/common/js/constants";
|
||||
import {parseEnvironment} from "@/business/components/api/test/model/EnvironmentModel";
|
||||
|
||||
export default {
|
||||
name: "MsApiCaseRunModeWithEnv",
|
||||
components: {EnvPopover, MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
runModeVisible: false,
|
||||
resourcePools: [],
|
||||
runConfig: {
|
||||
mode: "serial",
|
||||
reportType: "iddReport",
|
||||
onSampleError: false,
|
||||
runWithinResourcePool: false,
|
||||
resourcePoolId: null,
|
||||
envMap: new Map(),
|
||||
environmentGroupId: "",
|
||||
environmentType: ENV_TYPE.JSON
|
||||
},
|
||||
projectEnvListMap: {},
|
||||
projectList: [],
|
||||
projectIds: new Set(),
|
||||
};
|
||||
},
|
||||
props: ['projectId'],
|
||||
methods: {
|
||||
open() {
|
||||
this.runModeVisible = true;
|
||||
this.getResourcePools();
|
||||
this.getWsProjects();
|
||||
},
|
||||
changeMode() {
|
||||
this.runConfig.onSampleError = false;
|
||||
this.runConfig.runWithinResourcePool = false;
|
||||
this.runConfig.resourcePoolId = null;
|
||||
},
|
||||
close() {
|
||||
this.runConfig = {
|
||||
mode: "serial",
|
||||
reportType: "iddReport",
|
||||
onSampleError: false,
|
||||
runWithinResourcePool: false,
|
||||
resourcePoolId: null,
|
||||
envMap: new Map(),
|
||||
environmentGroupId: "",
|
||||
environmentType: ENV_TYPE.JSON
|
||||
};
|
||||
this.runModeVisible = false;
|
||||
},
|
||||
handleRunBatch() {
|
||||
this.$emit("handleRunBatch", this.runConfig);
|
||||
this.close();
|
||||
},
|
||||
getResourcePools() {
|
||||
this.result = this.$get('/testresourcepool/list/quota/valid', response => {
|
||||
this.resourcePools = response.data;
|
||||
});
|
||||
},
|
||||
setProjectEnvMap(projectEnvMap) {
|
||||
this.runConfig.envMap = strMapToObj(projectEnvMap);
|
||||
},
|
||||
setEnvGroup(id) {
|
||||
this.runConfig.environmentGroupId = id;
|
||||
},
|
||||
getWsProjects() {
|
||||
this.$get("/project/listAll", res => {
|
||||
this.projectList = res.data;
|
||||
})
|
||||
},
|
||||
getEnvironments() {
|
||||
return new Promise((resolve) => {
|
||||
if (this.projectId) {
|
||||
this.$get('/api/environment/list/' + this.projectId, response => {
|
||||
this.environments = response.data;
|
||||
this.environments.forEach(environment => {
|
||||
parseEnvironment(environment);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
showPopover() {
|
||||
this.projectIds.clear();
|
||||
this.projectIds.add(this.projectId);
|
||||
this.$refs.envPopover.openEnvSelect();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-mode-span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.ms-mode-div {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -206,10 +206,10 @@
|
|||
<!--高级搜索-->
|
||||
<ms-table-adv-search-bar :condition.sync="condition" :showLink="false" ref="searchBar" @search="initTable"/>
|
||||
|
||||
<api-case-batch-run :project-id="projectId" @batchRun="runBatch" ref="batchRun"/>
|
||||
|
||||
<ms-task-center ref="taskCenter" :show-menu="false"/>
|
||||
|
||||
<ms-api-case-run-mode-with-env @handleRunBatch="runBatch" ref="batchRun" :project-id="projectId"/>
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('test_track.plan_view.test_result')" width="60%"
|
||||
:visible.sync="resVisible" class="api-import" destroy-on-close @close="resVisible=false">
|
||||
<ms-request-result-tail :response="response" ref="debugResult"/>
|
||||
|
@ -232,6 +232,8 @@ import MsContainer from "../../../../common/components/MsContainer";
|
|||
import MsBottomContainer from "../BottomContainer";
|
||||
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
|
||||
import MsBatchEdit from "../basis/BatchEdit";
|
||||
import MsApiCaseRunModeWithEnv from "./ApiCaseRunModeWithEnv";
|
||||
|
||||
import {API_METHOD_COLOUR, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData";
|
||||
|
||||
import {getBodyUploadFiles, getCurrentProjectID, getUUID, strMapToObj} from "@/common/js/utils";
|
||||
|
@ -247,7 +249,7 @@ import MsTableAdvSearchBar from "@/business/components/common/components/search/
|
|||
import {API_CASE_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||
import {
|
||||
_filter,
|
||||
_sort,
|
||||
_sort, buildBatchParam,
|
||||
getCustomTableHeader,
|
||||
getCustomTableWidth,
|
||||
getLastTableSortField,
|
||||
|
@ -285,8 +287,9 @@ export default {
|
|||
MsTable,
|
||||
MsTableColumn,
|
||||
MsRequestResultTail,
|
||||
MsApiCaseRunModeWithEnv,
|
||||
PlanStatusTableItem: () => import("../../../../track/common/tableItems/plan/PlanStatusTableItem"),
|
||||
MsTaskCenter: () => import("../../../../task/TaskCenter"),
|
||||
MsTaskCenter: () => import("@/business/components/task/TaskCenter"),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -391,6 +394,7 @@ export default {
|
|||
resVisible: false,
|
||||
response: {},
|
||||
timeoutIndex: 0,
|
||||
runCaseIds: []
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -537,17 +541,16 @@ export default {
|
|||
return this.$t('api_test.home_page.detail_card.unexecute');
|
||||
}
|
||||
},
|
||||
|
||||
handleRunBatch() {
|
||||
this.$refs.batchRun.open();
|
||||
},
|
||||
runBatch(environment) {
|
||||
runBatch(config) {
|
||||
let obj = {};
|
||||
obj.projectId = this.projectId;
|
||||
obj.selectAllDate = this.selectAll;
|
||||
obj.unSelectIds = this.unSelection;
|
||||
obj.ids = Array.from(this.selectRows).map(row => row.id);
|
||||
obj.environmentId = environment.id;
|
||||
obj.config = config;
|
||||
obj.condition = this.condition;
|
||||
obj.condition.status = "";
|
||||
this.$post('/api/testcase/batch/run', obj, () => {
|
||||
|
@ -558,7 +561,7 @@ export default {
|
|||
} else {
|
||||
this.$store.state.currentApiCase = {case: true};
|
||||
}
|
||||
this.search();
|
||||
this.$refs.taskCenter.open();
|
||||
});
|
||||
},
|
||||
customHeader() {
|
||||
|
|
Loading…
Reference in New Issue