diff --git a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncChildWorkflowTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncChildWorkflowTest.kt index 02883a993b..1fa8899c27 100644 --- a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncChildWorkflowTest.kt +++ b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncChildWorkflowTest.kt @@ -26,7 +26,7 @@ import io.temporal.common.converter.JacksonJsonPayloadConverter import io.temporal.common.converter.KotlinObjectMapperFactory import io.temporal.internal.async.FunctionWrappingUtil import io.temporal.internal.sync.AsyncInternal -import io.temporal.testing.TestWorkflowRule +import io.temporal.testing.internal.SDKTestWorkflowRule import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -35,7 +35,7 @@ class KotlinAsyncChildWorkflowTest { @Rule @JvmField - var testWorkflowRule: TestWorkflowRule = TestWorkflowRule.newBuilder() + var testWorkflowRule: SDKTestWorkflowRule = SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(ParentWorkflowImpl::class.java, ChildWorkflowImpl::class.java) .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() diff --git a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncCompanionFunctionTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncCompanionFunctionTest.kt index aaef1f2ef5..831ca2e13a 100644 --- a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncCompanionFunctionTest.kt +++ b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncCompanionFunctionTest.kt @@ -26,9 +26,9 @@ import io.temporal.common.converter.JacksonJsonPayloadConverter import io.temporal.common.converter.KotlinObjectMapperFactory import io.temporal.internal.async.FunctionWrappingUtil import io.temporal.internal.sync.AsyncInternal -import io.temporal.testing.TestWorkflowRule -import junit.framework.Assert.assertTrue +import io.temporal.testing.internal.SDKTestWorkflowRule import org.junit.Assert +import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import java.util.concurrent.atomic.AtomicBoolean @@ -46,7 +46,7 @@ class KotlinAsyncCompanionFunctionTest { @Rule @JvmField - var testWorkflowRule: TestWorkflowRule = TestWorkflowRule.newBuilder() + var testWorkflowRule: SDKTestWorkflowRule = SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(CompanionFunctionReferenceWorkflowImpl::class.java) .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() diff --git a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncLambdaTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncLambdaTest.kt index 4d227590a9..594d60267e 100644 --- a/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncLambdaTest.kt +++ b/temporal-kotlin/src/test/kotlin/io/temporal/workflow/KotlinAsyncLambdaTest.kt @@ -26,9 +26,9 @@ import io.temporal.common.converter.JacksonJsonPayloadConverter import io.temporal.common.converter.KotlinObjectMapperFactory import io.temporal.internal.async.FunctionWrappingUtil import io.temporal.internal.sync.AsyncInternal -import io.temporal.testing.TestWorkflowRule -import junit.framework.Assert.assertTrue +import io.temporal.testing.internal.SDKTestWorkflowRule import org.junit.Assert +import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import java.util.concurrent.atomic.AtomicBoolean @@ -41,7 +41,7 @@ class KotlinAsyncLambdaTest { @Rule @JvmField - var testWorkflowRule: TestWorkflowRule = TestWorkflowRule.newBuilder() + var testWorkflowRule: SDKTestWorkflowRule = SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(LambdaWorkflowImpl::class.java) .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/ActivityFailureTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/ActivityFailureTest.java index b189fad0d0..44facaa909 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/ActivityFailureTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/ActivityFailureTest.java @@ -19,7 +19,7 @@ package io.temporal.opentracing; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import io.opentracing.Scope; import io.opentracing.mock.MockSpan; @@ -34,7 +34,7 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; import io.temporal.failure.ApplicationFailure; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -53,8 +53,8 @@ public class ActivityFailureTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/CustomSpanNamingTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/CustomSpanNamingTest.java index ee81b0c4cc..7e14e7594b 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/CustomSpanNamingTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/CustomSpanNamingTest.java @@ -35,7 +35,7 @@ import io.temporal.common.RetryOptions; import io.temporal.failure.ApplicationFailure; import io.temporal.opentracing.internal.ActionTypeAndNameSpanBuilderProvider; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -55,8 +55,8 @@ public class CustomSpanNamingTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors( diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/LocalActivityTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/LocalActivityTest.java index 34159455fb..77285e5a1a 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/LocalActivityTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/LocalActivityTest.java @@ -32,7 +32,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -50,8 +50,8 @@ public class LocalActivityTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/NoClientSpanTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/NoClientSpanTest.java index 15b4cb5135..d801977dba 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/NoClientSpanTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/NoClientSpanTest.java @@ -30,7 +30,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -47,8 +47,8 @@ public class NoClientSpanTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/SpanContextPropagationTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/SpanContextPropagationTest.java index 77bf7d3c3f..1f62477874 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/SpanContextPropagationTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/SpanContextPropagationTest.java @@ -19,9 +19,7 @@ package io.temporal.opentracing; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import io.opentracing.Scope; import io.opentracing.Span; @@ -37,9 +35,11 @@ import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; import io.temporal.failure.ApplicationFailure; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; -import io.temporal.workflow.*; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; import java.time.Duration; import org.junit.After; import org.junit.Before; @@ -54,8 +54,8 @@ public class SpanContextPropagationTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowReplayTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowReplayTest.java index e02ce10d3c..a381ef5ab6 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowReplayTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowReplayTest.java @@ -33,7 +33,7 @@ import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -52,8 +52,8 @@ public class WorkflowReplayTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowRetryTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowRetryTest.java index 79d42d01cc..502b2419bf 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowRetryTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/WorkflowRetryTest.java @@ -34,7 +34,7 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; import io.temporal.failure.ApplicationFailure; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; @@ -53,8 +53,8 @@ public class WorkflowRetryTest { new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor()) diff --git a/temporal-opentracing/src/test/java/io/temporal/opentracing/integration/JaegerTest.java b/temporal-opentracing/src/test/java/io/temporal/opentracing/integration/JaegerTest.java index 1b9020fe3c..e1d8c735c5 100644 --- a/temporal-opentracing/src/test/java/io/temporal/opentracing/integration/JaegerTest.java +++ b/temporal-opentracing/src/test/java/io/temporal/opentracing/integration/JaegerTest.java @@ -36,15 +36,21 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; -import io.temporal.opentracing.*; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.opentracing.OpenTracingClientInterceptor; +import io.temporal.opentracing.OpenTracingOptions; +import io.temporal.opentracing.OpenTracingSpanContextCodec; +import io.temporal.opentracing.OpenTracingWorkerInterceptor; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.worker.WorkerFactoryOptions; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; import java.time.Duration; import java.util.List; -import org.junit.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; public class JaegerTest { private static final OpenTracingOptions JAEGER_COMPATIBLE_CONFIG = @@ -57,8 +63,8 @@ public class JaegerTest { private Tracer tracer; @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowClientOptions( WorkflowClientOptions.newBuilder() .setInterceptors(new OpenTracingClientInterceptor(JAEGER_COMPATIBLE_CONFIG)) diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/WorkflowRetryAfterActivityFailureTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/WorkflowRetryAfterActivityFailureTest.java index 8e5ff14a24..dc27325dba 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/WorkflowRetryAfterActivityFailureTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/WorkflowRetryAfterActivityFailureTest.java @@ -29,7 +29,7 @@ import io.temporal.common.RetryOptions; import io.temporal.failure.ApplicationFailure; import io.temporal.failure.TerminatedFailure; -import io.temporal.testing.TestWorkflowRule; +import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.workflow.shared.TestActivities.TestActivity1; import io.temporal.workflow.shared.TestWorkflows.TestWorkflow1; import java.time.Duration; @@ -42,8 +42,8 @@ public class WorkflowRetryAfterActivityFailureTest { private static AtomicInteger failureCounter = new AtomicInteger(1); @Rule - public TestWorkflowRule testWorkflowRule = - TestWorkflowRule.newBuilder() + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(WorkflowImpl.class) .setActivityImplementations(new FailingActivityImpl()) .build(); diff --git a/temporal-testing-junit4/src/main/java/io/temporal/testing/TestWorkflowRule.java b/temporal-testing-junit4/src/main/java/io/temporal/testing/TestWorkflowRule.java index 9e8ac97892..76bc670292 100644 --- a/temporal-testing-junit4/src/main/java/io/temporal/testing/TestWorkflowRule.java +++ b/temporal-testing-junit4/src/main/java/io/temporal/testing/TestWorkflowRule.java @@ -25,6 +25,8 @@ import io.temporal.api.workflowservice.v1.WorkflowServiceGrpc; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; +import io.temporal.client.WorkflowOptions; +import io.temporal.client.WorkflowStub; import io.temporal.common.interceptors.WorkerInterceptor; import io.temporal.internal.common.DebugModeUtils; import io.temporal.worker.Worker; @@ -68,8 +70,6 @@ */ public class TestWorkflowRule implements TestRule { - private static final long DEFAULT_TEST_TIMEOUT_SECONDS = 10; - private final String namespace; private final boolean useExternalService; private final boolean doNotStart; @@ -112,11 +112,8 @@ private TestWorkflowRule(Builder builder) { ? WorkflowImplementationOptions.getDefaultInstance() : builder.workflowImplementationOptions; globalTimeout = - !DebugModeUtils.isTemporalDebugModeOn() - ? Timeout.seconds( - builder.testTimeoutSeconds == 0 - ? DEFAULT_TEST_TIMEOUT_SECONDS - : builder.testTimeoutSeconds) + !DebugModeUtils.isTemporalDebugModeOn() && builder.testTimeoutSeconds != 0 + ? Timeout.seconds(builder.testTimeoutSeconds) : null; WorkflowClientOptions clientOptions = @@ -145,7 +142,6 @@ public static class Builder { private String target; private boolean useExternalService; private boolean doNotStart; - private long testTimeoutSeconds; private long initialTimeMillis; private Class[] workflowTypes; @@ -154,6 +150,7 @@ public static class Builder { private WorkflowClientOptions workflowClientOptions; private WorkerFactoryOptions workerFactoryOptions; private WorkerOptions workerOptions; + private long testTimeoutSeconds; protected Builder() {} @@ -221,7 +218,11 @@ public Builder setTarget(String target) { return this; } - /** Global test timeout. Default is 10 seconds. */ + /** + * @deprecated Temporal test rule shouldn't be responsible for enforcing test timeouts. Use + * toolchain of your test framework to enforce timeouts. + */ + @Deprecated public Builder setTestTimeoutSeconds(long testTimeoutSeconds) { this.testTimeoutSeconds = testTimeoutSeconds; return this; @@ -369,4 +370,18 @@ public History getWorkflowExecutionHistory(WorkflowExecution execution) { public Worker getWorker() { return testEnvironment.getWorkerFactory().getWorker(getTaskQueue()); } + + public T newWorkflowStub(Class workflow) { + return getWorkflowClient() + .newWorkflowStub(workflow, newWorkflowOptionsForTaskQueue(getTaskQueue())); + } + + public WorkflowStub newUntypedWorkflowStub(String workflow) { + return getWorkflowClient() + .newUntypedWorkflowStub(workflow, newWorkflowOptionsForTaskQueue(getTaskQueue())); + } + + private static WorkflowOptions newWorkflowOptionsForTaskQueue(String taskQueue) { + return WorkflowOptions.newBuilder().setTaskQueue(taskQueue).build(); + } } diff --git a/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestOptions.java b/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestOptions.java index 025b18c56c..df65263a98 100644 --- a/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestOptions.java +++ b/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestOptions.java @@ -29,10 +29,6 @@ public class SDKTestOptions { // stepping through code in a debugger without timing out. private static final boolean DEBUGGER_TIMEOUTS = false; - public static WorkflowOptions newWorkflowOptionsForTaskQueue(String taskQueue) { - return WorkflowOptions.newBuilder().setTaskQueue(taskQueue).build(); - } - public static WorkflowOptions newWorkflowOptionsForTaskQueue200sTimeout(String taskQueue) { return WorkflowOptions.newBuilder() .setWorkflowRunTimeout(Duration.ofSeconds(200)) diff --git a/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestWorkflowRule.java b/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestWorkflowRule.java index 795c058bfd..9a12781ce2 100644 --- a/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestWorkflowRule.java +++ b/temporal-testing-junit4/src/main/java/io/temporal/testing/internal/SDKTestWorkflowRule.java @@ -38,6 +38,7 @@ import io.temporal.client.WorkflowQueryException; import io.temporal.client.WorkflowStub; import io.temporal.common.interceptors.WorkerInterceptor; +import io.temporal.internal.common.DebugModeUtils; import io.temporal.internal.common.WorkflowExecutionHistory; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.testing.TestWorkflowEnvironment; @@ -52,18 +53,25 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.junit.Test; import org.junit.rules.TestRule; +import org.junit.rules.Timeout; import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Intended to be used only in the Java SDK test code. This Rule duplicates {@link TestWorkflowRule} + * and provides additional convenience methods for SDK development + */ public class SDKTestWorkflowRule implements TestRule { + private static final Logger log = LoggerFactory.getLogger(SDKTestWorkflowRule.class); + + private static final long DEFAULT_TEST_TIMEOUT_SECONDS = 10; public static final String NAMESPACE = "UnitTest"; public static final String BINARY_CHECKSUM = "testChecksum"; @@ -78,17 +86,28 @@ public class SDKTestWorkflowRule implements TestRule { private static final List> delayedCallbacks = new ArrayList<>(); private static final ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1); - private static final Logger log = LoggerFactory.getLogger(SDKTestWorkflowRule.class); + + @Nullable private final Timeout globalTimeout; + private final TestWorkflowRule testWorkflowRule; - private SDKTestWorkflowRule(TestWorkflowRule.Builder testWorkflowRuleBuilder) { + private SDKTestWorkflowRule(SDKTestWorkflowRule.Builder builder) { if (useExternalService) { - testWorkflowRuleBuilder.setUseExternalService(true); + builder.testWorkflowRuleBuilder.setUseExternalService(true); if (temporalServiceAddress != null) { - testWorkflowRuleBuilder.setTarget(temporalServiceAddress); + builder.testWorkflowRuleBuilder.setTarget(temporalServiceAddress); } } - testWorkflowRule = testWorkflowRuleBuilder.build(); + + globalTimeout = + !DebugModeUtils.isTemporalDebugModeOn() + ? Timeout.seconds( + builder.testTimeoutSeconds == 0 + ? DEFAULT_TEST_TIMEOUT_SECONDS + : builder.testTimeoutSeconds) + : null; + + testWorkflowRule = builder.testWorkflowRuleBuilder.build(); } public static Builder newBuilder() { @@ -96,6 +115,7 @@ public static Builder newBuilder() { } public static class Builder { + private long testTimeoutSeconds; private boolean workerFactoryOptionsAreSet = false; TestWorkflowRule.Builder testWorkflowRuleBuilder; @@ -158,8 +178,9 @@ public Builder setTarget(String target) { return this; } + /** Global test timeout. Default is 10 seconds. */ public Builder setTestTimeoutSeconds(long testTimeoutSeconds) { - testWorkflowRuleBuilder.setTestTimeoutSeconds(testTimeoutSeconds); + this.testTimeoutSeconds = testTimeoutSeconds; return this; } @@ -176,12 +197,20 @@ public SDKTestWorkflowRule build() { new TracingWorkerInterceptor(new TracingWorkerInterceptor.FilteredTrace())) .build()); } - return new SDKTestWorkflowRule(testWorkflowRuleBuilder); + return new SDKTestWorkflowRule(this); } } - public Statement apply(Statement base, Description description) { - return testWorkflowRule.apply(base, description); + public Statement apply(@Nonnull Statement base, Description description) { + Statement testWorkflowStatement = base; + + Test annotation = description.getAnnotation(Test.class); + boolean timeoutIsOverriddenOnTestAnnotation = annotation != null && annotation.timeout() > 0; + if (globalTimeout != null && !timeoutIsOverriddenOnTestAnnotation) { + testWorkflowStatement = globalTimeout.apply(testWorkflowStatement, description); + } + + return testWorkflowRule.apply(testWorkflowStatement, description); } public WorkflowServiceGrpc.WorkflowServiceBlockingStub blockingStub() { @@ -258,8 +287,7 @@ public TestWorkflowEnvironment getTestEnvironment() { } public T newWorkflowStub(Class workflow) { - return getWorkflowClient() - .newWorkflowStub(workflow, SDKTestOptions.newWorkflowOptionsForTaskQueue(getTaskQueue())); + return testWorkflowRule.newWorkflowStub(workflow); } public T newWorkflowStubTimeoutOptions(Class workflow) { @@ -273,10 +301,8 @@ public T newWorkflowStub200sTimeoutOptions(Class workflow) { workflow, SDKTestOptions.newWorkflowOptionsForTaskQueue200sTimeout(getTaskQueue())); } - public WorkflowStub newUntypedWorkflowStub(String workflow) { - return getWorkflowClient() - .newUntypedWorkflowStub( - workflow, SDKTestOptions.newWorkflowOptionsForTaskQueue(getTaskQueue())); + public WorkflowStub newUntypedWorkflowStub(String workflow) { + return testWorkflowRule.newUntypedWorkflowStub(workflow); } public WorkflowStub newUntypedWorkflowStubTimeoutOptions(String workflow) {