Skip to content

Commit

Permalink
Test for TestWorkflowMutableStateImpl (#979)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobht authored Nov 28, 2024
1 parent fb7d322 commit 2da5fe4
Show file tree
Hide file tree
Showing 5 changed files with 422 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
*
* * 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.testservice;

import com.uber.cadence.*;

public class TestWorkflowMutableStateAttrUtil {

static void validateScheduleActivityTask(ScheduleActivityTaskDecisionAttributes a)
throws BadRequestError {
if (a == null) {
throw new BadRequestError("ScheduleActivityTaskDecisionAttributes is not set on decision.");
}

if (a.getTaskList() == null || a.getTaskList().getName().isEmpty()) {
throw new BadRequestError("TaskList is not set on decision.");
}
if (a.getActivityId() == null || a.getActivityId().isEmpty()) {
throw new BadRequestError("ActivityId is not set on decision.");
}
if (a.getActivityType() == null
|| a.getActivityType().getName() == null
|| a.getActivityType().getName().isEmpty()) {
throw new BadRequestError("ActivityType is not set on decision.");
}
if (a.getStartToCloseTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid StartToCloseTimeoutSeconds is not set on decision.");
}
if (a.getScheduleToStartTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid ScheduleToStartTimeoutSeconds is not set on decision.");
}
if (a.getScheduleToCloseTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid ScheduleToCloseTimeoutSeconds is not set on decision.");
}
if (a.getHeartbeatTimeoutSeconds() < 0) {
throw new BadRequestError("Ac valid HeartbeatTimeoutSeconds is not set on decision.");
}
}

static void validateStartChildExecutionAttributes(StartChildWorkflowExecutionDecisionAttributes a)
throws BadRequestError {
if (a == null) {
throw new BadRequestError(
"StartChildWorkflowExecutionDecisionAttributes is not set on decision.");
}

if (a.getWorkflowId().isEmpty()) {
throw new BadRequestError("Required field WorkflowID is not set on decision.");
}

if (a.getWorkflowType() == null || a.getWorkflowType().getName().isEmpty()) {
throw new BadRequestError("Required field WorkflowType is not set on decision.");
}

RetryPolicy retryPolicy = a.getRetryPolicy();
if (retryPolicy != null) {
RetryState.validateRetryPolicy(retryPolicy);
}
}

public static void inheritUnsetPropertiesFromParentWorkflow(
StartWorkflowExecutionRequest startRequest, StartChildWorkflowExecutionDecisionAttributes a) {
// Inherit tasklist from parent workflow execution if not provided on decision
if (a.getTaskList() == null || a.getTaskList().getName().isEmpty()) {
a.setTaskList(startRequest.getTaskList());
}

// Inherit workflow timeout from parent workflow execution if not provided on decision
if (a.getExecutionStartToCloseTimeoutSeconds() <= 0) {
a.setExecutionStartToCloseTimeoutSeconds(
startRequest.getExecutionStartToCloseTimeoutSeconds());
}

// Inherit decision task timeout from parent workflow execution if not provided on decision
if (a.getTaskStartToCloseTimeoutSeconds() <= 0) {
a.setTaskStartToCloseTimeoutSeconds(startRequest.getTaskStartToCloseTimeoutSeconds());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package com.uber.cadence.internal.testservice;

import static com.uber.cadence.internal.testservice.TestWorkflowMutableStateAttrUtil.*;

import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinition;
Expand Down Expand Up @@ -72,7 +74,6 @@
import com.uber.cadence.RespondDecisionTaskCompletedRequest;
import com.uber.cadence.RespondDecisionTaskFailedRequest;
import com.uber.cadence.RespondQueryTaskCompletedRequest;
import com.uber.cadence.RetryPolicy;
import com.uber.cadence.ScheduleActivityTaskDecisionAttributes;
import com.uber.cadence.SignalExternalWorkflowExecutionDecisionAttributes;
import com.uber.cadence.SignalExternalWorkflowExecutionFailedCause;
Expand Down Expand Up @@ -592,87 +593,19 @@ private void processScheduleActivityTask(
ctx.lockTimer();
}

private void validateScheduleActivityTask(ScheduleActivityTaskDecisionAttributes a)
throws BadRequestError {
if (a == null) {
throw new BadRequestError("ScheduleActivityTaskDecisionAttributes is not set on decision.");
}

if (a.getTaskList() == null || a.getTaskList().getName().isEmpty()) {
throw new BadRequestError("TaskList is not set on decision.");
}
if (a.getActivityId() == null || a.getActivityId().isEmpty()) {
throw new BadRequestError("ActivityId is not set on decision.");
}
if (a.getActivityType() == null
|| a.getActivityType().getName() == null
|| a.getActivityType().getName().isEmpty()) {
throw new BadRequestError("ActivityType is not set on decision.");
}
if (a.getStartToCloseTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid StartToCloseTimeoutSeconds is not set on decision.");
}
if (a.getScheduleToStartTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid ScheduleToStartTimeoutSeconds is not set on decision.");
}
if (a.getScheduleToCloseTimeoutSeconds() <= 0) {
throw new BadRequestError("A valid ScheduleToCloseTimeoutSeconds is not set on decision.");
}
if (a.getHeartbeatTimeoutSeconds() < 0) {
throw new BadRequestError("Ac valid HeartbeatTimeoutSeconds is not set on decision.");
}
}

private void processStartChildWorkflow(
RequestContext ctx,
StartChildWorkflowExecutionDecisionAttributes a,
long decisionTaskCompletedId)
throws BadRequestError, InternalServiceError {
validateStartChildExecutionAttributes(a);
inheritUnsetPropertiesFromParentWorkflow(startRequest, a);
StateMachine<ChildWorkflowData> child = StateMachines.newChildWorkflowStateMachine(service);
childWorkflows.put(ctx.getNextEventId(), child);
child.action(StateMachines.Action.INITIATE, ctx, a, decisionTaskCompletedId);
ctx.lockTimer();
}

/** Clone of the validateStartChildExecutionAttributes from historyEngine.go */
private void validateStartChildExecutionAttributes(
StartChildWorkflowExecutionDecisionAttributes a) throws BadRequestError {
if (a == null) {
throw new BadRequestError(
"StartChildWorkflowExecutionDecisionAttributes is not set on decision.");
}

if (a.getWorkflowId().isEmpty()) {
throw new BadRequestError("Required field WorkflowID is not set on decision.");
}

if (a.getWorkflowType() == null || a.getWorkflowType().getName().isEmpty()) {
throw new BadRequestError("Required field WorkflowType is not set on decision.");
}

// Inherit tasklist from parent workflow execution if not provided on decision
if (a.getTaskList() == null || a.getTaskList().getName().isEmpty()) {
a.setTaskList(startRequest.getTaskList());
}

// Inherit workflow timeout from parent workflow execution if not provided on decision
if (a.getExecutionStartToCloseTimeoutSeconds() <= 0) {
a.setExecutionStartToCloseTimeoutSeconds(
startRequest.getExecutionStartToCloseTimeoutSeconds());
}

// Inherit decision task timeout from parent workflow execution if not provided on decision
if (a.getTaskStartToCloseTimeoutSeconds() <= 0) {
a.setTaskStartToCloseTimeoutSeconds(startRequest.getTaskStartToCloseTimeoutSeconds());
}

RetryPolicy retryPolicy = a.getRetryPolicy();
if (retryPolicy != null) {
RetryState.validateRetryPolicy(retryPolicy);
}
}

private void processSignalExternalWorkflowExecution(
RequestContext ctx,
SignalExternalWorkflowExecutionDecisionAttributes a,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
*
* * 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.testservice;

import static com.uber.cadence.internal.testservice.TestWorkflowMutableStateAttrUtil.validateStartChildExecutionAttributes;

import com.uber.cadence.RetryPolicy;
import com.uber.cadence.StartChildWorkflowExecutionDecisionAttributes;
import com.uber.cadence.WorkflowType;
import java.util.Arrays;
import java.util.Collection;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class TestWorkflowMutableStateAttrUtil_inheritUnsetPropertiesFromParentWorkflow
extends TestCase {

private final StartChildWorkflowExecutionDecisionAttributes attributes;
private final String errorMessage;

public TestWorkflowMutableStateAttrUtil_inheritUnsetPropertiesFromParentWorkflow(
String testName,
StartChildWorkflowExecutionDecisionAttributes attributes,
String errorMessage) {
this.attributes = attributes;
this.errorMessage = errorMessage;
}

@Parameterized.Parameters(name = "{index}: {0}")
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{"valid", createAtt(), null},
{"null", null, "StartChildWorkflowExecutionDecisionAttributes is not set on decision."},
{
"WorkflowId empty",
createAtt().setWorkflowId(""),
"Required field WorkflowID is not set on decision."
},
{
"WorkflowType null",
createAtt().setWorkflowType(null),
"Required field WorkflowType is not set on decision."
},
{
"WorkflowType name empty",
createAtt().setWorkflowType(new WorkflowType().setName("")),
"Required field WorkflowType is not set on decision."
},
{"RetryPolicy null", createAtt().setRetryPolicy(null), null},
});
}

@Test
public void testValidateScheduleActivityTask() {
try {
validateStartChildExecutionAttributes(attributes);
if (errorMessage != null) {
fail("Expected exception");
}
} catch (Exception e) {
assertEquals(errorMessage, e.getMessage());
}
}

private static StartChildWorkflowExecutionDecisionAttributes createAtt() {
return new StartChildWorkflowExecutionDecisionAttributes()
.setWorkflowId("testWorkflowId")
.setWorkflowType(new WorkflowType().setName("testWorkflowType"))
.setRetryPolicy(
new RetryPolicy()
.setInitialIntervalInSeconds(12)
.setBackoffCoefficient(3.4)
.setMaximumIntervalInSeconds(56)
.setMaximumAttempts(78)
.setExpirationIntervalInSeconds(99));
}
}
Loading

0 comments on commit 2da5fe4

Please sign in to comment.