diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/pipeline/impl/PipelineServiceImpl.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/pipeline/impl/PipelineServiceImpl.java index 177585af..2e6bb342 100644 --- a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/pipeline/impl/PipelineServiceImpl.java +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/process/service/pipeline/impl/PipelineServiceImpl.java @@ -163,6 +163,8 @@ public class PipelineServiceImpl extends ServiceImpl i }); } }); + }else { + throw new ServiceException(GlobalErrorCodeConstants.PIPELINE_ERROR.getCode(),"模板不存在"); } pipStageDao.insertBatch(pipStageList); pipTaskDao.insertBatch(pipTaskList); @@ -183,8 +185,12 @@ public class PipelineServiceImpl extends ServiceImpl i }); }); }); - pipStageDao.updateBatch(pipStageList); - pipTaskDao.updateBatch(pipTaskList); + if (!CollectionUtils.isEmpty(pipStageList)){ + pipStageDao.updateBatch(pipStageList); + } + if (!CollectionUtils.isEmpty(pipTaskList)){ + pipTaskDao.updateBatch(pipTaskList); + } } //TODO 创建对应的鉴权关系 diff --git a/ops-server/src/test/java/cd/casic/server/PipelineTest.java b/ops-server/src/test/java/cd/casic/server/PipelineTest.java new file mode 100644 index 00000000..1e0f7b23 --- /dev/null +++ b/ops-server/src/test/java/cd/casic/server/PipelineTest.java @@ -0,0 +1,286 @@ +package cd.casic.server; + +import cd.casic.ci.process.dal.req.pipeline.PipelineCreateReq; +import cd.casic.ci.process.dal.req.pipeline.PipelineQueryReq; +import cd.casic.ci.process.dal.req.pipeline.PipelineReq; +import cd.casic.ci.process.dal.req.pipeline.PipelineUpdateReq; +import cd.casic.ci.process.dal.resp.pipeline.PipelineFindResp; +import cd.casic.ci.process.dal.resp.template.TemplateFindResp; +import cd.casic.ci.process.dal.resp.template.TemplateStageResp; +import cd.casic.ci.process.dal.resp.template.TemplateTasksResp; +import cd.casic.ci.process.process.service.pipeline.impl.PipelineServiceImpl; +import cd.casic.ci.process.process.service.template.impl.TemplateManagerServiceImpl; +import cd.casic.framework.commons.exception.ServiceException; +import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants; +import cd.casic.framework.commons.pojo.PageResult; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = {OpsServerApplication.class}) +@ActiveProfiles("local") +@Slf4j +public class PipelineTest { + @Autowired + private PipelineServiceImpl pipelineService; + + @MockBean + private TemplateManagerServiceImpl templateManagerService; + + @BeforeEach + void setUp() { + // 模拟当前登录用户 ID +// when(webFrameworkUtils.getLoginUserId()).thenReturn(1L); + } + + @Test + void testCreatePipeline_WithoutTemplateId() { + PipelineCreateReq req = new PipelineCreateReq(); + req.setName("Test Pipeline"); + req.setTemplateId(null); // 不使用模板 + + String result = pipelineService.createPipeline(req); + + assertNotNull(result); + assertTrue(result.length() > 0); + } + + @Test + void testCreatePipeline_WithTemplateId_TemplateNotFound() { + PipelineCreateReq req = new PipelineCreateReq(); + req.setTemplateId("non-existent-template-id"); + + // 模板服务返回 null 表示未找到模板 + when(templateManagerService.findTemplateById("non-existent-template-id")).thenReturn(null); + + String result = pipelineService.createPipeline(req); + + assertNotNull(result); + assertTrue(result.length() > 0); + } + + @Test + void testCreatePipeline_WithTemplateId_TemplateFound_NoStages() { + PipelineCreateReq req = new PipelineCreateReq(); + req.setTemplateId("empty-template-id"); + + TemplateFindResp template = new TemplateFindResp(); + template.setId("empty-template-id"); + template.setStageList(new ArrayList<>()); + // TemplateFindResp templateFindResp = new TemplateFindResp(); +// List stageResps = new ArrayList<>(); +// TemplateStageResp templateStageResp = new TemplateStageResp(); +// List childTaskList = new ArrayList<>(); +// List childStageList = new ArrayList<>(); +// +// templateFindResp.setStageList(); + + when(templateManagerService.findTemplateById("empty-template-id")).thenReturn(template); + + String result = pipelineService.createPipeline(req); + + assertNotNull(result); + assertTrue(result.length() > 0); + } + + @Test + void testCreatePipeline_WithTemplateId_TemplateFound_WithStagesAndTasks() { + PipelineCreateReq req = new PipelineCreateReq(); + req.setTemplateId("valid-template-id"); + + TemplateFindResp template = new TemplateFindResp(); + template.setId("valid-template-id"); + + // 构建阶段 + TemplateStageResp stage1 = new TemplateStageResp(); + stage1.setId("stage-1"); + stage1.setStageName("Build Stage"); + stage1.setCode(false); + + // 构建子阶段 + TemplateStageResp subStage = new TemplateStageResp(); + subStage.setId("sub-stage-1"); + subStage.setStageName("Sub Build Stage"); + subStage.setCode(true); + + // 构建任务 + TemplateTasksResp task1 = new TemplateTasksResp(); + task1.setId("task-1"); + task1.setTaskName("Maven Build Task"); + + subStage.setTaskValues(List.of(task1)); + stage1.setStageList(List.of(subStage)); + + template.setStageList(List.of(stage1)); + + when(templateManagerService.findTemplateById("valid-template-id")).thenReturn(template); + + String result = pipelineService.createPipeline(req); + + assertNotNull(result); + assertTrue(result.length() > 0); + } + + + + + /** + * 测试正常查询流水线列表 + */ + @Test + void testFindPipelineList_Normal() { + PipelineQueryReq req = new PipelineQueryReq(); + req.setName("test-ljc"); + + // 验证结果 + List result = pipelineService.findPipelineList(req); + + assertNotNull(result); + assertFalse(result.isEmpty()); + + result.forEach(p -> { + assertNotNull(p.getId()); + assertNotNull(p.getName()); + assertNotNull(p.getCreatorName()); + }); + } + + /** + * 测试无匹配数据时返回空列表 + */ + @Test + void testFindPipelineList_EmptyResult() { + PipelineQueryReq req = new PipelineQueryReq(); + req.setName("non-exist-pipeline"); + req.setId("non-exist-pipeline"); + List idList = new ArrayList<>(); + idList.add("non-exist-pipeline"); + req.setIdList(idList); + req.setGroupId("1"); + req.setCreator("1"); + req.setCollect(1); + + List result = pipelineService.findPipelineList(req); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + void testDeleteByPipelineId(){ + PipelineReq pipelineReq = new PipelineReq(); + pipelineReq.setId("717383892016959488"); + + pipelineService.deletePipeline(pipelineReq); + + } + + @Test + void testDeleteByPipelineIdNoSuccess(){ + PipelineReq pipelineReq = new PipelineReq(); + pipelineReq.setId("1"); + + pipelineService.deletePipeline(pipelineReq); + + } + + + @Test + public void testUpdatePipeline() { + // 准备测试数据 + PipelineUpdateReq request = new PipelineUpdateReq(); + request.setId("1"); + request.setName("Updated Pipeline Name"); + + // 执行方法 + pipelineService.updatePipeline(request); + } + + + /** + * 测试正常查询流水线列表 + */ + @Test + void testFindPipelinePage_Normal() { + PipelineQueryReq req = new PipelineQueryReq(); + req.setName("test-ljc"); + + // 验证结果 + PageResult pipelinePage = pipelineService.findPipelinePage(req); + + assertNotNull(pipelinePage); + assertFalse(pipelinePage.getList().isEmpty()); + + pipelinePage.getList().forEach(p -> { + assertNotNull(p.getId()); + assertNotNull(p.getName()); + assertNotNull(p.getCreatorName()); + }); + } + + /** + * 测试无匹配数据时返回空列表 + */ + @Test + void testFindPipelinePage_EmptyResult() { + PipelineQueryReq req = new PipelineQueryReq(); + req.setName("non-exist-pipeline"); + req.setId("non-exist-pipeline"); + List idList = new ArrayList<>(); + idList.add("non-exist-pipeline"); + req.setIdList(idList); + req.setGroupId("1"); + req.setCreator("1"); + req.setCollect(1); + + PageResult pipelinePage = pipelineService.findPipelinePage(req); + + assertNotNull(pipelinePage); + assertTrue(pipelinePage.getList().isEmpty()); + } + + + + @Test + public void testPipelineClone_WithEmptyIdOrName_ShouldThrowException() { + PipelineReq req = new PipelineReq(); + req.setId("716293518217318400"); + req.setName("test-ljc-1"); + + pipelineService.pipelineClone(req); + +// assertThatThrownBy(() -> ) +// .isInstanceOf(ServiceException.class) +// .hasFieldOrPropertyWithValue("code", GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode()) +// .hasMessageContaining("参数不能为空"); + } + + @Test + public void testPipelineClone_WithNonExistentPipeline_ShouldThrowException() { + PipelineReq req = new PipelineReq(); + req.setId("non-existent-id"); + req.setName("New Pipeline Name"); + +// when(pipelineDao.selectById(req.getId())).thenReturn(null); + + assertThatThrownBy(() -> pipelineService.pipelineClone(req)) + .isInstanceOf(ServiceException.class) + .hasFieldOrPropertyWithValue("code", GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode()) + .hasMessageContaining("数据错误,请联系管理员"); + } + + +} diff --git a/ops-server/src/test/java/cd/casic/server/ResourceTest.java b/ops-server/src/test/java/cd/casic/server/ResourceTest.java new file mode 100644 index 00000000..6dff698c --- /dev/null +++ b/ops-server/src/test/java/cd/casic/server/ResourceTest.java @@ -0,0 +1,330 @@ +package cd.casic.server; + +import cd.casic.ci.process.dal.req.resource.ResourceReq; +import cd.casic.ci.process.dal.resp.resource.ResourceFindResp; +import cd.casic.ci.process.process.converter.ResourceConverter; +import cd.casic.ci.process.process.dal.pipeline.PipResourceCloudDao; +import cd.casic.ci.process.process.dal.pipeline.PipResourceK8SDao; +import cd.casic.ci.process.process.dal.pipeline.PipResourceMachineDao; +import cd.casic.ci.process.process.dal.pipeline.PipResourceManagerDao; +import cd.casic.ci.process.process.dataObject.resource.PipResourceCloud; +import cd.casic.ci.process.process.dataObject.resource.PipResourceK8S; +import cd.casic.ci.process.process.dataObject.resource.PipResourceMachine; +import cd.casic.ci.process.process.dataObject.resource.PipResourceManager; +import cd.casic.ci.process.process.service.resource.impl.ResourceManagerServiceImpl; +import cd.casic.module.execute.docker.dao.DockerEndpointDao; +import cd.casic.module.execute.docker.dataobject.dto.DockerEndpointDo; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest(classes = {OpsServerApplication.class}) +@ActiveProfiles("local") +@Slf4j +public class ResourceTest { + @Autowired + private ResourceManagerServiceImpl resourceManagerService; + + @MockBean + private PipResourceManagerDao resourceManagerDao; + + @MockBean + private PipResourceMachineDao machineDao; + + @MockBean + private PipResourceK8SDao k8SDao; + + @MockBean + private DockerEndpointDao dockerEndpointDao; + + @MockBean + private PipResourceCloudDao cloudDao; + + @MockBean + private ResourceConverter resourceConverter; + + @Test + void testCreateResourceWithMachine() { + // Arrange + ResourceReq resourceReq = new ResourceReq(); + PipResourceMachine resourceMachine = new PipResourceMachine(); + resourceMachine.setId("machineId"); + resourceReq.setResourceMachine(resourceMachine); + + when(machineDao.insert(any(PipResourceMachine.class))).thenAnswer(invocation -> { + PipResourceMachine machine = invocation.getArgument(0); + machine.setId("machineId"); // 模拟插入后生成ID + return null; + }); + + when(resourceManagerDao.insert(any(PipResourceManager.class))).thenAnswer(invocation -> { + PipResourceManager manager = invocation.getArgument(0); + manager.setId("resourceId"); // 模拟插入后生成ID + return null; + }); + + // Act + String result = resourceManagerService.createResource(resourceReq); + + // Assert + verify(machineDao, times(1)).insert(any(PipResourceMachine.class)); + verify(resourceManagerDao, times(1)).insert(any(PipResourceManager.class)); + + // 验证返回的ID + assert result.equals("resourceId"); + } + + @Test + void testCreateResourceWithK8s() { + // Arrange + ResourceReq resourceReq = new ResourceReq(); + PipResourceK8S pipResourceK8S = new PipResourceK8S(); + pipResourceK8S.setId("k8sId"); + resourceReq.setPipResourceK8S(pipResourceK8S); + + when(k8SDao.insert(any(PipResourceK8S.class))).thenAnswer(invocation -> { + PipResourceK8S k8s = invocation.getArgument(0); + k8s.setId("k8sId"); // 模拟插入后生成ID + return null; + }); + + when(resourceManagerDao.insert(any(PipResourceManager.class))).thenAnswer(invocation -> { + PipResourceManager manager = invocation.getArgument(0); + manager.setId("resourceId"); // 模拟插入后生成ID + return null; + }); + + // Act + String result = resourceManagerService.createResource(resourceReq); + + // Assert + verify(k8SDao, times(1)).insert(any(PipResourceK8S.class)); + verify(resourceManagerDao, times(1)).insert(any(PipResourceManager.class)); + + // 验证返回的ID + assert result.equals("resourceId"); + } + + @Test + void testCreateResourceWithDocker() { + // Arrange + ResourceReq resourceReq = new ResourceReq(); + DockerEndpointDo dockerEndpoint = new DockerEndpointDo(); + dockerEndpoint.setId("dockerId"); + resourceReq.setDockerEndpoint(dockerEndpoint); + + when(dockerEndpointDao.insert(any(DockerEndpointDo.class))).thenAnswer(invocation -> { + DockerEndpointDo endpoint = invocation.getArgument(0); + endpoint.setId("dockerId"); // 模拟插入后生成ID + return null; + }); + + when(resourceManagerDao.insert(any(PipResourceManager.class))).thenAnswer(invocation -> { + PipResourceManager manager = invocation.getArgument(0); + manager.setId("resourceId"); // 模拟插入后生成ID + return null; + }); + + // Act + String result = resourceManagerService.createResource(resourceReq); + + // Assert + verify(dockerEndpointDao, times(1)).insert(any(DockerEndpointDo.class)); + verify(resourceManagerDao, times(1)).insert(any(PipResourceManager.class)); + + // 验证返回的ID + assert result.equals("resourceId"); + } + + @Test + void testCreateResourceWithCloud() { + // Arrange + ResourceReq resourceReq = new ResourceReq(); + PipResourceCloud pipResourceCloud = new PipResourceCloud(); + pipResourceCloud.setId("cloudId"); + resourceReq.setPipResourceCloud(pipResourceCloud); + + when(cloudDao.insert(any(PipResourceCloud.class))).thenAnswer(invocation -> { + PipResourceCloud cloud = invocation.getArgument(0); + cloud.setId("cloudId"); // 模拟插入后生成ID + return null; + }); + + when(resourceManagerDao.insert(any(PipResourceManager.class))).thenAnswer(invocation -> { + PipResourceManager manager = invocation.getArgument(0); + manager.setId("resourceId"); // 模拟插入后生成ID + return null; + }); + + // Act + String result = resourceManagerService.createResource(resourceReq); + + // Assert + verify(cloudDao, times(1)).insert(any(PipResourceCloud.class)); + verify(resourceManagerDao, times(1)).insert(any(PipResourceManager.class)); + + // 验证返回的ID + assert result.equals("resourceId"); + } + + + + @Test + void testDeleteResource_WithAllSubResources() { + // Arrange + String resourceId = "res123"; + PipResourceManager pipResourceManager = new PipResourceManager(); + pipResourceManager.setId(resourceId); + pipResourceManager.setMachineId("machine123"); + pipResourceManager.setK8sId("k8s123"); + pipResourceManager.setDockerId("docker123"); + pipResourceManager.setCloudId("cloud123"); + + Mockito.when(resourceManagerDao.selectById(resourceId)).thenReturn(pipResourceManager); + + // Act + resourceManagerService.deleteResource(resourceId); + + // Assert + Mockito.verify(machineDao, Mockito.times(1)).deleteById("machine123"); + Mockito.verify(k8SDao, Mockito.times(1)).deleteById("k8s123"); + Mockito.verify(dockerEndpointDao, Mockito.times(1)).deleteById("docker123"); + Mockito.verify(cloudDao, Mockito.times(1)).deleteById("cloud123"); + Mockito.verify(resourceManagerDao, Mockito.times(1)).deleteById(resourceId); + } + + @Test + void testDeleteResource_WithOnlyMachineResource() { + // Arrange + String resourceId = "res123"; + PipResourceManager pipResourceManager = new PipResourceManager(); + pipResourceManager.setId(resourceId); + pipResourceManager.setMachineId("machine123"); + + Mockito.when(resourceManagerDao.selectById(resourceId)).thenReturn(pipResourceManager); + + // Act + resourceManagerService.deleteResource(resourceId); + + // Assert + Mockito.verify(machineDao, Mockito.times(1)).deleteById("machine123"); + Mockito.verify(k8SDao, never()).deleteById(anyString()); + Mockito.verify(dockerEndpointDao, never()).deleteById(anyString()); + Mockito.verify(cloudDao, never()).deleteById(anyString()); + Mockito.verify(resourceManagerDao, Mockito.times(1)).deleteById(resourceId); + } + + @Test + void testDeleteResource_ResourceNotFound() { + // Arrange + String resourceId = "nonExistent"; + + Mockito.when(resourceManagerDao.selectById(resourceId)).thenReturn(null); + + // Act & Assert + try { + resourceManagerService.deleteResource(resourceId); + } catch (Exception e) { + // Expect no exception, just skip deletion + } + + Mockito.verify(machineDao, never()).deleteById(anyString()); + Mockito.verify(k8SDao, never()).deleteById(anyString()); + Mockito.verify(dockerEndpointDao, never()).deleteById(anyString()); + Mockito.verify(cloudDao, never()).deleteById(anyString()); + Mockito.verify(resourceManagerDao, never()).deleteById(anyString()); + } + + + @Test + void testDeleteResourceWithAllSubResources() { + // Arrange + String resourceId = "resourceId"; + PipResourceManager pipResourceManager = new PipResourceManager(); + pipResourceManager.setId(resourceId); + pipResourceManager.setMachineId("machineId"); + pipResourceManager.setK8sId("k8sId"); + pipResourceManager.setDockerId("dockerId"); + pipResourceManager.setCloudId("cloudId"); + + when(resourceManagerDao.selectById(resourceId)).thenReturn(pipResourceManager); + + // Act + resourceManagerService.deleteResource(resourceId); + + // Assert + verify(resourceManagerDao, times(1)).selectById(resourceId); + verify(machineDao, times(1)).deleteById("machineId"); + verify(k8SDao, times(1)).deleteById("k8sId"); + verify(dockerEndpointDao, times(1)).deleteById("dockerId"); + verify(cloudDao, times(1)).deleteById("cloudId"); + verify(resourceManagerDao, times(1)).deleteById(resourceId); + } + + @Test + void testDeleteResourceWithOnlyMachine() { + // Arrange + String resourceId = "resourceId"; + PipResourceManager pipResourceManager = new PipResourceManager(); + pipResourceManager.setId(resourceId); + pipResourceManager.setMachineId("machineId"); + + when(resourceManagerDao.selectById(resourceId)).thenReturn(pipResourceManager); + + // Act + resourceManagerService.deleteResource(resourceId); + + // Assert + verify(resourceManagerDao, times(1)).selectById(resourceId); + verify(machineDao, times(1)).deleteById("machineId"); + verify(k8SDao, never()).deleteById(anyString()); + verify(dockerEndpointDao, never()).deleteById(anyString()); + verify(cloudDao, never()).deleteById(anyString()); + verify(resourceManagerDao, times(1)).deleteById(resourceId); + } + + @Test + void testDeleteResourceWithNoSubResources() { + // Arrange + String resourceId = "resourceId"; + PipResourceManager pipResourceManager = new PipResourceManager(); + pipResourceManager.setId(resourceId); + + when(resourceManagerDao.selectById(resourceId)).thenReturn(pipResourceManager); + + // Act + resourceManagerService.deleteResource(resourceId); + + // Assert + verify(resourceManagerDao, times(1)).selectById(resourceId); + verify(machineDao, never()).deleteById(anyString()); + verify(k8SDao, never()).deleteById(anyString()); + verify(dockerEndpointDao, never()).deleteById(anyString()); + verify(cloudDao, never()).deleteById(anyString()); + verify(resourceManagerDao, times(1)).deleteById(resourceId); + } + + + + @Test + void testFindResourceById_ResourceExists() { + + ResourceFindResp resourceById = resourceManagerService.findResourceById("1"); + + assertNull(resourceById); + } + + +}