From c36952b0ba76c205b1845e14df14347fe77bcca7 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Thu, 24 Dec 2020 17:35:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=89=A7=E8=A1=8C=E7=BB=93=E6=9E=9C=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../APIScenarioReportController.java | 17 +- .../controller/ApiAutomationController.java | 2 +- .../dto/definition/RunDefinitionRequest.java | 4 + .../api/jmeter/APIBackendListenerClient.java | 22 +-- .../api/service/ApiAutomationService.java | 38 ++-- .../api/service/ApiScenarioReportService.java | 183 +++++------------- .../api/automation/report/ApiReportDetail.vue | 4 +- .../api/automation/scenario/DebugRun.vue | 4 +- 8 files changed, 85 insertions(+), 189 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java index b5f0109caa..09114930f9 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java @@ -7,7 +7,6 @@ import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.automation.ExecuteType; import io.metersphere.api.service.ApiScenarioReportService; -import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; @@ -27,12 +26,9 @@ public class APIScenarioReportController { @Resource private ApiScenarioReportService apiReportService; - @GetMapping("/get/{reportId}/{infoDb}") - public APIScenarioReportResult get(@PathVariable String reportId, @PathVariable Boolean infoDb) { - if (infoDb) { - return apiReportService.get(reportId); - } - return apiReportService.getCacheResult(reportId); + @GetMapping("/get/{reportId}") + public APIScenarioReportResult get(@PathVariable String reportId) { + return apiReportService.get(reportId); } @PostMapping("/list/{goPage}/{pageSize}") @@ -42,13 +38,6 @@ public class APIScenarioReportController { return PageUtils.setPageInfo(page, apiReportService.list(request)); } - @PostMapping("/add") - @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) - public void add(@RequestBody APIScenarioReportResult node) { - node.setExecuteType(ExecuteType.Saved.name()); - apiReportService.save(node, ApiRunMode.SCENARIO.name()); - } - @PostMapping("/update") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public String update(@RequestBody APIScenarioReportResult node) { diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index fd7e1e3b1b..044508da51 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -81,7 +81,7 @@ public class ApiAutomationController { @PostMapping(value = "/run/debug") public void runDebug(@RequestPart("request") RunDefinitionRequest request, @RequestPart(value = "files") List bodyFiles) { request.setExecuteType(ExecuteType.Debug.name()); - apiAutomationService.run(request, bodyFiles); + apiAutomationService.debugRun(request, bodyFiles); } @PostMapping(value = "/run") diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java index b329cfcffa..34e4655a21 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java @@ -21,6 +21,10 @@ public class RunDefinitionRequest { private String projectId; + private String scenarioId; + + private String scenarioName; + private String environmentId; private MsTestElement testElement; diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index b4abea3e3d..a5e259cf01 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -189,27 +189,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo(); reportUrl = baseSystemConfigDTO.getUrl() + "/#/api/automation/report"; - String scenaName = scenarioReport.getName(); - if (scenaName == null) { - scenaName = ""; - } else { - String[] sceneNameArr = scenaName.split("-"); - if (sceneNameArr.length >= 4) { - //如果以yyyy-MM-dd 时间类型结尾 - String endStr = "-" + sceneNameArr[sceneNameArr.length - 3] + "-" + sceneNameArr[sceneNameArr.length - 2] + "-" + sceneNameArr[sceneNameArr.length - 1]; - scenaName = scenaName.split(endStr)[0]; - } else { - //如果以时间戳结尾 - scenaName = scenaName.split("-")[0]; - } - } - ApiScenarioReport savedReport = apiScenarioReportService.get(testId); - String scenarioID = ""; - if(savedReport!=null){ - scenarioID = savedReport.getScenarioId(); - } - - testResult.setTestId(scenarioID); + testResult.setTestId(scenarioReport.getScenarioId()); } else { apiTestService.changeStatus(testId, APITestStatus.Completed); report = apiReportService.getRunningReport(testResult.getTestId()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index b027338cef..bf7077a9b0 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -260,10 +260,15 @@ public class ApiAutomationService { return new ArrayList<>(); } - private void createAPIScenarioReportResult(String id, String triggerMode, String execType, String projectId, String userID) { + private void createAPIScenarioReportResult(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID) { APIScenarioReportResult report = new APIScenarioReportResult(); report.setId(id); - report.setName("测试执行结果"); + report.setTestId(id); + if (StringUtils.isNotEmpty(scenarioName)) { + report.setName(scenarioName); + } else { + report.setName("零时调试名称"); + } report.setCreateTime(System.currentTimeMillis()); report.setUpdateTime(System.currentTimeMillis()); report.setStatus(APITestStatus.Running.name()); @@ -272,12 +277,12 @@ public class ApiAutomationService { } else { report.setUserId(SessionUtils.getUserId()); } - report.setTriggerMode(triggerMode); report.setExecuteType(execType); report.setProjectId(projectId); - apiReportService.addResult(report); - + report.setScenarioName(scenarioName); + report.setScenarioId(scenarioId); + apiScenarioReportMapper.insert(report); } /** @@ -292,10 +297,21 @@ public class ApiAutomationService { testPlan.setHashTree(new LinkedList<>()); HashTree jmeterTestPlanHashTree = new ListedHashTree(); String projectID = request.getProjectId(); + // 批量执行的结果直接存储为报告 + if (apiScenarios.size() > 1) { + request.setExecuteType(ExecuteType.Saved.name()); + } + boolean isOne = true; for (ApiScenarioWithBLOBs item : apiScenarios) { MsThreadGroup group = new MsThreadGroup(); group.setLabel(item.getName()); - group.setName(item.getName()); + // 批量执行的结果直接存储为报告 + if (isOne) { + group.setName(request.getId()); + isOne = false; + } else { + group.setName(UUID.randomUUID().toString()); + } projectID = item.getProjectId(); try { ObjectMapper mapper = new ObjectMapper(); @@ -318,6 +334,9 @@ public class ApiAutomationService { group.setEnableCookieShare(scenario.isEnableCookieShare()); LinkedList scenarios = new LinkedList<>(); scenarios.add(scenario); + // 创建场景报告 + createAPIScenarioReportResult(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), + request.getExecuteType(), projectID, request.getReportUserID()); group.setHashTree(scenarios); testPlan.getHashTree().add(group); } catch (Exception ex) { @@ -332,9 +351,6 @@ public class ApiAutomationService { } // 调用执行方法 jMeterService.runDefinition(request.getId(), jmeterTestPlanHashTree, request.getReportId(), runMode); - - createAPIScenarioReportResult(request.getId(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), - request.getExecuteType(), projectID, request.getReportUserID()); return request.getId(); } @@ -346,7 +362,7 @@ public class ApiAutomationService { * @param bodyFiles * @return */ - public String run(RunDefinitionRequest request, List bodyFiles) { + public String debugRun(RunDefinitionRequest request, List bodyFiles) { List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles); EnvironmentConfig envConfig = null; @@ -359,7 +375,7 @@ public class ApiAutomationService { HashTree hashTree = request.getTestElement().generateHashTree(config); // 调用执行方法 jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name()); - createAPIScenarioReportResult(request.getId(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), + createAPIScenarioReportResult(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId()); return request.getId(); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 9e6aef5552..3c306f6453 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -1,7 +1,6 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; @@ -15,30 +14,26 @@ import io.metersphere.base.mapper.ApiScenarioReportDetailMapper; import io.metersphere.base.mapper.ApiScenarioReportMapper; import io.metersphere.base.mapper.TestPlanApiScenarioMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper; -import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.ApiRunMode; -import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.DateUtils; -import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.i18n.Translator; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import sun.security.util.Cache; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; @Service @Transactional(rollbackFor = Exception.class) public class ApiScenarioReportService { - - private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); @Resource private ExtApiScenarioReportMapper extApiScenarioReportMapper; @Resource @@ -50,77 +45,18 @@ public class ApiScenarioReportService { @Resource private TestPlanApiScenarioMapper testPlanApiScenarioMapper; - public String getApiScenarioId(String name, String projectID) { - ApiScenarioExample example = new ApiScenarioExample(); - example.createCriteria().andNameEqualTo(name).andProjectIdEqualTo(projectID).andStatusNotEqualTo("Trash"); - List list = apiScenarioMapper.selectByExample(example); - if (list.isEmpty()) { - return null; - } else { - return list.get(0).getId(); - } - } - public ApiScenarioReport complete(TestResult result, String runMode) { - Object obj = cache.get(result.getTestId()); - if (obj == null) { - MSException.throwException(Translator.get("api_report_is_null")); - } - APIScenarioReportResult report = (APIScenarioReportResult) obj; - report.setTestId(result.getTestId()); - if (CollectionUtils.isNotEmpty(result.getScenarios())) { - try { - report.setName(result.getScenarios().get(0).getName() + "-" + DateUtils.getTimeString(System.currentTimeMillis())); - } catch (Exception e) { - LogUtil.error(e.getMessage()); - } - } - // report detail - ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); - detail.setReportId(result.getTestId()); - detail.setProjectId(report.getProjectId()); - report.setTestId(result.getTestId()); - detail.setContent(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8)); - // report - report.setUpdateTime(System.currentTimeMillis()); - if (!StringUtils.equals(report.getStatus(), APITestStatus.Debug.name())) { - if (result.getError() > 0) { - report.setStatus(APITestStatus.Error.name()); + // 更新场景 + if (result != null) { + if (StringUtils.equals(runMode, ApiRunMode.SCENARIO_PLAN.name())) { + return updatePlanCase(result); } else { - report.setStatus(APITestStatus.Success.name()); + return updateScenario(result); } } - report.setContent(new String(detail.getContent(), StandardCharsets.UTF_8)); - this.save(report, runMode); - // 此方法适用于前端发起 - if (!report.getTriggerMode().equals(ReportTriggerMode.SCHEDULE.name())) { - cache.put(report.getId(), report); - } - return report; - } - - /** - * 获取零时执行报告 - * - * @param testId - */ - public APIScenarioReportResult getCacheResult(String testId) { - Object res = cache.get(testId); - if (res != null) { - APIScenarioReportResult reportResult = (APIScenarioReportResult) res; - if (!reportResult.getStatus().equals(APITestStatus.Running.name())) { - cache.remove(testId); - } - return reportResult; - } return null; } - - public void addResult(APIScenarioReportResult res) { - cache.put(res.getId(), res); - } - public APIScenarioReportResult get(String reportId) { APIScenarioReportResult reportResult = extApiScenarioReportMapper.get(reportId); ApiScenarioReportDetail detail = apiScenarioReportDetailMapper.selectByPrimaryKey(reportId); @@ -143,26 +79,14 @@ public class ApiScenarioReportService { } } - public ApiScenarioReport createReport(APIScenarioReportResult test, String scenarioName, String scenarioId, String result, String testId) { - checkNameExist(test); - ApiScenarioReport report = new ApiScenarioReport(); - if (StringUtils.isNotEmpty(testId)) { - report.setId(testId); - } else { - report.setId(UUID.randomUUID().toString()); - } - report.setProjectId(test.getProjectId()); - report.setName(scenarioName + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); - report.setTriggerMode(test.getTriggerMode()); - report.setDescription(test.getDescription()); - report.setCreateTime(System.currentTimeMillis()); + public ApiScenarioReport editReport(ScenarioResult test) { + ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(test.getName()); + report.setId(report.getId()); + report.setName(report.getScenarioName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis())); report.setUpdateTime(System.currentTimeMillis()); - report.setStatus(result); - report.setUserId(test.getUserId()); - report.setExecuteType(test.getExecuteType()); - report.setScenarioId(scenarioId); - report.setScenarioName(scenarioName); - apiScenarioReportMapper.insert(report); + String status = test.getError() == 0 ? "Success" : "Error"; + report.setStatus(status); + apiScenarioReportMapper.updateByPrimaryKeySelective(report); return report; } @@ -194,20 +118,8 @@ public class ApiScenarioReportService { return testResult; } - public void save(APIScenarioReportResult test, String runModel) { - TestResult result = JSON.parseObject(test.getContent(), TestResult.class); - // 更新场景 - if (result != null) { - if (StringUtils.equals(runModel, ApiRunMode.SCENARIO_PLAN.name())) { - updatePlanCase(result, test); - } else { - updateScenario(result, test); - } - } - } - - public void updatePlanCase(TestResult result, APIScenarioReportResult scenarioReportResult) { - TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(scenarioReportResult.getId()); + public ApiScenarioReport updatePlanCase(TestResult result) { + TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(result.getTestId()); ScenarioResult scenarioResult = result.getScenarios().get(0); if (scenarioResult.getError() > 0) { testPlanApiScenario.setLastResult("Fail"); @@ -217,33 +129,44 @@ public class ApiScenarioReportService { String passRate = new DecimalFormat("0%").format((float) scenarioResult.getSuccess() / (scenarioResult.getSuccess() + scenarioResult.getError())); testPlanApiScenario.setPassRate(passRate); // 存储场景报告 - String testId = null; - if (CollectionUtils.isNotEmpty(result.getScenarios()) && result.getScenarios().size() == 1) { - testId = scenarioReportResult.getTestId(); - } - ApiScenarioReport report = createReport(scenarioReportResult, scenarioResult.getName(), testPlanApiScenario.getApiScenarioId(), scenarioResult.getError() == 0 ? "Success" : "Error", testId); + ApiScenarioReport report = editReport(scenarioResult); // 报告详情内容 ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); TestResult newResult = createTestResult(result); List scenarioResults = new ArrayList(); + scenarioResult.setName(report.getScenarioName()); scenarioResults.add(scenarioResult); newResult.setScenarios(scenarioResults); detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); detail.setReportId(report.getId()); - detail.setProjectId(scenarioReportResult.getProjectId()); + detail.setProjectId(report.getProjectId()); apiScenarioReportDetailMapper.insert(detail); testPlanApiScenario.setReportId(report.getId()); testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario); + return report; } - public void updateScenario(TestResult result, APIScenarioReportResult scenarioReportResult) { - result.getScenarios().forEach(item -> { - ApiScenarioExample example = new ApiScenarioExample(); - example.createCriteria().andNameEqualTo(item.getName()).andProjectIdEqualTo(scenarioReportResult.getProjectId()); - List list = apiScenarioMapper.selectByExample(example); - if (list.size() > 0) { - ApiScenario scenario = list.get(0); + public ApiScenarioReport updateScenario(TestResult result) { + ApiScenarioReport lastReport = null; + for (ScenarioResult item : result.getScenarios()) { + // 更新报告状态 + ApiScenarioReport report = editReport(item); + + // 报告详情内容 + ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); + TestResult newResult = createTestResult(result); + List scenarioResults = new ArrayList(); + item.setName(report.getScenarioName()); + scenarioResults.add(item); + newResult.setScenarios(scenarioResults); + detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); + detail.setReportId(report.getId()); + detail.setProjectId(report.getProjectId()); + apiScenarioReportDetailMapper.insert(detail); + // 更新场景状态 + ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); + if (scenario != null) { if (item.getError() > 0) { scenario.setLastResult("Fail"); } else { @@ -251,28 +174,12 @@ public class ApiScenarioReportService { } String passRate = new DecimalFormat("0%").format((float) item.getSuccess() / (item.getSuccess() + item.getError())); scenario.setPassRate(passRate); - - // 存储场景报告 - String testId = null; - if (CollectionUtils.isNotEmpty(result.getScenarios()) && result.getScenarios().size() == 1) { - testId = scenarioReportResult.getTestId(); - } - ApiScenarioReport report = createReport(scenarioReportResult, scenario.getName(), scenario.getId(), scenario.getLastResult(), testId); - // 报告详情内容 - ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); - TestResult newResult = createTestResult(result); - List scenarioResults = new ArrayList(); - scenarioResults.add(item); - newResult.setScenarios(scenarioResults); - detail.setContent(JSON.toJSONString(newResult).getBytes(StandardCharsets.UTF_8)); - detail.setReportId(report.getId()); - detail.setProjectId(scenario.getProjectId()); - apiScenarioReportDetailMapper.insert(detail); - // 更新场景状态 scenario.setReportId(report.getId()); apiScenarioMapper.updateByPrimaryKey(scenario); } - }); + lastReport = report; + } + return lastReport; } public String update(APIScenarioReportResult test) { diff --git a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue index 48457f01cf..c9f8b20e9b 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue @@ -2,7 +2,7 @@ -
+
@@ -96,7 +96,7 @@ getReport() { this.init(); if (this.reportId) { - let url = "/api/scenario/report/get/" + this.reportId + "/" + this.infoDb; + let url = "/api/scenario/report/get/" + this.reportId; this.$get(url, response => { this.report = response.data || {}; if (response.data) { diff --git a/frontend/src/business/components/api/automation/scenario/DebugRun.vue b/frontend/src/business/components/api/automation/scenario/DebugRun.vue index 3b4ba69e7b..ef4f21e5ed 100644 --- a/frontend/src/business/components/api/automation/scenario/DebugRun.vue +++ b/frontend/src/business/components/api/automation/scenario/DebugRun.vue @@ -92,11 +92,11 @@ let testPlan = createComponent('TestPlan'); let threadGroup = createComponent('ThreadGroup'); threadGroup.hashTree = []; - threadGroup.name = this.runData.name ? this.runData.name : "Debug-Scenario"; + threadGroup.name = this.reportId; threadGroup.enableCookieShare = this.runData.enableCookieShare; threadGroup.hashTree.push(this.runData); testPlan.hashTree.push(threadGroup); - let reqObj = {id: this.reportId, reportId: this.reportId, environmentId: this.environment, testElement: testPlan, projectId: getCurrentProjectID()}; + let reqObj = {id: this.reportId, reportId: this.reportId, scenarioName: this.runData.name, scenarioId: this.runData.id, environmentId: this.environment, testElement: testPlan, projectId: getCurrentProjectID()}; let bodyFiles = this.getBodyUploadFiles(reqObj); let url = "/api/automation/run/debug"; this.$fileUpload(url, null, bodyFiles, reqObj, response => {