feat(testing): add IGrainStorage provider test kit - #10490
Merged
Merged
Conversation
9 tasks
ReubenBond
force-pushed
the
rb-fix-pr-9742
branch
from
August 11, 2026 17:20
972c5f7 to
f607a69
Compare
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
…scenarios Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Co-authored-by: ReubenBond <203839+ReubenBond@users.noreply.github.com>
Rebase the test kit integration onto the current solution layout, restore repository package sources, and make the reusable storage contract tests compile and pass across supported target frameworks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Accept provider-specific inconsistency exception subclasses and both deletion and tombstone ETag behavior when clearing missing state. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
ReubenBond
force-pushed
the
rb-fix-pr-9742
branch
from
August 11, 2026 17:45
f607a69 to
8939052
Compare
Require Orleans 10 or later in the package documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new reusable test-kit library to Orleans for validating IGrainStorage implementations via a shared xUnit contract suite, plus sample/adopter tests to exercise it against existing providers.
Changes:
- Introduces
Microsoft.Orleans.Persistence.TestKitwith anInProcessTestClusterBuilder-based fixture and a baseGrainStorageTestRunnercontract suite. - Adds a new test project demonstrating the kit against
MemoryGrainStorage. - Integrates the kit into existing Azure Table storage tests and solution/project references (including API baseline).
Show a summary per file
| File | Description |
|---|---|
| Orleans.slnx | Adds the new test kit project and its tests to the solution. |
| src/Orleans.Persistence.TestKit/Orleans.Persistence.TestKit.csproj | Defines the new public test kit package/project configuration. |
| src/Orleans.Persistence.TestKit/README.md | Documents usage, available tests, and integration patterns for the kit. |
| src/Orleans.Persistence.TestKit/GrainStorageTestRunner.cs | Implements the reusable IGrainStorage contract test suite and helpers. |
| src/Orleans.Persistence.TestKit/GrainStorageTestFixture.cs | Provides an in-proc test cluster fixture to configure and resolve the storage provider under test. |
| src/Orleans.Persistence.TestKit/TestStates/TestState1.cs | Adds a canonical test state type used by the contract suite. |
| src/api/Orleans.Persistence.TestKit/Orleans.Persistence.TestKit.cs | Adds the generated public API baseline for the new package. |
| test/Orleans.Persistence.TestKit.Tests/Orleans.Persistence.TestKit.Tests.csproj | Adds a new test project to validate/demo the kit. |
| test/Orleans.Persistence.TestKit.Tests/MemoryGrainStorageTests.cs | Demonstrates and runs the contract suite against Memory grain storage. |
| test/Extensions/Orleans.Azure.Tests/Persistence/AzureTableGrainStorageTestKitTests.cs | Runs the contract suite against Azure Table grain storage (skippable). |
| test/Extensions/Orleans.Azure.Tests/Orleans.Azure.Tests.csproj | References the new test kit from the Azure test project. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (1)
src/Orleans.Persistence.TestKit/GrainStorageTestRunner.cs:96
- Typo in local variable name: "recordExitsAfterClearing" should be "recordExistsAfterClearing".
var recordExitsAfterClearing = grainState.RecordExists;
Assert.False(recordExitsAfterClearing);
- Files reviewed: 11/11 changed files
- Comments generated: 7
- Review effort level: Lite
| <TargetFrameworks>$(DefaultTargetFrameworks)</TargetFrameworks> | ||
| <OrleansBuildTimeCodeGen>true</OrleansBuildTimeCodeGen> | ||
| <IsOrleansFrameworkPart>false</IsOrleansFrameworkPart> | ||
| <IsPackable>false</IsPackable> |
Comment on lines
+70
to
+72
| Assert.Equal(grainState.ETag, storedGrainState.ETag); | ||
| Assert.Equal(grainState.State, storedGrainState.State); | ||
| Assert.True(storedGrainState.RecordExists); |
Comment on lines
+88
to
+89
| var recordExitsAfterWriting = grainState.RecordExists; | ||
| Assert.True(recordExitsAfterWriting); |
Comment on lines
+98
to
+101
| var storedGrainState = new GrainState<T> { State = new T(), ETag = clearedStateVersion }; | ||
| await Storage.WriteStateAsync(grainTypeName, grainId, storedGrainState).ConfigureAwait(false); | ||
| Assert.Equal(storedGrainState.State, Activator.CreateInstance<T>()); | ||
| Assert.True(storedGrainState.RecordExists); |
Comment on lines
+193
to
+199
| int StartOfRange = 33900; | ||
| int CountOfRange = countOfGrains; | ||
|
|
||
| // Since the version is NULL, storage provider tries to insert this data as new state. | ||
| // If there is already data with this class, the writing fails and the storage provider throws. | ||
| var grainStates = Enumerable.Range(StartOfRange, CountOfRange) | ||
| .Select(i => GetTestReferenceAndState($"{prefix}-{Guid.NewGuid():N}-{i}", null)) |
Comment on lines
+215
to
+217
| int MaxNumberOfThreads = Environment.ProcessorCount * 3; | ||
|
|
||
| await Parallel.ForEachAsync(grainStates, new ParallelOptions { MaxDegreeOfParallelism = MaxNumberOfThreads }, async (grainData, ct) => |
Comment on lines
+102
to
+103
| var builder = new InProcessTestClusterBuilder(); | ||
| builder.ConfigureSilo((_, siloBuilder) => ConfigureSilo(siloBuilder)); |
This was referenced Aug 28, 2026
Merged
This was referenced Aug 31, 2026
Merged
This was referenced Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Orleans storage providers need a reusable public contract suite for validating
IGrainStoragebehavior. The original implementation in #9742 could no longer merge cleanly and its CI autobuild was broken by repository feed changes.Solution
Microsoft.Orleans.Persistence.TestKitpackage with reusable xUnit storage contract tests and anInProcessTestClusterBuilderfixture.Rationale
A shared suite makes provider behavior consistent and gives third-party provider authors the same contract coverage as Orleans-owned implementations. Provider-specific exception subclasses and both delete-on-clear and tombstone-on-clear semantics remain supported.
Supersedes #9742.
Microsoft Reviewers: Open in CodeFlow