From 6fd1ffdda7e5a4f2685101b87cb3e9350fa68dd7 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Fri, 24 Sep 2021 18:59:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89)=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B9=B6=E5=8F=91=E6=89=B9=E9=87=8F=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=94=A8=E4=BE=8B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/dns/MsDNSCacheManager.java | 2 +- .../metersphere/api/jmeter/MessageCache.java | 4 ++ .../api/service/ApiAutomationService.java | 8 ++- .../ApiDefinitionExecResultService.java | 25 ++++--- .../api/service/ApiDefinitionService.java | 10 ++- .../api/service/ApiTestCaseService.java | 7 +- .../components/EditCompleteContainer.vue | 3 +- .../components/list/ApiCaseSimpleList.vue | 70 +++++++++++++++++++ 8 files changed, 108 insertions(+), 21 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java index 5a36f8e1ff..fb771e9f96 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/dns/MsDNSCacheManager.java @@ -47,7 +47,7 @@ public class MsDNSCacheManager extends MsTestElement { } public static void addEnvironmentDNS(HashTree samplerHashTree, String name, EnvironmentConfig config, HttpConfig httpConfig) { - if (config.getCommonConfig().isEnableHost() && CollectionUtils.isNotEmpty(config.getCommonConfig().getHosts()) && httpConfig != null) { + if (config.getCommonConfig().isEnableHost() && CollectionUtils.isNotEmpty(config.getCommonConfig().getHosts()) && httpConfig != null && httpConfig.getDomain() != null) { String domain = httpConfig.getDomain().trim(); List hosts = new ArrayList<>(); config.getCommonConfig().getHosts().forEach(host -> { diff --git a/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java b/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java index 9544e14293..73bec5fcae 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/MessageCache.java @@ -1,5 +1,6 @@ package io.metersphere.api.jmeter; +import io.metersphere.base.domain.ApiDefinitionExecResult; import org.apache.jmeter.engine.StandardJMeterEngine; import javax.websocket.Session; @@ -16,4 +17,7 @@ public class MessageCache { public static ConcurrentHashMap runningEngine = new ConcurrentHashMap<>(); public static ConcurrentLinkedDeque terminationOrderDeque = new ConcurrentLinkedDeque<>(); + + public static ConcurrentHashMap batchTestCases = new ConcurrentHashMap<>(); + } 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 265f138ded..e393c69eb1 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -1966,7 +1966,7 @@ public class ApiAutomationService { } } } - if (CollectionUtils.isNotEmpty(object.getJSONArray("hashTree"))) { + if (object != null && CollectionUtils.isNotEmpty(object.getJSONArray("hashTree"))) { setHashTree(object.getJSONArray("hashTree")); } } @@ -1985,8 +1985,10 @@ public class ApiAutomationService { if (StringUtils.isNotEmpty(item.getScenarioDefinition())) { JSONObject scenario = JSONObject.parseObject(item.getScenarioDefinition()); JSONArray hashTree = scenario.getJSONArray("hashTree"); - setHashTree(hashTree); - scenario.put("hashTree", hashTree); + if (hashTree != null) { + setHashTree(hashTree); + scenario.put("hashTree", hashTree); + } item.setScenarioDefinition(JSON.toJSONString(scenario)); } }); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java index 2f237226a8..5bea05bdff 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.cache.TestPlanReportExecuteCatch; import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult; +import io.metersphere.api.jmeter.MessageCache; import io.metersphere.api.jmeter.TestResult; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; @@ -57,7 +58,8 @@ public class ApiDefinitionExecResultService { TestCaseReviewApiCaseMapper testCaseReviewApiCaseMapper; @Resource - SqlSessionFactory sqlSessionFactory; + private ApiDefinitionService apiDefinitionService; + @Resource private NoticeSendService noticeSendService; @@ -67,13 +69,14 @@ public class ApiDefinitionExecResultService { public void saveApiResult(TestResult result, String type, String triggerMode) { if (CollectionUtils.isNotEmpty(result.getScenarios())) { - SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); - ApiDefinitionExecResultMapper definitionExecResultMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class); final boolean[] isFirst = {true}; result.getScenarios().forEach(scenarioResult -> { if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) { scenarioResult.getRequestResults().forEach(item -> { - ApiDefinitionExecResult saveResult = definitionExecResultMapper.selectByPrimaryKey(result.getTestId()); + ApiDefinitionExecResult saveResult = MessageCache.batchTestCases.get(result.getTestId()); + if (saveResult == null) { + saveResult = apiDefinitionExecResultMapper.selectByPrimaryKey(result.getTestId()); + } item.getResponseResult().setConsole(result.getConsole()); boolean saved = true; if (saveResult == null || scenarioResult.getRequestResults().size() > 1) { @@ -88,6 +91,7 @@ public class ApiDefinitionExecResultService { saveResult.setName(item.getName()); saveResult.setTriggerMode(triggerMode); saveResult.setType(type); + saveResult.setCreateTime(item.getStartTime()); if (StringUtils.isNotEmpty(result.getUserId())) { saveResult.setUserId(result.getUserId()); } else { @@ -98,7 +102,6 @@ public class ApiDefinitionExecResultService { String status = item.isSuccess() ? "success" : "error"; saveResult.setName(getName(type, item.getName(), status, saveResult.getCreateTime(), saveResult.getId())); saveResult.setStatus(status); - saveResult.setCreateTime(item.getStartTime()); saveResult.setResourceId(item.getName()); saveResult.setContent(JSON.toJSONString(item)); saveResult.setStartTime(item.getStartTime()); @@ -108,23 +111,23 @@ public class ApiDefinitionExecResultService { ApiDefinitionExecResult prevResult = extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(item.getName(), type); if (prevResult != null) { prevResult.setContent(null); - definitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult); + apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult); } if (StringUtils.isNotEmpty(saveResult.getTriggerMode()) && saveResult.getTriggerMode().equals("CASE")) { saveResult.setTriggerMode(TriggerMode.MANUAL.name()); } if (!saved) { - definitionExecResultMapper.insert(saveResult); + apiDefinitionExecResultMapper.insert(saveResult); } else { - definitionExecResultMapper.updateByPrimaryKeyWithBLOBs(saveResult); + apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(saveResult); } + apiDefinitionService.removeCache(result.getTestId()); // 发送通知 sendNotice(saveResult); }); } }); - sqlSession.flushStatements(); } } @@ -284,7 +287,7 @@ public class ApiDefinitionExecResultService { if (StringUtils.equals(type, ApiRunMode.SCHEDULE_API_PLAN.name())) { TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName()); - if(StringUtils.isEmpty(creator)){ + if (StringUtils.isEmpty(creator)) { creator = testPlanService.findScheduleCreateUserById(apiCase.getTestPlanId()); } apiCase.setStatus(status); @@ -299,7 +302,7 @@ public class ApiDefinitionExecResultService { testPlanApiCaseService.setExecResult(item.getName(), status, item.getStartTime()); testCaseReviewApiCaseService.setExecResult(item.getName(), status, item.getStartTime()); } - if(creator == null){ + if (creator == null) { creator = ""; } saveResult.setUserId(creator); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 416d5a7d72..10351697e9 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -97,8 +97,6 @@ public class ApiDefinitionService { @Resource private ExtSwaggerUrlScheduleMapper extSwaggerUrlScheduleMapper; @Resource - private ScheduleMapper scheduleMapper; - @Resource private ApiTestCaseMapper apiTestCaseMapper; @Resource private ApiTestEnvironmentService environmentService; @@ -117,7 +115,7 @@ public class ApiDefinitionService { @Resource private ExtApiTestCaseMapper extApiTestCaseMapper; - private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); + private static Cache cache = Cache.newHardMemoryCache(0, 3600); private ThreadLocal currentApiOrder = new ThreadLocal<>(); private ThreadLocal currentApiCaseOrder = new ThreadLocal<>(); @@ -800,6 +798,12 @@ public class ApiDefinitionService { return null; } + public void removeCache(String testId) { + if (StringUtils.isNotEmpty(testId)) { + cache.remove(testId); + } + } + /** * 获取存储执行结果报告 * diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index 1340f3daa8..7938a45274 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -18,6 +18,7 @@ import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.jmeter.JMeterService; +import io.metersphere.api.jmeter.MessageCache; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.*; @@ -494,7 +495,7 @@ public class ApiTestCaseService { ExtTestPlanApiCaseMapper batchMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class); Long nextOrder = ServiceUtils.getNextOrder(request.getPlanId(), extTestPlanApiCaseMapper::getLastOrder); - for (ApiTestCase apiTestCase: apiTestCases) { + for (ApiTestCase apiTestCase : apiTestCases) { TestPlanApiCase testPlanApiCase = new TestPlanApiCase(); testPlanApiCase.setId(UUID.randomUUID().toString()); testPlanApiCase.setCreateUser(SessionUtils.getUserId()); @@ -701,7 +702,7 @@ public class ApiTestCaseService { public void batchRun(ApiCaseBatchRequest request) { ServiceUtils.getSelectAllIds(request, request.getCondition(), - (query) -> extApiTestCaseMapper.selectIdsByQuery((ApiTestCaseRequest)query)); + (query) -> extApiTestCaseMapper.selectIdsByQuery((ApiTestCaseRequest) query)); Map executeQueue = new HashMap<>(); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class); @@ -727,6 +728,7 @@ public class ApiTestCaseService { runCaseRequest.setReportId(executeQueue.get(caseId).getId()); runCaseRequest.setEnvironmentId(request.getEnvironmentId()); run(runCaseRequest); + MessageCache.batchTestCases.put(executeQueue.get(caseId).getId(), executeQueue.get(caseId)); } } @@ -1089,6 +1091,7 @@ public class ApiTestCaseService { /** * 用例自定义排序 + * * @param request */ public void updateOrder(ResetOrderRequest request) { diff --git a/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue b/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue index a641f40cde..39ae9777c0 100644 --- a/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue +++ b/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue @@ -212,7 +212,7 @@ export default { mockSetting() { let mockParam = {}; mockParam.projectId = this.projectId; - if(this.currentApi.id){ + if (this.currentApi.id) { mockParam.apiId = this.currentApi.id; this.$post('/mockConfig/genMockConfig', mockParam, response => { let mockConfig = response.data; @@ -283,6 +283,7 @@ export default { this.api = this.$store.state.currentApiCase.api; this.$refs.caseList.open(); } + this.$store.state.currentApiCase = {case: true}; } else if (tabType === "test") { this.showApiList = false; this.showTestCaseList = false; diff --git a/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue b/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue index 5678a5a019..58b6209f07 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue @@ -230,6 +230,7 @@ import { getCustomTableHeader, getCustomTableWidth, getLastTableSortField, + handleRowDrop } from "@/common/js/tableUtils"; import {API_CASE_LIST} from "@/common/js/constants"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; @@ -361,6 +362,7 @@ export default { environments: [], resVisible: false, response: {}, + timeoutIndex: 0, }; }, props: { @@ -526,6 +528,7 @@ export default { this.$refs.caseTable.openCustomHeader(); }, initTable(id) { + this.timeoutIndex = 0; if (this.$refs.caseTable) { this.$refs.caseTable.clearSelectRows(); } @@ -603,6 +606,73 @@ export default { isNext = true; } }); + + this.$nextTick(() => { + if (this.$refs.caseTable) { + this.$refs.caseTable.clear(); + } + handleRowDrop(this.tableData, (param) => { + param.groupId = this.condition.projectId; + editApiTestCaseOrder(param); + }); + }) + if (isNext) { + this.refreshStatus(); + } + }); + } + }, + refreshStatus() { + if (this.apiDefinitionId) { + this.condition.apiDefinitionId = this.apiDefinitionId; + } + this.condition.status = ""; + this.condition.moduleIds = this.selectNodeIds; + if (this.condition.filters && !this.condition.filters.status) { + this.$delete(this.condition.filters, 'status'); + } + if (!this.selectAll) { + this.selectAll = false; + this.unSelection = []; + this.selectDataCounts = 0; + } + this.condition.projectId = this.projectId; + if (this.currentProtocol != null) { + this.condition.protocol = this.currentProtocol; + } + //检查是否只查询本周数据 + this.isSelectThissWeekData(); + this.condition.selectThisWeedData = false; + this.condition.id = null; + if (this.selectDataRange == 'thisWeekCount') { + this.condition.selectThisWeedData = true; + } else if (this.selectDataRange != null) { + let selectParamArr = this.selectDataRange.split("single:"); + if (selectParamArr.length === 2) { + this.condition.id = selectParamArr[1]; + } + } + if (this.condition.projectId) { + this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => { + let isNext = false; + let tableData = response.data.listObject; + this.tableData.forEach(item => { + for (let i in tableData) { + if (item.id === tableData[i].id) { + item.status = tableData[i].status; + item.lastResultId = tableData[i].lastResultId; + } + } + if (item.status === 'Running') { + isNext = true; + } + }); + if (isNext && this.$store.state.currentApiCase && this.$store.state.currentApiCase.case && this.timeoutIndex < 12) { + this.timeoutIndex++; + setTimeout(() => { + this.refreshStatus(); + }, 12000); + } }); } },