diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/listener/MessageListener.java b/backend/services/api-test/src/main/java/io/metersphere/api/listener/MessageListener.java index 5eb9fcdc0b..6ed6933ef2 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/listener/MessageListener.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/listener/MessageListener.java @@ -110,15 +110,9 @@ public class MessageListener { */ private boolean isStopOnFailure(ApiNoticeDTO dto, ExecutionQueue queue, ApiExecuteResourceType resourceType) { if (BooleanUtils.isTrue(queue.getRunModeConfig().getStopOnFailure()) && StringUtils.equals(dto.getReportStatus(), ApiReportStatus.ERROR.name())) { - String reportId = queue.getRunModeConfig().isIntegratedReport() ? queue.getRunModeConfig().getCollectionReport().getReportId() : dto.getReportId(); - if (resourceType.equals(ApiExecuteResourceType.API_SCENARIO)) { - apiScenarioBatchRunService.updateStopOnFailureReport(queue); - } else { - apiScenarioBatchRunService.updateStopOnFailureApiReport(queue); - } switch (resourceType) { - case API_CASE -> apiReportService.updateReportStatus(reportId, ApiReportStatus.ERROR.name()); - case API_SCENARIO -> apiScenarioReportService.updateReportStatus(reportId, ApiReportStatus.ERROR.name()); + case API_CASE -> apiTestCaseBatchRunService.updateStopOnFailureApiReport(queue); + case API_SCENARIO -> apiScenarioBatchRunService.updateStopOnFailureReport(queue); default -> { } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiBatchRunBaseService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiBatchRunBaseService.java index 1c38101ba1..9d04034e54 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiBatchRunBaseService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiBatchRunBaseService.java @@ -1,9 +1,11 @@ package io.metersphere.api.service; +import io.metersphere.api.domain.ApiScenarioReport; import io.metersphere.api.service.queue.ApiExecutionQueueService; import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO; import io.metersphere.sdk.dto.queue.ExecutionQueue; import io.metersphere.sdk.dto.queue.ExecutionQueueDetail; +import io.metersphere.sdk.util.LogUtils; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -52,4 +54,42 @@ public class ApiBatchRunBaseService { return queue; } + public ApiScenarioReport computeRequestRate(ApiScenarioReport report , long total) { + // 计算各个概率 + double successRate = calculateRate(report.getSuccessCount(), total); + double errorRate = calculateRate(report.getErrorCount(), total); + double pendingRate = calculateRate(report.getPendingCount(), total); + double fakeErrorRate = calculateRate(report.getFakeErrorCount(), total); + + // 计算总和 + double sum = successRate + errorRate + pendingRate + fakeErrorRate; + + LogUtils.info("偏移总量重新计算", sum); + + // 避免分母为零 + double adjustment = sum > 0 ? 1.0 / sum : 0.0; + + // 调整概率,使总和精确为100% + successRate *= adjustment; + errorRate *= adjustment; + pendingRate *= adjustment; + fakeErrorRate *= adjustment; + + report.setRequestPassRate(formatRate(successRate)); + report.setRequestErrorRate(formatRate(errorRate)); + report.setRequestPendingRate(formatRate(pendingRate)); + report.setRequestFakeErrorRate(formatRate(fakeErrorRate)); + + return report; + } + + // 计算概率 + private static double calculateRate(long count, double total) { + return total > 0 ? count / total : 0.0; + } + + // 格式化概率,保留两位小数 + private static String formatRate(double rate) { + return String.format("%.2f", rate * 100); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseBatchRunService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseBatchRunService.java index 7ffe6d5b95..425c539b5a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseBatchRunService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseBatchRunService.java @@ -5,10 +5,7 @@ import io.metersphere.api.dto.ApiDefinitionExecuteInfo; import io.metersphere.api.dto.ApiParamConfig; import io.metersphere.api.dto.debug.ApiResourceRunRequest; import io.metersphere.api.dto.definition.ApiTestCaseBatchRunRequest; -import io.metersphere.api.mapper.ApiDefinitionMapper; -import io.metersphere.api.mapper.ApiTestCaseBlobMapper; -import io.metersphere.api.mapper.ApiTestCaseMapper; -import io.metersphere.api.mapper.ExtApiTestCaseMapper; +import io.metersphere.api.mapper.*; import io.metersphere.api.service.ApiBatchRunBaseService; import io.metersphere.api.service.ApiCommonService; import io.metersphere.api.service.ApiExecuteService; @@ -69,6 +66,12 @@ public class ApiTestCaseBatchRunService { private ApiCommonService apiCommonService; @Resource private ApiDefinitionMapper apiDefinitionMapper; + @Resource + private ApiReportMapper apiReportMapper; + @Resource + private ApiReportDetailMapper apiReportDetailMapper; + @Resource + private ApiReportStepMapper apiReportStepMapper; /** * 异步批量执行 @@ -412,4 +415,26 @@ public class ApiTestCaseBatchRunService { public String getEnvId(ApiRunModeConfigDTO runModeConfig, ApiTestCase apiTestCase) { return StringUtils.isBlank(runModeConfig.getEnvironmentId()) ? apiTestCase.getEnvironmentId() : runModeConfig.getEnvironmentId(); } + + public void updateStopOnFailureApiReport(ExecutionQueue queue) { + ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig(); + if (runModeConfig.isIntegratedReport()) { + // 获取未执行的请求数,更新统计指标 + String reportId = runModeConfig.getCollectionReport().getReportId(); + ApiReport report = apiReportMapper.selectByPrimaryKey(reportId); + ApiReportDetailExample example = new ApiReportDetailExample(); + example.createCriteria().andReportIdEqualTo(reportId); + ApiReportStepExample stepExample = new ApiReportStepExample(); + stepExample.createCriteria().andReportIdEqualTo(reportId); + long total = apiReportStepMapper.countByExample(stepExample); + long pendCount = total - apiReportDetailMapper.countByExample(example); + report.setPendingCount(pendCount); + ApiScenarioReport apiScenarioReport = new ApiScenarioReport(); + BeanUtils.copyBean(apiScenarioReport, report); + apiScenarioReport = apiBatchRunBaseService.computeRequestRate(apiScenarioReport, total); + BeanUtils.copyBean(report, apiScenarioReport); + report.setStatus(ApiReportStatus.ERROR.name()); + apiReportMapper.updateByPrimaryKeySelective(report); + } + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioBatchRunService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioBatchRunService.java index 9362574e63..8aefc60a7e 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioBatchRunService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioBatchRunService.java @@ -60,12 +60,6 @@ public class ApiScenarioBatchRunService { private ApiBatchRunBaseService apiBatchRunBaseService; @Resource private ExtApiScenarioMapper extApiScenarioMapper; - @Resource - private ApiReportMapper apiReportMapper; - @Resource - private ApiReportDetailMapper apiReportDetailMapper; - @Resource - private ApiReportStepMapper apiReportStepMapper; /** * 异步批量执行 @@ -455,72 +449,12 @@ public class ApiScenarioBatchRunService { report.setPendingCount(pendingCount); // 计算各种通过率 long total = apiScenarioReportService.getRequestTotal(report); - report = computeRequestRate(report, total); + report = apiBatchRunBaseService.computeRequestRate(report, total); + report.setStatus(ApiReportStatus.ERROR.name()); apiScenarioReportMapper.updateByPrimaryKeySelective(report); } } catch (Exception e) { LogUtils.error("失败停止,补充报告步骤失败:", e); } } - public void updateStopOnFailureApiReport(ExecutionQueue queue) { - ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig(); - if (runModeConfig.isIntegratedReport()) { - // 获取未执行的请求数,更新统计指标 - String reportId = runModeConfig.getCollectionReport().getReportId(); - ApiReport report = apiReportMapper.selectByPrimaryKey(reportId); - ApiReportDetailExample example = new ApiReportDetailExample(); - example.createCriteria().andReportIdEqualTo(reportId); - ApiReportStepExample stepExample = new ApiReportStepExample(); - stepExample.createCriteria().andReportIdEqualTo(reportId); - long total = apiReportStepMapper.countByExample(stepExample); - long pendCount = total - apiReportDetailMapper.countByExample(example); - report.setPendingCount(pendCount); - ApiScenarioReport apiScenarioReport = new ApiScenarioReport(); - BeanUtils.copyBean(apiScenarioReport, report); - apiScenarioReport = computeRequestRate(apiScenarioReport, total); - BeanUtils.copyBean(report, apiScenarioReport); - apiReportMapper.updateByPrimaryKeySelective(report); - } - - } - - public ApiScenarioReport computeRequestRate(ApiScenarioReport report , long total) { - // 计算各个概率 - double successRate = calculateRate(report.getSuccessCount(), total); - double errorRate = calculateRate(report.getErrorCount(), total); - double pendingRate = calculateRate(report.getPendingCount(), total); - double fakeErrorRate = calculateRate(report.getFakeErrorCount(), total); - - // 计算总和 - double sum = successRate + errorRate + pendingRate + fakeErrorRate; - - LogUtils.info("偏移总量重新计算", sum); - - // 避免分母为零 - double adjustment = sum > 0 ? 1.0 / sum : 0.0; - - // 调整概率,使总和精确为100% - successRate *= adjustment; - errorRate *= adjustment; - pendingRate *= adjustment; - fakeErrorRate *= adjustment; - - report.setRequestPassRate(formatRate(successRate)); - report.setRequestErrorRate(formatRate(errorRate)); - report.setRequestPendingRate(formatRate(pendingRate)); - report.setRequestFakeErrorRate(formatRate(fakeErrorRate)); - - return report; - } - - // 计算概率 - private static double calculateRate(long count, double total) { - return total > 0 ? count / total : 0.0; - } - - // 格式化概率,保留两位小数 - private static String formatRate(double rate) { - return String.format("%.2f", rate * 100); - } - }