feat(接口测试): 场景批量修改定时任务

This commit is contained in:
Jianguo-Genius 2024-11-04 19:05:53 +08:00 committed by Craftsman
parent b2f262628a
commit ddce1de3fd
8 changed files with 136 additions and 12 deletions

View File

@ -2,11 +2,7 @@ package io.metersphere.api.controller.scenario;
import io.metersphere.api.constants.ApiResource; import io.metersphere.api.constants.ApiResource;
import io.metersphere.api.dto.response.ApiScenarioBatchOperationResponse; import io.metersphere.api.dto.response.ApiScenarioBatchOperationResponse;
import io.metersphere.api.dto.scenario.ApiScenarioBatchCopyMoveRequest; import io.metersphere.api.dto.scenario.*;
import io.metersphere.api.dto.scenario.ApiScenarioBatchEditRequest;
import io.metersphere.api.dto.scenario.ApiScenarioBatchRequest;
import io.metersphere.api.dto.scenario.ApiScenarioBatchRunRequest;
import io.metersphere.api.service.ApiBatchRunBaseService;
import io.metersphere.api.service.ApiValidateService; import io.metersphere.api.service.ApiValidateService;
import io.metersphere.api.service.scenario.ApiScenarioBatchRunService; import io.metersphere.api.service.scenario.ApiScenarioBatchRunService;
import io.metersphere.api.service.scenario.ApiScenarioNoticeService; import io.metersphere.api.service.scenario.ApiScenarioNoticeService;
@ -22,7 +18,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -103,4 +98,13 @@ public class ApiScenarioBatchOperationController {
apiValidateService.validateApiMenuInProject(request.getProjectId(), ApiResource.PROJECT.name()); apiValidateService.validateApiMenuInProject(request.getProjectId(), ApiResource.PROJECT.name());
apiScenarioBatchRunService.asyncBatchRun(request, SessionUtils.getUserId()); apiScenarioBatchRunService.asyncBatchRun(request, SessionUtils.getUserId());
} }
@PostMapping(value = "/batch-operation/schedule-config")
@Operation(summary = "接口测试-接口场景管理-定时任务批量配置")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE)
@CheckOwner(resourceId = "#request.getProject()", resourceType = "project")
public void scheduleConfig(@Validated @RequestBody ApiScenarioBatchScheduleConfigRequest request) {
apiValidateService.validateApiMenuInProject(request.getProjectId(), ApiResource.PROJECT.name());
apiScenarioService.batchScheduleConfig(request, SessionUtils.getUserId());
}
} }

View File

