|
@@ -5,7 +5,6 @@ import cn.seecoder.common.util.OpType;
|
|
|
import cn.seecoder.web.dao.apitest.ApiTestMapper;
|
|
import cn.seecoder.web.dao.apitest.ApiTestMapper;
|
|
|
import cn.seecoder.web.dao.pipeline.PipelineMapper;
|
|
import cn.seecoder.web.dao.pipeline.PipelineMapper;
|
|
|
import cn.seecoder.web.dao.pipeline.PipelineRecordMapper;
|
|
import cn.seecoder.web.dao.pipeline.PipelineRecordMapper;
|
|
|
-import cn.seecoder.web.dao.user.UserMapper;
|
|
|
|
|
import cn.seecoder.web.model.po.apitest.ApiTestInfo;
|
|
import cn.seecoder.web.model.po.apitest.ApiTestInfo;
|
|
|
import cn.seecoder.web.model.po.apitest.ApiTestResult;
|
|
import cn.seecoder.web.model.po.apitest.ApiTestResult;
|
|
|
import cn.seecoder.web.model.po.apitest.TestInfo;
|
|
import cn.seecoder.web.model.po.apitest.TestInfo;
|
|
@@ -42,6 +41,7 @@ import java.util.HashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.CountDownLatch;
|
|
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
@@ -54,15 +54,12 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
|
|
|
|
|
private final PipelineRecordMapper pipelineRecordMapper;
|
|
private final PipelineRecordMapper pipelineRecordMapper;
|
|
|
|
|
|
|
|
- private final UserMapper userMapper;
|
|
|
|
|
-
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
public ApiTestServiceImpl(ApiTestMapper apiTestMapper, PipelineMapper pipelineMapper,
|
|
public ApiTestServiceImpl(ApiTestMapper apiTestMapper, PipelineMapper pipelineMapper,
|
|
|
- PipelineRecordMapper pipelineRecordMapper, UserMapper userMapper) {
|
|
|
|
|
|
|
+ PipelineRecordMapper pipelineRecordMapper) {
|
|
|
this.apiTestMapper = apiTestMapper;
|
|
this.apiTestMapper = apiTestMapper;
|
|
|
this.pipelineMapper = pipelineMapper;
|
|
this.pipelineMapper = pipelineMapper;
|
|
|
this.pipelineRecordMapper = pipelineRecordMapper;
|
|
this.pipelineRecordMapper = pipelineRecordMapper;
|
|
|
- this.userMapper = userMapper;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -101,6 +98,10 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
@Override
|
|
@Override
|
|
|
public void executeApiTest(Integer testId) throws InterruptedException {
|
|
public void executeApiTest(Integer testId) throws InterruptedException {
|
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
|
|
|
+ if (testInfo == null) {
|
|
|
|
|
+ log.warn("API test not found, testId={}", testId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
String url = testInfo.getUrl();
|
|
String url = testInfo.getUrl();
|
|
|
Map<String, Object> params = parseJson2Map(testInfo.getParams());
|
|
Map<String, Object> params = parseJson2Map(testInfo.getParams());
|
|
|
int qps = testInfo.getQps();
|
|
int qps = testInfo.getQps();
|
|
@@ -108,10 +109,12 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
Integer projectId = testInfo.getProjectId();
|
|
Integer projectId = testInfo.getProjectId();
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
- if (method.equals("GET")) { // GET方法
|
|
|
|
|
|
|
+ if ("GET".equals(method)) { // GET方法
|
|
|
handleRequest(url, params, qps, testId, "GET", projectId);
|
|
handleRequest(url, params, qps, testId, "GET", projectId);
|
|
|
- } else if (method.equals("POST")) { // POST方法
|
|
|
|
|
|
|
+ } else if ("POST".equals(method)) { // POST方法
|
|
|
handleRequest(url, params, qps, testId, "POST", projectId);
|
|
handleRequest(url, params, qps, testId, "POST", projectId);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.warn("Unsupported API test method, testId={}, method={}", testId, method);
|
|
|
}
|
|
}
|
|
|
// ANA 日志需要打出测试信息和执行结果,具体信息在handleRequest方法内
|
|
// ANA 日志需要打出测试信息和执行结果,具体信息在handleRequest方法内
|
|
|
|
|
|
|
@@ -121,6 +124,10 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
public List<ApiTestResultVO> getApiTestResultByTestId(Integer testId) {
|
|
public List<ApiTestResultVO> getApiTestResultByTestId(Integer testId) {
|
|
|
|
|
|
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
|
|
|
+ if (testInfo == null) {
|
|
|
|
|
+ log.warn("API test not found, testId={}", testId);
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 获取最新的部署构建信息id
|
|
// 获取最新的部署构建信息id
|
|
|
List<Integer> pipelineIds = pipelineMapper.selectByProjectId(testInfo.getProjectId()).stream().map(PipelinePO::getId).collect(Collectors.toList());
|
|
List<Integer> pipelineIds = pipelineMapper.selectByProjectId(testInfo.getProjectId()).stream().map(PipelinePO::getId).collect(Collectors.toList());
|
|
@@ -142,6 +149,10 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
@Override
|
|
@Override
|
|
|
public ApiTestResultVO getLatestTestResultByTestId(Integer testId) {
|
|
public ApiTestResultVO getLatestTestResultByTestId(Integer testId) {
|
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
TestInfo testInfo = apiTestMapper.selectByTestId(testId);
|
|
|
|
|
+ if (testInfo == null) {
|
|
|
|
|
+ log.warn("API test not found, testId={}", testId);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
List<Integer> pipelineIds = pipelineMapper.selectByProjectId(testInfo.getProjectId()).stream().map(PipelinePO::getId).collect(Collectors.toList());
|
|
List<Integer> pipelineIds = pipelineMapper.selectByProjectId(testInfo.getProjectId()).stream().map(PipelinePO::getId).collect(Collectors.toList());
|
|
|
PipelineRecordPO latestRecord;
|
|
PipelineRecordPO latestRecord;
|
|
@@ -211,7 +222,7 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
// 分隔字符串
|
|
// 分隔字符串
|
|
|
public List<Integer> splitTimeList(String time) {
|
|
public List<Integer> splitTimeList(String time) {
|
|
|
List<Integer> timeList = new ArrayList<>();
|
|
List<Integer> timeList = new ArrayList<>();
|
|
|
- if (time.length() == 0) {
|
|
|
|
|
|
|
+ if (time.isEmpty()) {
|
|
|
return timeList;
|
|
return timeList;
|
|
|
}
|
|
}
|
|
|
String[] tl = time.split(",");
|
|
String[] tl = time.split(",");
|
|
@@ -223,15 +234,20 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
|
|
|
|
|
// 处理请求
|
|
// 处理请求
|
|
|
public void handleRequest(String url, Map<String, Object> params, int qps, int testId, String method, Integer projectId) throws InterruptedException {
|
|
public void handleRequest(String url, Map<String, Object> params, int qps, int testId, String method, Integer projectId) throws InterruptedException {
|
|
|
- ArrayList<Integer> timeList = new ArrayList<>();
|
|
|
|
|
- final int[] success = {0};
|
|
|
|
|
- final int[] failure = {0};
|
|
|
|
|
|
|
+ if (qps <= 0) {
|
|
|
|
|
+ log.warn("Invalid API test qps, testId={}, qps={}", testId, qps);
|
|
|
|
|
+ qps = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<Integer> timeList = Collections.synchronizedList(new ArrayList<>());
|
|
|
|
|
+ AtomicInteger success = new AtomicInteger();
|
|
|
|
|
+ AtomicInteger failure = new AtomicInteger();
|
|
|
|
|
+ AtomicInteger remainingRequests = new AtomicInteger(qps);
|
|
|
Runnable task = () -> {
|
|
Runnable task = () -> {
|
|
|
- for (int i = 0; i < qps / 10; i++) {
|
|
|
|
|
|
|
+ while (remainingRequests.getAndDecrement() > 0) {
|
|
|
int[] arr = new int[2];
|
|
int[] arr = new int[2];
|
|
|
- if (method.equals("GET")) {
|
|
|
|
|
|
|
+ if ("GET".equals(method)) {
|
|
|
arr = doGet(url, params);
|
|
arr = doGet(url, params);
|
|
|
- } else if (method.equals("POST")) {
|
|
|
|
|
|
|
+ } else if ("POST".equals(method)) {
|
|
|
try {
|
|
try {
|
|
|
arr = doPost(url, params);
|
|
arr = doPost(url, params);
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
@@ -239,8 +255,8 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
timeList.add(arr[1]);
|
|
timeList.add(arr[1]);
|
|
|
- if (arr[0] == 1) success[0]++;
|
|
|
|
|
- else failure[0]++;
|
|
|
|
|
|
|
+ if (arr[0] == 1) success.incrementAndGet();
|
|
|
|
|
+ else failure.incrementAndGet();
|
|
|
try {
|
|
try {
|
|
|
Thread.sleep(100);
|
|
Thread.sleep(100);
|
|
|
} catch (InterruptedException e) {
|
|
} catch (InterruptedException e) {
|
|
@@ -250,12 +266,13 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
startTaskAllInOnce(10, task);
|
|
startTaskAllInOnce(10, task);
|
|
|
- Integer max_time = Collections.max(timeList);
|
|
|
|
|
- Integer min_time = Collections.min(timeList);
|
|
|
|
|
- Integer sum_time = 0;
|
|
|
|
|
|
|
+ Integer max_time = timeList.isEmpty() ? 0 : Collections.max(timeList);
|
|
|
|
|
+ Integer min_time = timeList.isEmpty() ? 0 : Collections.min(timeList);
|
|
|
|
|
+ int sum_time = 0;
|
|
|
for (Integer time : timeList) {
|
|
for (Integer time : timeList) {
|
|
|
sum_time += time;
|
|
sum_time += time;
|
|
|
}
|
|
}
|
|
|
|
|
+ double averageTime = timeList.isEmpty() ? 0.0 : (double) sum_time / timeList.size();
|
|
|
DecimalFormat df = new DecimalFormat("#.00");
|
|
DecimalFormat df = new DecimalFormat("#.00");
|
|
|
StringBuilder tl = new StringBuilder();
|
|
StringBuilder tl = new StringBuilder();
|
|
|
for (int j = 0; j < timeList.size(); j++) {
|
|
for (int j = 0; j < timeList.size(); j++) {
|
|
@@ -278,12 +295,12 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
TestResult testResult = TestResult.builder()
|
|
TestResult testResult = TestResult.builder()
|
|
|
.testId(testId)
|
|
.testId(testId)
|
|
|
.executeTime(executeTime)
|
|
.executeTime(executeTime)
|
|
|
- .success(success[0])
|
|
|
|
|
- .failure(failure[0])
|
|
|
|
|
|
|
+ .success(success.get())
|
|
|
|
|
+ .failure(failure.get())
|
|
|
.timeList(tl.toString())
|
|
.timeList(tl.toString())
|
|
|
.maxTime(max_time)
|
|
.maxTime(max_time)
|
|
|
.minTime(min_time)
|
|
.minTime(min_time)
|
|
|
- .averageTime((Double.valueOf(df.format(sum_time / qps))))
|
|
|
|
|
|
|
+ .averageTime(Double.valueOf(df.format(averageTime)))
|
|
|
.pipelineRecordId(latestRecord == null ? -1 : latestRecord.getId())
|
|
.pipelineRecordId(latestRecord == null ? -1 : latestRecord.getId())
|
|
|
.build();
|
|
.build();
|
|
|
apiTestMapper.execute(testResult);
|
|
apiTestMapper.execute(testResult);
|
|
@@ -295,13 +312,14 @@ public class ApiTestServiceImpl implements ApiTestService {
|
|
|
object.put("apiTest_id", testId);
|
|
object.put("apiTest_id", testId);
|
|
|
object.put("project_id", projectId);
|
|
object.put("project_id", projectId);
|
|
|
object.put("user_id", UserService.loginUser().getId());
|
|
object.put("user_id", UserService.loginUser().getId());
|
|
|
- object.put("success", success[0]);
|
|
|
|
|
- object.put("failure", failure[0]);
|
|
|
|
|
|
|
+ object.put("success", success.get());
|
|
|
|
|
+ object.put("failure", failure.get());
|
|
|
|
|
|
|
|
String data = com.alibaba.fastjson.JSONObject.toJSONString(object);
|
|
String data = com.alibaba.fastjson.JSONObject.toJSONString(object);
|
|
|
LogTrackingUtil.log(data, OpType.INTERFACE_TEST);
|
|
LogTrackingUtil.log(data, OpType.INTERFACE_TEST);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
|
|
+ log.warn("Failed to track API test execution, testId={}", testId, e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|