refactor(接口测试): 优化批量执行报告生成逻辑

This commit is contained in:
AgAngle 2024-03-27 21:06:27 +08:00 committed by Craftsman
parent fc7f961274
commit 008f930a98
9 changed files with 159 additions and 78 deletions

View File

@ -19,4 +19,9 @@ public class ExecutionQueueDetail implements Serializable {
* 排序
*/
private Integer sort;
/**
* 当前资源产生的执行报告id
*/
private String reportId;
}

View File

@ -13,6 +13,7 @@ import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
public interface ExtApiScenarioMapper {
@ -55,4 +56,6 @@ public interface ExtApiScenarioMapper {
void updatePos(String id, long pos);
Long getPos(String projectId);
List<ApiScenario> getApiCaseExecuteInfoByIds(List<String> subIds);
}

View File

@ -520,6 +520,14 @@
ORDER BY pos DESC
LIMIT 1;
</select>
<select id="getApiCaseExecuteInfoByIds" resultType="io.metersphere.api.domain.ApiScenario">
select id, name, environment_id, project_id
from api_scenario
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<sql id="report_filters">
<if test="${filter} != null and ${filter}.size() > 0">

View File

@ -463,10 +463,10 @@
</sql>
<sql id="queryVersionCondition">
<if test="request.versionId != null">
<if test="request.versionId != null and request.versionId != ''">
and ${versionTable}.version_id = #{request.versionId}
</if>
<if test="request.versionId == null and request.apiDefinitionId == null">
<if test="request.versionId == null and request.versionId != '' and request.apiDefinitionId == null and request.apiDefinitionId == ''">
AND a.latest = 1
</if>
</sql>

View File

@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
@ -25,7 +26,7 @@ public class ApiBatchRunBaseService {
* @param runModeConfig
* @return
*/
public ExecutionQueue initExecutionqueue(List<String> resourceIds, ApiRunModeConfigDTO runModeConfig, String resourceType, String userId) {
public ExecutionQueue initExecutionqueue(List<String> resourceIds, ApiRunModeConfigDTO runModeConfig, String resourceType, Map<String, String> caseReportMap, String userId) {
ExecutionQueue queue = getExecutionQueue(runModeConfig, resourceType, userId);
List<ExecutionQueueDetail> queueDetails = new ArrayList<>();
AtomicInteger sort = new AtomicInteger(1);
@ -33,6 +34,8 @@ public class ApiBatchRunBaseService {
ExecutionQueueDetail queueDetail = new ExecutionQueueDetail();
queueDetail.setResourceId(resourceId);
queueDetail.setSort(sort.getAndIncrement());
// caseReportMap null 说明是集合报告生成一个虚拟的报告ID
queueDetail.setReportId(caseReportMap == null ? UUID.randomUUID().toString() : caseReportMap.get(resourceId));
queueDetails.add(queueDetail);
}
apiExecutionQueueService.insertQueue(queue, queueDetails);

View File

@ -17,16 +17,14 @@ import io.metersphere.api.service.queue.ApiExecutionSetService;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.service.EnvironmentService;
import io.metersphere.sdk.constants.ApiBatchRunMode;
import io.metersphere.sdk.constants.ApiExecuteResourceType;
import io.metersphere.sdk.constants.ApiExecuteRunMode;
import io.metersphere.sdk.constants.TaskTriggerMode;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
import io.metersphere.sdk.dto.api.task.CollectionReportDTO;
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
import io.metersphere.sdk.dto.queue.ExecutionQueue;
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.DateUtils;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.sdk.util.SubListUtils;
import jakarta.annotation.Resource;
@ -73,6 +71,7 @@ public class ApiTestCaseBatchRunService {
/**
* 异步批量执行
*
* @param request
* @param userId
*/
@ -82,6 +81,7 @@ public class ApiTestCaseBatchRunService {
/**
* 批量执行
*
* @param request
* @param userId
*/
@ -109,10 +109,26 @@ public class ApiTestCaseBatchRunService {
if (runModeConfig.isIntegratedReport()) {
initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
}
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
// 分批查询
SubListUtils.dealForSubList(ids, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
// 初始化报告返回用例和报告的 map
Map<String, String> caseReportMap = initReport(ids, runModeConfig, apiTestCases, apiCaseMap, userId);
// 先初始化集成报告设置好报告ID再初始化执行队列
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_CASE.name(), userId);
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_CASE.name(), caseReportMap, userId);
// 执行第一个任务
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
// 集成报告执行前先设置成 RUNNING
setRunningIntegrateReport(runModeConfig);
executeNextTask(queue, nextDetail);
}
@ -133,36 +149,30 @@ public class ApiTestCaseBatchRunService {
apiExecutionSetService.initSet(apiReport.getId(), ids);
}
AtomicInteger errorCount = new AtomicInteger();
AtomicLong sort = new AtomicLong(1);
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
// 分批处理
// 分批查询
SubListUtils.dealForSubList(ids, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
// 初始化报告返回用例和报告的 map
Map<String, String> caseReportMap = initReport(ids, runModeConfig, apiTestCases, apiCaseMap, userId);
// 集成报告执行前先设置成 RUNNING
setRunningIntegrateReport(runModeConfig);
// 分批查询
SubListUtils.dealForSubList(ids, 100, subIds -> {
List<ApiTestCase> apiTestCases = extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds);
// 获取用例和定义信息的mapkey 为用例IDvalue 为接口定义信息
Map<String, ApiDefinitionExecuteInfo> definitionExecuteInfoMap = apiCommonService.getApiDefinitionExecuteInfoMap(apiTestCaseService::getModuleInfoByIds, subIds);
Map<String, String> caseReportMap = null;
String integratedReportId = null;
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
ApiTestCaseBlobExample example = new ApiTestCaseBlobExample();
example.createCriteria().andIdIn(subIds);
Map<String, ApiTestCaseBlob> apiTestCaseBlobMap = apiTestCaseBlobMapper.selectByExampleWithBLOBs(example).stream()
AtomicInteger errorCount = new AtomicInteger();
Map<String, ApiTestCaseBlob> apiTestCaseBlobMap = apiTestCaseService.getBlobByIds(subIds).stream()
.collect(Collectors.toMap(ApiTestCaseBlob::getId, Function.identity()));
if (runModeConfig.isIntegratedReport()) {
// 获取集成报告ID
integratedReportId = runModeConfig.getCollectionReport().getReportId();
initApiReportSteps(subIds, apiCaseMap, integratedReportId, sort);
} else {
// 初始化非集成报告
List<ApiTestCaseRecord> apiTestCaseRecords = initApiReport(runModeConfig, apiTestCases, userId);
caseReportMap = apiTestCaseRecords.stream()
.collect(Collectors.toMap(ApiTestCaseRecord::getApiTestCaseId, ApiTestCaseRecord::getApiReportId));
}
// 获取用例和定义信息的mapkey 为用例IDvalue 为接口定义信息
Map<String, ApiDefinitionExecuteInfo> definitionExecuteInfoMap = apiTestCaseService.getModuleInfoByIds(subIds).stream()
.collect(Collectors.toMap(ApiDefinitionExecuteInfo::getResourceId, Function.identity()));
// 这里ID顺序和队列的ID顺序保持一致
for (String id : subIds) {
@ -174,7 +184,7 @@ public class ApiTestCaseBatchRunService {
if (apiTestCase == null) {
if (runModeConfig.isIntegratedReport()) {
// 用例不存在则在执行集合中删除
apiExecutionSetService.removeItem(integratedReportId, id);
apiExecutionSetService.removeItem(runModeConfig.getCollectionReport().getReportId(), id);
}
LogUtils.info("当前执行任务的用例已删除 {}", id);
break;
@ -196,6 +206,31 @@ public class ApiTestCaseBatchRunService {
});
}
/**
* 集成报告执行前先设置成 RUNNING
* @param runModeConfig
*/
private void setRunningIntegrateReport(ApiRunModeConfigDTO runModeConfig) {
if (runModeConfig.isIntegratedReport()) {
apiReportService.updateReportStatus(runModeConfig.getCollectionReport().getReportId(), ApiReportStatus.RUNNING.name());
}
}
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, List<ApiTestCase> apiTestCases, Map<String, ApiTestCase> apiCaseMap, String userId) {
// 先初始化所有报告
if (runModeConfig.isIntegratedReport()) {
// 获取集成报告ID
String integratedReportId = runModeConfig.getCollectionReport().getReportId();
initApiReportSteps(ids, apiCaseMap, integratedReportId);
return null;
} else {
// 初始化非集成报告
List<ApiTestCaseRecord> apiTestCaseRecords = initApiReport(runModeConfig, apiTestCases, userId);
return apiTestCaseRecords.stream()
.collect(Collectors.toMap(ApiTestCaseRecord::getApiTestCaseId, ApiTestCaseRecord::getApiReportId));
}
}
/**
* 初始化集成报告的报告步骤
*
@ -203,21 +238,14 @@ public class ApiTestCaseBatchRunService {
* @param apiCaseMap
* @param reportId
*/
private void initApiReportSteps(List<String> ids, Map<String, ApiTestCase> apiCaseMap, String reportId, AtomicLong sort) {
private void initApiReportSteps(List<String> ids, Map<String, ApiTestCase> apiCaseMap, String reportId) {
AtomicLong sort = new AtomicLong(1);
List<ApiReportStep> apiReportSteps = ids.stream()
.map(id -> getApiReportStep(apiCaseMap.get(id), reportId, sort.getAndIncrement()))
.collect(Collectors.toList());
apiReportService.insertApiReportStep(apiReportSteps);
}
/**
* 初始化集成报告的报告步骤
*/
private void initApiReportSteps(ApiTestCase apiTestCase, String reportId, long sort) {
ApiReportStep apiReportStep = getApiReportStep(apiTestCase, reportId, sort);
apiReportService.insertApiReportStep(List.of(apiReportStep));
}
private ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId, long sort) {
ApiReportStep apiReportStep = new ApiReportStep();
apiReportStep.setReportId(reportId);
@ -246,7 +274,7 @@ public class ApiTestCaseBatchRunService {
*/
private ApiReport initIntegratedReport(ApiRunModeConfigDTO runModeConfig, List<String> ids, String userId, String projectId) {
ApiReport apiReport = getApiReport(runModeConfig, userId);
apiReport.setName(runModeConfig.getCollectionReport().getReportName());
apiReport.setName(runModeConfig.getCollectionReport().getReportName() + DateUtils.getTimeString(System.currentTimeMillis()));
apiReport.setIntegrated(true);
apiReport.setProjectId(projectId);
// 初始化集成报告与用例的关联关系
@ -271,6 +299,7 @@ public class ApiTestCaseBatchRunService {
public void executeNextTask(ExecutionQueue queue, ExecutionQueueDetail queueDetail) {
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
String resourceId = queueDetail.getResourceId();
String reportId = queueDetail.getReportId();
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(resourceId);
ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(resourceId);
@ -281,14 +310,6 @@ public class ApiTestCaseBatchRunService {
}
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId());
String reportId;
if (runModeConfig.isIntegratedReport()) {
String integratedReportId = runModeConfig.getCollectionReport().getReportId();
initApiReportSteps(apiTestCase, integratedReportId, queueDetail.getSort());
reportId = UUID.randomUUID().toString();
} else {
reportId = initApiReport(runModeConfig, List.of(apiTestCase), queue.getUserId()).get(0).getApiReportId();
}
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiTestCase, runModeConfig);
taskRequest.setQueueId(queue.getQueueId());
execute(taskRequest, apiTestCase, apiTestCaseBlob, BeanUtils.copyBean(new ApiDefinitionExecuteInfo(), apiDefinition));
@ -348,7 +369,7 @@ public class ApiTestCaseBatchRunService {
private ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, ApiTestCase apiTestCase, String userId) {
ApiReport apiReport = getApiReport(runModeConfig, userId);
apiReport.setEnvironmentId(getEnvId(runModeConfig, apiTestCase));
apiReport.setName(apiTestCase.getName());
apiReport.setName(apiTestCase.getName() + DateUtils.getTimeString(System.currentTimeMillis()));
apiReport.setProjectId(apiTestCase.getProjectId());
apiReport.setTriggerMode(TaskTriggerMode.BATCH.name());
return apiReport;

View File

@ -724,7 +724,7 @@ public class ApiTestCaseService extends MoveNodeService {
ApiReport apiReport = getApiReport(userId);
apiReport.setId(reportId);
apiReport.setTriggerMode(TaskTriggerMode.MANUAL.name());
apiReport.setName(apiTestCase.getName());
apiReport.setName(apiTestCase.getName() + DateUtils.getTimeString(System.currentTimeMillis()));
apiReport.setRunMode(ApiBatchRunMode.PARALLEL.name());
apiReport.setPoolId(poolId);
apiReport.setEnvironmentId(apiTestCase.getEnvironmentId());

View File

@ -16,10 +16,7 @@ import io.metersphere.api.service.ApiBatchRunBaseService;
import io.metersphere.api.service.ApiExecuteService;
import io.metersphere.api.service.queue.ApiExecutionQueueService;
import io.metersphere.api.service.queue.ApiExecutionSetService;
import io.metersphere.sdk.constants.ApiBatchRunMode;
import io.metersphere.sdk.constants.ApiExecuteResourceType;
import io.metersphere.sdk.constants.ApiExecuteRunMode;
import io.metersphere.sdk.constants.TaskTriggerMode;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
import io.metersphere.sdk.dto.api.task.CollectionReportDTO;
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
@ -33,6 +30,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@ -93,8 +91,14 @@ public class ApiScenarioBatchRunService {
if (runModeConfig.isIntegratedReport()) {
initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
}
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
// 集成报告执行前先设置成 RUNNING
setRunningIntegrateReport(runModeConfig);
// 先初始化集成报告设置好报告ID再初始化执行队列
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_SCENARIO.name(), userId);
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_SCENARIO.name(), scenarioReportMap, userId);
// 执行第一个任务
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
executeNextTask(queue, nextDetail);
@ -117,11 +121,15 @@ public class ApiScenarioBatchRunService {
apiExecutionSetService.initSet(apiScenarioReport.getId(), ids);
}
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
// 集成报告执行前先设置成 RUNNING
setRunningIntegrateReport(runModeConfig);
AtomicInteger errorCount = new AtomicInteger();
AtomicInteger sort = new AtomicInteger(1);
// 这里ID顺序和队列的ID顺序保持一致
for (String id : ids) {
String reportId = IDGenerator.nextStr();
String reportId = null;
try {
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(id);
if (apiScenarioDetail == null) {
@ -132,8 +140,17 @@ public class ApiScenarioBatchRunService {
LogUtils.info("当前执行任务的用例已删除 {}", id);
break;
}
if (runModeConfig.isIntegratedReport()) {
// 集成报告生成虚拟的报告ID
reportId = IDGenerator.nextStr();
} else {
reportId = scenarioReportMap.get(id);
}
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiScenarioDetail, runModeConfig);
execute(taskRequest, apiScenarioDetail, userId, sort.getAndIncrement());
execute(taskRequest, apiScenarioDetail);
} catch (Exception e) {
LogUtils.error("执行用例失败 {}-{}", reportId, id);
LogUtils.error(e);
@ -145,6 +162,39 @@ public class ApiScenarioBatchRunService {
}
}
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
Map<String, String> scenarioReportMap = new HashMap<>();
Boolean isIntegratedReport = runModeConfig.isIntegratedReport();
AtomicInteger sort = new AtomicInteger(1);
// 这里ID顺序和队列的ID顺序保持一致
for (String id : ids) {
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(id);
if (apiScenarioDetail == null) {
break;
}
if (runModeConfig.isIntegratedReport()) {
// 初始化集成报告步骤
initIntegratedReportSteps(apiScenarioDetail, runModeConfig.getCollectionReport().getReportId(), sort.getAndIncrement());
} else {
// 初始化非集成报告
String reportId = initScenarioReport(runModeConfig, apiScenarioDetail, userId).getApiScenarioReportId();
// 初始化报告步骤
apiScenarioService.initScenarioReportSteps(apiScenarioDetail.getSteps(), reportId);
scenarioReportMap.put(id, reportId);
}
}
return isIntegratedReport ? null : scenarioReportMap;
}
/**
* 集成报告执行前先设置成 RUNNING
* @param runModeConfig
*/
private void setRunningIntegrateReport(ApiRunModeConfigDTO runModeConfig) {
if (runModeConfig.isIntegratedReport()) {
apiScenarioReportService.updateReportStatus(runModeConfig.getCollectionReport().getReportId(), ApiReportStatus.RUNNING.name());
}
}
/**
* 初始化集成报告的报告步骤
@ -214,15 +264,15 @@ public class ApiScenarioBatchRunService {
LogUtils.info("当前执行任务的用例已删除 {}", queueDetail.getResourceId());
return;
}
TaskRequestDTO taskRequest = getTaskRequestDTO(IDGenerator.nextStr(), apiScenarioDetail, queue.getRunModeConfig());
TaskRequestDTO taskRequest = getTaskRequestDTO(queueDetail.getReportId(), apiScenarioDetail, queue.getRunModeConfig());
taskRequest.setQueueId(queue.getQueueId());
execute(taskRequest, apiScenarioDetail, queue.getUserId(), queueDetail.getSort());
execute(taskRequest, apiScenarioDetail);
}
/**
* 执行批量的单个任务
*/
public void execute(TaskRequestDTO taskRequest, ApiScenarioDetail apiScenarioDetail, String userId, int sort) {
public void execute(TaskRequestDTO taskRequest, ApiScenarioDetail apiScenarioDetail) {
ApiRunModeConfigDTO runModeConfig = taskRequest.getRunModeConfig();
String reportId = taskRequest.getReportId();
String envId = getEnvId(runModeConfig, apiScenarioDetail);
@ -240,15 +290,6 @@ public class ApiScenarioBatchRunService {
parseParam.setEnvironmentId(envId);
parseParam.setGrouped(envGroup);
if (runModeConfig.isIntegratedReport()) {
// 初始化集成报告步骤
initIntegratedReportSteps(apiScenarioDetail, runModeConfig.getCollectionReport().getReportId(), sort);
} else {
// 初始化非集成报告
initScenarioReport(reportId, runModeConfig, apiScenarioDetail, userId).getApiScenarioReportId();
// 初始化报告步骤
apiScenarioService.initScenarioReportSteps(apiScenarioDetail.getSteps(), reportId);
}
taskRequest.setReportId(reportId);
ApiScenarioParseTmpParam tmpParam = apiScenarioService.parse(msScenario, apiScenarioDetail.getSteps(), parseParam);
@ -279,10 +320,10 @@ public class ApiScenarioBatchRunService {
* @param apiScenario
* @return
*/
public ApiScenarioRecord initScenarioReport(String reportId, ApiRunModeConfigDTO runModeConfig, ApiScenario apiScenario, String userId) {
public ApiScenarioRecord initScenarioReport(ApiRunModeConfigDTO runModeConfig, ApiScenario apiScenario, String userId) {
// 初始化报告
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, apiScenario, userId);
apiScenarioReport.setId(reportId);
apiScenarioReport.setId(IDGenerator.nextStr());
// 创建报告和用例的关联关系
ApiScenarioRecord apiScenarioRecord = apiScenarioService.getApiScenarioRecord(apiScenario, apiScenarioReport);
apiScenarioReportService.insertApiScenarioReport(List.of(apiScenarioReport), List.of(apiScenarioRecord));

View File

@ -811,7 +811,7 @@ public class ApiScenarioService extends MoveNodeService {
* 解析步骤树结构
* 获取待更新的 ApiScenarioStep 列表
*/
private List<ApiScenarioStep> getApiScenarioSteps(ApiScenarioStepRequest parent,
private List<ApiScenarioStep> getApiScenarioSteps(ApiScenarioStepCommonDTO parent,
List<ApiScenarioStepRequest> steps, List<ApiScenarioCsvStep> csvSteps) {
if (CollectionUtils.isEmpty(steps)) {
return Collections.emptyList();
@ -1292,7 +1292,7 @@ public class ApiScenarioService extends MoveNodeService {
ApiScenarioReport scenarioReport = getScenarioReport(userId);
scenarioReport.setId(reportId);
scenarioReport.setTriggerMode(TaskTriggerMode.MANUAL.name());
scenarioReport.setName(apiScenario.getName());
scenarioReport.setName(apiScenario.getName() + DateUtils.getTimeString(System.currentTimeMillis()));
scenarioReport.setRunMode(ApiBatchRunMode.PARALLEL.name());
scenarioReport.setPoolId(poolId);
scenarioReport.setEnvironmentId(apiScenario.getEnvironmentId());