@ -19,7 +19,7 @@ public class ApiScenarioBatchEditRequest extends ApiScenarioBatchRequest impleme
@Schema(description = "标签") @Schema(description = "标签")
private LinkedHashSet<String> tags; private LinkedHashSet<String> tags;
@Schema(description = "批量编辑的类型 用例等级: Priority,状态 :Status,标签: Tags,用例环境: Environment") @Schema(description = "批量编辑的类型 用例等级: Priority,状态 :Status,标签: Tags,用例环境: Environment, 定时任务Schedule")
@NotBlank @NotBlank
private String type; private String type;
@Schema(description = "默认覆盖原标签") @Schema(description = "默认覆盖原标签")
@ -40,7 +40,8 @@ public class ApiScenarioBatchEditRequest extends ApiScenarioBatchRequest impleme
@Schema(description = "用例等级") @Schema(description = "用例等级")
@Size(max = 50, message = "{api_test_case.priority.length_range}") @Size(max = 50, message = "{api_test_case.priority.length_range}")
private String priority; private String priority;
@Schema(description = "定时任务是否开启")
private boolean scheduleOpen;
public List<String> getTags() { public List<String> getTags() {
if (tags == null) { if (tags == null) {
return new ArrayList<>(0); return new ArrayList<>(0);

View File

@ -0,0 +1,26 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
public class ApiScenarioBatchScheduleConfigRequest extends ApiScenarioBatchRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "启用/禁用")
private boolean enable;
@Schema(description = "Cron表达式")
@NotBlank
private String cron;
@Schema(description = "定时任务配置")
private ApiRunModeConfigDTO config;
}

View File

@ -235,6 +235,27 @@ public class ApiScenarioLogService {
operationLogService.batchAdd(logs); operationLogService.batchAdd(logs);
} }
public void batchScheduleConfigLog(String projectId, List<ApiScenario> scenarioList, String operator) {
Project project = projectMapper.selectByPrimaryKey(projectId);
List<LogDTO> logs = new ArrayList<>();
scenarioList.forEach(apiScenario -> {
LogDTO dto = LogDTOBuilder.builder()
.projectId(project.getId())
.organizationId(project.getOrganizationId())
.type(OperationLogType.UPDATE.name())
.module(OperationLogModule.API_SCENARIO_MANAGEMENT_SCENARIO)
.sourceId(apiScenario.getId())
.method("POST")
.path("/api/scenario/batch-operation/schedule-config")
.createUser(operator)
.content(Translator.get("api_automation_schedule") + ":" + apiScenario.getName())
.build().getLogDTO();
logs.add(dto);
}
);
operationLogService.batchAdd(logs);
}
public LogDTO exportExcelLog(String sourceId, String exportType, String userId, @NotNull Project project) { public LogDTO exportExcelLog(String sourceId, String exportType, String userId, @NotNull Project project) {
LogDTO dto = new LogDTO( LogDTO dto = new LogDTO(
project.getId(), project.getId(),

View File

@ -173,6 +173,7 @@ public class ApiScenarioService extends MoveNodeService {
public static final String STATUS = "Status"; public static final String STATUS = "Status";
public static final String TAGS = "Tags"; public static final String TAGS = "Tags";
public static final String ENVIRONMENT = "Environment"; public static final String ENVIRONMENT = "Environment";
public static final String SCHEDULE = "Schedule";
private static final String SCENARIO_TABLE = "api_scenario"; private static final String SCENARIO_TABLE = "api_scenario";
private static final String SCENARIO = "SCENARIO"; private static final String SCENARIO = "SCENARIO";
@ -273,6 +274,7 @@ public class ApiScenarioService extends MoveNodeService {
case STATUS -> batchUpdateStatus(example, updateScenario, request.getStatus(), mapper); case STATUS -> batchUpdateStatus(example, updateScenario, request.getStatus(), mapper);
case TAGS -> batchUpdateTags(example, updateScenario, request, ids, mapper); case TAGS -> batchUpdateTags(example, updateScenario, request, ids, mapper);
case ENVIRONMENT -> batchUpdateEnvironment(example, updateScenario, request, mapper); case ENVIRONMENT -> batchUpdateEnvironment(example, updateScenario, request, mapper);
case SCHEDULE -> batchUpdateSchedule(example, request, mapper, userId);
default -> throw new MSException(Translator.get("batch_edit_type_error")); default -> throw new MSException(Translator.get("batch_edit_type_error"));
} }
sqlSession.flushStatements(); sqlSession.flushStatements();
@ -282,6 +284,15 @@ public class ApiScenarioService extends MoveNodeService {
apiScenarioNoticeService.batchSendNotice(ids, userId, projectId, NoticeConstants.Event.UPDATE); apiScenarioNoticeService.batchSendNotice(ids, userId, projectId, NoticeConstants.Event.UPDATE);
} }
private void batchUpdateSchedule(ApiScenarioExample example, ApiScenarioBatchEditRequest request, ApiScenarioMapper mapper, String userId) {
List<ApiScenario> apiScenarioList = mapper.selectByExample(example);
//批量编辑定时任务
for (ApiScenario apiScenario : apiScenarioList) {
scheduleService.updateIfExist(apiScenario.getId(), request.isScheduleOpen(), ApiScenarioScheduleJob.getJobKey(apiScenario.getId()),
ApiScenarioScheduleJob.getTriggerKey(apiScenario.getId()), ApiScenarioScheduleJob.class, userId);
}
}
private void batchUpdateEnvironment(ApiScenarioExample example, ApiScenario updateScenario, private void batchUpdateEnvironment(ApiScenarioExample example, ApiScenario updateScenario,
ApiScenarioBatchEditRequest request, ApiScenarioMapper mapper) { ApiScenarioBatchEditRequest request, ApiScenarioMapper mapper) {
if (BooleanUtils.isFalse(request.isGrouped())) { if (BooleanUtils.isFalse(request.isGrouped())) {
@ -2576,4 +2587,36 @@ public class ApiScenarioService extends MoveNodeService {
return response; return response;
} }
public void batchScheduleConfig(ApiScenarioBatchScheduleConfigRequest request, String operator) {
List<String> scenarioIds = doSelectIds(request, false);
if (CollectionUtils.isNotEmpty(scenarioIds)) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(scenarioIds).andDeletedEqualTo(false);
List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(apiScenarios)) {
apiScenarios.forEach(apiScenario -> {
ScheduleConfig scheduleConfig = ScheduleConfig.builder()
.resourceId(apiScenario.getId())
.key(apiScenario.getId())
.projectId(apiScenario.getProjectId())
.name(apiScenario.getName())
.enable(request.isEnable())
.cron(request.getCron())
.resourceType(ScheduleResourceType.API_SCENARIO.name())
.config(JSON.toJSONString(request.getConfig()))
.build();
scheduleService.scheduleConfig(
scheduleConfig,
ApiScenarioScheduleJob.getJobKey(apiScenario.getId()),
ApiScenarioScheduleJob.getTriggerKey(apiScenario.getId()),
ApiScenarioScheduleJob.class,
operator);
});
apiScenarioLogService.batchScheduleConfigLog(request.getProjectId(), apiScenarios, operator);
}
}
}
} }

View File

@ -2102,6 +2102,7 @@ public class ApiScenarioControllerTests extends BaseTest {
@Order(23) @Order(23)
void scheduleTest() throws Exception { void scheduleTest() throws Exception {
String testUrl = "/schedule-config"; String testUrl = "/schedule-config";
String batchUrl = "/batch-operation/schedule-config";
String deleteUrl = "/schedule-config-delete/"; String deleteUrl = "/schedule-config-delete/";
if (CollectionUtils.isEmpty(BATCH_OPERATION_SCENARIO_ID)) { if (CollectionUtils.isEmpty(BATCH_OPERATION_SCENARIO_ID)) {
@ -2112,14 +2113,18 @@ public class ApiScenarioControllerTests extends BaseTest {
String scenarioId = BATCH_OPERATION_SCENARIO_ID.getLast(); String scenarioId = BATCH_OPERATION_SCENARIO_ID.getLast();
deleteUrl += scenarioId; deleteUrl += scenarioId;
ApiScenarioScheduleConfigRequest request = new ApiScenarioScheduleConfigRequest(); ApiScenarioScheduleConfigRequest request = new ApiScenarioScheduleConfigRequest();
request.setScenarioId(scenarioId); request.setScenarioId(scenarioId);
request.setEnable(true); request.setEnable(true);
request.setCron("0 0 0 * * ?"); request.setCron("0 0 0 * * ?");
ApiScenarioBatchScheduleConfigRequest batchRequest = new ApiScenarioBatchScheduleConfigRequest();
batchRequest.setEnable(false);
batchRequest.setCron("0 0 0 * * ?");
batchRequest.setProjectId(DEFAULT_PROJECT_ID);
batchRequest.setSelectIds(List.of(BATCH_OPERATION_SCENARIO_ID.getFirst()));
//先测试一下没有开启模块时接口能否使用 //先测试一下没有开启模块时接口能否使用
apiScenarioBatchOperationTestService.removeApiModule(DEFAULT_PROJECT_ID); apiScenarioBatchOperationTestService.removeApiModule(DEFAULT_PROJECT_ID);
this.requestPost(testUrl, request).andExpect(status().is5xxServerError()); this.requestPost(testUrl, request).andExpect(status().is5xxServerError());
this.requestPost(batchUrl, batchRequest).andExpect(status().is5xxServerError());
this.requestGet(deleteUrl, request).andExpect(status().is5xxServerError()); this.requestGet(deleteUrl, request).andExpect(status().is5xxServerError());
//恢复 //恢复
apiScenarioBatchOperationTestService.resetProjectModule(DEFAULT_PROJECT_ID); apiScenarioBatchOperationTestService.resetProjectModule(DEFAULT_PROJECT_ID);
@ -2128,11 +2133,29 @@ public class ApiScenarioControllerTests extends BaseTest {
String scheduleId = resultHolder.getData().toString(); String scheduleId = resultHolder.getData().toString();
apiScenarioBatchOperationTestService.checkSchedule(scheduleId, scenarioId, request.isEnable()); apiScenarioBatchOperationTestService.checkSchedule(scheduleId, scenarioId, request.isEnable());
this.requestPostWithOk(batchUrl, batchRequest);
apiScenarioBatchOperationTestService.checkSchedule(BATCH_OPERATION_SCENARIO_ID.getFirst(), batchRequest.isEnable());
batchRequest.setEnable(false);
this.requestPostWithOk(batchUrl, batchRequest);
apiScenarioBatchOperationTestService.checkSchedule(BATCH_OPERATION_SCENARIO_ID.getFirst(), batchRequest.isEnable());
//增加日志检查 //增加日志检查
LOG_CHECK_LIST.add( LOG_CHECK_LIST.add(
new CheckLogModel(scenarioId, OperationLogType.UPDATE, "/api/scenario/schedule-config") new CheckLogModel(scenarioId, OperationLogType.UPDATE, "/api/scenario/schedule-config")
); );
LOG_CHECK_LIST.add(
new CheckLogModel(BATCH_OPERATION_SCENARIO_ID.getFirst(), OperationLogType.UPDATE, "/api/scenario/batch-operation/schedule-config")
);
// 批量定时任务的开关
ApiScenarioBatchEditRequest batchEditRequest = new ApiScenarioBatchEditRequest();
batchEditRequest.setProjectId(DEFAULT_PROJECT_ID);
batchEditRequest.setType("Schedule");
batchEditRequest.setScheduleOpen(true);
batchEditRequest.setSelectIds(List.of(BATCH_OPERATION_SCENARIO_ID.getFirst()));
requestPostAndReturn(BATCH_EDIT, batchEditRequest);
apiScenarioBatchOperationTestService.checkSchedule(BATCH_OPERATION_SCENARIO_ID.getFirst(), batchEditRequest.isScheduleOpen());
batchEditRequest.setScheduleOpen(false);
requestPostAndReturn(BATCH_EDIT, batchEditRequest);
apiScenarioBatchOperationTestService.checkSchedule(BATCH_OPERATION_SCENARIO_ID.getFirst(), batchEditRequest.isScheduleOpen());
//关闭 //关闭
request.setEnable(false); request.setEnable(false);
result = this.requestPostAndReturn(testUrl, request); result = this.requestPostAndReturn(testUrl, request);
@ -2203,6 +2226,7 @@ public class ApiScenarioControllerTests extends BaseTest {
//校验权限 //校验权限
this.requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, testUrl, request); this.requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, testUrl, request);
//反例scenarioId不存在 //反例scenarioId不存在
request = new ApiScenarioScheduleConfigRequest(); request = new ApiScenarioScheduleConfigRequest();
request.setCron("0 0 0 * * ?"); request.setCron("0 0 0 * * ?");

View File

@ -209,6 +209,11 @@ public class ApiScenarioBatchOperationTestService {
Assertions.assertEquals(scheduler.checkExists(ApiScenarioScheduleJob.getJobKey(resourceId)), isEnable); Assertions.assertEquals(scheduler.checkExists(ApiScenarioScheduleJob.getJobKey(resourceId)), isEnable);
} }
public void checkSchedule(String resourceId, boolean isEnable) throws Exception {
Assertions.assertEquals(extScheduleMapper.countByResourceId(resourceId), 1L);
Assertions.assertEquals(scheduler.checkExists(ApiScenarioScheduleJob.getJobKey(resourceId)), isEnable);
}
public void checkScheduleIsRemove(String resourceId) throws Exception { public void checkScheduleIsRemove(String resourceId) throws Exception {
Assertions.assertEquals(extScheduleMapper.countByResourceId(resourceId), 0L); Assertions.assertEquals(extScheduleMapper.countByResourceId(resourceId), 0L);
Assertions.assertEquals(scheduler.checkExists(ApiScenarioScheduleJob.getJobKey(resourceId)), false); Assertions.assertEquals(scheduler.checkExists(ApiScenarioScheduleJob.getJobKey(resourceId)), false);

View File

@ -233,7 +233,7 @@ public class TestPlanController {
} }
@PostMapping(value = "/batch-schedule-config") @PostMapping(value = "/batch-schedule-config")
@Operation(summary = "接口测试-接口场景管理-定时任务配置") @Operation(summary = "接口测试-接口场景管理-定时任务批量配置")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE) @RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public void batchScheduleConfig(@Validated @RequestBody TestPlanScheduleBatchConfigRequest request) { public void batchScheduleConfig(@Validated @RequestBody TestPlanScheduleBatchConfigRequest request) {