TestingHost architecture
The Microsoft.Orleans.TestingHost package composes real silo and client hosts with test-oriented discovery, transport, statistics, directory, and lifecycle controls. It is an integration harness, not a mock grain runtime. Grain activation, scheduling, serialization, messaging, placement, and most provider behavior execute through the same runtime components as a hosted cluster.
This page describes the harness internals. For practical setup, fixture patterns, topology changes, and guidance on choosing mocks or a cluster, see Test Orleans applications.
Cluster object model
Section titled “Cluster object model ”InProcessTestClusterBuilder accumulates host, silo, and client delegates. Build passes its options to an InProcessTestCluster; the cluster retains that mutable options object. DeployAsync starts the configured silo hosts and initializes the client when requested. With client initialization enabled, it performs a best-effort initial membership-view check but can continue after warning that views have not stabilized. Each InProcessSiloHandle owns one Generic Host and exposes its service provider for test inspection.
The processes are shared, but the hosts and dependency-injection containers are not. Static process state can still leak between silos, which is one reason production code should not use static mutable state for silo-local behavior.
API: InProcessTestClusterBuilder, InProcessTestCluster, and InProcessSiloHandle. Implementation: builder, cluster, and silo handle.
Defaults
Section titled “Defaults”InProcessTestClusterBuilder defaults to:
| Setting | Default |
|---|---|
| InProcessTestClusterOptions.InitialSilosCount | 2 |
| InProcessTestClusterOptions.ClusterId | Newly generated |
| InProcessTestClusterOptions.ServiceId | Newly generated GUID |
| InProcessTestClusterOptions.InitializeClientOnDeploy | true |
| Test-cluster membership | true |
| Test-cluster grain directory | true |
| InProcessTestClusterOptions.UseDistributedGrainDirectory | false |
| InProcessTestClusterOptions.GatewayPerSilo | true |
| InProcessTestClusterOptions.UseRealEnvironmentStatistics | false |
| Connection transport | In-memory |
Simulated environment statistics make resource-based tests deterministic, but they do not reproduce operating-system CPU or memory pressure. Opt into real statistics only when the test specifically needs those signals.
These defaults are defined by InProcessTestClusterBuilder and InProcessTestClusterOptions; see their builder and options implementations.
Configuration layers
Section titled “Configuration layers ”The builder separates three scopes:
- ConfigureHost applies to both silo and client Generic Hosts and is useful for shared configuration or keyed SDK clients.
- ConfigureSilo receives per-silo options and an ISiloBuilder.
- ConfigureClient configures the cluster client.
Delegates run for each relevant host. A singleton registered by a silo delegate is singleton within that silo’s container, not across the cluster. A concrete instance captured by a delegate is shared because the test supplied the same object.
Dynamic topology
Section titled “Dynamic topology ”StartAdditionalSiloAsync and StartSilosAsync create new hosts using the cluster’s current options and configuration delegates. StopSiloAsync, StopSilosAsync, StopAllSilosAsync, WaitForLivenessToStabilizeAsync, and WaitForClusterManifestToStabilizeAsync coordinate membership and manifest transitions for failure and elasticity tests.
The overloads which take startAdditionalSiloOnNewPort are obsolete. Tests should use the parameterless StartAdditionalSilo overloads or StartSilosAsync. Lower-level StartSiloAsync overloads remain available when a test must supply an instance number or configuration overrides.
Stopping a host gracefully exercises shutdown. Disposing or terminating a handle without graceful membership update is a different failure mode and should be chosen deliberately when testing failure detection.
Class-configurator test cluster and custom silo creation
Section titled “Class-configurator test cluster and custom silo creation ”TestClusterBuilder is the class-configurator-based harness. It defaults to two silos, in-memory transport, generated cluster identity, test membership, client initialization, file logging, and homogeneous-silo assumptions. It also installs ConfigureDistributedGrainDirectory, so its silos opt into the experimental distributed grain directory instead of the production runtime’s default LocalGrainDirectory.
ISiloConfigurator, IHostConfigurator, and IClientBuilderConfigurator are serializable configuration identities which can be applied to every host. Assigning TestClusterBuilder.CreateSiloAsync sets TestClusterOptions.ConnectionTransport to TcpSocket, so the built-in client uses its TCP transport instead of the harness’s in-memory transport. The delegate bypasses DefaultCreateSiloAsync and cannot access the harness’s private in-memory transport hub, so it must configure the custom silo host with a compatible transport.
TestCluster supports suites built around SiloHandle and configurator types. It does not use separate application domains; its hosts run in-process unless a custom silo creation path provides different isolation.
API: TestClusterBuilder, TestCluster, and TestClusterOptions. Implementation: builder, cluster, and options.
Fidelity boundaries
Section titled “Fidelity boundaries ”TestingHost deliberately substitutes infrastructure. Tests must account for those boundaries:
- in-memory transport does not reproduce sockets, TLS, packet loss, or network buffers;
- test membership does not prove a production membership provider’s transaction behavior;
- the test grain directory can bypass production directory edge cases;
- simulated statistics do not reproduce load shedding;
- one process shares thread-pool and static state; and
- graceful stop does not model abrupt process or machine loss.
Use the smallest substitution which keeps the invariant under test real. Directory, membership, transport, and provider contract tests often need their production component explicitly enabled.
Test architecture in the repository
Section titled “Test architecture in the repository”Repository fixtures such as BaseInProcessTestClusterFixture wrap cluster setup and disposal, while specialized suites configure the component being exercised. For example, AQStreamingTests uses ConfigureHost, ConfigureSilo, and ConfigureClient to combine real Azure Queue adapters with an in-process Orleans cluster.
