Skip to content

Commit ec7cb54

Browse files
authored
Merge pull request #60 from Polly-Contrib/v0_2_1
V0.3
2 parents 9e7e483 + ff7e3b9 commit ec7cb54

File tree

75 files changed

+6899
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+6899
-96
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ TestResults
1414
*.sln.docstates
1515
.vs/
1616
.vscode/
17+
.idea
1718

1819
# Build results
1920
[Dd]ebug/
@@ -118,4 +119,4 @@ tools
118119

119120
*.lock.json
120121
*.nuget.targets
121-
*.nuget.props
122+
*.nuget.props

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.3.0
2+
- Add a new Fluent-builder syntax
3+
- Add intuitive syntax for result stubbing, for use in unit-tests or in other systems on how those systems handle faults
4+
- Compiles on mac and linux
5+
- Add support for .NET Standard 2.1
6+
- Validates constant `injectionRate` at Policy configuration time
7+
18
## 0.2.0
29
- Makes InjectLatency policies cancellable (both sync and async)
310
- Add support for cancellation on async configuration-providing delegates

GitVersionConfig.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
next-version: 0.2.0
1+
next-version: 0.3.0

README.md

Lines changed: 129 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -34,94 +34,169 @@ Simmy offers the following chaos-injection policies:
3434

3535
|Policy| What does the policy do?|
3636
| ------------- |------------- |
37-
|**[Fault](#Inject-fault)**|Injects exceptions or substitute results, to fake faults in your system.|
37+
|**[Exception](#Inject-exception)**|Injects exceptions in your system.|
38+
|**[Result](#Inject-result)**|Substitute results to fake faults in your system.|
3839
|**[Latency](#Inject-latency)**|Injects latency into executions before the calls are made.|
3940
|**[Behavior](#Inject-behavior)**|Allows you to inject _any_ extra behaviour, before a call is placed. |
4041

4142
# Usage
43+
## Step 1: Set up the Monkey Policy
44+
45+
## Inject exception
46+
```csharp
47+
var chaosPolicy = MonkeyPolicy.InjectException(Action<InjectOutcomeOptions<Exception>>);
48+
```
49+
For example:
50+
```csharp
51+
// Following example causes the policy to throw SocketException with a probability of 5% if enabled
52+
var fault = new SocketException(errorCode: 10013);
53+
var chaosPolicy = MonkeyPolicy.InjectException(with =>
54+
with.Fault(fault)
55+
.InjectionRate(0.05)
56+
.Enabled()
57+
);
58+
```
4259

43-
## Inject fault
60+
## Inject result
4461
```csharp
45-
var chaosPolicy = MonkeyPolicy.InjectFault(
46-
Exception | Func<Context, CancellationToken, Exception> fault,
47-
double | Func<Context, CancellationToken, double> injectionRate,
48-
Func<bool> | Func<Context, CancellationToken, bool> enabled
62+
var chaosPolicy = MonkeyPolicy.InjectResult(Action<InjectOutcomeOptions<TResult>>);
63+
```
64+
For example:
65+
```csharp
66+
// Following example causes the policy to return a bad request HttpResponseMessage with a probability of 5% if enabled
67+
var result = new HttpResponseMessage(HttpStatusCode.BadRequest);
68+
var chaosPolicy = MonkeyPolicy.InjectResult<HttpResponseMessage>(with =>
69+
with.Result(result)
70+
.InjectionRate(0.05)
71+
.Enabled()
4972
);
5073
```
5174

5275
## Inject latency
5376
```csharp
54-
var chaosPolicy = MonkeyPolicy.InjectLatency(
55-
TimeSpan | Func<Context, CancellationToken, Timespan> latency,
56-
double | Func<Context, CancellationToken, double> injectionRate,
57-
Func<bool> | Func<Context, CancellationToken, bool> enabled
58-
);
77+
var chaosPolicy = MonkeyPolicy.InjectLatency(Action<InjectLatencyOptions>);
78+
```
79+
For example:
80+
```csharp
81+
// Following example causes policy to introduce an added latency of 5 seconds to a randomly-selected 10% of the calls.
82+
var isEnabled = true;
83+
var chaosPolicy = MonkeyPolicy.InjectLatency(with =>
84+
with.Latency(TimeSpan.FromSeconds(5))
85+
.InjectionRate(0.1)
86+
.Enabled(isEnabled)
87+
);
5988
```
6089

6190
## Inject behavior
6291
```csharp
63-
var chaosPolicy = MonkeyPolicy.InjectBehaviour(
64-
Action | Action<Context, CancellationToken> behaviour,
65-
double | Func<Context, CancellationToken, double> injectionRate,
66-
Func<bool> | Func<Context, CancellationToken, bool> enabled
67-
);
92+
var chaosPolicy = MonkeyPolicy.InjectBehaviour(Action<InjectBehaviourOptions>);
93+
```
94+
For example:
95+
```csharp
96+
// Following example causes policy to execute a method to restart a virtual machine; the probability that method will be executed is 1% if enabled
97+
var chaosPolicy = MonkeyPolicy.InjectBehaviour(with =>
98+
with.Behaviour(() => restartRedisVM())
99+
.InjectionRate(0.01)
100+
.EnabledWhen((ctx, ct) => isEnabled(ctx, ct))
101+
);
68102
```
69103

70104
## Parameters
105+
All the parameters are expressed in a Fluent-builder syntax way.
71106

72-
* **enabled:** Faults are only injected when returns true.
73-
* **injectionRate:** A decimal between 0 and 1 inclusive. The policy will inject the fault, randomly, that proportion of the time, eg: if 0.2, twenty percent of calls will be randomly affected; if 0.01, one percent of calls; if 1, all calls.
74-
* **fault:** The fault to inject.
75-
* **latency:** The latency to inject.
76-
* **behaviour:** The behaviour to inject.
107+
### Enabled
108+
Determines whether the policy is enabled or not.
77109

78-
### Context-driven behaviour
110+
* Configure that the monkey policy is enabled.
111+
```csharp
112+
PolicyOptions.Enabled();
113+
```
79114

80-
All parameters are available in a `Func<Context, ...>` form. This allows you to control the chaos injected:
115+
* Receives a boolean value indicating whether the monkey policy is enabled.
116+
```csharp
117+
PolicyOptions.Enabled(bool);
118+
```
81119

82-
+ in a **dynamic** manner: by eg driving the chaos from external configuration files
83-
+ in a **targeted** manner: by tagging your policy executions with a [`Context.OperationKey`](https://github.com/App-vNext/Polly/wiki/Keys-And-Context-Data#pre-defined-keys-on-context) and introducing chaos targeting particular tagged operations
120+
* Receives a delegate which can be executed to determine whether the monkey policy should be enabled.
121+
```csharp
122+
PolicyOptions.EnabledWhen(Func<Context, CancellationToken, bool>);
123+
```
84124

85-
The [example app](https://github.com/Polly-Contrib/Polly.Contrib.SimmyDemo_WebApi) demonstrates both these approaches in practice.
125+
### InjectionRate
126+
A decimal between 0 and 1 inclusive. The policy will inject the fault, randomly, that proportion of the time, eg: if 0.2, twenty percent of calls will be randomly affected; if 0.01, one percent of calls; if 1, all calls.
86127

87-
# Basic examples
128+
* Receives a double value between [0, 1] indicating the rate at which this monkey policy should inject chaos.
129+
```csharp
130+
PolicyOptions.InjectionRate(Double);
131+
```
88132

89-
## Step 1: Set up the Monkey Policy
133+
* Receives a delegate which can be executed to determine the rate at which this monkey policy should inject chaos.
134+
```csharp
135+
PolicyOptions.InjectionRate(Func<Context, CancellationToken, Double>);
136+
```
90137

91138
### Fault
139+
The fault to inject. The `Fault` api has overloads to build the policy in a generic way: `PolicyOptions.Fault<TResult>(...)`
92140

141+
* Receives an exception to configure the fault to inject with the monkey policy.
93142
```csharp
94-
// Following example causes the policy to throw SocketException with a probability of 5% if enabled
95-
var fault = new SocketException(errorCode: 10013);
96-
var faultPolicy = MonkeyPolicy.InjectFault<SocketException>(
97-
fault,
98-
injectionRate: 0.05,
99-
enabled: () => isEnabled()
100-
);
143+
PolicyOptions.Fault(Exception);
144+
```
145+
146+
* Receives a delegate representing the fault to inject with the monkey policy.
147+
```csharp
148+
PolicyOptions.Fault(Func<Context, CancellationToken, Exception>);
149+
```
150+
151+
### Result
152+
The result to inject.
153+
154+
* Receives a generic TResult value to configure the result to inject with the monkey policy.
155+
```csharp
156+
PolicyOptions.Result<TResult>(TResult);
157+
```
158+
159+
* Receives a delegate representing the result to inject with the monkey policy.
160+
```csharp
161+
PolicyOptions.Result<TResult>(Func<Context, CancellationToken, TResult>);
101162
```
102163

103164
### Latency
165+
The latency to inject.
166+
167+
* Receives a TimeSpan value to configure the latency to inject with the monkey policy.
104168
```csharp
169+
PolicyOptions.Latency(TimeSpan);
170+
```
105171

106-
// Following example causes policy to introduce an added latency of 5 seconds to a randomly-selected 10% of the calls.
107-
var chaosPolicy = MonkeyPolicy.InjectLatency(
108-
latency: TimeSpan.FromSeconds(5),
109-
injectionRate: 0.1,
110-
enabled: () => isEnabled()
111-
);
172+
* Receives a delegate representing the latency to inject with the monkey policy.
173+
```csharp
174+
PolicyOptions.Latency(Func<Context, CancellationToken, TimeSpan>);
112175
```
113176

114-
### Behavior
177+
### Behaviour
178+
The behaviour to inject.
115179

180+
* Receives an Action to configure the behaviour to inject with the monkey policy.
116181
```csharp
117-
// Following example causes policy to execute a method to restart a virtual machine; the probability that method will be executed is 1% if enabled
118-
var chaosPolicy = MonkeyPolicy.InjectBehaviour(
119-
behaviour: () => restartRedisVM(),
120-
injectionRate: 0.01,
121-
enabled: () => isEnabled()
122-
);
182+
PolicyOptions.Behaviour(Action);
123183
```
124184

185+
* Receives a delegate representing the Action to inject with the monkey policy.
186+
```csharp
187+
PolicyOptions.Behaviour(Action<Context, CancellationToken>);
188+
```
189+
190+
### Context-driven behaviour
191+
192+
All parameters are available in a `Func<Context, ...>` form. This allows you to control the chaos injected:
193+
194+
+ in a **dynamic** manner: by eg driving the chaos from external configuration files
195+
+ in a **targeted** manner: by tagging your policy executions with a [`Context.OperationKey`](https://github.com/App-vNext/Polly/wiki/Keys-And-Context-Data#pre-defined-keys-on-context) and introducing chaos targeting particular tagged operations
196+
197+
The [example app](https://github.com/Polly-Contrib/Polly.Contrib.SimmyDemo_WebApi) demonstrates both these approaches in practice.
198+
199+
125200
## Step 2: Execute code through the Monkey Policy
126201

127202
```csharp
@@ -137,10 +212,10 @@ var policyWrap = Policy
137212
policyWrap.Execute(() => someMethod())
138213

139214
// All policies are also available in async forms.
140-
var chaosLatencyPolicy = MonkeyPolicy.InjectLatencyAsync(
141-
latency: TimeSpan.FromSeconds(5),
142-
injectionRate: 0.1,
143-
enabled: () => isEnabled()
215+
var chaosLatencyPolicy = MonkeyPolicy.InjectLatencyAsync(with =>
216+
with.Latency(TimeSpan.FromSeconds(5))
217+
.InjectionRate(0.1)
218+
.Enabled()
144219
);
145220
var policyWrap = Policy
146221
.WrapAsync(fallbackPolicy, timeoutPolicy, chaosLatencyPolicy);
@@ -180,10 +255,10 @@ Simmy was [the brainchild of](https://github.com/App-vNext/Polly/issues/499) [@m
180255
### Blog posts
181256
* [Simmy, the monkey for making chaos](http://elvanydev.com/chaos-injection-with-simmy/) -by [Geovanny Alzate Sandoval](https://twitter.com/geovany0114)
182257
* [Simmy and Azure App Configuration](http://elvanydev.com/simmy-with-azure-app-configuration/) -by [Geovanny Alzate Sandoval](https://twitter.com/geovany0114)
183-
* [Simmy Chaos Engine for .NET – Part 1, Injecting Faults](https://nodogmablog.bryanhogan.net/2019/07/simmy-chaos-engine-for-net-part-1-injecting-faults/) -by [Bryan Hogan](https://twitter.com/bryanjhogan)
184-
* [Simmy Chaos Engine for .NET – Part 2, Resilience and Injected Faults](https://nodogmablog.bryanhogan.net/2019/07/simmy-chaos-engine-for-net-part-2-resilience-and-injected-faults/) -by [Bryan Hogan](https://twitter.com/bryanjhogan)
258+
* [Simmy series on No Dogma blog](https://nodogmablog.bryanhogan.net/tag/simmy/) -by [Bryan Hogan](https://twitter.com/bryanjhogan)
185259

186260
### Samples
187261
* [Dylan Reisenberger](http://www.thepollyproject.org/author/dylan/) presents an [intentionally simple example](https://github.com/Polly-Contrib/Polly.Contrib.SimmyDemo_WebApi) .NET Core WebAPI app demonstrating how we can set up Simmy chaos policies for certain environments and without changing any existing configuration code injecting faults or chaos by modifying external configuration.
188262

189263
* [Geovanny Alzate Sandoval](https://github.com/vany0114) made a [microservices based sample application](https://github.com/vany0114/chaos-injection-using-simmy) to demonstrate how chaos engineering works with Simmy using chaos policies in a distributed system and how we can inject even a custom behavior given our needs or infrastructure, this time injecting custom behavior to generate chaos in our Service Fabric Cluster.
264+

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
os: Visual Studio 2017
1+
os: Visual Studio 2019
22

33
# Build script
44
build_script:

build.cake

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ var configuration = Argument<string>("configuration", "Release");
99
// EXTERNAL NUGET TOOLS
1010
//////////////////////////////////////////////////////////////////////
1111

12-
#Tool "xunit.runner.console"
13-
#Tool "GitVersion.CommandLine"
14-
#Tool "Brutal.Dev.StrongNameSigner"
12+
#tool nuget:?package=xunit.runner.console&version=2.4.1
13+
#tool nuget:?package=GitVersion.CommandLine&version=5.0.1
14+
#tool nuget:?package=Brutal.Dev.StrongNameSigner&version=2.4.0
1515

1616
//////////////////////////////////////////////////////////////////////
1717
// EXTERNAL NUGET LIBRARIES
1818
//////////////////////////////////////////////////////////////////////
1919

20-
#addin "Cake.FileHelpers"
20+
#addin nuget:?package=Cake.FileHelpers&version=3.2.1
2121

2222
///////////////////////////////////////////////////////////////////////////////
2323
// GLOBAL VARIABLES
@@ -192,7 +192,7 @@ Task("__BuildSolutions")
192192
settings
193193
.SetConfiguration(configuration)
194194
.WithProperty("TreatWarningsAsErrors", "true")
195-
.UseToolVersion(MSBuildToolVersion.VS2017)
195+
.UseToolVersion(MSBuildToolVersion.VS2019)
196196
.SetVerbosity(Verbosity.Minimal)
197197
.SetNodeReuse(false));
198198
}

build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ if(-Not $SkipToolPackageRestore.IsPresent)
111111
# Install just Cake if missing config
112112
else
113113
{
114-
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install Cake -Version 0.25.0 -ExcludeVersion" # Pin Cake version to 0.25.0; see https://github.com/App-vNext/Polly/issues/416
114+
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install Cake -Version 0.35.0 -ExcludeVersion"
115115
Write-Verbose ($NuGetOutput | Out-String)
116116
}
117117
Pop-Location

src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourAsyncSpecs.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Polly.Contrib.Simmy.Specs.Behavior
88
{
99
[Collection(Helpers.Constants.AmbientContextDependentTestCollection)]
10+
[Obsolete]
1011
public class InjectBehaviourAsyncSpecs : IDisposable
1112
{
1213
public InjectBehaviourAsyncSpecs()

0 commit comments

Comments
 (0)