feat(UI自动化): UI场景批量执行

This commit is contained in:
chenjianxing 2022-05-24 15:25:06 +08:00 committed by jianxing
parent 794d8a7a9f
commit 27188fe5fe
13 changed files with 246 additions and 131 deletions

View File

@ -2,6 +2,7 @@ package io.metersphere.api.dto;
import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.base.domain.ApiScenarioWithBLOBs; import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.UiScenarioWithBLOBs;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -12,6 +13,7 @@ import java.util.Map;
public class RunModeDataDTO { public class RunModeDataDTO {
// 执行HashTree // 执行HashTree
private ApiScenarioWithBLOBs scenario; private ApiScenarioWithBLOBs scenario;
private UiScenarioWithBLOBs uiScenario;
// 测试场景/测试用例 // 测试场景/测试用例
private String testId; private String testId;

View File

@ -0,0 +1,9 @@
package io.metersphere.api.dto;
import lombok.Data;
@Data
public class UiExecutionQueueParam {
private String browser;
private Boolean headlessEnabled = false;
}

View File

@ -46,6 +46,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -54,36 +55,37 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@Transactional(rollbackFor = Exception.class)
public class ApiScenarioExecuteService { public class ApiScenarioExecuteService {
@Resource @Resource
private ApiScenarioEnvService apiScenarioEnvService; private ApiScenarioEnvService apiScenarioEnvService;
@Resource @Resource
private ApiScenarioMapper apiScenarioMapper; private ApiScenarioMapper apiScenarioMapper;
@Resource @Resource
private ApiExecutionQueueService apiExecutionQueueService; protected ApiExecutionQueueService apiExecutionQueueService;
@Resource @Resource
private ExtApiScenarioMapper extApiScenarioMapper; private ExtApiScenarioMapper extApiScenarioMapper;
@Resource @Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper; private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource @Resource
private ApiScenarioReportMapper apiScenarioReportMapper; protected ApiScenarioReportMapper apiScenarioReportMapper;
@Resource @Resource
@Lazy @Lazy
private TestPlanScenarioCaseService testPlanScenarioCaseService; private TestPlanScenarioCaseService testPlanScenarioCaseService;
@Resource @Resource
private ApiScenarioReportService apiScenarioReportService; protected ApiScenarioReportService apiScenarioReportService;
@Resource @Resource
private EnvironmentGroupProjectService environmentGroupProjectService; private EnvironmentGroupProjectService environmentGroupProjectService;
@Resource @Resource
private ApiScenarioReportStructureService reportStructureService; private ApiScenarioReportStructureService apiScenarioReportStructureService;
@Resource @Resource
private ApiScenarioSerialService serialService; private ApiScenarioSerialService apiScenarioSerialService;
@Resource @Resource
private ApiScenarioParallelService parallelService; private ApiScenarioParallelService apiScenarioParallelService;
@Resource @Resource
private TcpApiParamService tcpApiParamService; private TcpApiParamService tcpApiParamService;
@Resource @Resource
private JMeterService jMeterService; protected JMeterService jMeterService;
public List<MsExecResponseDTO> run(RunScenarioRequest request) { public List<MsExecResponseDTO> run(RunScenarioRequest request) {
if (LoggerUtil.getLogger().isDebugEnabled()) { if (LoggerUtil.getLogger().isDebugEnabled()) {
@ -112,9 +114,8 @@ public class ApiScenarioExecuteService {
LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查"); LoggerUtil.info("Scenario run-执行脚本装载-开始针对所有执行场景进行环境检查");
apiScenarioEnvService.checkEnv(request, apiScenarios); apiScenarioEnvService.checkEnv(request, apiScenarios);
// 集合报告设置 // 集合报告设置
if (!request.isRerun() && StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString()) if (!request.isRerun() && GenerateHashTreeUtil.isSetReport(request.getConfig())) {
&& StringUtils.isNotEmpty(request.getConfig().getReportName())) { if (isSerial(request)) {
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
request.setExecuteType(ExecuteType.Completed.name()); request.setExecuteType(ExecuteType.Completed.name());
} else { } else {
request.setExecuteType(ExecuteType.Marge.name()); request.setExecuteType(ExecuteType.Marge.name());
@ -151,25 +152,15 @@ public class ApiScenarioExecuteService {
} else { } else {
LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId); LoggerUtil.info("Scenario run-执行脚本装载-初始化集成报告:" + serialReportId);
request.getConfig().setReportId(UUID.randomUUID().toString()); request.getConfig().setReportId(UUID.randomUUID().toString());
String reportScenarioIds = generateScenarioIds(scenarioIds);
String reportScenarioIds = JSON.toJSONString(CollectionUtils.isNotEmpty(scenarioIds) && scenarioIds.size() > 50 ? scenarioIds.subList(0, 50) : scenarioIds); APIScenarioReportResult report = getApiScenarioReportResult(request, serialReportId, scenarioNames, reportScenarioIds);
APIScenarioReportResult report = apiScenarioReportService.init(request.getConfig().getReportId(), reportScenarioIds,
scenarioNames.toString(), request.getTriggerMode(), ExecuteType.Saved.name(), request.getProjectId(),
request.getReportUserID(), request.getConfig());
report.setVersionId(apiScenarios.get(0).getVersionId()); report.setVersionId(apiScenarios.get(0).getVersionId());
report.setName(request.getConfig().getReportName());
report.setId(serialReportId);
report.setReportType(ReportTypeConstants.SCENARIO_INTEGRATED.name());
request.getConfig().setAmassReport(serialReportId);
if (request.getConfig() != null) {
report.setEnvConfig(JSON.toJSONString(request.getConfig()));
}
report.setStatus(APITestStatus.Running.name());
apiScenarioReportMapper.insert(report); apiScenarioReportMapper.insert(report);
responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode())); responseDTOS.add(new MsExecResponseDTO(JSON.toJSONString(scenarioIds), serialReportId, request.getRunMode()));
reportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType()); apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig().getReportType());
} }
} }
@ -184,21 +175,49 @@ public class ApiScenarioExecuteService {
apiScenarioReportService.batchSave(executeQueue, serialReportId, request.getRunMode(), responseDTOS); apiScenarioReportService.batchSave(executeQueue, serialReportId, request.getRunMode(), responseDTOS);
} }
// 开始执行 // 开始执行
String finalSerialReportId = serialReportId; execute(request, serialReportId, executeQueue, executionQueue);
Thread thread = new Thread(new Runnable() {
@Override return responseDTOS;
public void run() {
Thread.currentThread().setName("SCENARIO-PARALLEL-THREAD");
if (StringUtils.equals(request.getConfig().getMode(), RunModeConstants.SERIAL.toString())) {
serialService.serial(executionQueue, executionQueue.getQueue());
} else {
parallelService.parallel(executeQueue, request, finalSerialReportId, executionQueue);
} }
protected void execute(RunScenarioRequest request, String serialReportId, Map<String, RunModeDataDTO> executeQueue, DBTestQueue executionQueue) {
String finalSerialReportId = serialReportId;
Thread thread = new Thread(() ->
{
Thread.currentThread().setName("SCENARIO-PARALLEL-THREAD");
if (isSerial(request)) {
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
} else {
apiScenarioParallelService.parallel(executeQueue, request, finalSerialReportId, executionQueue);
} }
}); });
thread.start(); thread.start();
}
return responseDTOS; protected boolean isSerial(RunScenarioRequest request) {
return request.getConfig() != null &&
StringUtils.equals(request.getConfig().getMode(), RunModeConstants.SERIAL.toString());
}
protected String generateScenarioIds(List<String> scenarioIds) {
return JSON.toJSONString(CollectionUtils.isNotEmpty(scenarioIds) && scenarioIds.size() > 50 ? scenarioIds.subList(0, 50) : scenarioIds);
}
protected APIScenarioReportResult getApiScenarioReportResult(RunScenarioRequest request, String serialReportId,
StringBuilder scenarioNames, String reportScenarioIds) {
APIScenarioReportResult report = apiScenarioReportService.init(request.getConfig().getReportId(), reportScenarioIds,
scenarioNames.toString(), request.getTriggerMode(), ExecuteType.Saved.name(), request.getProjectId(),
request.getReportUserID(), request.getConfig());
report.setName(request.getConfig().getReportName());
report.setId(serialReportId);
report.setReportType(ReportTypeConstants.SCENARIO_INTEGRATED.name());
request.getConfig().setAmassReport(serialReportId);
if (request.getConfig() != null) {
report.setEnvConfig(JSON.toJSONString(request.getConfig()));
}
report.setStatus(APITestStatus.Running.name());
return report;
} }
public List<ApiScenarioWithBLOBs> get(RunScenarioRequest request) { public List<ApiScenarioWithBLOBs> get(RunScenarioRequest request) {
@ -208,17 +227,21 @@ public class ApiScenarioExecuteService {
ApiScenarioExample example = new ApiScenarioExample(); ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(ids); example.createCriteria().andIdIn(ids);
List<ApiScenarioWithBLOBs> apiScenarios = apiScenarioMapper.selectByExampleWithBLOBs(example); List<ApiScenarioWithBLOBs> apiScenarios = apiScenarioMapper.selectByExampleWithBLOBs(example);
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { if (isSerial(request)) {
if (request.getCondition() == null || !request.getCondition().isSelectAll()) { if (request.getCondition() == null || !request.getCondition().isSelectAll()) {
// 按照id指定顺序排序 // 按照id指定顺序排序
sortById(ids, apiScenarios);
}
}
return apiScenarios;
}
protected void sortById(List<String> ids, List apiScenarios) {
FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(ids); FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(ids);
fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE); fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
BeanComparator beanComparator = new BeanComparator("id", fixedOrderComparator); BeanComparator beanComparator = new BeanComparator("id", fixedOrderComparator);
Collections.sort(apiScenarios, beanComparator); Collections.sort(apiScenarios, beanComparator);
} }
}
return apiScenarios;
}
/** /**
@ -283,7 +306,7 @@ public class ApiScenarioExecuteService {
} }
// 生成文档结构 // 生成文档结构
if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) { if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) {
reportStructureService.save(scenario, report.getId(), request.getConfig() != null ? request.getConfig().getReportType() : null); apiScenarioReportStructureService.save(scenario, report.getId(), request.getConfig() != null ? request.getConfig().getReportType() : null);
} }
// 重置报告ID // 重置报告ID
reportId = UUID.randomUUID().toString(); reportId = UUID.randomUUID().toString();
@ -306,26 +329,31 @@ public class ApiScenarioExecuteService {
report.setVersionId(item.getVersionId()); report.setVersionId(item.getVersionId());
scenarioNames.append(item.getName()).append(","); scenarioNames.append(item.getName()).append(",");
RunModeDataDTO runModeDataDTO = new RunModeDataDTO(); RunModeDataDTO runModeDataDTO = getRunModeDataDTO(item.getId(), report);
runModeDataDTO.setTestId(item.getId()); runModeDataDTO.setScenario(item);
runModeDataDTO.setPlanEnvMap(new HashMap<>());
if (request.getConfig().getEnvMap() != null) { if (request.getConfig().getEnvMap() != null) {
runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap()); runModeDataDTO.setPlanEnvMap(request.getConfig().getEnvMap());
} }
runModeDataDTO.setReport(report);
runModeDataDTO.setReportId(report.getId());
executeQueue.put(report.getId(), runModeDataDTO);
runModeDataDTO.setScenario(item);
executeQueue.put(report.getId(), runModeDataDTO); executeQueue.put(report.getId(), runModeDataDTO);
// 生成报告结构 // 生成报告结构
if (!StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString())) { if (!GenerateHashTreeUtil.isSetReport(request.getConfig())) {
reportStructureService.save(item, report.getId(), request.getConfig().getReportType()); apiScenarioReportStructureService.save(item, report.getId(), request.getConfig().getReportType());
} }
// 重置报告ID // 重置报告ID
reportId = UUID.randomUUID().toString(); reportId = UUID.randomUUID().toString();
} }
} }
protected RunModeDataDTO getRunModeDataDTO(String id, APIScenarioReportResult report) {
RunModeDataDTO runModeDataDTO = new RunModeDataDTO();
runModeDataDTO.setTestId(id);
runModeDataDTO.setPlanEnvMap(new HashMap<>());
runModeDataDTO.setReport(report);
runModeDataDTO.setReportId(report.getId());
return runModeDataDTO;
}
public void testElement(RunDefinitionRequest request) { public void testElement(RunDefinitionRequest request) {
if (request.getTestElement() != null) { if (request.getTestElement() != null) {
tcpApiParamService.checkTestElement(request.getTestElement()); tcpApiParamService.checkTestElement(request.getTestElement());
@ -370,7 +398,7 @@ public class ApiScenarioExecuteService {
report.setVersionId(scenario.getVersionId()); report.setVersionId(scenario.getVersionId());
String scenarioDefinition = JSON.toJSONString(request.getTestElement().getHashTree().get(0).getHashTree().get(0)); String scenarioDefinition = JSON.toJSONString(request.getTestElement().getHashTree().get(0).getHashTree().get(0));
scenario.setScenarioDefinition(scenarioDefinition); scenario.setScenarioDefinition(scenarioDefinition);
reportStructureService.save(scenario, report.getId(), reportType); apiScenarioReportStructureService.save(scenario, report.getId(), reportType);
} else { } else {
if (request.getTestElement() != null && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree())) { if (request.getTestElement() != null && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree())) {
ApiScenarioWithBLOBs apiScenario = new ApiScenarioWithBLOBs(); ApiScenarioWithBLOBs apiScenario = new ApiScenarioWithBLOBs();
@ -379,7 +407,7 @@ public class ApiScenarioExecuteService {
if (testElement != null) { if (testElement != null) {
apiScenario.setName(testElement.getName()); apiScenario.setName(testElement.getName());
apiScenario.setScenarioDefinition(JSON.toJSONString(testElement)); apiScenario.setScenarioDefinition(JSON.toJSONString(testElement));
reportStructureService.save(apiScenario, report.getId(), reportType); apiScenarioReportStructureService.save(apiScenario, report.getId(), reportType);
} }
} }
} }

View File

@ -6,7 +6,6 @@ import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.utils.GenerateHashTreeUtil; import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.jmeter.utils.SmoothWeighted; import io.metersphere.api.jmeter.utils.SmoothWeighted;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.BaseSystemConfigDTO; import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.JmeterRunRequestDTO;
@ -16,16 +15,20 @@ import io.metersphere.vo.BooleanPool;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Map; import java.util.Map;
@Service @Service
@Transactional(rollbackFor = Exception.class)
public class ApiScenarioParallelService { public class ApiScenarioParallelService {
@Resource @Resource
private JMeterService jMeterService; protected JMeterService jMeterService;
@Resource @Resource
private RedisTemplate<String, Object> redisTemplate; protected SystemParameterService systemParameterService;
@Resource
protected RedisTemplate<String, Object> redisTemplate;
public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) { public void parallel(Map<String, RunModeDataDTO> executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) {
// 初始化分配策略 // 初始化分配策略
@ -34,24 +37,16 @@ public class ApiScenarioParallelService {
SmoothWeighted.setServerConfig(request.getConfig().getResourcePoolId(), redisTemplate); SmoothWeighted.setServerConfig(request.getConfig().getResourcePoolId(), redisTemplate);
} }
// 获取可以执行的资源池 // 获取可以执行的资源池
BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo(); BaseSystemConfigDTO baseInfo = systemParameterService.getBaseInfo();
for (String reportId : executeQueue.keySet()) { for (String reportId : executeQueue.keySet()) {
if (Thread.currentThread().isInterrupted()) { if (Thread.currentThread().isInterrupted()) {
break; break;
} }
RunModeDataDTO dataDTO = executeQueue.get(reportId); RunModeDataDTO dataDTO = executeQueue.get(reportId);
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null); JmeterRunRequestDTO runRequest = getJmeterRunRequestDTO(request, serialReportId, executionQueue, baseInfo, reportId, dataDTO);
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
runRequest.setQueueId(executionQueue.getId());
runRequest.setPool(pool); runRequest.setPool(pool);
runRequest.setPoolId(request.getConfig().getResourcePoolId()); runRequest.setPoolId(request.getConfig().getResourcePoolId());
runRequest.setTestPlanReportId(request.getTestPlanReportId());
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, executionQueue.getDetailMap().get(reportId)));
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
runRequest.setRetryNum(request.getConfig().getRetryNum());
runRequest.setRetryEnable(request.getConfig().isRetryEnable());
// 本地执行生成hashTree // 本地执行生成hashTree
if (!pool.isPool()) { if (!pool.isPool()) {
runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest)); runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest));
@ -60,4 +55,17 @@ public class ApiScenarioParallelService {
jMeterService.run(runRequest); jMeterService.run(runRequest);
} }
} }
protected JmeterRunRequestDTO getJmeterRunRequestDTO(RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue,
BaseSystemConfigDTO baseInfo, String reportId, RunModeDataDTO dataDTO) {
JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null);
runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString());
runRequest.setQueueId(executionQueue.getId());
runRequest.setTestPlanReportId(request.getTestPlanReportId());
runRequest.setPlatformUrl(GenerateHashTreeUtil.getPlatformUrl(baseInfo, runRequest, executionQueue.getDetailMap().get(reportId)));
runRequest.setRunType(RunModeConstants.PARALLEL.toString());
runRequest.setRetryNum(request.getConfig().getRetryNum());
runRequest.setRetryEnable(request.getConfig().isRetryEnable());
return runRequest;
}
} }

View File

@ -39,6 +39,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap; import java.util.HashMap;
@ -47,6 +48,7 @@ import java.util.LinkedList;
import java.util.Map; import java.util.Map;
@Service @Service
@Transactional(rollbackFor = Exception.class)
public class ApiScenarioSerialService { public class ApiScenarioSerialService {
@Resource @Resource
private ApiScenarioReportMapper apiScenarioReportMapper; private ApiScenarioReportMapper apiScenarioReportMapper;
@ -80,31 +82,12 @@ public class ApiScenarioSerialService {
runRequest.setRetryEnable(queue.getRetryEnable() == null ? false : queue.getRetryEnable()); runRequest.setRetryEnable(queue.getRetryEnable() == null ? false : queue.getRetryEnable());
runRequest.setRetryNum(queue.getRetryNumber()); runRequest.setRetryNum(queue.getRetryNumber());
// 判断触发资源对象是用例/场景更新对应报告状态 // 判断触发资源对象是用例/场景更新对应报告状态
if (!StringUtils.equals(executionQueue.getReportType(), RunModeConstants.SET_REPORT.toString()) if (!GenerateHashTreeUtil.isSetReport(executionQueue.getReportType())
|| StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) { || StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiRunMode.DEFINITION.name())) {
if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId()); updateReportToRunning(queue, runRequest);
if (report != null) {
report.setStatus(APITestStatus.Running.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
this.put("userId", report.getCreateUser());
}});
apiScenarioReportMapper.updateByPrimaryKey(report);
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ], 报告ID [ " + report.getId() + " ]");
}
} else { } else {
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId()); updateDefinitionExecResultToRunning(queue, runRequest);
if (execResult != null) {
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
this.put("userId", execResult.getUserId());
}});
execResult.setStartTime(System.currentTimeMillis());
execResult.setStatus(APITestStatus.Running.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ], 报告ID [" + execResult.getId() + "]");
}
} }
} }
@ -166,6 +149,33 @@ public class ApiScenarioSerialService {
} }
} }
protected void updateDefinitionExecResultToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
ApiDefinitionExecResultWithBLOBs execResult = apiDefinitionExecResultMapper.selectByPrimaryKey(queue.getReportId());
if (execResult != null) {
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
this.put("userId", execResult.getUserId());
}});
execResult.setStartTime(System.currentTimeMillis());
execResult.setStatus(APITestStatus.Running.name());
apiDefinitionExecResultMapper.updateByPrimaryKeySelective(execResult);
LoggerUtil.info("进入串行模式,准备执行资源:[" + execResult.getName() + " ], 报告ID [" + execResult.getId() + "]");
}
}
public void updateReportToRunning(ApiExecutionQueueDetail queue, JmeterRunRequestDTO runRequest) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(queue.getReportId());
if (report != null) {
report.setStatus(APITestStatus.Running.name());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
runRequest.setExtendedParameters(new HashMap<String, Object>() {{
this.put("userId", report.getCreateUser());
}});
apiScenarioReportMapper.updateByPrimaryKey(report);
LoggerUtil.info("进入串行模式,准备执行资源:[ " + report.getName() + " ], 报告ID [ " + report.getId() + " ]");
}
}
private void initEnv(HashTree hashTree) { private void initEnv(HashTree hashTree) {
ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); ApiTestEnvironmentService apiTestEnvironmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
HashTreeUtil hashTreeUtil = new HashTreeUtil(); HashTreeUtil hashTreeUtil = new HashTreeUtil();

View File

@ -154,11 +154,7 @@ public class GenerateHashTreeUtil {
LoggerUtil.info("报告ID" + runRequest.getReportId() + " 场景资源:" + item.getName() + ", 生成执行脚本JMX成功"); LoggerUtil.info("报告ID" + runRequest.getReportId() + " 场景资源:" + item.getName() + ", 生成执行脚本JMX成功");
} catch (Exception ex) { } catch (Exception ex) {
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); remakeException(runRequest);
remakeReportService.remake(runRequest);
ResultDTO dto = new ResultDTO();
BeanUtils.copyBean(dto, runRequest);
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
LoggerUtil.error("报告ID" + runRequest.getReportId() + " 场景资源:" + item.getName() + ", 生成执行脚本失败", ex); LoggerUtil.error("报告ID" + runRequest.getReportId() + " 场景资源:" + item.getName() + ", 生成执行脚本失败", ex);
} }
ParameterConfig config = new ParameterConfig(); ParameterConfig config = new ParameterConfig();
@ -170,8 +166,20 @@ public class GenerateHashTreeUtil {
return jmeterHashTree; return jmeterHashTree;
} }
public static void remakeException(JmeterRunRequestDTO runRequest) {
RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class);
remakeReportService.remake(runRequest);
ResultDTO dto = new ResultDTO();
BeanUtils.copyBean(dto, runRequest);
CommonBeanFactory.getBean(ApiExecutionQueueService.class).queueNext(dto);
}
public static boolean isSetReport(RunModeConfigDTO config) { public static boolean isSetReport(RunModeConfigDTO config) {
return config != null && StringUtils.equals(config.getReportType(), RunModeConstants.SET_REPORT.toString()) && StringUtils.isNotEmpty(config.getReportName()); return config != null && isSetReport(config.getReportType()) && StringUtils.isNotEmpty(config.getReportName());
}
public static boolean isSetReport(String reportType) {
return StringUtils.equals(reportType, RunModeConstants.SET_REPORT.toString());
} }
public static String getPlatformUrl(BaseSystemConfigDTO baseInfo, JmeterRunRequestDTO request, String queueDetailId) { public static String getPlatformUrl(BaseSystemConfigDTO baseInfo, JmeterRunRequestDTO request, String queueDetailId) {

View File

@ -6,7 +6,6 @@ import io.metersphere.api.exec.utils.GenerateHashTreeUtil;
import io.metersphere.api.jmeter.utils.ServerConfig; import io.metersphere.api.jmeter.utils.ServerConfig;
import io.metersphere.api.jmeter.utils.SmoothWeighted; import io.metersphere.api.jmeter.utils.SmoothWeighted;
import io.metersphere.api.service.RemakeReportService; import io.metersphere.api.service.RemakeReportService;
import io.metersphere.base.domain.TestResource;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.config.JmeterProperties; import io.metersphere.config.JmeterProperties;
@ -194,15 +193,6 @@ public class JMeterService {
} }
} }
@Deprecated
public void run(JmeterRunRequestDTO request, List<TestResource> resources) {
if (request.getPool().isPool()) {
this.runNode(request);
} else {
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
}
}
public void addQueue(JmeterRunRequestDTO request) { public void addQueue(JmeterRunRequestDTO request) {
this.runLocal(request); this.runLocal(request);
} }

View File

@ -1,7 +1,9 @@
package io.metersphere.api.service; package io.metersphere.api.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.RunModeDataDTO; import io.metersphere.api.dto.RunModeDataDTO;
import io.metersphere.api.dto.UiExecutionQueueParam;
import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.queue.DBTestQueue;
import io.metersphere.api.exec.scenario.ApiScenarioSerialService; import io.metersphere.api.exec.scenario.ApiScenarioSerialService;
@ -40,7 +42,7 @@ import java.util.stream.Collectors;
@Service @Service
public class ApiExecutionQueueService { public class ApiExecutionQueueService {
@Resource @Resource
private ApiExecutionQueueMapper queueMapper; protected ApiExecutionQueueMapper queueMapper;
@Resource @Resource
private ApiExecutionQueueDetailMapper executionQueueDetailMapper; private ApiExecutionQueueDetailMapper executionQueueDetailMapper;
@Resource @Resource
@ -48,6 +50,8 @@ public class ApiExecutionQueueService {
@Resource @Resource
private ApiScenarioSerialService apiScenarioSerialService; private ApiScenarioSerialService apiScenarioSerialService;
@Resource @Resource
private UiScenarioSerialServiceProxy uiScenarioSerialServiceProxy;
@Resource
private ApiScenarioReportService apiScenarioReportService; private ApiScenarioReportService apiScenarioReportService;
@Resource @Resource
private ApiScenarioReportMapper apiScenarioReportMapper; private ApiScenarioReportMapper apiScenarioReportMapper;
@ -60,7 +64,7 @@ public class ApiExecutionQueueService {
@Resource @Resource
private JMeterService jMeterService; private JMeterService jMeterService;
@Resource @Resource
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper; protected ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
@Resource @Resource
private ApiScenarioReportResultMapper apiScenarioReportResultMapper; private ApiScenarioReportResultMapper apiScenarioReportResultMapper;
@Lazy @Lazy
@ -72,14 +76,7 @@ public class ApiExecutionQueueService {
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) { public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
LoggerUtil.info("开始生成执行链"); LoggerUtil.info("开始生成执行链");
ApiExecutionQueue executionQueue = new ApiExecutionQueue(); ApiExecutionQueue executionQueue = getApiExecutionQueue(poolId, reportId, reportType, runMode, config);
executionQueue.setId(UUID.randomUUID().toString());
executionQueue.setCreateTime(System.currentTimeMillis());
executionQueue.setPoolId(poolId);
executionQueue.setFailure(config.isOnSampleError());
executionQueue.setReportId(reportId);
executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString());
executionQueue.setRunMode(runMode);
queueMapper.insert(executionQueue); queueMapper.insert(executionQueue);
DBTestQueue resQueue = new DBTestQueue(); DBTestQueue resQueue = new DBTestQueue();
BeanUtils.copyBean(resQueue, executionQueue); BeanUtils.copyBean(resQueue, executionQueue);
@ -125,7 +122,13 @@ public class ApiExecutionQueueService {
Map<String, RunModeDataDTO> runMap = (Map<String, RunModeDataDTO>) runObj; Map<String, RunModeDataDTO> runMap = (Map<String, RunModeDataDTO>) runObj;
final int[] sort = {0}; final int[] sort = {0};
runMap.forEach((k, v) -> { runMap.forEach((k, v) -> {
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], executionQueue.getId(), JSON.toJSONString(v.getPlanEnvMap())); String envMap = JSON.toJSONString(v.getPlanEnvMap());
if (StringUtils.startsWith(type, "UI_")) {
UiExecutionQueueParam param = new UiExecutionQueueParam();
BeanUtils.copyBean(param, config);
envMap = JSONObject.toJSONString(param);
}
ApiExecutionQueueDetail queue = detail(k, v.getTestId(), config.getMode(), sort[0], executionQueue.getId(), envMap);
queue.setSort(sort[0]); queue.setSort(sort[0]);
if (sort[0] == 0) { if (sort[0] == 0) {
resQueue.setQueue(queue); resQueue.setQueue(queue);
@ -146,7 +149,19 @@ public class ApiExecutionQueueService {
return resQueue; return resQueue;
} }
private ApiExecutionQueueDetail detail(String reportId, String testId, String type, int sort, String queueId, String envMap) { protected ApiExecutionQueue getApiExecutionQueue(String poolId, String reportId, String reportType, String runMode, RunModeConfigDTO config) {
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
executionQueue.setId(UUID.randomUUID().toString());
executionQueue.setCreateTime(System.currentTimeMillis());
executionQueue.setPoolId(poolId);
executionQueue.setFailure(config.isOnSampleError());
executionQueue.setReportId(reportId);
executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString());
executionQueue.setRunMode(runMode);
return executionQueue;
}
protected ApiExecutionQueueDetail detail(String reportId, String testId, String type, int sort, String queueId, String envMap) {
ApiExecutionQueueDetail queue = new ApiExecutionQueueDetail(); ApiExecutionQueueDetail queue = new ApiExecutionQueueDetail();
queue.setCreateTime(System.currentTimeMillis()); queue.setCreateTime(System.currentTimeMillis());
queue.setId(UUID.randomUUID().toString()); queue.setId(UUID.randomUUID().toString());
@ -162,9 +177,7 @@ public class ApiExecutionQueueService {
private boolean failure(DBTestQueue executionQueue, ResultDTO dto) { private boolean failure(DBTestQueue executionQueue, ResultDTO dto) {
LoggerUtil.info("进入失败停止处理:" + executionQueue.getId()); LoggerUtil.info("进入失败停止处理:" + executionQueue.getId());
boolean isError = false; boolean isError = false;
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO.name(), if (StringUtils.contains(dto.getRunMode(), ApiRunMode.SCENARIO.name())) {
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) { if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
ApiScenarioReportResultExample example = new ApiScenarioReportResultExample(); ApiScenarioReportResultExample example = new ApiScenarioReportResultExample();
example.createCriteria().andReportIdEqualTo(dto.getReportId()).andStatusEqualTo(ExecuteResult.Error.name()); example.createCriteria().andReportIdEqualTo(dto.getReportId()).andStatusEqualTo(ExecuteResult.Error.name());
@ -315,9 +328,13 @@ public class ApiExecutionQueueService {
boolean isNext = redisTemplate.opsForValue().setIfAbsent(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), executionQueue.getQueue().getQueueId()); boolean isNext = redisTemplate.opsForValue().setIfAbsent(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), executionQueue.getQueue().getQueueId());
if (isNext) { if (isNext) {
redisTemplate.expire(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), 60, TimeUnit.MINUTES); redisTemplate.expire(RunModeConstants.SERIAL.name() + "_" + executionQueue.getQueue().getReportId(), 60, TimeUnit.MINUTES);
if (StringUtils.startsWith(executionQueue.getRunMode(), "UI")) {
uiScenarioSerialServiceProxy.serial(executionQueue, executionQueue.getQueue());
} else {
apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue()); apiScenarioSerialService.serial(executionQueue, executionQueue.getQueue());
} }
} }
}
} else { } else {
if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) { if (StringUtils.equals(dto.getReportType(), RunModeConstants.SET_REPORT.toString())) {
String reportId = dto.getReportId(); String reportId = dto.getReportId();

View File

@ -142,7 +142,7 @@ public class ApiScenarioReportStructureService {
} }
public static StepTreeDTO dataFormatting(UiScenarioWithBLOBs uiScenario, String reportType) { public static StepTreeDTO dataFormatting(UiScenarioWithBLOBs uiScenario, String reportType) {
return dataFormatting(uiScenario.getId(), uiScenario.getName(), uiScenario.getScenarioDefinition(), reportType); return dataFormatting(null, uiScenario.getName(), uiScenario.getScenarioDefinition(), reportType);
} }
public static StepTreeDTO dataFormatting(String id, String name, String scenarioDefinition, String reportType) { public static StepTreeDTO dataFormatting(String id, String name, String scenarioDefinition, String reportType) {

View File

@ -107,7 +107,10 @@ public class RemakeReportService {
} }
apiScenarioReportMapper.updateByPrimaryKeySelective(report); apiScenarioReportMapper.updateByPrimaryKeySelective(report);
} }
} else { } else if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.UI_SCENARIO_PLAN.name(),
request.getRunMode(), ApiRunMode.UI_SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.UI_JENKINS_SCENARIO_PLAN.name())) {
remarkUiScenarioPlan(request);
}else {
ApiScenarioReportWithBLOBs report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId()); ApiScenarioReportWithBLOBs report = apiScenarioReportMapper.selectByPrimaryKey(request.getReportId());
if (report != null) { if (report != null) {
report.setStatus(APITestStatus.Error.name()); report.setStatus(APITestStatus.Error.name());
@ -135,6 +138,11 @@ public class RemakeReportService {
} }
} }
private void remarkUiScenarioPlan(JmeterRunRequestDTO request) {
// todo
}
public void remakeScenario(String runMode, String scenarioId, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiScenarioReportWithBLOBs report) { public void remakeScenario(String runMode, String scenarioId, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiScenarioReportWithBLOBs report) {
// 生成失败报告 // 生成失败报告
if (StringUtils.equalsAny(runMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCENARIO_PLAN.name())) { if (StringUtils.equalsAny(runMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name(), ApiRunMode.SCENARIO_PLAN.name())) {

View File

@ -1,7 +1,6 @@
package io.metersphere.api.service; package io.metersphere.api.service;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.dto.RequestResult; import io.metersphere.dto.RequestResult;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -26,15 +25,7 @@ public class UiReportServiceProxy {
} }
private Object invoke(Function<Class, Method> getDeclaredMethod, Object... args) { private Object invoke(Function<Class, Method> getDeclaredMethod, Object... args) {
Object uiAutomationService = CommonBeanFactory.getBean("uiReportService"); return CommonBeanFactory.invoke("uiReportService", getDeclaredMethod, args);
try {
Class<?> clazz = uiAutomationService.getClass();
Method postProcessUiReport = getDeclaredMethod.apply(clazz);
return postProcessUiReport.invoke(uiAutomationService, args);
} catch (Exception e) {
LogUtil.error(e);
}
return null;
} }
} }

View File

@ -0,0 +1,31 @@
package io.metersphere.api.service;
import io.metersphere.base.domain.ApiExecutionQueue;
import io.metersphere.base.domain.ApiExecutionQueueDetail;
import io.metersphere.commons.utils.CommonBeanFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Method;
import java.util.function.Function;
@Service
@Transactional(rollbackFor = Exception.class)
public class UiScenarioSerialServiceProxy {
public Object serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) {
return invoke((clazz) -> {
try {
return clazz.getDeclaredMethod("serial", ApiExecutionQueue.class, ApiExecutionQueueDetail.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}, executionQueue, queue);
}
private Object invoke(Function<Class, Method> getDeclaredMethod, Object... args) {
return CommonBeanFactory.invoke("uiScenarioSerialService", getDeclaredMethod, args);
}
}

View File

@ -5,7 +5,9 @@ import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
public class CommonBeanFactory implements ApplicationContextAware { public class CommonBeanFactory implements ApplicationContextAware {
private static ApplicationContext context; private static ApplicationContext context;
@ -36,5 +38,16 @@ public class CommonBeanFactory implements ApplicationContextAware {
public static <T> Map<String, T> getBeansOfType(Class<T> className) { public static <T> Map<String, T> getBeansOfType(Class<T> className) {
return context.getBeansOfType(className); return context.getBeansOfType(className);
} }
public static Object invoke(String beanName, Function<Class, Method> methodFunction, Object... args) {
Object bean = getBean(beanName);
try {
Class<?> clazz = bean.getClass();
return methodFunction.apply(clazz).invoke(bean, args);
} catch (Exception e) {
LogUtil.error(e);
}
return null;
}
} }