提交 d34c4271 authored 作者: 黄夏豪's avatar 黄夏豪

fix(base): 修了一些BUG

上级 0af44d11
package org.matrix.actuators.httpclient; package org.matrix.actuators.httpclient;
import com.alibaba.fastjson.JSONObject;
import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpHeaderValues;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.HttpHostConnectException;
...@@ -74,7 +75,6 @@ public class HttpClientActuator implements Actuator { ...@@ -74,7 +75,6 @@ public class HttpClientActuator implements Actuator {
); );
} }
for (RequestBody requestBody : httpRequestDetail.getRequestBodies()) { for (RequestBody requestBody : httpRequestDetail.getRequestBodies()) {
//todo 李迪凡 将requestBody中的key和value里的 动态变量补全
requestBody.setKey( requestBody.setKey(
completeExpressionUtil.completeDynamicVariable( completeExpressionUtil.completeDynamicVariable(
requestBody.getKey(), requestBody.getKey(),
...@@ -89,7 +89,6 @@ public class HttpClientActuator implements Actuator { ...@@ -89,7 +89,6 @@ public class HttpClientActuator implements Actuator {
); );
} }
if (!StringUtils.isEmpty(httpRequestDetail.getStringValue())){ if (!StringUtils.isEmpty(httpRequestDetail.getStringValue())){
//todo 李迪凡 将httpRequestDetail的stringValue 动态变量补全
httpRequestDetail.setStringValue( httpRequestDetail.setStringValue(
completeExpressionUtil.completeDynamicVariable( completeExpressionUtil.completeDynamicVariable(
httpRequestDetail.getStringValue(), httpRequestDetail.getStringValue(),
...@@ -97,7 +96,6 @@ public class HttpClientActuator implements Actuator { ...@@ -97,7 +96,6 @@ public class HttpClientActuator implements Actuator {
projectId) projectId)
); );
} }
//todo 李迪凡 将httpRequestDetail的url 动态变量补全
httpRequestDetail.setUrl(completeExpressionUtil.completeDynamicVariable( httpRequestDetail.setUrl(completeExpressionUtil.completeDynamicVariable(
httpRequestDetail.getUrl(), httpRequestDetail.getUrl(),
envId, envId,
...@@ -123,6 +121,8 @@ public class HttpClientActuator implements Actuator { ...@@ -123,6 +121,8 @@ public class HttpClientActuator implements Actuator {
response = client.execute(requestBase); response = client.execute(requestBase);
Long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); Long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
return new HttpResponseDetail( return new HttpResponseDetail(
url,
StringUtils.isEmpty(httpRequestDetail.getStringValue())? JSONObject.toJSONString(httpRequestDetail.getRequestBodies()) :httpRequestDetail.getStringValue(),
response, response,
EntityUtils.toString(response.getEntity(), "UTF-8"), EntityUtils.toString(response.getEntity(), "UTF-8"),
HttpStatus.valueOf(response.getStatusLine().getStatusCode()), HttpStatus.valueOf(response.getStatusLine().getStatusCode()),
...@@ -131,6 +131,8 @@ public class HttpClientActuator implements Actuator { ...@@ -131,6 +131,8 @@ public class HttpClientActuator implements Actuator {
}catch (HttpHostConnectException e){ }catch (HttpHostConnectException e){
Long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); Long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
return new HttpResponseDetail( return new HttpResponseDetail(
url,
StringUtils.isEmpty(httpRequestDetail.getStringValue())? JSONObject.toJSONString(httpRequestDetail.getRequestBodies()) :httpRequestDetail.getStringValue(),
response, response,
String.format("目标主机拒绝连接,本次请求URL: %s ",httpRequestDetail.getUrl()), String.format("目标主机拒绝连接,本次请求URL: %s ",httpRequestDetail.getUrl()),
HttpStatus.SERVICE_UNAVAILABLE, HttpStatus.SERVICE_UNAVAILABLE,
......
...@@ -18,6 +18,12 @@ import org.springframework.http.HttpStatus; ...@@ -18,6 +18,12 @@ import org.springframework.http.HttpStatus;
@NoArgsConstructor @NoArgsConstructor
public class HttpResponseDetail extends BaseTestCaseResponseDetail { public class HttpResponseDetail extends BaseTestCaseResponseDetail {
@ApiModelProperty("请求路径")
private String url;
@ApiModelProperty("请求入参")
private String requestParam;
@ApiModelProperty("HttpClient响应体") @ApiModelProperty("HttpClient响应体")
private CloseableHttpResponse response; private CloseableHttpResponse response;
......
...@@ -17,7 +17,6 @@ import org.matrix.database.entity.TestCaseBTO; ...@@ -17,7 +17,6 @@ import org.matrix.database.entity.TestCaseBTO;
import org.matrix.database.service.ITestDataService; import org.matrix.database.service.ITestDataService;
import org.matrix.database.service.impl.ActionServiceImpl; import org.matrix.database.service.impl.ActionServiceImpl;
import org.matrix.enums.ActionType; import org.matrix.enums.ActionType;
import org.matrix.enums.ModuleType;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
import org.matrix.socket.queue.LogQueueRuntime; import org.matrix.socket.queue.LogQueueRuntime;
import org.matrix.util.BeanFlattener; import org.matrix.util.BeanFlattener;
...@@ -255,7 +254,7 @@ public class MoveActuator implements Actuator { ...@@ -255,7 +254,7 @@ public class MoveActuator implements Actuator {
long caseDataId = Long.parseLong(runtimeDetail); long caseDataId = Long.parseLong(runtimeDetail);
TestCaseBTO caseBTO = dataService.toCaseBTO(caseDataId); TestCaseBTO caseBTO = dataService.toCaseBTO(caseDataId);
return (HttpResponseDetail) caseActuator.executeTestCase(caseBTO, envId, projectId) return (HttpResponseDetail) caseActuator.executeTestCase(caseBTO, envId, projectId)
.getBaseTestCaseRequestDetail(); .getBaseTestCaseResponseDetail();
} }
/** /**
......
...@@ -183,7 +183,7 @@ public class SqlExpActuator implements Actuator { ...@@ -183,7 +183,7 @@ public class SqlExpActuator implements Actuator {
long caseDataId = Long.parseLong(dynamicVar.getDetail()); long caseDataId = Long.parseLong(dynamicVar.getDetail());
TestCaseBTO caseBTO = dataService.toCaseBTO(caseDataId); TestCaseBTO caseBTO = dataService.toCaseBTO(caseDataId);
HttpResponseDetail responseDetail = (HttpResponseDetail) caseActuator.executeTestCase(caseBTO, envId, projectId) HttpResponseDetail responseDetail = (HttpResponseDetail) caseActuator.executeTestCase(caseBTO, envId, projectId)
.getBaseTestCaseRequestDetail(); .getBaseTestCaseResponseDetail();
return responseDetail.getResponseBody(); return responseDetail.getResponseBody();
} }
......
...@@ -19,7 +19,7 @@ import org.matrix.actuators.httpclient.HttpRequestDetail; ...@@ -19,7 +19,7 @@ import org.matrix.actuators.httpclient.HttpRequestDetail;
import org.matrix.actuators.httpclient.HttpResponseDetail; import org.matrix.actuators.httpclient.HttpResponseDetail;
import org.matrix.database.service.IExecutionHistoryService; import org.matrix.database.service.IExecutionHistoryService;
import org.matrix.enums.ExecutionHistoryStatus; import org.matrix.enums.ExecutionHistoryStatus;
import org.matrix.enums.ModuleType; import org.matrix.exception.ExecutionRunningException;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
import org.matrix.socket.ExecutionStatusMonitorSocketHandler; import org.matrix.socket.ExecutionStatusMonitorSocketHandler;
import org.matrix.socket.pool.TestCaseExecuteSocketPool; import org.matrix.socket.pool.TestCaseExecuteSocketPool;
...@@ -39,6 +39,7 @@ import static org.matrix.enums.ModuleType.CASE_ACTUATOR; ...@@ -39,6 +39,7 @@ import static org.matrix.enums.ModuleType.CASE_ACTUATOR;
/** /**
* 测试用例执行器 * 测试用例执行器
*
* @author huangxiahao * @author huangxiahao
*/ */
@Component @Component
...@@ -70,7 +71,7 @@ public class CaseActuator implements Actuator { ...@@ -70,7 +71,7 @@ public class CaseActuator implements Actuator {
public TestDataExecuteResult executeTestCase(TestCaseBTO testCaseBto, Long envId, Long projectId) { public TestDataExecuteResult executeTestCase(TestCaseBTO testCaseBto, Long envId, Long projectId) {
try { try {
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "开始执行用例!!"); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "开始执行用例!!");
LogQueueRuntime.addNewLog(this.getClass(),CASE_ACTUATOR, String.format("当前正在执行用例ID: %s 用例名: %s", testCaseBto.getTestCase().getId(), testCaseBto.getTestCase().getName())); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, String.format("当前正在执行用例ID: %s 用例名: %s", testCaseBto.getTestCase().getId(), testCaseBto.getTestCase().getName()));
//执行前置动作 //执行前置动作
executeMove(testCaseBto.getTestCase().getMoveAfterCase() executeMove(testCaseBto.getTestCase().getMoveAfterCase()
, envId, projectId, null, MoveStrategy.PRE_MOVE); , envId, projectId, null, MoveStrategy.PRE_MOVE);
...@@ -103,7 +104,7 @@ public class CaseActuator implements Actuator { ...@@ -103,7 +104,7 @@ public class CaseActuator implements Actuator {
testCaseBto.getTestData().getId(), testCaseBto.getTestData().getId(),
baseTestCaseResponseDetail, baseTestCaseResponseDetail,
checkPointResult); checkPointResult);
LogQueueRuntime.addNewLog(this.getClass(),CASE_ACTUATOR, JSON.toJSONString(testDataExecuteResult)); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, JSON.toJSONString(testDataExecuteResult));
//将线程中正在执行的DataId清除 //将线程中正在执行的DataId清除
LogQueueRuntime.clearTestData(); LogQueueRuntime.clearTestData();
return testDataExecuteResult; return testDataExecuteResult;
...@@ -133,13 +134,13 @@ public class CaseActuator implements Actuator { ...@@ -133,13 +134,13 @@ public class CaseActuator implements Actuator {
//try catch 一下避免发生错误后导致循环进行不下去 //try catch 一下避免发生错误后导致循环进行不下去
try { try {
changeExecutionHistoryStatus(ExecutionHistoryStatus.RUN); changeExecutionHistoryStatus(ExecutionHistoryStatus.RUN);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR,"[用例执行器] 开始执行数据组ID:" + testData.getId()); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "[用例执行器] 开始执行数据组ID:" + testData.getId());
HttpResponseDetail baseTestCaseResponseDetail = getHttpResponseDetail( HttpResponseDetail baseTestCaseResponseDetail = getHttpResponseDetail(
envId, envId,
projectId, projectId,
testCaseBto.getTestCase(), testCaseBto.getTestCase(),
testData); testData);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR,"[用例执行器] 即将开始执行中置动作"); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "[用例执行器] 即将开始执行中置动作");
//执行中置动作 //执行中置动作
executeMove(testCaseBto.getTestCase().getMoveAfterTest() executeMove(testCaseBto.getTestCase().getMoveAfterTest()
, envId, projectId, baseTestCaseResponseDetail.getResponseBody(), MoveStrategy.MID_MOVE); , envId, projectId, baseTestCaseResponseDetail.getResponseBody(), MoveStrategy.MID_MOVE);
...@@ -158,12 +159,12 @@ public class CaseActuator implements Actuator { ...@@ -158,12 +159,12 @@ public class CaseActuator implements Actuator {
checkPointResult checkPointResult
); );
resultList.add(testDataExecuteResult); resultList.add(testDataExecuteResult);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR,"用例执行结果:" + JSON.toJSONString(testDataExecuteResult)); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "用例执行结果:" + JSON.toJSONString(testDataExecuteResult));
//执行后置动作 //执行后置动作
executeMove(testCaseBto.getTestCase().getMoveAfterTest() executeMove(testCaseBto.getTestCase().getMoveAfterTest()
, envId, projectId, baseTestCaseResponseDetail.getResponseBody(), MoveStrategy.AFT_MOVE); , envId, projectId, baseTestCaseResponseDetail.getResponseBody(), MoveStrategy.AFT_MOVE);
changeExecutionHistoryStatus(ExecutionHistoryStatus.FINISH); changeExecutionHistoryStatus(ExecutionHistoryStatus.FINISH);
}catch (Exception e){ } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
TestDataExecuteResult testDataExecuteResult = new TestDataExecuteResult( TestDataExecuteResult testDataExecuteResult = new TestDataExecuteResult(
dataStartTime, dataStartTime,
...@@ -175,10 +176,12 @@ public class CaseActuator implements Actuator { ...@@ -175,10 +176,12 @@ public class CaseActuator implements Actuator {
null null
); );
resultList.add(testDataExecuteResult); resultList.add(testDataExecuteResult);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR,String.format("[用例执行器] 执行数据组ID:%s 数据组名称:%s 产生错误:%s",testData.getId(),testData.getName(),e.getMessage())); changeExecutionHistoryStatus(ExecutionHistoryStatus.ERROR);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, String.format("[用例执行器] 执行数据组ID:%s 数据组名称:%s 产生错误:%s", testData.getId(), testData.getName(), e.getMessage()));
} }
} }
}finally { } finally {
clearMoveData();
//将线程中正在执行的DataId清除 //将线程中正在执行的DataId清除
LogQueueRuntime.clearTestData(); LogQueueRuntime.clearTestData();
} }
...@@ -197,7 +200,7 @@ public class CaseActuator implements Actuator { ...@@ -197,7 +200,7 @@ public class CaseActuator implements Actuator {
private void executeMove(String moveString, Long envId, Long projectId, String caseResultData, MoveStrategy strategy) { private void executeMove(String moveString, Long envId, Long projectId, String caseResultData, MoveStrategy strategy) {
String[] moveIds = StringUtils.isEmpty(moveString) ? new String[]{} : moveString.split(","); String[] moveIds = StringUtils.isEmpty(moveString) ? new String[]{} : moveString.split(",");
for (String moveId : moveIds) { for (String moveId : moveIds) {
if (!StringUtils.isEmpty(moveId)){ if (!StringUtils.isEmpty(moveId)) {
getMoveActuator().runMove( getMoveActuator().runMove(
Long.valueOf(moveId), Long.valueOf(moveId),
envId, envId,
...@@ -210,6 +213,13 @@ public class CaseActuator implements Actuator { ...@@ -210,6 +213,13 @@ public class CaseActuator implements Actuator {
} }
} }
/**
* 清空动作的变量吃
*/
private void clearMoveData() {
getMoveActuator().clearMoveRes();
}
private CheckPointResult getCheckPointResult(TestCase testCase private CheckPointResult getCheckPointResult(TestCase testCase
, TestData testData , TestData testData
, Long envId , Long envId
...@@ -263,7 +273,7 @@ public class CaseActuator implements Actuator { ...@@ -263,7 +273,7 @@ public class CaseActuator implements Actuator {
runCaseResult.setJobId(caseExecuteVo.getJobId()); runCaseResult.setJobId(caseExecuteVo.getJobId());
Long currentThreadId = ThreadUtil.currentThreadId(); Long currentThreadId = ThreadUtil.currentThreadId();
try { try {
if (session!=null&&session.isOpen()){ if (session != null && session.isOpen()) {
session.sendMessage(new TextMessage(JSONObject.toJSONString(caseExecuteVo))); session.sendMessage(new TextMessage(JSONObject.toJSONString(caseExecuteVo)));
} }
//将websocketSession 加入到socket池子中 //将websocketSession 加入到socket池子中
...@@ -276,7 +286,13 @@ public class CaseActuator implements Actuator { ...@@ -276,7 +286,13 @@ public class CaseActuator implements Actuator {
} }
} }
//建立执行历史(ExecutionHistory) //建立执行历史(ExecutionHistory)
if (caseExecuteVo.getJobId() != -1L) {
if (!LogQueueRuntime.checkJobIsInRun(caseExecuteVo.getJobId(), caseExecuteVo.getUserId(), caseExecuteVo.getType())) {
insertExecutionHistory(uniqueKey, caseExecuteVo); insertExecutionHistory(uniqueKey, caseExecuteVo);
}
} else {
insertExecutionHistory(uniqueKey, caseExecuteVo);
}
for (TestCaseListDataBto testCaseListDataBto : testCaseListDataBtoList) { for (TestCaseListDataBto testCaseListDataBto : testCaseListDataBtoList) {
LocalDateTime caseStartTime = LocalDateTime.now(); LocalDateTime caseStartTime = LocalDateTime.now();
try { try {
...@@ -289,19 +305,47 @@ public class CaseActuator implements Actuator { ...@@ -289,19 +305,47 @@ public class CaseActuator implements Actuator {
, uniqueKey , uniqueKey
); );
//执行测试用例 //执行测试用例
if (testCaseListDataBto.getTestDataList()!=null&&testCaseListDataBto.getTestDataList().size()>0){ if (testCaseListDataBto.getTestDataList() != null && testCaseListDataBto.getTestDataList().size() > 0) {
List<TestDataExecuteResult> resultList = List<TestDataExecuteResult> resultList =
executeTestCases(testCaseListDataBto, caseExecuteVo.getEnvId(), caseExecuteVo.getProjectId()); executeTestCases(testCaseListDataBto, caseExecuteVo.getEnvId(), caseExecuteVo.getProjectId());
TestCaseReport testCaseReport = new TestCaseReport( TestCaseReport testCaseReport = new TestCaseReport(
caseStartTime,LocalDateTime.now(),testCaseListDataBto.getTestCase().getId(),true,resultList caseStartTime,
LocalDateTime.now(),
testCaseListDataBto.getTestCase().getId(),
testCaseListDataBto.getTestCase().getName(),
TestCaseTypeEnum.getTypeByValue( testCaseListDataBto.getTestCase().getType()).toString(),
testCaseListDataBto.getTestCase().getDetail(),
testCaseListDataBto.getTestCase().getDes(),
testCaseListDataBto.getTestCase().getMoveBefore(),
testCaseListDataBto.getTestCase().getMoveAfterTest(),
testCaseListDataBto.getTestCase().getMoveAfterCase(),
true,
resultList
); );
runCaseResult.getCaseReports().add(testCaseReport); runCaseResult.getCaseReports().add(testCaseReport);
} }
}catch (Exception e){ } catch (ExecutionRunningException runningException) {
if (session != null && session.isOpen()) {
session.sendMessage(new TextMessage("-1.-1.-1.-1." + runningException.getMessage()));
}
break;
} catch (Exception e) {
TestCaseReport testCaseReport = new TestCaseReport( TestCaseReport testCaseReport = new TestCaseReport(
caseStartTime,LocalDateTime.now(),testCaseListDataBto.getTestCase().getId(),false,null caseStartTime,
LocalDateTime.now(),
testCaseListDataBto.getTestCase().getId(),
testCaseListDataBto.getTestCase().getName(),
TestCaseTypeEnum.getTypeByValue( testCaseListDataBto.getTestCase().getType()).toString(),
testCaseListDataBto.getTestCase().getDetail(),
testCaseListDataBto.getTestCase().getDes(),
testCaseListDataBto.getTestCase().getMoveBefore(),
testCaseListDataBto.getTestCase().getMoveAfterTest(),
testCaseListDataBto.getTestCase().getMoveAfterCase(),
false,
null
); );
runCaseResult.getCaseReports().add(testCaseReport); runCaseResult.getCaseReports().add(testCaseReport);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, String.format("[用例执行器] 产生错误:%s", e.getMessage()));
} }
} }
} catch (GlobalException | IOException e) { } catch (GlobalException | IOException e) {
...@@ -309,9 +353,9 @@ public class CaseActuator implements Actuator { ...@@ -309,9 +353,9 @@ public class CaseActuator implements Actuator {
try { try {
if (session != null && session.isOpen()) { if (session != null && session.isOpen()) {
TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId()); TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId());
if (currentTestExecute!=null){ if (currentTestExecute != null) {
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR,e.getMessage()); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, e.getMessage());
}else { } else {
//这里加-1.-1.-1是用来表明这里发出去的数据是不属于任何执行中的用例的 //这里加-1.-1.-1是用来表明这里发出去的数据是不属于任何执行中的用例的
session.sendMessage(new TextMessage(String.format("-1.-1.-1.%s", e.getMessage()))); session.sendMessage(new TextMessage(String.format("-1.-1.-1.%s", e.getMessage())));
} }
...@@ -346,38 +390,41 @@ public class CaseActuator implements Actuator { ...@@ -346,38 +390,41 @@ public class CaseActuator implements Actuator {
executionHistory.setDataId(testDataList.get(i).getId()); executionHistory.setDataId(testDataList.get(i).getId());
executionHistory.setUniqueKey(uniqueKey); executionHistory.setUniqueKey(uniqueKey);
executionHistory.setExecutionKey(firstExecutionKey); executionHistory.setExecutionKey(firstExecutionKey);
if (i==0){ executionHistory.setCaseExecuteVoString(JSONObject.toJSONString(caseExecuteVo));
if (i == 0) {
executionHistory.setStartTime(LocalDateTime.now()); executionHistory.setStartTime(LocalDateTime.now());
} }
executionHistories.add(executionHistory); executionHistories.add(executionHistory);
} }
} }
Long lastExecutionKey = getExecutionKey(caseExecuteVo); Long lastExecutionKey = getExecutionKey(caseExecuteVo);
if (!lastExecutionKey.equals(firstExecutionKey)){ if (!lastExecutionKey.equals(firstExecutionKey)) {
insertExecutionHistory(uniqueKey, caseExecuteVo); insertExecutionHistory(uniqueKey, caseExecuteVo);
} }
executionHistoryService.saveBatch(executionHistories); executionHistoryService.saveBatch(executionHistories);
} }
/** /**
* 根据userId,jobId,caseId 往前查一个执行号 并且+1 ,如果jobId等于-1 则根据 userId,jobId,caseId 查否则根据 userId,jobId * 根据userId,jobId,caseId 往前查一个执行号 并且+1 ,如果jobId等于-1 则根据 userId,jobId,caseId 查否则根据 userId,jobId
*
* @return 新的执行号 * @return 新的执行号
*/ */
private Long getExecutionKey(CaseExecuteVo caseExecuteVo){ private Long getExecutionKey(CaseExecuteVo caseExecuteVo) {
LambdaQueryWrapper<ExecutionHistory> executionHistoryLambdaQueryWrapper = Wrappers.lambdaQuery(ExecutionHistory.class); LambdaQueryWrapper<ExecutionHistory> executionHistoryLambdaQueryWrapper = Wrappers.lambdaQuery(ExecutionHistory.class);
executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getUserId,caseExecuteVo.getUserId()); executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getUserId, caseExecuteVo.getUserId());
executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getJobId,caseExecuteVo.getJobId()); executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getJobId, caseExecuteVo.getJobId());
executionHistoryLambdaQueryWrapper.orderByDesc(ExecutionHistory::getId); executionHistoryLambdaQueryWrapper.orderByDesc(ExecutionHistory::getId);
executionHistoryLambdaQueryWrapper.last("limit 1"); executionHistoryLambdaQueryWrapper.last("limit 1");
if (caseExecuteVo.getJobId()==-1L){ if (caseExecuteVo.getJobId() == -1L) {
TestCaseListDataBto testCaseListDataBto = caseExecuteVo.getTestCaseListDataBtoList().get(0); TestCaseListDataBto testCaseListDataBto = caseExecuteVo.getTestCaseListDataBtoList().get(0);
if (testCaseListDataBto!=null){ if (testCaseListDataBto != null) {
executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getCaseId,testCaseListDataBto.getTestCase().getId()); executionHistoryLambdaQueryWrapper.eq(ExecutionHistory::getCaseId, testCaseListDataBto.getTestCase().getId());
} }
} }
ExecutionHistory one = executionHistoryService.getOne(executionHistoryLambdaQueryWrapper); ExecutionHistory one = executionHistoryService.getOne(executionHistoryLambdaQueryWrapper);
if(one!=null && one.getExecutionKey()!=null){ if (one != null && one.getExecutionKey() != null) {
return one.getExecutionKey()+1L; return one.getExecutionKey() + 1L;
}else { } else {
return 1L; return 1L;
} }
...@@ -386,21 +433,21 @@ public class CaseActuator implements Actuator { ...@@ -386,21 +433,21 @@ public class CaseActuator implements Actuator {
public void changeExecutionHistoryStatus( public void changeExecutionHistoryStatus(
ExecutionHistoryStatus executionHistoryStatus) { ExecutionHistoryStatus executionHistoryStatus) {
TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId()); TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId());
if (currentTestExecute!=null){ if (currentTestExecute != null) {
ExecutionHistory executionHistory = new ExecutionHistory(); ExecutionHistory executionHistory = new ExecutionHistory();
if (executionHistoryStatus.equals(ExecutionHistoryStatus.RUN)){ if (executionHistoryStatus.equals(ExecutionHistoryStatus.RUN)) {
executionHistory.setStartTime(LocalDateTime.now()); executionHistory.setStartTime(LocalDateTime.now());
}else if (executionHistoryStatus.equals(ExecutionHistoryStatus.FINISH)){ } else if (executionHistoryStatus.equals(ExecutionHistoryStatus.FINISH) || executionHistoryStatus.equals(ExecutionHistoryStatus.ERROR)) {
executionHistory.setEndTime(LocalDateTime.now()); executionHistory.setEndTime(LocalDateTime.now());
} }
executionHistory.setStatus(executionHistoryStatus); executionHistory.setStatus(executionHistoryStatus);
executionHistoryService.update(executionHistory, Wrappers executionHistoryService.update(executionHistory, Wrappers
.lambdaUpdate(ExecutionHistory.class) .lambdaUpdate(ExecutionHistory.class)
.eq(ExecutionHistory::getJobId,currentTestExecute.getTestJobId()) .eq(ExecutionHistory::getJobId, currentTestExecute.getTestJobId())
.eq(ExecutionHistory::getCaseId,currentTestExecute.getTestCaseId()) .eq(ExecutionHistory::getCaseId, currentTestExecute.getTestCaseId())
.eq(ExecutionHistory::getDataId,currentTestExecute.getTestDataId()) .eq(ExecutionHistory::getDataId, currentTestExecute.getTestDataId())
.eq(ExecutionHistory::getUniqueKey,currentTestExecute.getUniqueKey()) .eq(ExecutionHistory::getUniqueKey, currentTestExecute.getUniqueKey())
.eq(ExecutionHistory::getUserId,currentTestExecute.getUserId()) .eq(ExecutionHistory::getUserId, currentTestExecute.getUserId())
); );
//发送执行状态 //发送执行状态
try { try {
...@@ -420,17 +467,14 @@ public class CaseActuator implements Actuator { ...@@ -420,17 +467,14 @@ public class CaseActuator implements Actuator {
} }
/** /**
* 将所有还未完成的执行历史设置为ERROR * 将所有还未完成的执行历史设置为ERROR
*/ */
public void endExecutionHistory() { public void endExecutionHistory() {
TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId()); TestExecuteLog currentTestExecute = LogQueueRuntime.getCurrentTestExecute(ThreadUtil.currentThreadId());
if (currentTestExecute!=null){ if (currentTestExecute != null) {
LambdaUpdateWrapper<ExecutionHistory> wrapper = Wrappers LambdaUpdateWrapper<ExecutionHistory> wrapper = Wrappers
.lambdaUpdate(ExecutionHistory.class) .lambdaUpdate(ExecutionHistory.class)
.eq(ExecutionHistory::getJobId, currentTestExecute.getTestJobId())
.eq(ExecutionHistory::getCaseId, currentTestExecute.getTestCaseId())
.eq(ExecutionHistory::getUniqueKey, currentTestExecute.getUniqueKey()) .eq(ExecutionHistory::getUniqueKey, currentTestExecute.getUniqueKey())
.eq(ExecutionHistory::getUserId, currentTestExecute.getUserId()) .eq(ExecutionHistory::getUserId, currentTestExecute.getUserId())
.ne(ExecutionHistory::getStatus, ExecutionHistoryStatus.FINISH); .ne(ExecutionHistory::getStatus, ExecutionHistoryStatus.FINISH);
...@@ -456,5 +500,4 @@ public class CaseActuator implements Actuator { ...@@ -456,5 +500,4 @@ public class CaseActuator implements Actuator {
} }
} }
} }
...@@ -17,6 +17,8 @@ public class RunCaseResult extends BaseTime{ ...@@ -17,6 +17,8 @@ public class RunCaseResult extends BaseTime{
private Long jobId; private Long jobId;
private String uniqueKey;
/** /**
* Key为caseId,List为case下的每一个执行结果 * Key为caseId,List为case下的每一个执行结果
*/ */
......
...@@ -18,6 +18,28 @@ public class TestCaseReport extends BaseTime{ ...@@ -18,6 +18,28 @@ public class TestCaseReport extends BaseTime{
private Long caseId; private Long caseId;
private String caseName;
private String type;
private String detail;
private String description;
/**
* 前置行动ID组,例如:1,2,3
*/
private String moveBefore;
/**
* 后置行动ID组,例如:1,2,3
*/
private String moveAfterCase;
/**
* 测试执行后行动ID组,例如:1,2,3
*/
private String moveAfterTest;
/** /**
* 执行状态 * 执行状态
*/ */
...@@ -26,11 +48,18 @@ public class TestCaseReport extends BaseTime{ ...@@ -26,11 +48,18 @@ public class TestCaseReport extends BaseTime{
/** /**
* case下的每一个执行结果 * case下的每一个执行结果
*/ */
private List<TestDataExecuteResult> dataExecuteResults = new ArrayList<>(); private List<TestDataExecuteResult> dataExecuteResults ;
public TestCaseReport(LocalDateTime startTime, LocalDateTime endTime, Long caseId, Boolean status, List<TestDataExecuteResult> dataExecuteResults) { public TestCaseReport(LocalDateTime startTime, LocalDateTime endTime, Long caseId, String caseName, String type, String detail, String description, String moveBefore, String moveAfterCase, String moveAfterTest, Boolean status, List<TestDataExecuteResult> dataExecuteResults) {
super(startTime, endTime); super(startTime, endTime);
this.caseId = caseId; this.caseId = caseId;
this.caseName = caseName;
this.type = type;
this.detail = detail;
this.description = description;
this.moveBefore = moveBefore;
this.moveAfterCase = moveAfterCase;
this.moveAfterTest = moveAfterTest;
this.status = status; this.status = status;
this.dataExecuteResults = dataExecuteResults; this.dataExecuteResults = dataExecuteResults;
} }
......
...@@ -20,4 +20,13 @@ public enum TestCaseTypeEnum { ...@@ -20,4 +20,13 @@ public enum TestCaseTypeEnum {
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public static TestCaseTypeEnum getTypeByValue(Integer value){
for (TestCaseTypeEnum testCaseTypeEnum : TestCaseTypeEnum.values()) {
if (value.equals(testCaseTypeEnum.getValue())){
return testCaseTypeEnum;
}
}
return null;
}
} }
...@@ -23,17 +23,17 @@ public class TestDataExecuteResult extends BaseTime{ ...@@ -23,17 +23,17 @@ public class TestDataExecuteResult extends BaseTime{
private Long dataId; private Long dataId;
private BaseTestCaseResponseDetail baseTestCaseRequestDetail; private BaseTestCaseResponseDetail baseTestCaseResponseDetail;
private CheckPointResult checkPointResult; private CheckPointResult checkPointResult;
public TestDataExecuteResult(LocalDateTime startTime, LocalDateTime endTime, Boolean executionStatus, Long caseId, Long dataId, BaseTestCaseResponseDetail baseTestCaseRequestDetail, CheckPointResult checkPointResult) { public TestDataExecuteResult(LocalDateTime startTime, LocalDateTime endTime, Boolean executionStatus, Long caseId, Long dataId, BaseTestCaseResponseDetail baseTestCaseResponseDetail, CheckPointResult checkPointResult) {
super(startTime, endTime); super(startTime, endTime);
this.executionStatus = executionStatus; this.executionStatus = executionStatus;
this.caseId = caseId; this.caseId = caseId;
this.dataId = dataId; this.dataId = dataId;
this.baseTestCaseRequestDetail = baseTestCaseRequestDetail; this.baseTestCaseResponseDetail = baseTestCaseResponseDetail;
this.checkPointResult = checkPointResult; this.checkPointResult = checkPointResult;
} }
} }
...@@ -44,6 +44,8 @@ public class ExecutionHistory extends BaseEntity { ...@@ -44,6 +44,8 @@ public class ExecutionHistory extends BaseEntity {
private ExecutionHistoryStatus status = ExecutionHistoryStatus.READY; private ExecutionHistoryStatus status = ExecutionHistoryStatus.READY;
private String caseExecuteVoString;
/** /**
* 创建时间 * 创建时间
*/ */
......
...@@ -39,6 +39,7 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> { ...@@ -39,6 +39,7 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> {
"\tkeh.job_id jobId,\n" + "\tkeh.job_id jobId,\n" +
"\tkeh.execution_key executionKey,\n" + "\tkeh.execution_key executionKey,\n" +
"\tkeh.url url,\n" + "\tkeh.url url,\n" +
"\tkeh.case_execute_vo_string caseExecuteVoString,\n" +
"\tIF(MIN( keh.`status` )= 0 or MIN( keh.`status` ) = 1,1,MAX(keh.`status`)) `status`,\n" + "\tIF(MIN( keh.`status` )= 0 or MIN( keh.`status` ) = 1,1,MAX(keh.`status`)) `status`,\n" +
"\tktc.`name` caseName,\n" + "\tktc.`name` caseName,\n" +
"\tktd.`name` dataName," + "\tktd.`name` dataName," +
...@@ -63,6 +64,8 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> { ...@@ -63,6 +64,8 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> {
"</if>" + "</if>" +
"</where>" + "</where>" +
"GROUP BY keh.unique_key " + "GROUP BY keh.unique_key " +
"ORDER BY\n" +
"\tstartTime desc"+
"</script>") "</script>")
IPage<ExecutionHistoryVo> pageByCaseIdAndJobId(IPage<ExecutionHistoryVo> page, Long caseId, Long jobId,Long userId,String uniqueKey); IPage<ExecutionHistoryVo> pageByCaseIdAndJobId(IPage<ExecutionHistoryVo> page, Long caseId, Long jobId,Long userId,String uniqueKey);
...@@ -82,6 +85,7 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> { ...@@ -82,6 +85,7 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> {
"\tkeh.job_id jobId,\n" + "\tkeh.job_id jobId,\n" +
"\tkeh.url url,\n" + "\tkeh.url url,\n" +
"\tkeh.execution_key executionKey,\n" + "\tkeh.execution_key executionKey,\n" +
"\tkeh.case_execute_vo_string caseExecuteVoString,\n" +
"IF\n" + "IF\n" +
"\t(\n" + "\t(\n" +
"\tMIN( keh.`status` )= 0 or MIN( keh.`status` ) = 1,\n" + "\tMIN( keh.`status` )= 0 or MIN( keh.`status` ) = 1,\n" +
...@@ -110,6 +114,8 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> { ...@@ -110,6 +114,8 @@ public interface ExecutionHistoryMapper extends BaseMapper<ExecutionHistory> {
"GROUP BY case_id ) ) \n" + "GROUP BY case_id ) ) \n" +
"GROUP BY\n" + "GROUP BY\n" +
"\tkeh.unique_key\n" + "\tkeh.unique_key\n" +
"ORDER BY\n" +
"\tstartTime desc"+
"</script>") "</script>")
ExecutionHistoryVo selectLastExecutionHistoryVo( Long caseId, Long jobId,Long userId); ExecutionHistoryVo selectLastExecutionHistoryVo( Long caseId, Long jobId,Long userId);
......
package org.matrix.exception;
/**
* 当用户需要执行的 用例或者任务 正在执行中时抛出这个异常.
*
* @author huangxiahao
* @since 2022/1/19 at 12:53 PM
* Suffering is the most powerful teacher of life.
*/
public class ExecutionRunningException extends RuntimeException {
public ExecutionRunningException(String message) {
super(message);
}
public ExecutionRunningException(String message, Throwable cause) {
super(message, cause);
}
public ExecutionRunningException(Throwable cause) {
super(cause);
}
public ExecutionRunningException() {
super();
}
}
...@@ -2,16 +2,16 @@ package org.matrix.socket; ...@@ -2,16 +2,16 @@ package org.matrix.socket;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.beanutils.BeanUtils;
import org.matrix.actuators.datasource.IDataSourceService; import org.matrix.actuators.datasource.IDataSourceService;
import org.matrix.actuators.httpclient.HttpResponseDetail;
import org.matrix.actuators.sql.SqlExpActuator; import org.matrix.actuators.sql.SqlExpActuator;
import org.matrix.actuators.usecase.CaseActuator; import org.matrix.actuators.usecase.CaseActuator;
import org.matrix.database.entity.TestCase; import org.matrix.actuators.usecase.RunCaseResult;
import org.matrix.database.entity.TestCaseListDataBto; import org.matrix.actuators.usecase.TestCaseReport;
import org.matrix.database.entity.TestData; import org.matrix.actuators.usecase.TestDataExecuteResult;
import org.matrix.database.entity.TestJob; import org.matrix.database.entity.*;
import org.matrix.database.service.IExecutionHistoryService;
import org.matrix.database.service.ITestCaseService; import org.matrix.database.service.ITestCaseService;
import org.matrix.database.service.ITestDataService; import org.matrix.database.service.ITestDataService;
import org.matrix.database.service.ITestJobService; import org.matrix.database.service.ITestJobService;
...@@ -21,8 +21,14 @@ import org.matrix.socket.pool.MonitorSocketPool; ...@@ -21,8 +21,14 @@ import org.matrix.socket.pool.MonitorSocketPool;
import org.matrix.socket.vo.CaseExecuteVo; import org.matrix.socket.vo.CaseExecuteVo;
import org.matrix.socket.vo.ExecuteMonitorVo; import org.matrix.socket.vo.ExecuteMonitorVo;
import org.matrix.socket.vo.SocketVo; import org.matrix.socket.vo.SocketVo;
import org.matrix.testNg.web.entity.DataBean;
import org.matrix.testNg.web.entity.DataBeans;
import org.matrix.testNg.web.entity.DataMove;
import org.matrix.testNg.web.entity.ReportMessage;
import org.matrix.testNg.web.report.TestNgImpl;
import org.matrix.testNg.web.vo.DataBeansJobVo;
import org.matrix.testNg.web.vo.DataBeansMoveVo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.CloseStatus;
...@@ -30,6 +36,8 @@ import org.springframework.web.socket.TextMessage; ...@@ -30,6 +36,8 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler; import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -42,6 +50,8 @@ import java.util.Map; ...@@ -42,6 +50,8 @@ import java.util.Map;
@Component @Component
public class ExecutionSocketHandler extends TextWebSocketHandler { public class ExecutionSocketHandler extends TextWebSocketHandler {
public static final MonitorSocketPool EXECUTE_MONITOR_SOCKET_POOL = new MonitorSocketPool(); public static final MonitorSocketPool EXECUTE_MONITOR_SOCKET_POOL = new MonitorSocketPool();
final CaseActuator caseActuator; final CaseActuator caseActuator;
...@@ -51,8 +61,10 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -51,8 +61,10 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
final SqlExpActuator sqlExpActuator; final SqlExpActuator sqlExpActuator;
final JdbcTemplate jdbcTemplate; final JdbcTemplate jdbcTemplate;
final IDataSourceService dataSourceService; final IDataSourceService dataSourceService;
final IExecutionHistoryService executionHistoryService;
final TestNgImpl testNg;
public ExecutionSocketHandler(CaseActuator caseActuator, ITestDataService testDataService, ITestJobService testJobService, ITestCaseService testCaseService, SqlExpActuator sqlExpActuator, JdbcTemplate jdbcTemplate, IDataSourceService dataSourceService) { public ExecutionSocketHandler(CaseActuator caseActuator, ITestDataService testDataService, ITestJobService testJobService, ITestCaseService testCaseService, SqlExpActuator sqlExpActuator, JdbcTemplate jdbcTemplate, IDataSourceService dataSourceService, TestNgImpl testNg, IExecutionHistoryService executionHistoryService) {
this.caseActuator = caseActuator; this.caseActuator = caseActuator;
this.testDataService = testDataService; this.testDataService = testDataService;
this.testJobService = testJobService; this.testJobService = testJobService;
...@@ -60,6 +72,8 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -60,6 +72,8 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
this.sqlExpActuator = sqlExpActuator; this.sqlExpActuator = sqlExpActuator;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dataSourceService = dataSourceService; this.dataSourceService = dataSourceService;
this.testNg = testNg;
this.executionHistoryService = executionHistoryService;
} }
@Override @Override
...@@ -81,7 +95,7 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -81,7 +95,7 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
List<Map<String, Object>> list = jdbcTemplate.queryForList(sqlStatement); List<Map<String, Object>> list = jdbcTemplate.queryForList(sqlStatement);
List<TestCase> testCaseList = new ArrayList<>(); List<TestCase> testCaseList = new ArrayList<>();
for (Map<String, Object> objectMap : list) { for (Map<String, Object> objectMap : list) {
TestCase testCase = BeanUtil.mapToBean(objectMap,TestCase.class,false); TestCase testCase = BeanUtil.mapToBean(objectMap, TestCase.class, false);
testCaseList.add(testCase); testCaseList.add(testCase);
} }
for (TestCase testCase : testCaseList) { for (TestCase testCase : testCaseList) {
...@@ -91,10 +105,18 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -91,10 +105,18 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
testCaseListDataBto.setTestDataList(testDataList); testCaseListDataBto.setTestDataList(testDataList);
caseExecuteVo.getTestCaseListDataBtoList().add(testCaseListDataBto); caseExecuteVo.getTestCaseListDataBtoList().add(testCaseListDataBto);
} }
if (testCaseList.size()>0){ if (testCaseList.size() > 0) {
caseExecuteVo.setProjectId(testCaseList.get(0).getProjectId()); caseExecuteVo.setProjectId(testCaseList.get(0).getProjectId());
} }
caseActuator.runTestCase(session, caseExecuteVo); RunCaseResult runCaseResult = caseActuator.runTestCase(session, caseExecuteVo);
ReportMessage reportMessage = testNg.getReporterUrls(initTestNgData(runCaseResult, caseExecuteVo));
ExecutionHistory history = new ExecutionHistory();
history.setUrl(reportMessage.getUrl());
history.setStatus(null);
history.setUpdateTime(null);
executionHistoryService
.update(history,Wrappers.lambdaUpdate(ExecutionHistory.class)
.eq(ExecutionHistory::getUniqueKey,caseExecuteVo.getUniqueKey()));
} else if (SocketType.TEST_CASE_MONITOR.equals(socketVo.getSocketType())) { } else if (SocketType.TEST_CASE_MONITOR.equals(socketVo.getSocketType())) {
ExecuteMonitorVo caseExecuteVo = JSON.parseObject(payload, ExecuteMonitorVo.class); ExecuteMonitorVo caseExecuteVo = JSON.parseObject(payload, ExecuteMonitorVo.class);
EXECUTE_MONITOR_SOCKET_POOL.add(caseExecuteVo.getUniqueKey(), session); EXECUTE_MONITOR_SOCKET_POOL.add(caseExecuteVo.getUniqueKey(), session);
...@@ -108,6 +130,49 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -108,6 +130,49 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
} }
} }
public DataBeansJobVo initTestNgData(RunCaseResult caseResult, CaseExecuteVo caseExecuteVo) {
//用例总数
Integer total = caseExecuteVo.getTestCaseListDataBtoList().size();
//通过用例数
Integer passNum = (int) caseResult.getCaseReports().stream().filter(TestCaseReport::getStatus).count();
//失败用例数
Integer failNum = total - passNum;
//执行总时间
String allTime = caseResult.getDurationTimeStr();
//用例通过率
Integer probability = BigDecimal.valueOf(passNum).divide(BigDecimal.valueOf(total), 2, RoundingMode.UP).multiply(BigDecimal.valueOf(100)).intValue();
DataBean dataBean = new DataBean(total, passNum, failNum, allTime, probability);
List<DataBeansMoveVo> dataBeansMoveVos = new ArrayList<>();
for (TestCaseReport caseReport : caseResult.getCaseReports()) {
DataBeansMoveVo dataBeansMoveVo = new DataBeansMoveVo();
dataBeansMoveVo.setDataMove(new DataMove(
caseReport.getMoveBefore(),
caseReport.getMoveAfterTest(),
caseReport.getMoveAfterCase()
));
List<DataBeans> dataBeansList = new ArrayList<>();
for (TestDataExecuteResult dataExecuteResult : caseReport.getDataExecuteResults()) {
DataBeans dataBeans = new DataBeans();
dataBeans.setTestCaseName(caseReport.getCaseName());
dataBeans.setType(caseReport.getType());
if (dataExecuteResult.getBaseTestCaseResponseDetail() != null){
if (dataExecuteResult.getBaseTestCaseResponseDetail() instanceof HttpResponseDetail){
HttpResponseDetail httpResponseDetail = (HttpResponseDetail)dataExecuteResult.getBaseTestCaseResponseDetail();
dataBeans.setDetail(httpResponseDetail.getResponseBody());
}
}
dataBeans.setResult(dataExecuteResult.getExecutionStatus());
dataBeans.setDescription(caseReport.getDescription());
dataBeans.setDuration(dataExecuteResult.getDurationTimeMillis());
dataBeans.setResultMessage(dataExecuteResult.getCheckPointResult());
dataBeansList.add(dataBeans);
}
dataBeansMoveVo.setDataBeansList(dataBeansList);
dataBeansMoveVos.add(dataBeansMoveVo);
}
return new DataBeansJobVo(dataBean,dataBeansMoveVos);
}
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
......
package org.matrix.socket.pool; package org.matrix.socket.pool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
...@@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
* *
* @author huangxiahao * @author huangxiahao
*/ */
@Slf4j
public class MonitorSocketPool { public class MonitorSocketPool {
/** /**
...@@ -33,7 +35,7 @@ public class MonitorSocketPool { ...@@ -33,7 +35,7 @@ public class MonitorSocketPool {
if (webSocketSessions != null) { if (webSocketSessions != null) {
List<String> list = socketKeyMap.get(clientSocket.getId()); List<String> list = socketKeyMap.get(clientSocket.getId());
if (list!=null&&list.contains(key)){ if (list!=null&&list.contains(key)){
clientSocket.sendMessage(new TextMessage("请勿重复订阅")); log.info("用户重复订阅 批次:{}",key);
}else { }else {
webSocketSessions.add(clientSocket); webSocketSessions.add(clientSocket);
} }
......
...@@ -8,6 +8,7 @@ import org.matrix.actuators.util.ThreadUtil; ...@@ -8,6 +8,7 @@ import org.matrix.actuators.util.ThreadUtil;
import org.matrix.database.entity.ExecutionRecord; import org.matrix.database.entity.ExecutionRecord;
import org.matrix.database.service.IExecutionRecordService; import org.matrix.database.service.IExecutionRecordService;
import org.matrix.enums.ModuleType; import org.matrix.enums.ModuleType;
import org.matrix.exception.ExecutionRunningException;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
import org.matrix.socket.ExecutionSocketHandler; import org.matrix.socket.ExecutionSocketHandler;
import org.matrix.socket.vo.TestExecuteLog; import org.matrix.socket.vo.TestExecuteLog;
...@@ -19,6 +20,7 @@ import org.slf4j.LoggerFactory; ...@@ -19,6 +20,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -35,14 +37,14 @@ public class LogQueueRuntime { ...@@ -35,14 +37,14 @@ public class LogQueueRuntime {
private static IExecutionRecordService EXECUTION_RECORD_SERVICE; private static IExecutionRecordService EXECUTION_RECORD_SERVICE;
public static IExecutionRecordService getExecutionRecordService(){ public static IExecutionRecordService getExecutionRecordService() {
if (EXECUTION_RECORD_SERVICE==null){ if (EXECUTION_RECORD_SERVICE == null) {
EXECUTION_RECORD_SERVICE = SpringUtils.getBean("executionRecordImpl"); EXECUTION_RECORD_SERVICE = SpringUtils.getBean("executionRecordImpl");
} }
return EXECUTION_RECORD_SERVICE; return EXECUTION_RECORD_SERVICE;
} }
public static ExecutionRecord addExecutionRecord(TestExecuteLog testExecuteLog,String log){ public static ExecutionRecord addExecutionRecord(TestExecuteLog testExecuteLog, String log) {
return getExecutionRecordService().addExecutionRecord(testExecuteLog, log); return getExecutionRecordService().addExecutionRecord(testExecuteLog, log);
} }
...@@ -54,12 +56,12 @@ public class LogQueueRuntime { ...@@ -54,12 +56,12 @@ public class LogQueueRuntime {
LOG_MAP.put(threadId, testExecuteLog); LOG_MAP.put(threadId, testExecuteLog);
} }
public static void setTestData(Long dataId){ public static void setTestData(Long dataId) {
Long currentThreadId = ThreadUtil.currentThreadId(); Long currentThreadId = ThreadUtil.currentThreadId();
LOG_MAP.get(currentThreadId).setTestDataId(dataId); LOG_MAP.get(currentThreadId).setTestDataId(dataId);
} }
public static void clearTestData(){ public static void clearTestData() {
Long currentThreadId = ThreadUtil.currentThreadId(); Long currentThreadId = ThreadUtil.currentThreadId();
LOG_MAP.get(currentThreadId).setTestDataId(-1L); LOG_MAP.get(currentThreadId).setTestDataId(-1L);
} }
...@@ -70,12 +72,12 @@ public class LogQueueRuntime { ...@@ -70,12 +72,12 @@ public class LogQueueRuntime {
classLog.info(logMsg.toLogString()); classLog.info(logMsg.toLogString());
Long currentThreadId = ThreadUtil.currentThreadId(); Long currentThreadId = ThreadUtil.currentThreadId();
TestExecuteLog testExecuteLog = LOG_MAP.get(currentThreadId); TestExecuteLog testExecuteLog = LOG_MAP.get(currentThreadId);
if (testExecuteLog !=null){ if (testExecuteLog != null) {
testExecuteLog.addLog(logMsg); testExecuteLog.addLog(logMsg);
String messageToDb = JSONObject.toJSONString(logMsg); String messageToDb = JSONObject.toJSONString(logMsg);
ExecutionRecord executionRecord = addExecutionRecord(testExecuteLog, messageToDb); ExecutionRecord executionRecord = addExecutionRecord(testExecuteLog, messageToDb);
sendMessage(currentThreadId,testExecuteLog.getUniqueKey(),executionRecord.getId(),messageToDb); sendMessage(currentThreadId, testExecuteLog.getUniqueKey(), executionRecord.getId(), messageToDb);
}else { } else {
throw new GlobalException("该线程中的TestCaseLog对象未初始化,请先调用put方法初始化对象"); throw new GlobalException("该线程中的TestCaseLog对象未初始化,请先调用put方法初始化对象");
} }
} }
...@@ -84,39 +86,43 @@ public class LogQueueRuntime { ...@@ -84,39 +86,43 @@ public class LogQueueRuntime {
LOG_MAP.remove(threadId); LOG_MAP.remove(threadId);
} }
public static void sendMessage(Long threadId,String uniqueKey,Long logId, String log) { public static void sendMessage(Long threadId, String uniqueKey, Long logId, String log) {
try {
TestExecuteLog testExecuteLog = LOG_MAP.get(threadId); TestExecuteLog testExecuteLog = LOG_MAP.get(threadId);
// 测试任务ID.测试用例ID.测试数据ID // 测试任务ID.测试用例ID.测试数据ID
String message = JSONObject.toJSONString(log); String message = JSONObject.toJSONString(log);
String logMessage = String logMessage =
String.format( String.format(
"%s.%s.%s.%s.%s" "%s.%s.%s.%s.%s"
,testExecuteLog.getTestJobId() , testExecuteLog.getTestJobId()
,testExecuteLog.getTestCaseId() , testExecuteLog.getTestCaseId()
,testExecuteLog.getTestDataId() , testExecuteLog.getTestDataId()
,logId , logId
,message , message
); );
//如果uniqueKey中存在监听的socket则向该socket发送消息 //如果uniqueKey中存在监听的socket则向该socket发送消息
List<WebSocketSession> webSocketSessions = ExecutionSocketHandler.EXECUTE_MONITOR_SOCKET_POOL.get(uniqueKey); List<WebSocketSession> webSocketSessions = ExecutionSocketHandler.EXECUTE_MONITOR_SOCKET_POOL.get(uniqueKey);
if (webSocketSessions!=null){ if (webSocketSessions != null) {
for (WebSocketSession webSocketSession : webSocketSessions) { for (WebSocketSession webSocketSession : webSocketSessions) {
webSocketSession.sendMessage(new TextMessage( socketSendMessage(webSocketSession, logMessage);
logMessage
));
} }
} }
//如果线程中存在socket则向该socket发送消息 //如果线程中存在socket则向该socket发送消息
WebSocketSession webSocketSession = TestCaseExecuteSocketPool.get(threadId); WebSocketSession webSocketSession = TestCaseExecuteSocketPool.get(threadId);
if (webSocketSession != null) { if (webSocketSession != null) {
webSocketSession.sendMessage(new TextMessage( socketSendMessage(webSocketSession, logMessage);
logMessage }
}
private static void socketSendMessage(WebSocketSession socketSession, String message) {
try {
if (socketSession != null && socketSession.isOpen()) {
socketSession.sendMessage(new TextMessage(
message
)); ));
} }
} catch (Exception e) { } catch (IOException e) {
LogFactory.get().log(Level.INFO,"发送socket消息失败,socket已经断开连接"); LogFactory.get().log(Level.INFO, "发送socket消息失败,socket已经断开连接");
remove(threadId);
} }
} }
...@@ -127,22 +133,35 @@ public class LogQueueRuntime { ...@@ -127,22 +133,35 @@ public class LogQueueRuntime {
testExecuteLog.setUserId(userId); testExecuteLog.setUserId(userId);
testExecuteLog.setType(type); testExecuteLog.setType(type);
testExecuteLog.setUniqueKey(uniqueKey); testExecuteLog.setUniqueKey(uniqueKey);
if (checkIsInRun(testExecuteLog)){ if (checkIsInRun(testExecuteLog)) {
throw new GlobalException("当前用例正在执行中"); throw new ExecutionRunningException("当前 任务/用例 正在执行中");
} }
LogQueueRuntime.put(ThreadUtil.currentThreadId(), testExecuteLog); LogQueueRuntime.put(ThreadUtil.currentThreadId(), testExecuteLog);
} }
public static Boolean checkIsInRun(TestExecuteLog testExecuteLog){ public static Boolean checkJobIsInRun(Long jobId, Long userId, TestExecuteType type) {
TestExecuteLog testExecuteLog = new TestExecuteLog();
testExecuteLog.setTestJobId(jobId);
testExecuteLog.setUserId(userId);
testExecuteLog.setType(type);
for (TestExecuteLog value : LOG_MAP.values()) {
if (value.equals(testExecuteLog)) {
return true;
}
}
return false;
}
public static Boolean checkIsInRun(TestExecuteLog testExecuteLog) {
for (TestExecuteLog value : LOG_MAP.values()) { for (TestExecuteLog value : LOG_MAP.values()) {
if (value.equals(testExecuteLog)){ if (value.equals(testExecuteLog)) {
return true; return true;
} }
} }
return false; return false;
} }
public static TestExecuteLog getCurrentTestExecute(Long threadId){ public static TestExecuteLog getCurrentTestExecute(Long threadId) {
return LOG_MAP.get(threadId); return LOG_MAP.get(threadId);
} }
......
...@@ -10,6 +10,7 @@ import java.util.Objects; ...@@ -10,6 +10,7 @@ import java.util.Objects;
/** /**
* 用例日志临时存储对象 * 用例日志临时存储对象
*
* @author huangxiahao * @author huangxiahao
*/ */
@Data @Data
...@@ -24,7 +25,7 @@ public class TestExecuteLog { ...@@ -24,7 +25,7 @@ public class TestExecuteLog {
private TestExecuteType type = TestExecuteType.TEST_CASE; private TestExecuteType type = TestExecuteType.TEST_CASE;
private Long userId = -1L ; private Long userId = -1L;
private Long testCaseId = -1L; private Long testCaseId = -1L;
...@@ -36,9 +37,10 @@ public class TestExecuteLog { ...@@ -36,9 +37,10 @@ public class TestExecuteLog {
/** /**
* 前置条件:每个用例下的数据组是单线程执行的 * 前置条件:每个用例下的数据组是单线程执行的
* 由于arrayList是有序的,所以只需要向下新增就好了 * 由于arrayList是有序的,所以只需要向下新增就好了
*
* @param logMsg * @param logMsg
*/ */
public void addLog(LogMessage logMsg){ public void addLog(LogMessage logMsg) {
this.log.add(logMsg); this.log.add(logMsg);
} }
...@@ -51,7 +53,11 @@ public class TestExecuteLog { ...@@ -51,7 +53,11 @@ public class TestExecuteLog {
return false; return false;
} }
TestExecuteLog that = (TestExecuteLog) o; TestExecuteLog that = (TestExecuteLog) o;
if (this.testJobId==-1L){
return getType() == that.getType() && Objects.equals(getUserId(), that.getUserId()) && Objects.equals(getTestCaseId(), that.getTestCaseId()); return getType() == that.getType() && Objects.equals(getUserId(), that.getUserId()) && Objects.equals(getTestCaseId(), that.getTestCaseId());
}else {
return getType() == that.getType() && Objects.equals(getUserId(), that.getUserId()) && Objects.equals(getTestJobId(), that.getTestJobId());
}
} }
@Override @Override
......
...@@ -40,12 +40,12 @@ public class GenerateReporterJob { ...@@ -40,12 +40,12 @@ public class GenerateReporterJob {
Map context = new HashMap(); Map context = new HashMap();
ReporterDataJob reporterDatajob = new ReporterDataJob(); ReporterDataJob reporterDatajob = new ReporterDataJob();
DataBean dataBean = reporterDatajob.testDataBean(); DataBean dataBean = reporterDatajob.testDataBean();
List<DataMove> dataMoves = reporterDatajob.testDataBeanMove(); // List<DataMove> dataMoves = reporterDatajob.testDataBeanMove();
List<DataBeans> dataBeansList = reporterDatajob.testDataBeans(); List<DataBeans> dataBeansList = reporterDatajob.testDataBeans();
// 这里是公共的信息. // 这里是公共的信息.
for (DataBeans bean : dataBeansList) { for (DataBeans bean : dataBeansList) {
context.put("overView", dataBean); context.put("overView", dataBean);
context.put("move", dataMoves); // context.put("move", dataMoves);
if (bean.getResult()) { if (bean.getResult()) {
context.put("pass", dataBeansList); context.put("pass", dataBeansList);
} else { } else {
......
...@@ -22,35 +22,35 @@ public class ReporterData { ...@@ -22,35 +22,35 @@ public class ReporterData {
*/ */
public DataBean testDataBean() { public DataBean testDataBean() {
DataBeansVo dataBeansVo = ReporterUtils.map.get("dataBeansVo"); DataBeansVo dataBeansVo = ReporterUtils.map.get("dataBeansVo");
int passNum = 0; // int passNum = 0;
int failNum = 0; // int failNum = 0;
Long oneTime = 0L; // Long oneTime = 0L;
// 测试结果汇总数据 // 测试结果汇总数据
DataBean dataBean = dataBeansVo.getDataBean(); DataBean dataBean = dataBeansVo.getDataBean();
List<DataBeans> dataBeanLists = dataBeansVo.getDataBeanLists(); // List<DataBeans> dataBeanLists = dataBeansVo.getDataBeanLists();
for (DataBeans dataBeanList : dataBeanLists) { // for (DataBeans dataBeanList : dataBeanLists) {
Long duration = dataBeanList.getDuration(); // Long duration = dataBeanList.getDuration();
oneTime = oneTime + duration; // oneTime = oneTime + duration;
if (dataBeanList.getResult()) { // if (dataBeanList.getResult()) {
passNum += 1; // passNum += 1;
} else { // } else {
failNum += 1; // failNum += 1;
} // }
} // }
//成功 // //成功
dataBean.setPassNum(passNum); // dataBean.setPassNum(passNum);
//失败 // //失败
dataBean.setFailNum(failNum); // dataBean.setFailNum(failNum);
//总数 // //总数
dataBean.setTotal(passNum + failNum); // dataBean.setTotal(passNum + failNum);
//通过率 // //通过率
dataBean.setProbability(passNum / (passNum + failNum)); // dataBean.setProbability(passNum / (passNum + failNum));
Duration duration = SecToTime.secToTime(oneTime); // Duration duration = SecToTime.secToTime(oneTime);
Integer hour = duration.getHour(); // Integer hour = duration.getHour();
Integer minute = duration.getMinute(); // Integer minute = duration.getMinute();
Integer second = duration.getSecond(); // Integer second = duration.getSecond();
String allTime = hour + "." + minute + "." + second; // String allTime = hour + "." + minute + "." + second;
dataBean.setAllTime(allTime); // dataBean.setAllTime(allTime);
return dataBean; return dataBean;
} }
......
...@@ -23,38 +23,38 @@ public class ReporterDataJob { ...@@ -23,38 +23,38 @@ public class ReporterDataJob {
*/ */
public DataBean testDataBean() { public DataBean testDataBean() {
DataBeansJobVo dataBeansJobVo = ReporterUtils.jobMap.get("job"); DataBeansJobVo dataBeansJobVo = ReporterUtils.jobMap.get("job");
int passNum = 0; // int passNum = 0;
int failNum = 0; // int failNum = 0;
Long oneTime = 0L; // Long oneTime = 0L;
// 测试结果汇总数据 // 测试结果汇总数据
DataBean dataBean = dataBeansJobVo.getDataBean(); DataBean dataBean = dataBeansJobVo.getDataBean();
List<DataBeansMoveVo> dataBeansMoveVos = dataBeansJobVo.getDataBeansMove(); // List<DataBeansMoveVo> dataBeansMoveVos = dataBeansJobVo.getDataBeansMove();
for (DataBeansMoveVo dataBeansMoveVo : dataBeansMoveVos) { // for (DataBeansMoveVo dataBeansMoveVo : dataBeansMoveVos) {
List<DataBeans> dataBeansList = dataBeansMoveVo.getDataBeansList(); // List<DataBeans> dataBeansList = dataBeansMoveVo.getDataBeansList();
for (DataBeans dataBeans : dataBeansList) { // for (DataBeans dataBeans : dataBeansList) {
Long duration = dataBeans.getDuration(); // Long duration = dataBeans.getDuration();
oneTime = oneTime + duration; // oneTime = oneTime + duration;
if (dataBeans.getResult()) { // if (dataBeans.getResult()) {
passNum += 1; // passNum += 1;
} else { // } else {
failNum += 1; // failNum += 1;
} // }
} // }
} // }
//成功 // //成功
dataBean.setPassNum(passNum); // dataBean.setPassNum(passNum);
//失败 // //失败
dataBean.setFailNum(failNum); // dataBean.setFailNum(failNum);
//总数 // //总数
dataBean.setTotal(passNum + failNum); // dataBean.setTotal(passNum + failNum);
//通过率 // //通过率
dataBean.setProbability(passNum / (passNum + failNum)); // dataBean.setProbability(passNum / (passNum + failNum));
Duration duration = SecToTime.secToTime(oneTime); // Duration duration = SecToTime.secToTime(oneTime);
Integer hour = duration.getHour(); // Integer hour = duration.getHour();
Integer minute = duration.getMinute(); // Integer minute = duration.getMinute();
Integer second = duration.getSecond(); // Integer second = duration.getSecond();
String allTime = hour + "." + minute + "." + second; // String allTime = hour + "." + minute + "." + second;
dataBean.setAllTime(allTime); // dataBean.setAllTime(allTime);
return dataBean; return dataBean;
} }
...@@ -63,11 +63,11 @@ public class ReporterDataJob { ...@@ -63,11 +63,11 @@ public class ReporterDataJob {
*/ */
public List<DataMove> testDataBeanMove() { public List<DataMove> testDataBeanMove() {
List<DataMove> dataMoveList = new ArrayList<>(); List<DataMove> dataMoveList = new ArrayList<>();
List<DataBeansMoveVo> dataBeansMoveVos = ReporterUtils.jobMap.get("job").getDataBeansMove(); // List<DataBeansMoveVo> dataBeansMoveVos = ReporterUtils.jobMap.get("job").getDataBeansMove();
for (DataBeansMoveVo dataBeansMoveVo : dataBeansMoveVos) { // for (DataBeansMoveVo dataBeansMoveVo : dataBeansMoveVos) {
DataMove dataMove = dataBeansMoveVo.getDataMove(); // DataMove dataMove = dataBeansMoveVo.getDataMove();
dataMoveList.add(dataMove); // dataMoveList.add(dataMove);
} // }
return dataMoveList; return dataMoveList;
} }
......
...@@ -17,6 +17,8 @@ spring: ...@@ -17,6 +17,8 @@ spring:
# username: root # username: root
# password: 123456 # password: 123456
mybatis-plus: mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-enums-package: org.matrix.enums type-enums-package: org.matrix.enums
baseJsPath: syntaxCheck.js baseJsPath: syntaxCheck.js
......
package org.matrix.fs.controller; package org.matrix.fs.controller;
import javafx.scene.control.Alert;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.UrlResource; import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
......
...@@ -20,8 +20,8 @@ spring: ...@@ -20,8 +20,8 @@ spring:
password: 123456 password: 123456
mybatis-plus: mybatis-plus:
# configuration: configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-enums-package: org.matrix.enums type-enums-package: org.matrix.enums
baseJsPath: syntaxCheck.js baseJsPath: syntaxCheck.js
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论