diff --git a/src/test/java/com/uber/cadence/internal/common/WorkflowExecutionUtilsTest.java b/src/test/java/com/uber/cadence/internal/common/WorkflowExecutionUtilsTest.java new file mode 100644 index 00000000..ea66b40a --- /dev/null +++ b/src/test/java/com/uber/cadence/internal/common/WorkflowExecutionUtilsTest.java @@ -0,0 +1,365 @@ +/** + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + *
Modifications copyright (C) 2017 Uber Technologies, Inc. + * + *
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file + * except in compliance with the License. A copy of the License is located at + * + *
http://aws.amazon.com/apache2.0 + * + *
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package com.uber.cadence.internal.common;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import com.uber.cadence.EventType;
+import com.uber.cadence.GetWorkflowExecutionHistoryResponse;
+import com.uber.cadence.History;
+import com.uber.cadence.HistoryEvent;
+import com.uber.cadence.StartChildWorkflowExecutionFailedEventAttributes;
+import com.uber.cadence.WorkflowExecution;
+import com.uber.cadence.WorkflowExecutionCloseStatus;
+import com.uber.cadence.client.WorkflowTerminatedException;
+import com.uber.cadence.client.WorkflowTimedOutException;
+import com.uber.cadence.serviceclient.IWorkflowService;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WorkflowExecutionUtilsTest {
+
+ private IWorkflowService mockService;
+ private WorkflowExecution workflowExecution;
+
+ @Before
+ public void setUp() {
+ mockService = mock(IWorkflowService.class);
+ workflowExecution =
+ new WorkflowExecution().setWorkflowId("testWorkflowId").setRunId("testRunId");
+ }
+
+ // Helper method to create a response with a single event
+ private GetWorkflowExecutionHistoryResponse createResponseWithEvent(HistoryEvent event) {
+ GetWorkflowExecutionHistoryResponse response = new GetWorkflowExecutionHistoryResponse();
+ response.setHistory(new History().setEvents(Collections.singletonList(event)));
+ return response;
+ }
+
+ // ===========================
+ // Test for successful completion case
+ // ===========================
+ @Test
+ public void testGetWorkflowExecutionResult_SuccessfulCompletion() throws Exception {
+ // Mock a completed event with a result
+ HistoryEvent completedEvent = new HistoryEvent();
+ completedEvent.setEventType(EventType.WorkflowExecutionCompleted);
+ byte[] expectedResult = "result".getBytes();
+ completedEvent.setWorkflowExecutionCompletedEventAttributes(
+ new com.uber.cadence.WorkflowExecutionCompletedEventAttributes().setResult(expectedResult));
+
+ // Mock the response from GetWorkflowExecutionHistoryWithTimeout
+ GetWorkflowExecutionHistoryResponse response = createResponseWithEvent(completedEvent);
+ when(mockService.GetWorkflowExecutionHistoryWithTimeout(any(), anyLong())).thenReturn(response);
+
+ byte[] result =
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), 5, TimeUnit.SECONDS);
+
+ assertArrayEquals(expectedResult, result);
+ }
+
+ // ===========================
+ // Test for canceled workflow case
+ // ===========================
+ @Test(expected = CancellationException.class)
+ public void testGetWorkflowExecutionResult_CancelledWorkflow() throws Exception {
+ // Mock a canceled event
+ HistoryEvent canceledEvent = new HistoryEvent();
+ canceledEvent.setEventType(EventType.WorkflowExecutionCanceled);
+ canceledEvent.setWorkflowExecutionCanceledEventAttributes(
+ new com.uber.cadence.WorkflowExecutionCanceledEventAttributes());
+
+ GetWorkflowExecutionHistoryResponse response = createResponseWithEvent(canceledEvent);
+ when(mockService.GetWorkflowExecutionHistoryWithTimeout(any(), anyLong())).thenReturn(response);
+
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), 5, TimeUnit.SECONDS);
+ }
+
+ // ===========================
+ // Test for terminated workflow case
+ // ===========================
+ @Test(expected = WorkflowTerminatedException.class)
+ public void testGetWorkflowExecutionResult_TerminatedWorkflow() throws Exception {
+ // Mock a terminated event
+ HistoryEvent terminatedEvent = new HistoryEvent();
+ terminatedEvent.setEventType(EventType.WorkflowExecutionTerminated);
+ terminatedEvent.setWorkflowExecutionTerminatedEventAttributes(
+ new com.uber.cadence.WorkflowExecutionTerminatedEventAttributes());
+
+ GetWorkflowExecutionHistoryResponse response = createResponseWithEvent(terminatedEvent);
+ when(mockService.GetWorkflowExecutionHistoryWithTimeout(any(), anyLong())).thenReturn(response);
+
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), 5, TimeUnit.SECONDS);
+ }
+
+ // ===========================
+ // Test for timed-out workflow case
+ // ===========================
+ @Test(expected = WorkflowTimedOutException.class)
+ public void testGetWorkflowExecutionResult_TimedOutWorkflow() throws Exception {
+ // Mock a timed-out event
+ HistoryEvent timedOutEvent = new HistoryEvent();
+ timedOutEvent.setEventType(EventType.WorkflowExecutionTimedOut);
+ timedOutEvent.setWorkflowExecutionTimedOutEventAttributes(
+ new com.uber.cadence.WorkflowExecutionTimedOutEventAttributes());
+
+ GetWorkflowExecutionHistoryResponse response = createResponseWithEvent(timedOutEvent);
+ when(mockService.GetWorkflowExecutionHistoryWithTimeout(any(), anyLong())).thenReturn(response);
+
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), 5, TimeUnit.SECONDS);
+ }
+
+ // ===========================
+ // Test for an unsupported close event type
+ // ===========================
+ @Test(expected = RuntimeException.class)
+ public void testGetWorkflowExecutionResult_UnsupportedCloseEvent() throws Exception {
+ // Mock an event type that doesn't represent a closed workflow
+ HistoryEvent unsupportedEvent = new HistoryEvent();
+ unsupportedEvent.setEventType(EventType.ActivityTaskScheduled); // Not a close event
+
+ GetWorkflowExecutionHistoryResponse response = createResponseWithEvent(unsupportedEvent);
+ when(mockService.GetWorkflowExecutionHistoryWithTimeout(any(), anyLong())).thenReturn(response);
+
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), 5, TimeUnit.SECONDS);
+ }
+
+ // ===========================
+ // Test for timeout exceeded while waiting
+ // ===========================
+ @Test(expected = TimeoutException.class)
+ public void testGetWorkflowExecutionResult_TimeoutExceeded() throws Exception {
+ // Simulate a delay by mocking the service call to throw a TimeoutException
+ WorkflowExecutionUtils.getWorkflowExecutionResult(
+ mockService, "testDomain", workflowExecution, Optional.empty(), -1, TimeUnit.MILLISECONDS);
+ }
+
+ // ===========================
+ // Test getId with StartChildWorkflowExecutionFailedEvent
+ // ===========================
+ @Test
+ public void testGetId_WithStartChildWorkflowExecutionFailedEvent() {
+ // Create a StartChildWorkflowExecutionFailed event with a workflow ID
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.StartChildWorkflowExecutionFailed);
+ StartChildWorkflowExecutionFailedEventAttributes attributes =
+ new StartChildWorkflowExecutionFailedEventAttributes();
+ attributes.setWorkflowId("testWorkflowId");
+ event.setStartChildWorkflowExecutionFailedEventAttributes(attributes);
+
+ // Call getId and verify it returns the workflow ID
+ String result = WorkflowExecutionUtils.getId(event);
+ assertEquals("testWorkflowId", result);
+ }
+
+ // ===========================
+ // Test getId with other event types (should return null)
+ // ===========================
+ @Test
+ public void testGetId_WithNonChildWorkflowEvent() {
+ // Create a HistoryEvent of a different type (e.g., WorkflowExecutionStarted)
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionStarted);
+
+ // Call getId and verify it returns null
+ String result = WorkflowExecutionUtils.getId(event);
+ assertNull(result);
+ }
+
+ @Test
+ public void testGetId_WithNullEvent() {
+ // Call getId with a null event and verify it returns null
+ String result = WorkflowExecutionUtils.getId(null);
+ assertNull(result);
+ }
+
+ // ===========================
+ // Test getCloseStatus for each close event type
+ // ===========================
+
+ @Test
+ public void testGetCloseStatus_Completed() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionCompleted);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.COMPLETED, result);
+ }
+
+ @Test
+ public void testGetCloseStatus_Canceled() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionCanceled);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.CANCELED, result);
+ }
+
+ @Test
+ public void testGetCloseStatus_Failed() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionFailed);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.FAILED, result);
+ }
+
+ @Test
+ public void testGetCloseStatus_TimedOut() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionTimedOut);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.TIMED_OUT, result);
+ }
+
+ @Test
+ public void testGetCloseStatus_ContinuedAsNew() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionContinuedAsNew);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.CONTINUED_AS_NEW, result);
+ }
+
+ @Test
+ public void testGetCloseStatus_Terminated() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.WorkflowExecutionTerminated);
+
+ WorkflowExecutionCloseStatus result = WorkflowExecutionUtils.getCloseStatus(event);
+ assertEquals(WorkflowExecutionCloseStatus.TERMINATED, result);
+ }
+
+ // ===========================
+ // Test getCloseStatus with an unsupported event type
+ // ===========================
+ @Test
+ public void testGetCloseStatus_InvalidEvent() {
+ HistoryEvent event = new HistoryEvent();
+ event.setEventType(EventType.ActivityTaskScheduled); // Unsupported close event type
+
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ WorkflowExecutionUtils.getCloseStatus(event);
+ });
+
+ assertTrue(exception.getMessage().contains("Not close event"));
+ }
+
+ // Helper method to create a response with events and a next page token
+ private GetWorkflowExecutionHistoryResponse createResponseWithEvents(
+ HistoryEvent[] events, byte[] nextPageToken) {
+ GetWorkflowExecutionHistoryResponse response = new GetWorkflowExecutionHistoryResponse();
+ response.setHistory(new History().setEvents(Arrays.asList(events)));
+ response.setNextPageToken(nextPageToken);
+ return response;
+ }
+ // ===========================
+ // Test for single-page history
+ // ===========================
+ @Test
+ public void testGetHistory_SinglePage() throws Exception {
+ // Create a single-page history with two events
+ HistoryEvent event1 =
+ new HistoryEvent().setEventType(EventType.WorkflowExecutionStarted).setEventId(1);
+ HistoryEvent event2 =
+ new HistoryEvent().setEventType(EventType.WorkflowExecutionCompleted).setEventId(2);
+
+ GetWorkflowExecutionHistoryResponse response =
+ createResponseWithEvents(new HistoryEvent[] {event1, event2}, null);
+ when(mockService.GetWorkflowExecutionHistory(any())).thenReturn(response);
+
+ Iterator