fix: 修复测试计划定时任务不执行的缺陷

修复测试计划定时任务不执行的缺陷和导入出现的问题
This commit is contained in:
song-tianyang 2021-05-25 19:27:13 +08:00 committed by jianxing
parent a8fcadbd1d
commit 151fe95722
10 changed files with 156 additions and 77 deletions

View File

@ -35,4 +35,8 @@ public class RunScenarioRequest extends ApiScenarioWithBLOBs {
private ApiScenarioRequest condition;
private RunModeConfig config;
private boolean isTestPlanScheduleJob = false;
//生成测试报告当isTestPlanScheduleJob为ture时使用
private String testPlanReportId;
}

View File

@ -35,4 +35,6 @@ public class SchedulePlanScenarioExecuteRequest {
private Map<String,Map<String,String>> testPlanScenarioIDMap;
private String testPlanReportId;
private RunModeConfig config;
}

View File

@ -726,15 +726,17 @@ public class ApiAutomationService {
report.setStatus(APITestStatus.Running.name());
if (StringUtils.isNotEmpty(userID)) {
report.setUserId(userID);
report.setCreateUser(userID);
} else {
report.setUserId(SessionUtils.getUserId());
report.setCreateUser(SessionUtils.getUserId());
}
report.setTriggerMode(triggerMode);
report.setExecuteType(execType);
report.setProjectId(projectId);
report.setScenarioName(scenarioName);
report.setScenarioId(scenarioId);
report.setCreateUser(SessionUtils.getUserId());
return report;
}
@ -894,7 +896,7 @@ public class ApiAutomationService {
APIScenarioReportResult report;
Map<String, String> planEnvMap = new HashMap<>();
//如果是测试计划页面触发的执行方式生成报告时createScenarioReport第二个参数需要特殊处理
if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(),ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
String testPlanScenarioId = item.getId();
if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) {
testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId());
@ -905,8 +907,15 @@ public class ApiAutomationService {
planEnvMap = JSON.parseObject(environment, Map.class);
}
}
report = createScenarioReport(reportId, testPlanScenarioId, item.getName(), request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
if(request.isTestPlanScheduleJob()){
String savedScenarioId = testPlanScenarioId + ":" + request.getTestPlanReportId();
report = createScenarioReport(reportId, savedScenarioId, item.getName(), request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
}else{
report = createScenarioReport(reportId, testPlanScenarioId, item.getName(), request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
}
} else {
report = createScenarioReport(reportId, item.getId(), item.getName(), request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
@ -1049,7 +1058,8 @@ public class ApiAutomationService {
if (reportIds != null) {
//如果是测试计划页面触发的执行方式生成报告时createScenarioReport第二个参数需要特殊处理
APIScenarioReportResult report = null;
if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
// if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
if (StringUtils.equalsAny(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(),ApiRunMode.SCHEDULE_SCENARIO_PLAN.name())) {
String testPlanScenarioId = item.getId();
if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) {
testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId());
@ -1060,8 +1070,14 @@ public class ApiAutomationService {
scenario.setEnvironmentMap(JSON.parseObject(environment, Map.class));
}
}
report = createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());
if(request.isTestPlanScheduleJob()){
String savedScenarioId = testPlanScenarioId + ":" + request.getTestPlanReportId();
report = createScenarioReport(group.getName(), savedScenarioId, item.getName(), request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
}else{
report = createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());
}
} else {
report = createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());

View File

@ -626,7 +626,6 @@ public class ApiTestCaseService {
HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs);
// 调用执行方法
jMeterService.runDefinition(id, jmeterHashTree, debugReportId, runMode);
} catch (Exception ex) {
LogUtil.error(ex.getMessage());
}

View File

@ -10,9 +10,8 @@ import java.util.Set;
@Getter
@Setter
public class TestCaseExcelData {
@ExcelIgnore
private String id;
@ExcelIgnore
private Integer num;
@ExcelIgnore
@ -41,10 +40,10 @@ public class TestCaseExcelData {
public Set<String> getExcludeColumnFiledNames(boolean needNum){
Set<String> excludeColumnFiledNames = new HashSet<>();
if(!needNum){
excludeColumnFiledNames.add("num");
excludeColumnFiledNames.add("customNum");
}
excludeColumnFiledNames.add("customNum");
excludeColumnFiledNames.add("id");
excludeColumnFiledNames.add("num");
return excludeColumnFiledNames;
}
}

View File

@ -59,7 +59,11 @@ public class TestPlanTestJob extends MsScheduleJob {
@Override
void businessExecute(JobExecutionContext context) {
testPlanService.run(this.resourceId, this.projectID, this.userId, ReportTriggerMode.SCHEDULE.name());
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String config = jobDataMap.getString("config");
testPlanService.run(this.resourceId, this.projectID, this.userId, ReportTriggerMode.SCHEDULE.name(),config);
}
public static JobKey getJobKey(String testId) {

View File

@ -161,7 +161,6 @@ public class TestCaseController {
}
@PostMapping("/importIgnoreError/{projectId}/{userId}")
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_CASE_READ_IMPORT)
@MsAuditLog(module = "track_test_case", type = OperLogConstants.IMPORT, project = "#projectId")
public ExcelResponse testCaseImportIgnoreError(MultipartFile file, @PathVariable String projectId, @PathVariable String userId, @PathVariable String importType, HttpServletRequest request) {
checkPermissionService.checkProjectOwner(projectId);

View File

@ -157,6 +157,6 @@ public class TestPlanController {
}
@PostMapping("/testplan/jenkins")
public void runJenkins(@RequestBody TestplanRunRequest testplanRunRequest){
testPlanService.run(testplanRunRequest.getTestPlanID(),testplanRunRequest.getProjectID(),testplanRunRequest.getUserId(),testplanRunRequest.getTriggerMode());
testPlanService.run(testplanRunRequest.getTestPlanID(),testplanRunRequest.getProjectID(),testplanRunRequest.getUserId(),testplanRunRequest.getTriggerMode(),null);
}
}

View File

@ -861,6 +861,50 @@ public class TestPlanService {
return extTestPlanMapper.findScheduleCreateUserById(testPlanId);
}
public String scenarioRunModeConfig(SchedulePlanScenarioExecuteRequest planScenarioExecuteRequest) {
Map<String, Map<String, String>> testPlanScenarioIdMap = planScenarioExecuteRequest.getTestPlanScenarioIDMap();
String returnStr = null;
for (Map.Entry<String, Map<String, String>> entry : testPlanScenarioIdMap.entrySet()) {
// String testPlanId = entry.getKey();
Map<String,String> scenarioMap = entry.getValue();
RunScenarioRequest request = new RunScenarioRequest();
request.setReportId(planScenarioExecuteRequest.getReportId());
request.setEnvironmentId(planScenarioExecuteRequest.getEnvironmentId());
request.setTriggerMode(planScenarioExecuteRequest.getTriggerMode());
request.setExecuteType(planScenarioExecuteRequest.getExecuteType());
request.setRunMode(planScenarioExecuteRequest.getRunMode());
request.setIds(new ArrayList<>(scenarioMap.keySet()));//场景IDS
request.setReportUserID(planScenarioExecuteRequest.getReportUserID());
request.setScenarioTestPlanIdMap(scenarioMap);//未知
request.setConfig(planScenarioExecuteRequest.getConfig());
request.setTestPlanScheduleJob(true);
request.setTestPlanReportId(planScenarioExecuteRequest.getTestPlanReportId());
request.setId(UUID.randomUUID().toString());
if (request.getConfig() != null) {
if (request.getConfig().getMode().equals(RunModeConstants.PARALLEL.toString())) {
// 校验并发数量
int count = 50;
BaseSystemConfigDTO dto = systemParameterService.getBaseInfo();
if (StringUtils.isNotEmpty(dto.getConcurrency())) {
count = Integer.parseInt(dto.getConcurrency());
}
if (request.getIds().size() > count) {
MSException.throwException("并发数量过大,请重新选择!");
}
returnStr = apiAutomationService.modeRun(request);
} else {
returnStr = apiAutomationService.modeRun(request);
}
} else {
returnStr = apiAutomationService.excute(request);
}
}
return returnStr;
}
/**
* 测试计划的定时任务--执行场景案例
*
@ -876,64 +920,9 @@ public class TestPlanService {
for (Map.Entry<String, Map<String, String>> entry : testPlanScenarioIdMap.entrySet()) {
Map<String, String> planScenarioIdMap = entry.getValue();
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectIds(new ArrayList<>(planScenarioIdMap.keySet()));
try {
boolean isFirst = true;
for (ApiScenarioWithBLOBs item : apiScenarios) {
String apiScenarioID = item.getId();
String planScenarioID = planScenarioIdMap.get(apiScenarioID);
if (StringUtils.isEmpty(planScenarioID)) {
continue;
}
if (item.getStepTotal() == 0) {
// 只有一个场景且没有测试步骤则提示
if (apiScenarios.size() == 1) {
MSException.throwException((item.getName() + "" + Translator.get("automation_exec_info")));
}
LogUtil.warn(item.getName() + "" + Translator.get("automation_exec_info"));
continue;
}
MsThreadGroup group = new MsThreadGroup();
group.setLabel(item.getName());
group.setName(UUID.randomUUID().toString());
// 批量执行的结果直接存储为报告
if (isFirst) {
group.setName(request.getId());
isFirst = false;
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JSONObject element = JSON.parseObject(item.getScenarioDefinition());
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
scenario.setHashTree(elements);
}
if (StringUtils.isNotEmpty(element.getString("variables"))) {
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
new TypeReference<LinkedList<ScenarioVariable>>() {
});
scenario.setVariables(variables);
}
group.setEnableCookieShare(scenario.isEnableCookieShare());
LinkedList<MsTestElement> scenarios = new LinkedList<>();
scenarios.add(scenario);
// 创建场景报告
//不同的运行模式第二个参数入参不同
APIScenarioReportResult report = apiAutomationService.createScenarioReport(group.getName(),
planScenarioID + ":" + request.getTestPlanReportId(),
item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
apiScenarioReportMapper.insert(report);
group.setHashTree(scenarios);
testPlan.getHashTree().add(group);
returnId = request.getId();
}
returnId = this.generateHashTreeByScenarioList(testPlan,planScenarioIdMap,request);
} catch (Exception ex) {
MSException.throwException(ex.getMessage());
}
@ -947,11 +936,74 @@ public class TestPlanService {
return returnId;
}
public void run(String testPlanID, String projectID, String userId, String triggerMode) {
private String generateHashTreeByScenarioList(MsTestPlan testPlan, Map<String, String> planScenarioIdMap,SchedulePlanScenarioExecuteRequest request) throws Exception {
String returnId = "";
boolean isFirst = true;
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectIds(new ArrayList<>(planScenarioIdMap.keySet()));
for (ApiScenarioWithBLOBs item : apiScenarios) {
String apiScenarioID = item.getId();
String planScenarioID = planScenarioIdMap.get(apiScenarioID);
if (StringUtils.isEmpty(planScenarioID)) {
continue;
}
if (item.getStepTotal() == 0) {
// 只有一个场景且没有测试步骤则提示
if (apiScenarios.size() == 1) {
MSException.throwException((item.getName() + "" + Translator.get("automation_exec_info")));
}
LogUtil.warn(item.getName() + "" + Translator.get("automation_exec_info"));
continue;
}
MsThreadGroup group = new MsThreadGroup();
group.setLabel(item.getName());
group.setName(UUID.randomUUID().toString());
// 批量执行的结果直接存储为报告
if (isFirst) {
group.setName(request.getId());
isFirst = false;
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JSONObject element = JSON.parseObject(item.getScenarioDefinition());
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
scenario.setHashTree(elements);
}
if (StringUtils.isNotEmpty(element.getString("variables"))) {
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
new TypeReference<LinkedList<ScenarioVariable>>() {
});
scenario.setVariables(variables);
}
group.setEnableCookieShare(scenario.isEnableCookieShare());
LinkedList<MsTestElement> scenarios = new LinkedList<>();
scenarios.add(scenario);
// 创建场景报告
//不同的运行模式第二个参数入参不同
APIScenarioReportResult report = apiAutomationService.createScenarioReport(group.getName(),
planScenarioID + ":" + request.getTestPlanReportId(),
item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), null);
apiScenarioReportMapper.insert(report);
group.setHashTree(scenarios);
testPlan.getHashTree().add(group);
returnId = request.getId();
}
return returnId;
}
public void run(String testPlanID, String projectID, String userId, String triggerMode,String apiRunConfig) {
Map<String, String> planScenarioIdMap;
Map<String, String> apiTestCaseIdMap;
Map<String, String> performanceIdMap;
if(StringUtils.isEmpty(apiRunConfig)){
apiRunConfig = "{\"mode\":\"parallel\",\"reportType\":\"iddReport\",\"onSampleError\":true,\"runWithinResourcePool\":true,\"resourcePoolId\":\"29773f4f-55e4-4bce-ad3d-b531b4eb59c2\"}";
}
planScenarioIdMap = new LinkedHashMap<>();
apiTestCaseIdMap = new LinkedHashMap<>();
performanceIdMap = new LinkedHashMap<>();
@ -1064,7 +1116,9 @@ public class TestPlanService {
scenarioRequest.setTestPlanID(testPlanID);
scenarioRequest.setRunMode(ApiRunMode.SCHEDULE_SCENARIO_PLAN.name());
scenarioRequest.setTestPlanReportId(planReportId);
String scenarioReportID = this.runScenarioCase(scenarioRequest);
RunModeConfig runModeConfig = JSONObject.parseObject(apiRunConfig, RunModeConfig.class);
scenarioRequest.setConfig(runModeConfig);
String scenarioReportID = this.scenarioRunModeConfig(scenarioRequest);
if (StringUtils.isNotEmpty(scenarioReportID)) {
scenarioIsExcuting = true;
scenarioCaseIdArray = JSONArray.toJSONString(new ArrayList<>(planScenarioIdMap.keySet()));

View File

@ -264,7 +264,9 @@ export default {
this.result = this.$get("/schedule/findOne/" + scheduleResourceID + "/" + taskType, response => {
if (response.data != null) {
this.schedule = response.data;
this.runConfig = JSON.parse(response.data.config);
if(response.data.config){
this.runConfig = JSON.parse(response.data.config);
}
} else {
this.schedule = {};
}