Class TestDurableWorkflow

Namespace
XBullet.EasyTesting.AzureFunctions
Assembly
XBullet.EasyTesting.AzureFunctions.dll

Connects an in-memory Durable client to named orchestrators and activities through a borrowed function host.

public sealed class TestDurableWorkflow : ITestScenarioResource, IAsyncDisposable
Inheritance
TestDurableWorkflow
Implements
Inherited Members
Extension Methods

Remarks

Each function uses the host's middleware and a fresh DI scope. Payloads use direct assignment by default; WithSerialization enables SDK converter snapshots. Time is advanced on individual contexts. This helper does not implement replay, persistence, continuations, scheduled starts, or production lifecycle policies. WithRetries enables bounded retry simulation. Dispose this workflow before its host; register the workflow, rather than its client, as a scenario resource.

Constructors

TestDurableWorkflow(TestDurableTaskClient?, TimeSpan?)

Creates a workflow that can be registered in DI and as a scenario resource before attaching its host.

public TestDurableWorkflow(TestDurableTaskClient? client = null, TimeSpan? shutdownTimeout = null)

Parameters

client TestDurableTaskClient

An optional caller-owned client registered in application DI. Its schedule, lookup, event, and wait handlers must be unset; this workflow wires them for its lifetime. Null creates an owned client.

shutdownTimeout TimeSpan?

A positive finite wall-clock cleanup limit, defaulting to five seconds. User code must honor cancellation.

Properties

Attempts

Gets immutable snapshots of activity and child attempts, including calls without retry options.

public IReadOnlyList<RecordedDurableTaskAttempt> Attempts { get; }

Property Value

IReadOnlyList<RecordedDurableTaskAttempt>

An ordered snapshot containing original exceptions; diagnostics omit exception contents.

Client

Gets the client wired for scheduling, metadata, events, and start/completion waits.

public TestDurableTaskClient Client { get; }

Property Value

TestDurableTaskClient

Use this client in starters or register it as DurableTaskClient in application DI. Do not replace its workflow handlers or reset it independently.

Methods

AddActivity<TFunction, TInput>(string, Func<TFunction, TInput, TestFunctionContext, Task>)

Registers an activity without a result.

public TestDurableWorkflow AddActivity<TFunction, TInput>(string name, Func<TFunction, TInput, TestFunctionContext, Task> invoke) where TFunction : notnull

Parameters

name string

The non-empty, unique, case-sensitive task name.

invoke Func<TFunction, TInput, TestFunctionContext, Task>

The non-null callback borrowing the scoped function and worker context.

Returns

TestDurableWorkflow

This workflow for chaining.

Type Parameters

TFunction

The function class already registered in the borrowed host.

TInput

The assignable input type.

AddActivity<TFunction, TInput, TResult>(string, Func<TFunction, TInput, TestFunctionContext, Task<TResult>>)

Registers an activity delegate under a case-sensitive task name.

public TestDurableWorkflow AddActivity<TFunction, TInput, TResult>(string name, Func<TFunction, TInput, TestFunctionContext, Task<TResult>> invoke) where TFunction : notnull

Parameters

name string

The non-empty task name. Duplicate registrations are rejected.

invoke Func<TFunction, TInput, TestFunctionContext, Task<TResult>>

The non-null callback receiving the scoped function, input, and worker context with its execution token.

Returns

TestDurableWorkflow

This workflow for chaining. Every activity call gets a separate invocation scope.

Type Parameters

TFunction

The function class already registered in the borrowed host.

TInput

The assignable activity input type, or deserialization target when serialization is enabled.

TResult

The activity result type.

AddOrchestrator<TFunction>(string, Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task>)

Registers an orchestrator without a result.

public TestDurableWorkflow AddOrchestrator<TFunction>(string name, Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task> invoke) where TFunction : notnull

Parameters

name string

The non-empty, unique, case-sensitive task name.

invoke Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task>

The non-null callback borrowing the scoped function and contexts.

Returns

TestDurableWorkflow

This workflow for chaining.

Type Parameters

TFunction

The function class already registered in the borrowed host.

AddOrchestrator<TFunction, TResult>(string, Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task<TResult>>)

Registers an orchestrator delegate under a case-sensitive task name.

public TestDurableWorkflow AddOrchestrator<TFunction, TResult>(string name, Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task<TResult>> invoke) where TFunction : notnull

Parameters

name string

The non-empty task name. Duplicate registrations are rejected.

