Application development - Testing
Temporal provides a framework to facilitate Workflow and integration testing.
Replay
Replay recreates the exact state of a Workflow Execution. You can replay a Workflow from the beginning of its history when resumed.
Replay allows code to resume only if it is compatible from a deterministic point of view.
To retrieve the Workflow History, use any of the following options and then pass the object to your SDK of choice.
- Proto History object
- Temporal Web UI
- Select a Workflow ID.
- Click Download.
- tctl commands; for example:
- Client
- Go
- Java
- PHP
- Python
- TypeScript
Use the worker.WorflowReplayer to replay an existing Workflow Execution from its Event History to replicate errors.
For example, the following code retrieves the Event History of a Workflow:
import (
"context"
"go.temporal.io/api/enums/v1"
"go.temporal.io/api/history/v1"
"go.temporal.io/sdk/client"
)
func GetWorkflowHistory(ctx context.Context, client client.Client, id, runID string) (*history.History, error) {
var hist history.History
iter := client.GetWorkflowHistory(ctx, id, runID, false, enums.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT)
for iter.HasNext() {
event, err := iter.Next()
if err != nil {
return nil, err
}
hist.Events = append(hist.Events, event)
}
return &hist, nil
}
This history can then be used to replay.
For example, the following code creates a WorkflowReplayer
and register the YourWorkflow
Workflow function.
Then it calls the ReplayWorkflowHistory
to replay the Event History and return an error code.
import (
"context"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
)
func ReplayWorkflow(ctx context.Context, client client.Client, id, runID string) error {
hist, err := GetWorkflowHistory(ctx, client, id, runID)
if err != nil {
return err
}
replayer := worker.NewWorkflowReplayer()
replayer.RegisterWorkflow(YourWorkflow)
return replayer.ReplayWorkflowHistory(nil, hist)
}
The code above will cause the Worker to re-execute the Workflow's Workflow Function using the original Event History. If a noticeably different code path was followed or some code caused a deadlock, it will be returned in the error code. Replaying a Workflow Execution locally is a good way to see exactly what code path was taken for given input and events.
Content is currently unavailable.
Content is currently unavailable.
To replay a Workflow Execution, use the replay_workflow()
method and pass a Workflow History as an argument.
In the following example, history_json_str
references the Workflow History as a JSON string.
async def run_replayer(history_json_str: str):
replayer = Replayer(workflows=[YourWorkflow])
await replayer.replay_workflow(history_json_str)
If the Workflow History is non-deterministic, run_replayer()
raises an error.
If the Workflow History is exported by Temporal Web UI or through tctl, you can pass the JSON file history object as a JSON string or as a Python dictionary through the json.load()
function, which takes a file object and returns the JSON object.
Workflows in Temporal may be replayed from the beginning of their history when resumed. In order for Temporal to recreate the exact state Workflow code was in, the code is required to be fully deterministic. To prevent breaking determinism, in the TypeScript SDK, Workflow code runs in an isolated execution environment and may not use any of the Node.js APIs or communicate directly with the outside world.
See how to replay in this video.