fix(测试场景并行): 优化测试场景并行流程,解决偶发性找不到报告数据的缺陷

优化测试场景并行流程,解决偶发性找不到报告数据的缺陷
This commit is contained in:
song-tianyang 2021-12-14 19:45:19 +08:00 committed by 刘瑞斌
parent 1dd4fa5d41
commit d37f90ba8a
6 changed files with 40 additions and 38 deletions

View File

@ -1575,7 +1575,6 @@ public class ApiAutomationService {
//存储报告
APIScenarioReportResult report = executeQueue.get(reportId).getReport();
batchMapper.insert(report);
MessageCache.scenarioExecResourceLock.put(reportId, report);
}
sqlSession.flushStatements();
if (sqlSession != null && sqlSessionFactory != null) {
@ -1583,9 +1582,19 @@ public class ApiAutomationService {
}
}
});
try {
thread.start();
while (!StringUtils.equals(thread.getState().name(), Thread.State.TERMINATED.name())){
Thread.sleep(500);
}
}catch (Exception e){
LogUtil.error("场景报告入库异常 报错:["+e.getMessage()+"]. 场景报告ID list"+JSONArray.toJSONString(executeQueue.keySet()));
LogUtil.error(e);
}
for (String reportId : executeQueue.keySet()) {
MessageCache.scenarioExecResourceLock.put(reportId, executeQueue.get(reportId).getReport());
// 增加一个本地锁防止并发找不到资源
if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) {
String testPlanScenarioId = "";

View File

@ -255,7 +255,6 @@ public class ApiDefinitionExecResultService {
if (StringUtils.equalsAny(saveResultType, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) {
saveResultType = ApiRunMode.API_PLAN.name();
}
String finalSaveResultType = saveResultType;
Map<String, String> apiIdResultMap = new HashMap<>();
Map<String, String> caseReportMap = new HashMap<>();
@ -270,7 +269,7 @@ public class ApiDefinitionExecResultService {
}
testPlanReportId = testIdArr[1];
}
String creator = TestPlanReportExecuteCatch.getCreator(testPlanReportId);
LogUtil.info("收到测试计划案例[" + result.getTestId() + "]的执行信息,开始保存. testID:[" + testId + "] 测试计划ID:[" + testPlanReportId + "]");
if (CollectionUtils.isNotEmpty(result.getScenarios())) {
result.getScenarios().forEach(scenarioResult -> {
final boolean[] isFirst = {true};
@ -294,6 +293,7 @@ public class ApiDefinitionExecResultService {
item.getResponseResult().setConsole(result.getConsole());
boolean saved = true;
if (saveResult == null || expectProcessResultCount > 1) {
LogUtil.info("测试计划案例[" + result.getTestId() + "]的执行结果信息未保存,新增。");
saveResult = new ApiDefinitionExecResult();
if (isFirst[0]) {
isFirst[0] = false;
@ -341,8 +341,10 @@ public class ApiDefinitionExecResultService {
saveResult.setTriggerMode(TriggerMode.MANUAL.name());
}
if (!saved) {
LogUtil.info("插入案例[" + saveResult.getId() + "]的执行结果。");
apiDefinitionExecResultMapper.insert(saveResult);
} else {
LogUtil.info("更新案例[" + saveResult.getId() + "]的执行结果。");
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(saveResult);
}
apiDefinitionService.removeCache(result.getTestId());
@ -353,9 +355,13 @@ public class ApiDefinitionExecResultService {
String caseId = item.getName();
if (StringUtils.equalsAny(type, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(caseId);
if(apiCase != null){
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
}else {
LogUtil.error("存储测试计划案例[" + result.getTestId() + "]的执行信息出错TestPlanApiCase id:["+caseId+"] 未找到! ");
}
} else {
testPlanApiCaseService.setExecResult(caseId, status, item.getStartTime());
testCaseReviewApiCaseService.setExecResult(caseId, status, item.getStartTime());

View File

@ -310,10 +310,9 @@ public class ApiScenarioReportService {
}
public ApiScenarioReport updateSchedulePlanCase(TestResult result, String runMode) {
LogUtil.info("收到测试计划场景[" + result.getTestId() + "]的执行信息,开始保存");
ApiScenarioReport lastReport = null;
List<ScenarioResult> scenarioResultList = result.getScenarios();
List<ScenarioResult> scenarioResultList = result.getScenarios() == null ? new ArrayList<>(0) : result.getScenarios();
LogUtil.info("收到测试计划场景[" + result.getTestId() + "]的执行信息,开始保存.步骤总数:" + scenarioResultList.size());
List<String> testPlanReportIdList = new ArrayList<>();
StringBuilder scenarioNames = new StringBuilder();
@ -322,15 +321,14 @@ public class ApiScenarioReportService {
Map<String, String> scenarioAndErrorMap = new HashMap<>();
Map<String, String> planScenarioReportMap = new HashMap<>();
for (ScenarioResult scenarioResult : scenarioResultList) {
LogUtil.info("收到测试计划场景[" + result.getTestId() + "]的执行信息并存储报告。报告ID:" + scenarioResult.getName());
// 存储场景报告
long startTime = System.currentTimeMillis();
if (CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) {
startTime = scenarioResult.getRequestResults().get(0).getStartTime();
}
ApiScenarioReport report = editReport(scenarioResult, startTime);
if(report != null){
if (report != null) {
TestResult newResult = createTestResult(result.getTestId(), scenarioResult);
newResult.setConsole(result.getConsole());
scenarioResult.setName(report.getScenarioName());
@ -357,7 +355,7 @@ public class ApiScenarioReportService {
String passRate = new DecimalFormat("0%").format((float) scenarioResult.getSuccess() / (scenarioResult.getSuccess() + scenarioResult.getError()));
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(planScenarioId);
if(testPlanApiScenario != null){
if (testPlanApiScenario != null) {
//更新测试计划场景相关状态
report.setScenarioId(testPlanApiScenario.getApiScenarioId());
if (scenarioResult.getError() > 0) {
@ -374,8 +372,8 @@ public class ApiScenarioReportService {
scenarioIdList.add(testPlanApiScenario.getApiScenarioId());
updatePlanTestCaseStates(testPlanApiScenario);
}else {
LogUtil.info("TestPlanReport_Id is null. scenario report id : ["+report.getId()+"]; planScenarioIdArr:["+report.getScenarioId()+"] DATA:"+JSON.toJSONString(scenarioResult));
} else {
LogUtil.info("TestPlanReport_Id is null. scenario report id : [" + report.getId() + "]; planScenarioIdArr:[" + report.getScenarioId() + "] DATA:" + JSON.toJSONString(scenarioResult));
}
report.setEndTime(System.currentTimeMillis());
@ -390,11 +388,13 @@ public class ApiScenarioReportService {
if (StringUtils.isNotEmpty(report.getTriggerMode()) && report.getTriggerMode().equals("CASE")) {
report.setTriggerMode(TriggerMode.MANUAL.name());
}
try {
apiScenarioReportDetailMapper.insert(detail);
} catch (Exception e) {
LogUtil.error("存储场景报告出错:" + e.getMessage() + "; 步骤信息:" + JSON.toJSONString(scenarioResult));
LogUtil.error(e);
}
scenarioNames.append(report.getName()).append(",");
// 更新场景状态
ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
if (scenario != null) {
@ -416,6 +416,8 @@ public class ApiScenarioReportService {
lastReport = report;
MessageCache.executionQueue.remove(report.getId());
reportIds.add(report.getId());
} else {
LogUtil.error("测试计划场景[" + result.getTestId() + "]的场景报告未找到。报告ID:" + scenarioResult.getName() + "。 步骤信息:" + JSON.toJSONString(scenarioResult));
}
}
testPlanLog.info("TestPlanReportId" + JSONArray.toJSONString(testPlanReportIdList) + " EXECUTE OVER. SCENARIO STATUS : " + JSONObject.toJSONString(scenarioAndErrorMap));

View File

@ -39,6 +39,7 @@ public class TestResultService {
private ApiAutomationService apiAutomationService;
public void saveResult(TestResult testResult, String runMode, String debugReportId, String testId) {
LogUtil.info("Save result:["+testId+"]; RUN MODE:"+runMode);
try {
ApiTestReportVariable reportTask = null;
if (StringUtils.equals(runMode, ApiRunMode.DEFINITION.name())) {

View File

@ -178,14 +178,14 @@ public class ScheduleService {
scheduleManager.removeJob(jobKey, triggerKey);
} catch (Exception e) {
LogUtil.error(e);
MSException.throwException("重置定时任务-删除时异常");
MSException.throwException("重置定时任务-删除旧定任务时出现异常");
}
try {
scheduleManager.addCronJob(jobKey, triggerKey, clazz, request.getValue(),
scheduleManager.getDefaultJobDataMap(request, request.getValue(), SessionUtils.getUser().getId()));
} catch (Exception e) {
LogUtil.error(e);
MSException.throwException("重置定时任务-删除时异常");
MSException.throwException("重置定时任务-启动新定时任务出现异常");
}
}

View File

@ -130,7 +130,6 @@ public class TestPlanReportService {
}
}
list = extTestPlanReportMapper.list(request);
this.checkReportStatus(list);
return list;
}
@ -1217,21 +1216,6 @@ public class TestPlanReportService {
testPlanReportContentMapper.updateByExampleSelective(bloBs,example);
}
private void checkReportStatus(List<TestPlanReportDTO> list) {
String errorStatus = "FAILED";
for (TestPlanReportDTO dto : list) {
if (StringUtils.equalsIgnoreCase(dto.getStatus(), "Running")) {
if (!TestPlanReportExecuteCatch.containsReport(dto.getId())) {
//测试计划报告处于Running状态且监听中不存在此ID更改Running的运行状态一般在测试计划执行结束之前服务关闭时会出现这种情况
TestPlanReport report = new TestPlanReport();
report.setId(dto.getId());
this.finishReport(report);
dto.setStatus(errorStatus);
}
}
}
}
private boolean checkTestPlanReportIsTimeOut(String planReportId) {
TestPlanExecuteInfo executeInfo = TestPlanReportExecuteCatch.getTestPlanExecuteInfo(planReportId);
int unFinishNum = executeInfo.countUnFinishedNum();