From 3b9cc98167b21fbca95bce45dd572802742e09c4 Mon Sep 17 00:00:00 2001 From: Moti Asayag Date: Thu, 15 Jun 2023 16:51:03 +0300 Subject: [PATCH] Add unit-tests Signed-off-by: Moti Asayag --- .../service/WorkFlowServiceImpl.java | 23 ++- .../service/WorkFlowServiceImplTest.java | 170 ++++++++++++++++++ 2 files changed, 180 insertions(+), 13 deletions(-) diff --git a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java index 79dba7fde..690b0209a 100644 --- a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java +++ b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java @@ -25,7 +25,6 @@ import java.util.UUID; import javax.annotation.PreDestroy; -import javax.persistence.EntityNotFoundException; import com.redhat.parodos.common.exceptions.IllegalWorkFlowStateException; import com.redhat.parodos.common.exceptions.ResourceNotFoundException; @@ -175,22 +174,20 @@ public WorkReport execute(WorkFlowRequestDTO workFlowRequestDTO) { * @param target target context to put arguments on */ private void mergeContextArgumentsFromExecution(UUID executionId, WorkContext target) { - WorkFlowExecution invokedBy = null; - try { - invokedBy = workFlowRepository.getById(executionId); - } - catch (EntityNotFoundException e) { + Optional invokedBy = workFlowRepository.findById(executionId); + if (invokedBy.isEmpty()) { throw new ResourceNotFoundException(ResourceType.WORKFLOW_EXECUTION, executionId); } - if (invokedBy != null) { - var source = invokedBy.getWorkFlowExecutionContext().getWorkContext(); - // TODO don't overwrite in case key already exists - Map sourceArguments = (Map) WorkContextDelegate.read(source, - WorkContextDelegate.ProcessType.WORKFLOW_EXECUTION, WorkContextDelegate.Resource.ARGUMENTS); - sourceArguments.entrySet().forEach(entry -> WorkContextDelegate.write(target, - WorkContextDelegate.ProcessType.WORKFLOW_EXECUTION, WorkContextDelegate.Resource.ARGUMENTS, entry)); + var source = invokedBy.get().getWorkFlowExecutionContext().getWorkContext(); + Map sourceArguments = (Map) WorkContextDelegate.read(source, + WorkContextDelegate.ProcessType.WORKFLOW_EXECUTION, WorkContextDelegate.Resource.ARGUMENTS); + if (sourceArguments == null) { + return; } + // TODO don't overwrite in case key already exists + sourceArguments.entrySet().forEach(entry -> WorkContextDelegate.write(target, + WorkContextDelegate.ProcessType.WORKFLOW_EXECUTION, WorkContextDelegate.Resource.ARGUMENTS, entry)); } @Override diff --git a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java index 4943a9762..6b4c9e548 100644 --- a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java +++ b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java @@ -33,6 +33,7 @@ import com.redhat.parodos.workflow.execution.repository.WorkFlowRepository; import com.redhat.parodos.workflow.execution.repository.WorkFlowTaskRepository; import com.redhat.parodos.workflow.option.WorkFlowOption; +import com.redhat.parodos.workflow.utils.WorkContextUtils; import com.redhat.parodos.workflows.work.DefaultWorkReport; import com.redhat.parodos.workflows.work.Work; import com.redhat.parodos.workflows.work.WorkContext; @@ -178,6 +179,175 @@ void executeWithDTOWithValidData() { verify(this.workFlowDefinitionRepository, times(2)).findFirstByName(any()); } + @Test + @WithMockUser(username = "test-user") + void executeWithDTOWithMissingInvokingExecutionContext() { + // given + User user = User.builder().username("test-user").build(); + user.setId(UUID.randomUUID()); + Work work = mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + when(work.execute(any())).thenReturn(new DefaultWorkReport(WorkStatus.COMPLETED, new WorkContext() { + { + put("foo", "bar"); + } + })); + when(this.workFlowDefinitionRepository.findFirstByName(any())) + .thenReturn(this.sampleWorkflowDefinition("test")); + when(this.workFlowWorkRepository.findFirstByWorkDefinitionId(any())).thenReturn(null); + when(this.workFlowDelegate.initWorkFlowContext(any(), any())).thenReturn(new WorkContext()); + when(this.workFlowDelegate.getWorkFlowByName(TEST_WORKFLOW_NAME)).thenReturn(workFlow); + UUID invokingExecutionId = UUID.randomUUID(); + when(this.workFlowRepository.findById(invokingExecutionId)).thenReturn(Optional.empty()); + WorkFlowDefinitionResponseDTO workFlowDefinitionResponseDTO = WorkFlowDefinitionResponseDTO.builder() + .name(TEST_WORKFLOW_NAME).works(List.of()).build(); + when(this.workFlowDefinitionService.getWorkFlowDefinitionByName(TEST_WORKFLOW_NAME)) + .thenReturn(workFlowDefinitionResponseDTO); + when(this.userService.getUserEntityByUsername("test-user")).thenReturn(user); + + // when + // @formatter:off + assertThat(assertThrows(ResourceNotFoundException.class, + () -> this.workFlowService.execute(WorkFlowRequestDTO.builder() + .projectId(UUID.randomUUID()) + .works(List.of()) + .workFlowName(TEST_WORKFLOW_NAME) + .invokingExecutionId(invokingExecutionId) + .build()))) + .hasMessage("Workflow execution with ID: " + invokingExecutionId + " not found"); + // @formatter:on + + // then + verify(this.workFlowDelegate, times(1)).getWorkFlowByName(any()); + verify(this.workFlowDelegate, times(1)).initWorkFlowContext(any(), any()); + verify(this.workFlowDefinitionRepository, times(1)).findFirstByName(any()); + verify(this.workFlowRepository, times(1)).findById(any()); + } + + @Test + @WithMockUser(username = "test-user") + void executeWithDTOWithEmptyInvokingExecutionContext() { + // given + User user = User.builder().username("test-user").build(); + user.setId(UUID.randomUUID()); + Work work = mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + when(work.execute(any())).thenReturn(new DefaultWorkReport(WorkStatus.COMPLETED, new WorkContext() { + { + put("foo", "bar"); + } + })); + when(this.workFlowDefinitionRepository.findFirstByName(any())) + .thenReturn(this.sampleWorkflowDefinition("test")); + when(this.workFlowWorkRepository.findFirstByWorkDefinitionId(any())).thenReturn(null); + when(this.workFlowDelegate.initWorkFlowContext(any(), any())).thenReturn(new WorkContext()); + when(this.workFlowDelegate.getWorkFlowByName(TEST_WORKFLOW_NAME)).thenReturn(workFlow); + WorkFlowExecution workFlowExecution = WorkFlowExecution.builder().status(WorkStatus.IN_PROGRESS).user(user) + .build(); + workFlowExecution.setId(UUID.randomUUID()); + when(this.workFlowRepository.save(any())).thenReturn(workFlowExecution); + UUID invokingExecutionId = UUID.randomUUID(); + + WorkContext invokingWorkContext = new WorkContext(); + // @formatter:off + WorkFlowExecution invokingWorkFlowExecution = WorkFlowExecution.builder() + .status(WorkStatus.COMPLETED) + .user(user) + .workFlowExecutionContext(WorkFlowExecutionContext.builder().workContext(invokingWorkContext).build()) + .build(); + // @formatter:on + when(this.workFlowRepository.findById(invokingExecutionId)).thenReturn(Optional.of(invokingWorkFlowExecution)); + WorkFlowDefinitionResponseDTO workFlowDefinitionResponseDTO = WorkFlowDefinitionResponseDTO.builder() + .name(TEST_WORKFLOW_NAME).works(List.of()).build(); + when(this.workFlowDefinitionService.getWorkFlowDefinitionByName(TEST_WORKFLOW_NAME)) + .thenReturn(workFlowDefinitionResponseDTO); + when(this.userService.getUserEntityByUsername("test-user")).thenReturn(user); + + // when + // @formatter:off + WorkReport report = this.workFlowService.execute(WorkFlowRequestDTO.builder() + .projectId(UUID.randomUUID()) + .works(List.of()) + .workFlowName(TEST_WORKFLOW_NAME) + .invokingExecutionId(invokingExecutionId) + .build()); + // @formatter:on + + // then + assertThat(report).isNotNull(); + assertThat(report.getStatus()).isEqualTo(WorkStatus.IN_PROGRESS); + assertThat(report.getError()).isNull(); + assertThat(report.getWorkContext()).isNotNull(); + assertThat(WorkContextUtils.getMainExecutionId(report.getWorkContext())).isEqualTo(workFlowExecution.getId()); + + verify(this.workFlowDelegate, times(2)).getWorkFlowByName(any()); + verify(this.workFlowDelegate, times(1)).initWorkFlowContext(any(), any()); + verify(this.workFlowDefinitionRepository, times(2)).findFirstByName(any()); + verify(this.workFlowRepository, times(1)).save(any()); + verify(this.workFlowRepository, times(2)).findById(any()); + } + + @Test + @WithMockUser(username = "test-user") + void executeWithDTOWithInvokingExecutionContext() { + // given + User user = User.builder().username("test-user").build(); + user.setId(UUID.randomUUID()); + Work work = mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + when(work.execute(any())).thenReturn(new DefaultWorkReport(WorkStatus.COMPLETED, new WorkContext() { + { + put("foo", "bar"); + } + })); + when(this.workFlowDefinitionRepository.findFirstByName(any())) + .thenReturn(this.sampleWorkflowDefinition("test")); + when(this.workFlowWorkRepository.findFirstByWorkDefinitionId(any())).thenReturn(null); + when(this.workFlowDelegate.initWorkFlowContext(any(), any())).thenReturn(new WorkContext()); + when(this.workFlowDelegate.getWorkFlowByName(TEST_WORKFLOW_NAME)).thenReturn(workFlow); + WorkFlowExecution workFlowExecution = WorkFlowExecution.builder().status(WorkStatus.IN_PROGRESS).user(user) + .build(); + workFlowExecution.setId(UUID.randomUUID()); + when(this.workFlowRepository.save(any())).thenReturn(workFlowExecution); + UUID invokingExecutionId = UUID.randomUUID(); + + WorkContext invokingWorkContext = new WorkContext(); + // @formatter:off + WorkFlowExecution invokingWorkFlowExecution = WorkFlowExecution.builder() + .status(WorkStatus.COMPLETED) + .user(user) + .workFlowExecutionContext(WorkFlowExecutionContext.builder().workContext(invokingWorkContext).build()) + .build(); + // @formatter:on + when(this.workFlowRepository.findById(invokingExecutionId)).thenReturn(Optional.of(invokingWorkFlowExecution)); + WorkFlowDefinitionResponseDTO workFlowDefinitionResponseDTO = WorkFlowDefinitionResponseDTO.builder() + .name(TEST_WORKFLOW_NAME).works(List.of()).build(); + when(this.workFlowDefinitionService.getWorkFlowDefinitionByName(TEST_WORKFLOW_NAME)) + .thenReturn(workFlowDefinitionResponseDTO); + when(this.userService.getUserEntityByUsername("test-user")).thenReturn(user); + + // when + // @formatter:off + WorkReport report = this.workFlowService.execute(WorkFlowRequestDTO.builder() + .projectId(UUID.randomUUID()) + .works(List.of()) + .workFlowName(TEST_WORKFLOW_NAME) + .invokingExecutionId(invokingExecutionId) + .build()); + // @formatter:on + + // then + assertNotNull(report); + assertEquals("IN_PROGRESS", report.getStatus().toString()); + assertNull(report.getError()); + + verify(this.workFlowDelegate, times(2)).getWorkFlowByName(any()); + verify(this.workFlowDelegate, times(1)).initWorkFlowContext(any(), any()); + verify(this.workFlowDefinitionRepository, times(2)).findFirstByName(any()); + verify(this.workFlowRepository, times(1)).save(any()); + verify(this.workFlowRepository, times(2)).findById(any()); + } + @Test @WithMockUser(username = "test-user") void executeWithDTOWithNoMainWorkFlow() {