fix(接口定义) 修复并发批量执行用例问题
This commit is contained in:
parent
ec092e4038
commit
6fd1ffdda7
|
@ -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<Host> hosts = new ArrayList<>();
|
||||
config.getCommonConfig().getHosts().forEach(host -> {
|
||||
|
|
|
@ -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<String, StandardJMeterEngine> runningEngine = new ConcurrentHashMap<>();
|
||||
|
||||
public static ConcurrentLinkedDeque<String> terminationOrderDeque = new ConcurrentLinkedDeque<>();
|
||||
|
||||
public static ConcurrentHashMap<String, ApiDefinitionExecResult> batchTestCases = new ConcurrentHashMap<>();
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Long> currentApiOrder = new ThreadLocal<>();
|
||||
private ThreadLocal<Long> currentApiCaseOrder = new ThreadLocal<>();
|
||||
|
@ -800,6 +798,12 @@ public class ApiDefinitionService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void removeCache(String testId) {
|
||||
if (StringUtils.isNotEmpty(testId)) {
|
||||
cache.remove(testId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储执行结果报告
|
||||
*
|
||||
|
|
|
@ -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<String, ApiDefinitionExecResult> 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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue