Rig.TUnit.Concurrency
0.1.0-beta.2
dotnet add package Rig.TUnit.Concurrency --version 0.1.0-beta.2
NuGet\Install-Package Rig.TUnit.Concurrency -Version 0.1.0-beta.2
<PackageReference Include="Rig.TUnit.Concurrency" Version="0.1.0-beta.2" />
<PackageVersion Include="Rig.TUnit.Concurrency" Version="0.1.0-beta.2" />
<PackageReference Include="Rig.TUnit.Concurrency" />
paket add Rig.TUnit.Concurrency --version 0.1.0-beta.2
#r "nuget: Rig.TUnit.Concurrency, 0.1.0-beta.2"
#:package Rig.TUnit.Concurrency@0.1.0-beta.2
#addin nuget:?package=Rig.TUnit.Concurrency&version=0.1.0-beta.2&prerelease
#tool nuget:?package=Rig.TUnit.Concurrency&version=0.1.0-beta.2&prerelease
Rig.TUnit.Concurrency
Concurrency + idempotency helpers:
ConcurrencyAssert.TwoWriters,Precondition.IfMatchFails/NotModified,SequenceIdempotencyChecker.
What this package is
A small toolbox for the three most common concurrency-test shapes:
- Two-writers-one-wins (optimistic concurrency) — parameterised on the
exception type so the same assertion works against EF Core's
DbUpdateConcurrencyException, Mongo'sMongoWriteException, Cosmos's412 Precondition Failed, etc. - HTTP ETag / If-Match — verify 412 on stale precondition and 304 on fresh one.
- Sequence idempotency — verify replaying the same sequence produces identical outcomes.
No containers, no dependencies beyond Rig.TUnit.Core — pure harness code.
When to use it
- Testing optimistic-concurrency writes across heterogeneous stores.
- Verifying HTTP cache-control semantics end-to-end.
- Regression-guarding event-replay idempotency.
- Not for: unit-testing lock contention — use
Rig.TUnit.Parallelism.ParallelIsolationContractfor that.
Prerequisites
- .NET 10 SDK.
Quick start
using Rig.TUnit.Concurrency;
using Microsoft.EntityFrameworkCore;
await ConcurrencyAssert.TwoWriters(order)
.OneWinsWith<DbUpdateConcurrencyException>(
a => a.TryUpdateAsync(newValue: 1),
b => b.TryUpdateAsync(newValue: 2));
Options
| Property | Type | Default | Description |
|---|---|---|---|
TimeoutPerBranch |
TimeSpan |
10s |
Per-writer deadline in TwoWriters |
ExpectedLosers |
int |
1 |
How many branches should raise the concurrency exception |
PollingInterval |
TimeSpan |
50ms |
Back-off for async sequence checks |
Fixture + helper APIs
Rig.TUnit.Concurrency.ConcurrencyAssertRig.TUnit.Concurrency.PreconditionRig.TUnit.Concurrency.SequenceIdempotencyChecker
Per-test isolation
All helpers are stateless — every call constructs its own harness. Safe under full parallelism.
Parallelism + performance
TwoWritersdispatches twoTasks and observes which throws.- Overhead: ~0.5 ms per assertion plus the cost of the writes.
- Safe under full parallelism.
Troubleshooting
- Both writers succeed — your store does not enforce optimistic concurrency at the row/document level. Fix the schema (add concurrency token / ETag) before re-running.
TimeoutPerBranchexceeded — one writer blocked indefinitely; likely a missing cancellation propagation in the code under test.
See docs/troubleshooting.md#concurrency.
Provider quirks + edge cases
OneWinsWith<TException>catches the first matching exception type from either branch; if your store wraps the underlying exception, match the outermost type or use a base class.Precondition.IfMatchFailsexpects HTTP status 412; some gateways translate to 409 — passexpectedStatus: HttpStatusCode.Conflictto override.
Benchmarks
See ConcurrencyBenchmarks.cs;
baseline in benchmarks/baseline-005.json.
Related docs
License
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Bogus (>= 35.6.1)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Rig.TUnit.Core (>= 0.1.0-beta.2)
- TUnit.Core (>= 1.34.5)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Rig.TUnit.Concurrency:
| Package | Downloads |
|---|---|
|
Rig.TUnit.All
Meta-package containing every Rig.TUnit.* package. DISCOURAGED — prefer per-feature or per-stack meta-packages (Rig.TUnit, Rig.TUnit.Microservices). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-beta.2 | 54 | 4/27/2026 |
| 0.0.0-alpha.0.14 | 58 | 4/26/2026 |