invoke Func<TFunction, TestOrchestrationContext, TestFunctionContext, Task<TResult>>

The non-null callback receiving the scoped function, orchestration context, and worker context with its execution token.

Returns

TestDurableWorkflow

This workflow for chaining. Register before the first schedule or after reset.

Type Parameters

TFunction

The function class already registered in the borrowed host.

TResult

The result returned by the orchestrator.

CaptureDiagnosticsAsync(CancellationToken)

Captures client operations and workflow summaries before scenario cleanup.

public ValueTask<object?> CaptureDiagnosticsAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Cancels before the snapshot is captured.

Returns

ValueTask<object>

A serializable snapshot containing instance IDs, names, statuses, parent IDs, and call counts; payloads and failures are excluded.

DisposeAsync()

Cancels and drains executions before releasing workflow-owned cancellation resources.

public ValueTask DisposeAsync()

Returns

ValueTask

A value task completing within the configured cleanup timeout. The host is never disposed by this workflow.

Remarks

On timeout, keep the host alive, release uncooperative work, and retry disposal. Client recordings remain available.

GetContext(string)

Gets the context of a scheduled root or child instance.

public TestOrchestrationContext GetContext(string instanceId)

Parameters

instanceId string

The non-empty case-sensitive instance ID.

Returns

TestOrchestrationContext

The borrowed context for advancing time and inspecting calls. Do not replace its identity or dispatch configuration while it executes.

GetResultAsync<TResult>(string, CancellationToken)

Waits for one instance's result and propagates its original failure.

public Task<TResult> GetResultAsync<TResult>(string instanceId, CancellationToken cancellationToken = default)

Parameters

instanceId string

The non-empty case-sensitive root or child instance ID.

cancellationToken CancellationToken

Cancels this wait without canceling execution. Use a timeout or cancellation for workflows waiting on events or timers.

Returns

Task<TResult>

The result after its invocation scope has closed.

Type Parameters

TResult

The assignable result type, or deserialization target when serialization is enabled; null requires a nullable type.

ResetAsync(CancellationToken)

Cancels and drains all executions, clears client recordings and instances, and retains registrations.

public ValueTask ResetAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Cancels cleanup waiting. Once cleanup begins, execution cancellation is not rolled back.

Returns

ValueTask

A value task completing when invocation scopes close and state is reset.

Remarks

Cleanup is bounded by the constructor timeout. Failed cleanup retains instance diagnostics for inspection and retry. Concurrent cleanup is rejected.

UseHost(AzureFunctionTestHost)

Attaches the host used for every subsequent function invocation.

public TestDurableWorkflow UseHost(AzureFunctionTestHost host)

Parameters

host AzureFunctionTestHost

The non-null caller-owned host containing the registered function classes. Attach exactly once, before scheduling.

Returns

TestDurableWorkflow

This workflow for chaining. Dispose the workflow before the host.

WithRetries(int, Action<RecordedDurableTaskAttempt>?)

Enables bounded simulation of SDK retry policies and handlers for connected task calls.

public TestDurableWorkflow WithRetries(int maximumAttempts = 100, Action<RecordedDurableTaskAttempt>? retryScheduled = null)

Parameters

maximumAttempts int

The positive upper bound per logical call, including the first attempt. Defaults to 100.

retryScheduled Action<RecordedDurableTaskAttempt>

An optional observer called outside workflow locks after accepting a retry. It may advance the caller's manual clock. Observer failures stop the call.

Returns

TestDurableWorkflow

This workflow for chaining. Configure before scheduling or after successful reset.

Remarks

Only calls with retry options retry. Policy delays use the calling context's manual clock; custom handlers control their own delay. Cancellation and sequence exhaustion are terminal. Reset preserves configuration and clears attempts. This does not emulate Durable replay or persisted retries.

WithSerialization(DataConverter?)

Enables serialization at connected workflow payload boundaries.

public TestDurableWorkflow WithSerialization(DataConverter? dataConverter = null)

Parameters

dataConverter DataConverter

The caller-owned, concurrently usable SDK converter; null selects the SDK JSON default.

Returns

TestDurableWorkflow

This workflow for chaining. Configure before scheduling or after a successful reset.

Remarks

Snapshots root/child inputs, activity inputs/results, orchestration results, events, and custom status. Reads deserialize to the requested type. Recordings retain original references. Reset preserves configuration. This checks converter compatibility without emulating worker bindings, history, or replay.