From 3cc4c181b8944807503fb34dd403f5052befb2f2 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 23 Mar 2021 22:23:38 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=AF=BC=E5=85=A5=E5=9C=BA=E6=99=AF=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=90=8D=E7=A7=B0=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/api/automation/scenario/EditApiScenario.vue | 7 ++++--- .../api/automation/scenario/maximize/MaximizeScenario.vue | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 770bf7bf68..eb56005aa0 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -574,14 +574,15 @@ this.isBtnHide = true; this.$refs.scenarioApiRelevance.open(); }, - recursiveSorting(arr) { + recursiveSorting(arr, scenarioProjectId) { for (let i in arr) { arr[i].index = Number(i) + 1; if (arr[i].type === ELEMENT_TYPE.LoopController && arr[i].hashTree && arr[i].hashTree.length > 1) { arr[i].countController.proceed = true; } if (!arr[i].projectId) { - arr[i].projectId = this.projectId; + // 如果自身没有ID并且场景有ID则赋值场景ID,否则赋值当前项目ID + arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; } if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) { this.recursiveSorting(arr[i].hashTree); @@ -606,7 +607,7 @@ this.scenarioDefinition[i].projectId = this.projectId; } if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) { - this.recursiveSorting(this.scenarioDefinition[i].hashTree); + this.recursiveSorting(this.scenarioDefinition[i].hashTree, this.scenarioDefinition[i].projectId); } // 添加debug结果 if (this.debugResult && this.debugResult.get(this.scenarioDefinition[i].id)) { diff --git a/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue b/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue index f532f6d1ce..0b25d137ba 100644 --- a/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/maximize/MaximizeScenario.vue @@ -490,14 +490,14 @@ apiListImport() { this.$refs.scenarioApiRelevance.open(); }, - recursiveSorting(arr) { + recursiveSorting(arr, scenarioProjectId) { for (let i in arr) { arr[i].index = Number(i) + 1; if (arr[i].type === ELEMENT_TYPE.LoopController && arr[i].hashTree && arr[i].hashTree.length > 1) { arr[i].countController.proceed = true; } if (!arr[i].projectId) { - arr[i].projectId = this.projectId; + arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId; } if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) { this.recursiveSorting(arr[i].hashTree); @@ -522,7 +522,7 @@ this.scenarioDefinition[i].projectId = this.projectId; } if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) { - this.recursiveSorting(this.scenarioDefinition[i].hashTree); + this.recursiveSorting(this.scenarioDefinition[i].hashTree, this.scenarioDefinition[i].projectId); } // 添加debug结果 if (this.debugResult && this.debugResult.get(this.scenarioDefinition[i].id)) { From d2fabf8e938d786c79b350a05d8c24945a3435ce Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 24 Mar 2021 09:55:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95=E6=9F=A5=E8=AF=A2=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=8F=90=E7=A4=BA=EF=BC=8C=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E5=9B=BE=E8=A1=A8=E4=B8=8D=E5=8E=BB=E5=8D=95=E4=B8=AA=E8=AE=A1?= =?UTF-8?q?=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/performance/test/EditPerformanceTest.vue | 6 ++---- .../components/performance/test/components/ExistFiles.vue | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/frontend/src/business/components/performance/test/EditPerformanceTest.vue b/frontend/src/business/components/performance/test/EditPerformanceTest.vue index c4fe35f1dc..30168db9c5 100644 --- a/frontend/src/business/components/performance/test/EditPerformanceTest.vue +++ b/frontend/src/business/components/performance/test/EditPerformanceTest.vue @@ -345,13 +345,11 @@ export default { this.$refs.basicConfig.threadGroups = threadGroups; this.$refs.pressureConfig.threadGroups = threadGroups; - threadGroups.forEach(tg => { - handler.calculateChart(tg); - }) + handler.calculateTotalChart(); }, tgTypeChange(threadGroup) { let handler = this.$refs.pressureConfig; - handler.calculateChart(threadGroup); + handler.calculateTotalChart(); } } } diff --git a/frontend/src/business/components/performance/test/components/ExistFiles.vue b/frontend/src/business/components/performance/test/components/ExistFiles.vue index ad48447019..224c874960 100644 --- a/frontend/src/business/components/performance/test/components/ExistFiles.vue +++ b/frontend/src/business/components/performance/test/components/ExistFiles.vue @@ -232,7 +232,7 @@ export default { callback(); } else { - this.$error(this.$t('load_test.project_file_exist')); + this.$error(this.$t('load_test.project_file_exist') + ', name: ' + file.name); } }); }, From 36e3e001d40126cbeb842d5c7ac0393e28754c9c Mon Sep 17 00:00:00 2001 From: Coooder-X <55648333+Coooder-X@users.noreply.github.com> Date: Wed, 24 Mar 2021 10:06:01 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):?= =?UTF-8?q?=20=E6=89=A7=E8=A1=8C=E7=94=A8=E4=BE=8B=E6=88=96=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=BB=93=E6=9D=9F=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E7=9A=84=E7=8A=B6=E6=80=81=20(#1694)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(测试跟踪): 测试用例下载模版增加标签列 * fix(接口定义): 扩大请求头键长度 * fix: schedule表对旧数据name字段兼容的补充 * feat(测试计划): 执行用例或定时任务结束后,自动更新测试计划的状态 --- .../api/jmeter/APIBackendListenerClient.java | 5 ++ .../commons/constants/TestPlanStatus.java | 2 +- .../notice/service/NoticeSendService.java | 37 ++++++++------- .../notice/service/NoticeService.java | 46 +++++++++++-------- .../track/controller/TestPlanController.java | 5 ++ .../track/service/TestPlanReportService.java | 14 ++++-- .../track/service/TestPlanService.java | 45 +++++++++++++++++- .../api/definition/components/Run.vue | 1 + .../tableItems/plan/PlanStatusTableItem.vue | 1 + .../track/plan/components/TestPlanList.vue | 7 ++- .../comonents/api/TestPlanApiCaseList.vue | 7 ++- .../functional/FunctionalTestCaseList.vue | 5 ++ .../comonents/load/TestPlanLoadCaseList.vue | 5 ++ frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 16 files changed, 138 insertions(+), 45 deletions(-) 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 b64f1bb209..6e5c3b058f 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -5,6 +5,7 @@ import io.metersphere.api.service.*; import io.metersphere.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiScenarioReport; import io.metersphere.base.domain.ApiTestReport; +import io.metersphere.base.domain.TestPlanReport; import io.metersphere.commons.constants.*; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; @@ -14,6 +15,7 @@ import io.metersphere.notice.sender.NoticeModel; import io.metersphere.notice.service.NoticeSendService; import io.metersphere.service.SystemParameterService; import io.metersphere.track.service.TestPlanReportService; +import io.metersphere.track.service.TestPlanService; import io.metersphere.track.service.TestPlanTestCaseService; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -197,6 +199,9 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult, ApiRunMode.SCHEDULE_API_PLAN.name()); List testPlanReportIdList = new ArrayList<>(); testPlanReportIdList.add(debugReportId); + for(String testPlanReportId : testPlanReportIdList) { // 更新每个测试计划的状态 + testPlanReportService.checkTestPlanStatus(testPlanReportId); + } testPlanReportService.updateReport(testPlanReportIdList, ApiRunMode.SCHEDULE_API_PLAN.name(), ReportTriggerMode.SCHEDULE.name()); } else { apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name()); diff --git a/backend/src/main/java/io/metersphere/commons/constants/TestPlanStatus.java b/backend/src/main/java/io/metersphere/commons/constants/TestPlanStatus.java index 72273b1a38..557decfe54 100644 --- a/backend/src/main/java/io/metersphere/commons/constants/TestPlanStatus.java +++ b/backend/src/main/java/io/metersphere/commons/constants/TestPlanStatus.java @@ -1,5 +1,5 @@ package io.metersphere.commons.constants; public enum TestPlanStatus { - Prepare, Underway, Completed + Prepare, Underway, Completed, Finished } diff --git a/backend/src/main/java/io/metersphere/notice/service/NoticeSendService.java b/backend/src/main/java/io/metersphere/notice/service/NoticeSendService.java index 3aea7a17cc..e94433c6fd 100644 --- a/backend/src/main/java/io/metersphere/notice/service/NoticeSendService.java +++ b/backend/src/main/java/io/metersphere/notice/service/NoticeSendService.java @@ -2,6 +2,7 @@ package io.metersphere.notice.service; import com.alibaba.nacos.client.utils.StringUtils; import io.metersphere.commons.constants.NoticeConstants; +import io.metersphere.commons.utils.LogUtil; import io.metersphere.notice.domain.MessageDetail; import io.metersphere.notice.sender.NoticeModel; import io.metersphere.notice.sender.NoticeSender; @@ -44,22 +45,26 @@ public class NoticeSendService { } public void send(String taskType, NoticeModel noticeModel) { - List messageDetails; - switch (taskType) { - case NoticeConstants.Mode.API: - messageDetails = noticeService.searchMessageByType(NoticeConstants.TaskType.JENKINS_TASK); - break; - case NoticeConstants.Mode.SCHEDULE: - messageDetails = noticeService.searchMessageByTestId(noticeModel.getTestId()); - break; - default: - messageDetails = noticeService.searchMessageByType(taskType); - break; - } - messageDetails.forEach(messageDetail -> { - if (StringUtils.equals(messageDetail.getEvent(), noticeModel.getEvent())) { - this.getNoticeSender(messageDetail).send(messageDetail, noticeModel); + try { + List messageDetails; + switch (taskType) { + case NoticeConstants.Mode.API: + messageDetails = noticeService.searchMessageByType(NoticeConstants.TaskType.JENKINS_TASK); + break; + case NoticeConstants.Mode.SCHEDULE: + messageDetails = noticeService.searchMessageByTestId(noticeModel.getTestId()); + break; + default: + messageDetails = noticeService.searchMessageByType(taskType); + break; } - }); + messageDetails.forEach(messageDetail -> { + if (StringUtils.equals(messageDetail.getEvent(), noticeModel.getEvent())) { + this.getNoticeSender(messageDetail).send(messageDetail, noticeModel); + } + }); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + } } } diff --git a/backend/src/main/java/io/metersphere/notice/service/NoticeService.java b/backend/src/main/java/io/metersphere/notice/service/NoticeService.java index 0ab7b30d26..932a14812a 100644 --- a/backend/src/main/java/io/metersphere/notice/service/NoticeService.java +++ b/backend/src/main/java/io/metersphere/notice/service/NoticeService.java @@ -5,6 +5,7 @@ import io.metersphere.base.domain.MessageTaskExample; import io.metersphere.base.mapper.MessageTaskMapper; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.user.SessionUser; +import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.i18n.Translator; import io.metersphere.notice.domain.MessageDetail; @@ -102,29 +103,34 @@ public class NoticeService { } public List searchMessageByType(String type) { - SessionUser user = SessionUtils.getUser(); - String orgId = user.getLastOrganizationId(); - List messageDetails = new ArrayList<>(); + try { + SessionUser user = SessionUtils.getUser(); + String orgId = user.getLastOrganizationId(); + List messageDetails = new ArrayList<>(); - MessageTaskExample example = new MessageTaskExample(); - example.createCriteria() - .andTaskTypeEqualTo(type) - .andOrganizationIdEqualTo(orgId); - List messageTaskLists = messageTaskMapper.selectByExampleWithBLOBs(example); + MessageTaskExample example = new MessageTaskExample(); + example.createCriteria() + .andTaskTypeEqualTo(type) + .andOrganizationIdEqualTo(orgId); + List messageTaskLists = messageTaskMapper.selectByExampleWithBLOBs(example); - Map> messageTaskMap = messageTaskLists.stream() - .collect(Collectors.groupingBy(NoticeService::fetchGroupKey)); - messageTaskMap.forEach((k, v) -> { - MessageDetail messageDetail = getMessageDetail(v); - messageDetails.add(messageDetail); - }); + Map> messageTaskMap = messageTaskLists.stream() + .collect(Collectors.groupingBy(NoticeService::fetchGroupKey)); + messageTaskMap.forEach((k, v) -> { + MessageDetail messageDetail = getMessageDetail(v); + messageDetails.add(messageDetail); + }); - return messageDetails.stream() - .sorted(Comparator.comparing(MessageDetail::getCreateTime, Comparator.nullsLast(Long::compareTo)).reversed()) - .collect(Collectors.toList()) - .stream() - .distinct() - .collect(Collectors.toList()); + return messageDetails.stream() + .sorted(Comparator.comparing(MessageDetail::getCreateTime, Comparator.nullsLast(Long::compareTo)).reversed()) + .collect(Collectors.toList()) + .stream() + .distinct() + .collect(Collectors.toList()); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + return new ArrayList<>(); + } } private MessageDetail getMessageDetail(List messageTasks) { diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 338f682d43..35c79d3b2c 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -37,6 +37,11 @@ public class TestPlanController { @Resource CheckPermissionService checkPermissionService; + @PostMapping("/autoCheck/{testPlanId}") + public void autoCheck(@PathVariable String testPlanId){ + testPlanService.checkStatus(testPlanId); + } + @PostMapping("/list/{goPage}/{pageSize}") public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) { String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId(); diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java index c6682eaf1d..6a1f028330 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java @@ -11,10 +11,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanMapper; import io.metersphere.base.mapper.ext.ExtTestPlanReportMapper; import io.metersphere.commons.constants.*; -import io.metersphere.commons.utils.CommonBeanFactory; -import io.metersphere.commons.utils.DateUtils; -import io.metersphere.commons.utils.ServiceUtils; -import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.commons.utils.*; import io.metersphere.dto.BaseSystemConfigDTO; import io.metersphere.i18n.Translator; import io.metersphere.notice.sender.NoticeModel; @@ -212,6 +209,15 @@ public class TestPlanReportService { } } + public void checkTestPlanStatus(String planReportId) { + try { + TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId); + testPlanService.checkStatus(testPlanReport.getTestPlanId()); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + } + } + /** * * @param planReportId 测试计划报告ID diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index c7c1fed489..a959dbf120 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -194,7 +194,10 @@ public class TestPlanService { !TestPlanStatus.Completed.name().equals(res.getStatus())) { //已完成,写入实际完成时间 testPlan.setActualEndTime(System.currentTimeMillis()); - } + } else if (!res.getStatus().equals(TestPlanStatus.Finished.name()) && + TestPlanStatus.Finished.name().equals(testPlan.getStatus())) { + testPlan.setActualEndTime(System.currentTimeMillis()); + } // 非已结束->已结束,更新结束时间 } List userIds = new ArrayList<>(); @@ -367,7 +370,7 @@ public class TestPlanService { testPlan.setTotal(apiExecResults.size() + scenarioExecResults.size() + functionalExecResults.size() + loadResults.size()); - testPlan.setPassRate(MathUtils.getPercentWithDecimal(testPlan.getTested() == 0 ? 0 : testPlan.getPassed() * 1.0 / testPlan.getTested())); + testPlan.setPassRate(MathUtils.getPercentWithDecimal(testPlan.getTested() == 0 ? 0 : testPlan.getPassed() * 1.0 / testPlan.getTotal())); testPlan.setTestRate(MathUtils.getPercentWithDecimal(testPlan.getTotal() == 0 ? 0 : testPlan.getTested() * 1.0 / testPlan.getTotal())); }); } @@ -383,6 +386,44 @@ public class TestPlanService { return testPlans; } + public void checkStatus(String testPlanId) { // 检查执行结果,自动更新计划状态 + List statusList = new ArrayList<>(); + statusList.addAll(extTestPlanTestCaseMapper.getExecResultByPlanId(testPlanId)); + statusList.addAll(testPlanApiCaseService.getExecResultByPlanId(testPlanId)); + statusList.addAll(testPlanScenarioCaseService.getExecResultByPlanId(testPlanId)); + statusList.addAll(testPlanLoadCaseService.getStatus(testPlanId)); +// Prepare, Pass, Failure, Blocking, Skip, Underway + TestPlanDTO testPlanDTO = new TestPlanDTO(); + testPlanDTO.setId(testPlanId); + if(statusList.size() == 0) { // 原先status不是prepare, 但删除所有关联用例的情况 + testPlanDTO.setStatus(TestPlanStatus.Prepare.name()); + editTestPlan(testPlanDTO); + return; + } + int passNum = 0, prepareNum = 0, failNum = 0; + for(String res : statusList) { + if(StringUtils.equals(res, TestPlanTestCaseStatus.Pass.name()) + || StringUtils.equals(res, "success") + || StringUtils.equals(res, ScenarioStatus.Success.name())) { + passNum++; + } else if (res == null) { + prepareNum++; + } else { + failNum++; + } + } + if(passNum == statusList.size()) { // 全部通过 + testPlanDTO.setStatus(TestPlanStatus.Completed.name()); + this.editTestPlan(testPlanDTO); + } else if(prepareNum == 0 && passNum + failNum == statusList.size()) { // 已结束 + testPlanDTO.setStatus(TestPlanStatus.Finished.name()); + editTestPlan(testPlanDTO); + } else if(prepareNum != 0) { // 进行中 + testPlanDTO.setStatus(TestPlanStatus.Underway.name()); + editTestPlan(testPlanDTO); + } + } + public List listTestPlanByProject(QueryTestPlanRequest request) { List testPlans = extTestPlanMapper.list(request); return testPlans; diff --git a/frontend/src/business/components/api/definition/components/Run.vue b/frontend/src/business/components/api/definition/components/Run.vue index 5cbf8751ed..4245075e55 100644 --- a/frontend/src/business/components/api/definition/components/Run.vue +++ b/frontend/src/business/components/api/definition/components/Run.vue @@ -86,6 +86,7 @@ this.$fileUpload(url, null, bodyFiles, reqObj, response => { this.runId = response.data; this.getResult(); + this.$emit('autoCheckStatus'); // 执行结束后,自动更新计划状态 }, error => { this.$emit('runRefresh', {}); }); diff --git a/frontend/src/business/components/track/common/tableItems/plan/PlanStatusTableItem.vue b/frontend/src/business/components/track/common/tableItems/plan/PlanStatusTableItem.vue index 786cb030cc..1bee6abea9 100644 --- a/frontend/src/business/components/track/common/tableItems/plan/PlanStatusTableItem.vue +++ b/frontend/src/business/components/track/common/tableItems/plan/PlanStatusTableItem.vue @@ -2,6 +2,7 @@
+
diff --git a/frontend/src/business/components/track/plan/components/TestPlanList.vue b/frontend/src/business/components/track/plan/components/TestPlanList.vue index 473047b812..e7b880c2e0 100644 --- a/frontend/src/business/components/track/plan/components/TestPlanList.vue +++ b/frontend/src/business/components/track/plan/components/TestPlanList.vue @@ -53,6 +53,10 @@ :command="{item: scope.row, status: 'Underway'}"> {{ $t('test_track.plan.plan_status_running') }} + + {{ $t('test_track.plan.plan_status_finished') }} + {{ $t('test_track.plan.plan_status_completed') }} @@ -82,7 +86,7 @@ show-overflow-tooltip :key="index"> + @runRefresh="runRefresh" ref="runTest" @autoCheckStatus="autoCheckStatus"/> { }); }, + autoCheckStatus() { // 检查执行结果,自动更新计划状态 + this.$post('/test/plan/autoCheck/' + this.planId, (response) => { + }); + }, handleDelete(apiCase) { if (this.planId) { this.$get('/test/plan/api/case/delete/' + apiCase.id, () => { diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue index 09a693c76d..9fbc3cafb5 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue @@ -431,6 +431,7 @@ export default { }, initTableData() { + this.autoCheckStatus(); if (this.planId) { // param.planId = this.planId; this.condition.planId = this.planId; @@ -479,6 +480,10 @@ export default { } getLabel(this, TEST_PLAN_FUNCTION_TEST_CASE); }, + autoCheckStatus() { + this.$post('/test/plan/autoCheck/' + this.planId, (response) => { + }); + }, showDetail(row, event, column) { this.isReadOnly = true; this.$refs.testPlanTestCaseEdit.openTestCaseEdit(row); diff --git a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue index db66a0d7ce..430e61a5fa 100644 --- a/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList.vue @@ -213,6 +213,7 @@ export default { this.$refs.headerCustom.open(this.tableLabel) }, initTable() { + this.autoCheckStatus(); this.selectRows = new Set(); this.condition.testPlanId = this.planId; if (this.selectProjectId && this.selectProjectId !== 'root') { @@ -247,6 +248,10 @@ export default { getLabel(this, TEST_PLAN_LOAD_CASE); }, + autoCheckStatus() { + this.$post('/test/plan/autoCheck/' + this.planId, (response) => { + }); + }, refreshStatus() { this.refreshScheduler = setInterval(() => { // 如果有状态不是最终状态则定时查询 diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index caf212e8f6..080a830a8a 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1242,6 +1242,7 @@ export default { input_plan_stage: "Please select stage", plan_status_prepare: "Not started", plan_status_running: "Starting", + plan_status_finished: "Finished", plan_status_completed: "Completed", plan_status_trash: "Trashed", planned_start_time: "Scheduled Start Time", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index aed3a90c5d..be06b88245 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -1246,6 +1246,7 @@ export default { input_plan_stage: "请选择测试阶段", plan_status_prepare: "未开始", plan_status_running: "进行中", + plan_status_finished: "已结束", plan_status_completed: "已完成", plan_status_trash: "废弃", planned_start_time: "计划开始", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 201f41e576..a0a0fcc566 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -1244,6 +1244,7 @@ export default { input_plan_stage: "請選擇測試階段", plan_status_prepare: "未開始", plan_status_running: "進行中", + plan_status_finished: "已結束", plan_status_completed: "已完成", plan_status_trash: "廢棄", planned_start_time: "計劃開始", From b02868245b8994a5d378db8427a595ec6072919f Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 24 Mar 2021 10:15:36 +0800 Subject: [PATCH 4/6] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89):?= =?UTF-8?q?=20=E7=94=A8=E4=BE=8B=E6=89=A7=E8=A1=8Cdubbo=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E4=B8=8D=E5=BC=BA=E5=88=B6=E9=80=89=E6=8B=A9=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/components/case/ApiCaseItem.vue | 15 ++++++++------- .../definition/components/case/ApiCaseList.vue | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue index 2d1ef42868..214901efcd 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue @@ -129,9 +129,10 @@ import MsJmxStep from "../step/JmxStep"; import ApiResponseComponent from "../../../automation/scenario/component/ApiResponseComponent"; import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn"; + const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); - const esbDefinition = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {}; - const esbDefinitionResponse = (requireComponent!=null&&requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {}; + const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {}; + const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {}; export default { name: "ApiCaseItem", @@ -157,7 +158,7 @@ return { result: {}, grades: [], - showXpackCompnent:false, + showXpackCompnent: false, isReadOnly: false, selectedEvent: Object, priorities: PRIORITY, @@ -198,7 +199,7 @@ isCaseEdit: Boolean, }, created() { - if (requireComponent != null && JSON.stringify(esbDefinition) != '{}'&& JSON.stringify(esbDefinitionResponse) != '{}') { + if (requireComponent != null && JSON.stringify(esbDefinition) != '{}' && JSON.stringify(esbDefinitionResponse) != '{}') { this.showXpackCompnent = true; } }, @@ -224,7 +225,7 @@ }); }, singleRun(data) { - if (!this.environment) { + if (this.api.protocol != "DUBBO" && this.api.protocol != "dubbo://" && !this.environment) { this.$warning(this.$t('api_test.environment.select_environment')); return; } @@ -316,10 +317,10 @@ } } - if(tmp.request.esbDataStruct != null){ + if (tmp.request.esbDataStruct != null) { tmp.esbDataStruct = JSON.stringify(tmp.request.esbDataStruct); } - if(tmp.request.backEsbDataStruct != null){ + if (tmp.request.backEsbDataStruct != null) { tmp.backEsbDataStruct = JSON.stringify(tmp.request.backEsbDataStruct); } diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue index cdc7166ee4..91d409047f 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue @@ -280,7 +280,7 @@ }, singleRun(row) { - if (!this.environment) { + if (this.currentApi.protocol != "DUBBO" && this.currentApi.protocol != "dubbo://" && !this.environment) { this.$warning(this.$t('api_test.environment.select_environment')); return; } @@ -298,7 +298,7 @@ }, batchRun() { - if (!this.environment) { + if (this.currentApi.protocol != "DUBBO" && this.currentApi.protocol != "dubbo://" && !this.environment) { this.$warning(this.$t('api_test.environment.select_environment')); return; } From 0d297aada9850e6eceb418e07d5d1610817f0bef Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 24 Mar 2021 10:30:11 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E6=89=B9=E9=87=8F=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E7=94=A8=E4=BE=8B=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/metersphere/commons/utils/ScriptEngineUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/io/metersphere/commons/utils/ScriptEngineUtils.java b/backend/src/main/java/io/metersphere/commons/utils/ScriptEngineUtils.java index 599d1b5234..2e2431d32d 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/ScriptEngineUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/ScriptEngineUtils.java @@ -22,7 +22,8 @@ public class ScriptEngineUtils { } } - public static String calculate(String input) { + // graal.js 禁止多线程同时访问,加上 synchronized + public synchronized static String calculate(String input) { try { return engine.eval("calculate('" + input + "')").toString(); } catch (ScriptException e) { From bfe6e732d572c329ce479d66d31d3546e9d13c43 Mon Sep 17 00:00:00 2001 From: BugKing Date: Wed, 24 Mar 2021 10:32:15 +0800 Subject: [PATCH 6/6] =?UTF-8?q?style(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA)?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E7=94=A8=E5=8A=9B=E5=88=97=E8=A1=A8=E6=A0=87=E7=AD=BE=E5=88=97?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plan/view/comonents/functional/FunctionalTestCaseList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue index 9fbc3cafb5..0be1a249c8 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue @@ -93,7 +93,7 @@ :key="index" >