fix(测试计划): 复制计划或计划组暂未复制定时任务
--bug=1042641 --user=宋昌昌 【测试计划】计划列表-操作-复制计划成功-首次进入计划详情-测试规划展示为空 https://www.tapd.cn/55049933/s/1532263
This commit is contained in:
parent
f1fc2f302f
commit
d71ce02d4c
|
@ -47,6 +47,8 @@ public class TestPlanController {
|
|||
@Resource
|
||||
private TestPlanService testPlanService;
|
||||
@Resource
|
||||
private TestPlanScheduleService testPlanScheduleService;
|
||||
@Resource
|
||||
private TestPlanManagementService testPlanManagementService;
|
||||
@Resource
|
||||
private TestPlanStatisticsService testPlanStatisticsService;
|
||||
|
@ -245,7 +247,7 @@ public class TestPlanController {
|
|||
@CheckOwner(resourceId = "#request.getResourceId()", resourceType = "test_plan")
|
||||
public String scheduleConfig(@Validated @RequestBody BaseScheduleConfigRequest request) {
|
||||
testPlanManagementService.checkModuleIsOpen(request.getResourceId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||
return testPlanService.scheduleConfig(request, SessionUtils.getUserId());
|
||||
return testPlanScheduleService.scheduleConfig(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@GetMapping(value = "/schedule-config-delete/{testPlanId}")
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.plan.service;
|
|||
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||
import io.metersphere.plan.job.TestPlanScheduleJob;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanConfigMapper;
|
||||
|
@ -12,7 +13,11 @@ import io.metersphere.sdk.constants.TestPlanConstants;
|
|||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.Schedule;
|
||||
import io.metersphere.system.dto.request.schedule.BaseScheduleConfigRequest;
|
||||
import io.metersphere.system.schedule.ScheduleService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
|
@ -33,7 +38,10 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
private ExtTestPlanMapper extTestPlanMapper;
|
||||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
|
||||
@Resource
|
||||
private ScheduleService scheduleService;
|
||||
@Resource
|
||||
private TestPlanScheduleService testPlanScheduleService;
|
||||
@Resource
|
||||
private TestPlanGroupService testPlanGroupService;
|
||||
@Resource
|
||||
|
@ -237,6 +245,10 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
beansOfType.forEach((k, v) -> {
|
||||
v.copyResource(originalTestPlan.getId(), testPlan.getId(), oldCollectionIdToNewCollectionId, operator, operatorTime);
|
||||
});
|
||||
|
||||
// 复制计划-定时任务信息
|
||||
copySchedule(originalTestPlan.getId(), testPlan.getId(), operator);
|
||||
|
||||
return testPlan;
|
||||
}
|
||||
|
||||
|
@ -280,9 +292,32 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
for (TestPlan child : childList) {
|
||||
copyPlan(child, testPlanGroup.getId(), TestPlanConstants.TEST_PLAN_TYPE_GROUP, operatorTime, operator);
|
||||
}
|
||||
|
||||
// 复制计划组-定时任务信息
|
||||
copySchedule(originalGroup.getId(), testPlanGroup.getId(), operator);
|
||||
return testPlanGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制 计划/计划组 定时任务
|
||||
* @param resourceId 来源ID
|
||||
* @param targetId 目标ID
|
||||
* @param operator 操作人
|
||||
*/
|
||||
private void copySchedule(String resourceId, String targetId, String operator) {
|
||||
Schedule originalSchedule = scheduleService.getScheduleByResource(resourceId, TestPlanScheduleJob.class.getName());
|
||||
if (originalSchedule != null) {
|
||||
// 来源的 "计划/计划组" 存在定时任务即复制, 无论开启或关闭
|
||||
BaseScheduleConfigRequest scheduleRequest = new BaseScheduleConfigRequest();
|
||||
scheduleRequest.setEnable(originalSchedule.getEnable());
|
||||
scheduleRequest.setCron(originalSchedule.getValue());
|
||||
// noinspection unchecked
|
||||
scheduleRequest.setRunConfig(JSON.parseMap(originalSchedule.getConfig()));
|
||||
scheduleRequest.setResourceId(targetId);
|
||||
testPlanScheduleService.scheduleConfig(scheduleRequest, operator);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCopyName(String name, long oldNum, long newNum) {
|
||||
if (!StringUtils.startsWith(name, "copy_")) {
|
||||
name = "copy_" + name;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanExample;
|
||||
import io.metersphere.plan.job.TestPlanScheduleJob;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.sdk.constants.ScheduleResourceType;
|
||||
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.request.ScheduleConfig;
|
||||
import io.metersphere.system.dto.request.schedule.BaseScheduleConfigRequest;
|
||||
import io.metersphere.system.schedule.ScheduleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanScheduleService {
|
||||
|
||||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private ScheduleService scheduleService;
|
||||
|
||||
public String scheduleConfig(BaseScheduleConfigRequest request, String operator) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getResourceId());
|
||||
if (testPlan == null) {
|
||||
throw new MSException(Translator.get("test_plan.not.exist"));
|
||||
}
|
||||
ScheduleConfig scheduleConfig = ScheduleConfig.builder()
|
||||
.resourceId(testPlan.getId())
|
||||
.key(testPlan.getId())
|
||||
.projectId(testPlan.getProjectId())
|
||||
.name(testPlan.getName())
|
||||
.enable(request.isEnable())
|
||||
.cron(request.getCron())
|
||||
.resourceType(ScheduleResourceType.TEST_PLAN.name())
|
||||
.config(JSON.toJSONString(request.getRunConfig()))
|
||||
.build();
|
||||
|
||||
if (request.isEnable() && StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
//配置开启的测试计划组定时任务,要将组下的所有测试计划定时任务都关闭掉
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria().andGroupIdEqualTo(testPlan.getId()).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||
example.setOrderByClause("pos asc");
|
||||
List<TestPlan> children = testPlanMapper.selectByExample(example);
|
||||
for (TestPlan child : children) {
|
||||
scheduleService.updateIfExist(child.getId(), false, TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.class, operator);
|
||||
}
|
||||
}
|
||||
|
||||
return scheduleService.scheduleConfig(
|
||||
scheduleConfig,
|
||||
TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.class,
|
||||
operator);
|
||||
}
|
||||
}
|
|
@ -13,14 +13,15 @@ import io.metersphere.project.request.ProjectApplicationRequest;
|
|||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.ScheduleExample;
|
||||
import io.metersphere.system.domain.TestPlanModule;
|
||||
import io.metersphere.system.domain.TestPlanModuleExample;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.dto.request.ScheduleConfig;
|
||||
import io.metersphere.system.dto.request.schedule.BaseScheduleConfigRequest;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
|
@ -884,40 +885,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
return new TestPlanOperationResponse(1);
|
||||
}
|
||||
|
||||
public String scheduleConfig(BaseScheduleConfigRequest request, String operator) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getResourceId());
|
||||
if (testPlan == null) {
|
||||
throw new MSException(Translator.get("test_plan.not.exist"));
|
||||
}
|
||||
ScheduleConfig scheduleConfig = ScheduleConfig.builder()
|
||||
.resourceId(testPlan.getId())
|
||||
.key(testPlan.getId())
|
||||
.projectId(testPlan.getProjectId())
|
||||
.name(testPlan.getName())
|
||||
.enable(request.isEnable())
|
||||
.cron(request.getCron())
|
||||
.resourceType(ScheduleResourceType.TEST_PLAN.name())
|
||||
.config(JSON.toJSONString(request.getRunConfig()))
|
||||
.build();
|
||||
|
||||
if (request.isEnable() && StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
//配置开启的测试计划组定时任务,要将组下的所有测试计划定时任务都关闭掉
|
||||
List<TestPlan> children = this.selectNotArchivedChildren(testPlan.getId());
|
||||
for (TestPlan child : children) {
|
||||
scheduleService.updateIfExist(child.getId(), false, TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.class, operator);
|
||||
}
|
||||
}
|
||||
|
||||
return scheduleService.scheduleConfig(
|
||||
scheduleConfig,
|
||||
TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
||||
TestPlanScheduleJob.class,
|
||||
operator);
|
||||
}
|
||||
|
||||
public void deleteScheduleConfig(String testPlanId) {
|
||||
scheduleService.deleteByResourceId(testPlanId, TestPlanScheduleJob.getJobKey(testPlanId), TestPlanScheduleJob.getTriggerKey(testPlanId));
|
||||
|
||||
|
|
|
@ -2182,24 +2182,26 @@ public class TestPlanTests extends BaseTest {
|
|||
@Test
|
||||
@Order(303)
|
||||
public void testCopy() throws Exception {
|
||||
//1. 已归档的不能再归档计划 无用例
|
||||
// 1. 已归档的不能再归档计划 无用例
|
||||
requestGet(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_1")).andExpect(status().is5xxServerError());
|
||||
|
||||
|
||||
//2.计划 有用例
|
||||
// 2.计划 有用例
|
||||
MvcResult mvcResult1 = this.requestGetWithOkAndReturn(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_4"));
|
||||
String returnStr1 = mvcResult1.getResponse().getContentAsString();
|
||||
ResultHolder holder1 = JSON.parseObject(returnStr1, ResultHolder.class);
|
||||
String returnId1 = holder1.getData().toString();
|
||||
Assertions.assertNotNull(returnId1);
|
||||
|
||||
//3.计划组 无计划
|
||||
// 3.计划组 无计划
|
||||
MvcResult mvcResult2 = this.requestGetWithOkAndReturn(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_2"));
|
||||
String returnStr2 = mvcResult2.getResponse().getContentAsString();
|
||||
ResultHolder holder2 = JSON.parseObject(returnStr2, ResultHolder.class);
|
||||
String returnId2 = holder2.getData().toString();
|
||||
Assertions.assertNotNull(returnId2);
|
||||
|
||||
// 4.计划组 有子计划
|
||||
this.requestGetWithOk(String.format(URL_TEST_PLAN_COPY, "oasis_test_plan_id_1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -20,8 +20,15 @@ VALUES ('wx_test_plan_id_1', 5000, 'songtianyang-fix-wx', 'NONE', '1', '测试
|
|||
'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000,
|
||||
1714980158000, '11'),
|
||||
('wx_test_plan_id_7', 30000, 'songtianyang-fix-wx', 'NONE', '1', '测试组4下计划', 'COMPLETED', 'TEST_PLAN', NULL,
|
||||
1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||
1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||
('oasis_test_plan_id_1', 30000, 'songtianyang-fix-wx', 'NONE', '1', '计划组-复制', 'COMPLETED', 'GROUP', NULL,
|
||||
1714980158000, 'admin', 1714980158000, 'admin', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||
('oasis_test_plan_id_2', 30000, 'songtianyang-fix-wx', 'oasis_test_plan_id_1', '1', '计划-复制', 'COMPLETED', 'TEST_PLAN', NULL,
|
||||
1714980158000, 'admin', 1714980158000, 'admin', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||
|
||||
-- 定时任务(复制)
|
||||
INSERT INTO `schedule` (`id`, `key`, `type`, `value`, `job`, `resource_type`, `enable`, `resource_id`, `create_user`, `create_time`, `update_time`, `project_id`, `name`, `config`) VALUE
|
||||
('schedule-id-oasis', 'oasis_test_plan_id_2', 'CRON', '0 0 0/6 * * ?', 'io.metersphere.plan.job.TestPlanScheduleJob', 'TEST_PLAN', true, 'oasis_test_plan_id_2', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'songtianyang-fix-wx', '计划-复制', '{"runMode":"SERIAL"}');
|
||||
|
||||
INSERT INTO `test_plan_functional_case`(`id`, `test_plan_id`, `functional_case_id`, `create_time`, `create_user`, `execute_user`, `last_exec_time`, `last_exec_result`, `pos`, `test_plan_collection_id`) VALUES
|
||||
('wx_tpfc_1', 'wx_test_plan_id_4', 'wx_fc_1', 1714980158000, 'admin', NULL, NULL, NULL, 1, '123'),
|
||||
|
|
Loading…
Reference in New Issue