MVFC.ChaosEngineering
1.3.4
dotnet add package MVFC.ChaosEngineering --version 1.3.4
NuGet\Install-Package MVFC.ChaosEngineering -Version 1.3.4
<PackageReference Include="MVFC.ChaosEngineering" Version="1.3.4" />
<PackageVersion Include="MVFC.ChaosEngineering" Version="1.3.4" />
<PackageReference Include="MVFC.ChaosEngineering" />
paket add MVFC.ChaosEngineering --version 1.3.4
#r "nuget: MVFC.ChaosEngineering, 1.3.4"
#:package MVFC.ChaosEngineering@1.3.4
#addin nuget:?package=MVFC.ChaosEngineering&version=1.3.4
#tool nuget:?package=MVFC.ChaosEngineering&version=1.3.4
MVFC.ChaosEngineering
A lightweight, high-performance ASP.NET Core middleware designed to inject controlled chaos into HTTP pipelines. It provides an essential toolkit for resilience testing in development and staging environments, helping teams build more robust distributed systems.
Overview
MVFC.ChaosEngineering offers a fluent, policy-driven approach to chaos testing. By intercepting incoming HTTP requests, it can inject a wide range of configurable failure modes — from artificial latency and exceptions to corrupted response bodies and bandwidth throttling.
Rules are matched using route patterns (with deterministic specificity precedence), evaluated based on configurable probabilities, and strictly scoped to specific environments to ensure that chaos never inadvertently impacts production workloads.
| Package | Service | Downloads |
|---|---|---|
| MVFC.ChaosEngineering | Chaos injection middleware for ASP.NET Core applications. |
Why Chaos Engineering?
Modern distributed systems are prone to unpredictable failures: cascading timeouts, partial network drops, sluggish consumers, and malformed upstream payloads. Standard testing methodologies often fail to catch these issues because they rely on stable infrastructure conditions.
MVFC.ChaosEngineering bridges this gap by introducing real-world HTTP failures directly into your ASP.NET Core pipeline. Since it operates in-process, there's no need for external proxies or sidecars. You retain full control over the "blast radius" using environment gating, ensuring that chaos is confined to Development or Staging and never leaks into Production.
Key Features
- 16 Diverse Chaos Kinds: Simulate exceptions, latency, random 5xx errors, timeouts, connection aborts, header injection, service throttling (429), body corruption, and more.
- Fluent Configuration: A readable, chainable
ChaosPolicyBuilderAPI for effortless rule definition. - Flexible Route Matching: Target specific endpoints (
/api/orders) or entire path segments (/api/payments/**) using wildcard patterns. Wildcards like/**now correctly include the base path (e.g.,/api/**matches both/apiand/api/v1). - Multi-Rule Configuration: Chain multiple
ForRouterules in a single policy. Rules are automatically sorted by specificity (path length), ensuring the most specific rule always wins. - Probabilistic Execution: Fine-tune how often each rule fires using a probability range from
0.0to1.0. - Request Filtering: Scope chaos injection to specific requests based on HTTP headers (e.g.,
X-Chaos: true). - Built-in Validation: Automatic safety checks during
.Build()to prevent misconfigurations (invalid probabilities, negative bandwidth, etc.). - Dynamic Configuration: Built-in support for
IOptionsMonitor, allowing real-time policy updates without application restarts. - Observability & Metrics: Integrated structured logging and OpenTelemetry-ready metrics (
System.Diagnostics.Metrics). - Environment Gating: Built-in safety mechanisms to restrict chaos to non-production environments.
- Zero External Dependencies: Lightweight implementation built directly on
Microsoft.AspNetCore.Httpand standard .NET abstractions.
Installation
dotnet add package MVFC.ChaosEngineering
Or via the NuGet Package Manager:
Install-Package MVFC.ChaosEngineering
Quick Start
var policy = new ChaosPolicyBuilder()
.OnEnvironments(ChaosEnvironment.Development, ChaosEnvironment.Staging)
.ForRoute("/api/payments/**").WithProbability(0.3).WithLatency(TimeSpan.FromSeconds(3))
.ForRoute("/api/orders").WithProbability(0.1).WithException<TimeoutException>()
.Build();
app.UseChaos(policy);
app.UseChaos(builder =>
builder
.OnEnvironments(ChaosEnvironment.Development)
.ForRoute("/api/products").WithRandomLatency(TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(2))
);
Dynamic Configuration (Options Pattern)
Register the chaos services and define your policy via IServiceCollection. This enables real-time updates via appsettings.json or other configuration providers.
// Program.cs
builder.Services.AddChaos(builder => {
builder
.OnEnvironments(ChaosEnvironment.Development, ChaosEnvironment.Staging)
.ForRoute("/api/**").WithProbability(0.05).WithStatusCode(500);
});
// ...
app.UseChaos(); // Automatically resolves policy from DI
How It Works
flowchart TD
A([HTTP Request]) --> B
subgraph B[ChaosMiddleware]
direction TB
E1[1. Evaluate ChaosPolicy]
E1 --> E2[Match route pattern]
E2 --> E3[Check probability]
end
B --> C{ShouldInject?}
C -- false --> D([Next Middleware → Response])
C -- true --> F
subgraph F[Execute ChaosKind]
direction TB
K1[Latency / RandomLatency]
K2[StatusCode / Random5xx]
K3[Exception / Abort]
K4[Timeout]
K5[HeaderInjection]
K6[Throttle 429]
K7[CorruptBody / EmptyBody]
K8[SlowBody / PartialResponse]
K9[BandwidthThrottle]
K10[ForcedRedirect]
K11[ContentTypeCorruption]
end
F --> G([HTTP Response / Short-circuit])
Chaos Kinds
To simulate realistic service degradation, the middleware supports three primary execution behaviors:
- Short-circuit: The middleware returns a response immediately, bypassing the rest of the pipeline.
- Pass-through + delay: The request continues normally, but an artificial delay is introduced before forwarding.
- Pass-through + intercept: The middleware calls the next handler, captures the response, and modifies it before sending it to the client.
| Kind | Description | Behavior |
|---|---|---|
Exception |
Throws a configured exception (defaults to ChaosException). |
Short-circuit |
Latency |
Introduces a fixed artificial delay. | Pass-through + delay |
RandomLatency |
Introduces a random delay within a specified [min, max] range. |
Pass-through + delay |
StatusCode |
Returns a specific HTTP status code (e.g., 503). | Short-circuit |
RandomStatusCode |
Randomly selects a 5xx series status code (500, 502, 503, 504). | Short-circuit |
Timeout |
Simulates an unresponsive service by introducing a long delay (100s). | Short-circuit |
Abort |
Immediately terminates the TCP connection. | Short-circuit |
HeaderInjection |
Adds X-Chaos-Injected and custom headers to the response. |
Pass-through + intercept |
Throttle |
Simulates rate limiting by returning HTTP 429 with Retry-After. |
Short-circuit |
CorruptBody |
Returns a malformed or truncated JSON response body. | Short-circuit |
EmptyBody |
Returns an empty response body with Content-Length: 0. |
Short-circuit |
SlowBody |
Streams the real response body in small chunks with a per-chunk delay. | Pass-through + intercept |
BandwidthThrottle |
Replays the response body at a fixed bytes-per-second rate. | Pass-through + intercept |
ForcedRedirect |
Forces a redirect (301/302) to a specific URL. | Short-circuit |
PartialResponse |
Writes a fraction of the response body and then aborts the connection. | Short-circuit |
ContentTypeCorruption |
Overwrites the Content-Type header with an invalid value. |
Pass-through + intercept |
SlowBody vs BandwidthThrottle: Use
SlowBodywhen you need granular control over chunk size and timing. UseBandwidthThrottlewhen you want to simulate specific network throughput (e.g., 512 KB/s).
Internal Architecture
The library follows a Strategy Pattern for fault injection. Each ChaosKind is handled by a specialized IChaosHandler implementation resolved via an internal DI-Ready Registry, ensuring the middleware remains clean, maintainable, and highly performant (O(1) resolution).
Performance
Benchmarks measured on .NET 10.0 RyuJIT x86-64-v3 (12th Gen Intel Core i5-12500H).
Full source in benchmarks/.
Handler Resolution
O(1) dictionary lookup — sub-nanosecond, zero allocations regardless of ChaosKind.
| Method | Mean | Allocated |
|---|---|---|
| ResolveBandwidth | 0.82 ns | 0 B |
| ResolveException | 0.82 ns | 0 B |
| ResolveUnknown | 0.84 ns | 0 B |
| ResolveStatusCode | 0.84 ns | 0 B |
| ResolveLatency | 0.87 ns | 0 B |
Route Matching
| Method | Mean | Allocated |
|---|---|---|
| NoMatch | 4.24 ns | 0 B |
| ExactMatch | 4.45 ns | 0 B |
| HeaderMatch | 15.64 ns | 24 B |
| WildcardMatch | 18.59 ns | 0 B |
Middleware Pipeline Overhead
| Scenario | Mean | Overhead | Allocated |
|---|---|---|---|
| No chaos registered | 5.33 μs | baseline | 7.25 KB |
| Chaos registered, no match | 5.48 μs | +3% | 7.28 KB |
| Chaos registered, match + inject | 6.20 μs | +16% | 7.94 KB |
The +3% overhead (≈150 ns) represents the cost of route evaluation when no rule matches — virtually invisible in production. The +16% reflects the actual fault injection cost, not middleware overhead.
Dynamic Exception Factory
You can now use a factory to decide which exception to throw based on the current HttpContext:
policy.ForRoute("/api/orders/**")
.WithException(context => new OrdersException("Custom error context: " + context.TraceIdentifier));
Builder API
Define complex chaos policies using a clean, expressive API that mirrors the underlying ChaosPolicyBuilder:
var policy = new ChaosPolicyBuilder()
// Environment Safety & Overrides
.OnEnvironments(ChaosEnvironment.Development, ChaosEnvironment.Staging)
.WithEnvironmentOverride("LocalTesting")
// Scoped Configuration
.ForRoute("/api/orders")
.WithProbability(0.2)
.WithStatusCode(503)
.ForRoute("/api/payments/**")
.WithProbability(0.05)
.WithException<TimeoutException>()
.ForRoute("/api/reports")
.WithProbability(1.0)
.WithBandwidthThrottle(bytesPerSecond: 1024)
// Multi-criteria matching: Path + Header
.ForRoute("/api/beta/**")
.WithRequestHeader("X-Chaos-Enable", "true")
.WithProbability(1.0)
.WithException<NotImplementedException>()
.Build();
Environment Gating
OnEnvironments evaluates ASPNETCORE_ENVIRONMENT at Build() time. If the current environment does not match any listed value, ChaosPolicy.Disabled is returned and the middleware becomes a no-op with zero overhead.
builder.OnEnvironments(ChaosEnvironment.Development);
// In Production → ChaosPolicy.Disabled → zero overhead
Use WithEnvironmentOverride to inject a fixed environment value in tests.
Observability
The library is designed for production use, with deep integration into modern observability stacks:
Metrics (OpenTelemetry)
It exposes several Counter and Histogram metrics under the MVFC.ChaosEngineering meter:
chaos.faults.injected: Total number of faults injected (withchaos.kindandchaos.route(actual request path) tags).chaos.requests.evaluated: Total number of requests that passed through the middleware.chaos.latency.duration: A histogram of injected latency (p95/p99 analysis).
Tracing
The middleware automatically enriches the current Activity with:
chaos.injected: true/falsechaos.kind: The type of faultchaos.id: Unique correlation ID for the specific faultchaos.path: The request path matching the rule
Playground
The playground/ folder contains a ready-to-run ASP.NET Core Minimal API with all 16 chaos kinds pre-configured — one endpoint per kind — backed by a .NET Aspire AppHost for easy local orchestration.
Running the playground:
cd playground/MVFC.ChaosEngineering.Playground.AppHost
dotnet run
Pre-configured endpoints:
| Route | Chaos Kind |
|---|---|
GET /api/orders/{id} |
StatusCode → 503 |
GET /api/payments/{id} |
Exception |
GET /api/slow |
Latency → 200ms |
GET /api/unstable |
RandomStatusCode |
GET /api/timeout |
Timeout |
GET /api/header-chaos |
HeaderInjection + custom header X-Chaos-Scenario |
GET /api/throttle |
Throttle → 429, Retry-After: 10s |
GET /api/corrupt-body |
CorruptBody |
GET /api/empty-body |
EmptyBody |
GET /api/slow-body |
SlowBody → 150ms/chunk, 32B |
GET /api/redirect |
ForcedRedirect → /api/products |
GET /api/random-latency |
RandomLatency → 50–500ms |
GET /api/partial |
PartialResponse → 32B |
GET /api/bandwidth |
BandwidthThrottle → 128B/s |
GET /api/wrong-content-type |
ContentTypeCorruption → text/plain |
GET /api/abort |
Abort |
Project Structure
- src: Library source code for
MVFC.ChaosEngineering. - playground: Demo API with all chaos kinds pre-configured + Aspire AppHost.
- tests: Test suite covering all chaos kinds and policy evaluation.
Changelog
See CHANGELOG.md for a history of changes and releases.
Contributing
See CONTRIBUTING.md.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.