Package io.temporal.testing
Interface TestWorkflowEnvironment
-
- All Superinterfaces:
java.lang.AutoCloseable
,java.io.Closeable
- All Known Implementing Classes:
TestWorkflowEnvironmentInternal
public interface TestWorkflowEnvironment extends java.io.Closeable
TestWorkflowEnvironment provides workflow unit testing capabilities.Testing the workflow code is hard as it might be potentially very long-running. The included in-memory implementation of the Temporal service supports an automatic time skipping. Anytime a workflow under the test as well as the unit test code are waiting on a timer (or sleep) the internal service time is automatically advanced to the nearest time that unblocks one of the waiting threads. This way a workflow that runs in production for months is unit tested in milliseconds. Here is an example of a test that executes in a few milliseconds instead of over two hours that are needed for the workflow to complete:
public class SignaledWorkflowImpl implements SignaledWorkflow { private String signalInput; @Override public String workflow1(String input) { Workflow.sleep(Duration.ofHours(1)); Workflow.await(() -> signalInput != null); Workflow.sleep(Duration.ofHours(1)); return signalInput + "-" + input; } @Override public void processSignal(String input) { signalInput = input; } } @Test public void testSignal() throws ExecutionException, InterruptedException { TestWorkflowEnvironment testEnvironment = TestWorkflowEnvironment.newInstance(); // Creates a worker that polls tasks from the service owned by the testEnvironment. Worker worker = testEnvironment.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(SignaledWorkflowImpl.class); worker.start(); // Creates a WorkflowClient that interacts with the server owned by the testEnvironment. WorkflowClient client = testEnvironment.getWorkflowClient(); SignaledWorkflow workflow = client.newWorkflowStub(SignaledWorkflow.class); // Starts a workflow execution CompletableFuture
result = WorkflowClient.execute(workflow::workflow1, "input1"); // The sleep forwards the service clock for 65 minutes without blocking. // This ensures that the signal is sent after the one hour sleep in the workflow code. testEnvironment.sleep(Duration.ofMinutes(65)); workflow.processSignal("signalInput"); // Blocks until workflow is complete. Workflow sleep forwards clock for one hour and // this call returns almost immediately. assertEquals("signalInput-input1", result.get()); // Closes workers and releases in-memory service. testEnvironment.close(); }
-
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Deprecated Methods Modifier and Type Method Description void
awaitTermination(long timeout, java.util.concurrent.TimeUnit unit)
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.void
close()
CallsshutdownNow()
andawaitTermination(long, TimeUnit)
.long
currentTimeMillis()
This time might not be equal toSystem.currentTimeMillis()
due to time skipping.java.lang.String
getDiagnostics()
Currently prints histories of all workflow instances stored in the service.java.lang.String
getNamespace()
io.temporal.worker.WorkerFactory
getWorkerFactory()
io.temporal.client.WorkflowClient
getWorkflowClient()
Creates a WorkflowClient that is connected to the in-memory test Temporal service.io.temporal.common.WorkflowExecutionHistory
getWorkflowExecutionHistory(io.temporal.api.common.v1.WorkflowExecution execution)
Deprecated.useWorkflowClient.fetchHistory(String, String)
io.temporal.serviceclient.WorkflowServiceStubs
getWorkflowService()
Deprecated.io.temporal.serviceclient.WorkflowServiceStubs
getWorkflowServiceStubs()
boolean
isShutdown()
WasshutdownNow()
orshutdown()
called?boolean
isStarted()
Wasstart()
called?boolean
isTerminated()
Are all tasks done aftershutdownNow()
orshutdown()
?static TestWorkflowEnvironment
newInstance()
Creates the environment with default options.static TestWorkflowEnvironment
newInstance(TestEnvironmentOptions options)
Creates the environment with suppliedoptions
.io.temporal.worker.Worker
newWorker(java.lang.String taskQueue)
Creates a new Worker instance that is connected to the in-memory test Temporal service.io.temporal.worker.Worker
newWorker(java.lang.String taskQueue, io.temporal.worker.WorkerOptions options)
Creates a new Worker instance that is connected to the in-memory test Temporal service.void
registerDelayedCallback(java.time.Duration delay, java.lang.Runnable r)
Registers a callback to run after the specified delay according to the test Temporal service internal clock.boolean
registerSearchAttribute(java.lang.String name, io.temporal.api.enums.v1.IndexedValueType type)
Register a Search Attribute with the server.void
shutdown()
Initiates an orderly shutdown in which polls are stopped and already received workflow and activity tasks are executed.void
shutdownNow()
Initiates an orderly shutdown in which polls are stopped and already received workflow and activity tasks are attempted to be stopped.void
shutdownTestService()
Deprecated.void
sleep(java.time.Duration duration)
Wait until internal test Temporal service time passes the specified duration.void
start()
Start all workers created by this factory.
-
-
-
Method Detail
-
newInstance
static TestWorkflowEnvironment newInstance()
Creates the environment with default options.
-
newInstance
static TestWorkflowEnvironment newInstance(TestEnvironmentOptions options)
Creates the environment with suppliedoptions
.
-
newWorker
io.temporal.worker.Worker newWorker(java.lang.String taskQueue)
Creates a new Worker instance that is connected to the in-memory test Temporal service.- Parameters:
taskQueue
- task queue to poll.
-
newWorker
io.temporal.worker.Worker newWorker(java.lang.String taskQueue, io.temporal.worker.WorkerOptions options)
Creates a new Worker instance that is connected to the in-memory test Temporal service.- Parameters:
taskQueue
- task queue to poll.
-
getWorkflowClient
io.temporal.client.WorkflowClient getWorkflowClient()
Creates a WorkflowClient that is connected to the in-memory test Temporal service.
-
currentTimeMillis
long currentTimeMillis()
This time might not be equal toSystem.currentTimeMillis()
due to time skipping.- Returns:
- the current in-memory test Temporal service time in milliseconds or
System.currentTimeMillis()
if an external service without time skipping support is used
-
sleep
void sleep(java.time.Duration duration)
Wait until internal test Temporal service time passes the specified duration. This call also indicates that workflow time might jump forward (if none of the activities are running) up to the specified duration.This method falls back to
Thread.sleep(long)
if an external service without time skipping support is used
-
registerDelayedCallback
void registerDelayedCallback(java.time.Duration delay, java.lang.Runnable r)
Registers a callback to run after the specified delay according to the test Temporal service internal clock.
-
registerSearchAttribute
boolean registerSearchAttribute(java.lang.String name, io.temporal.api.enums.v1.IndexedValueType type)
Register a Search Attribute with the server.- Parameters:
name
- Search Attribute nametype
- Search Attribute type to be used for an elastic search index- Returns:
true
if the search attribute was registered, false if it was registered already- See Also:
- Add a Custom Search Attribute Using tctl
-
getWorkflowService
@Deprecated io.temporal.serviceclient.WorkflowServiceStubs getWorkflowService()
Deprecated.- Returns:
- the in-memory test Temporal service that is owned by this.
-
getWorkflowServiceStubs
io.temporal.serviceclient.WorkflowServiceStubs getWorkflowServiceStubs()
- Returns:
WorkflowServiceStubs
connected to the test server (in-memory or external)
-
getNamespace
java.lang.String getNamespace()
-
getDiagnostics
java.lang.String getDiagnostics()
Currently prints histories of all workflow instances stored in the service. This is useful information to print in the case of a unit test failure. A convenient way to achieve this is to add the following Rule to a unit test:@Rule public TestWatcher watchman = new TestWatcher() { @Override protected void failed(Throwable e, Description description) { System.err.println(testEnvironment.getDiagnostics()); testEnvironment.close(); } };
- Returns:
- the diagnostic data about the internal service state.
-
getWorkflowExecutionHistory
@Deprecated io.temporal.common.WorkflowExecutionHistory getWorkflowExecutionHistory(@Nonnull io.temporal.api.common.v1.WorkflowExecution execution)
Deprecated.useWorkflowClient.fetchHistory(String, String)
- Parameters:
execution
- identifies the workflowId and runId (optionally) to reach the history for- Returns:
- history of the execution
-
close
void close()
CallsshutdownNow()
andawaitTermination(long, TimeUnit)
.- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
-
getWorkerFactory
io.temporal.worker.WorkerFactory getWorkerFactory()
-
start
void start()
Start all workers created by this factory.
-
isStarted
boolean isStarted()
Wasstart()
called?
-
isShutdown
boolean isShutdown()
WasshutdownNow()
orshutdown()
called?
-
isTerminated
boolean isTerminated()
Are all tasks done aftershutdownNow()
orshutdown()
?
-
shutdownTestService
@Deprecated void shutdownTestService()
Deprecated.Initiates Test Service shutdown. This method is temporarily exposed to solve long poll thread shutdown forio.temporal.workflow.interceptorsTests.InterceptorExceptionTests#testExceptionOnStart()
. See issue: https://github.com/temporalio/sdk-java/issues/608
-
shutdown
void shutdown()
Initiates an orderly shutdown in which polls are stopped and already received workflow and activity tasks are executed. After the shutdown calls toActivityExecutionContext.heartbeat(Object)
start throwingActivityWorkerShutdownException
. Invocation has no additional effect if already shut down. This method does not wait for previously received tasks to complete execution. UseawaitTermination(long, TimeUnit)
to do that.
-
shutdownNow
void shutdownNow()
Initiates an orderly shutdown in which polls are stopped and already received workflow and activity tasks are attempted to be stopped. This implementation cancels tasks via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate. Also, after the shutdownNow calls toActivityExecutionContext.heartbeat(Object)
start throwingActivityWorkerShutdownException
. Invocation has no additional effect if already shut down. This method does not wait for previously received tasks to complete execution. UseawaitTermination(long, TimeUnit)
to do that.
-
awaitTermination
void awaitTermination(long timeout, java.util.concurrent.TimeUnit unit)
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
-
-