[
  {
    "path": ".gitignore",
    "content": "# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)\n[Bb]in/\n[Oo]bj/\n\n# mstest test results\nTestResults\n\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n.vs/\n.vscode/\n.idea\n\n# Build results\n[Dd]ebug/\n[Rr]elease/\nx64/\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.log\n*.vspscc\n*.vssscc\n.builds\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# GhostDoc\n*.GhostDoc.xml\n\n# Installshield output folder \n[Ee]xpress\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish\n\n# Publish Web Output\n*.Publish.xml\n\n# NuGet Packages Directory\npackages\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\n[Bb]in\n[Oo]bj\nsql\nTestResults\n[Tt]est[Rr]esult*\n*.Cache\nClientBin\n[Ss]tyle[Cc]op.*\n~$*\n*.dbmdl\nGenerated_Code #added for RIA/Silverlight projects\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\n\nartifacts\nbuild\ntools\n\n*.lock.json\n*.nuget.targets\n*.nuget.props\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## 0.3.0\r\n- Add a new Fluent-builder syntax \r\n- Add intuitive syntax for result stubbing, for use in unit-tests or in other systems on how those systems handle faults\r\n- Compiles on mac and linux\r\n- Add support for .NET Standard 2.1\r\n- Validates constant `injectionRate` at Policy configuration time\r\n\r\n## 0.2.0\r\n- Makes InjectLatency policies cancellable (both sync and async)\r\n- Add support for cancellation on async configuration-providing delegates \r\n\r\n## 0.1.0\r\n- Initial launch\r\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "We ask our contributors to abide by the [Code of Conduct of the .NET Foundation](https://www.dotnetfoundation.org/code-of-conduct).\r\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Please see the Instructions for Contributing in the [Polly ReadMe](https://github.com/App-vNext/Polly#instructions-for-contributing) and [Polly wiki](https://github.com/App-vNext/Polly/wiki/Git-Workflow).\r\n\r\n"
  },
  {
    "path": "GitVersionConfig.yaml",
    "content": "next-version: 0.3.0"
  },
  {
    "path": "LICENSE.txt",
    "content": "New BSD License\r\n=\r\nCopyright (c) 2018-2019, App vNext\r\nAll rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without\r\nmodification, are permitted provided that the following conditions are met:\r\n    * Redistributions of source code must retain the above copyright\r\n      notice, this list of conditions and the following disclaimer.\r\n    * Redistributions in binary form must reproduce the above copyright\r\n      notice, this list of conditions and the following disclaimer in the\r\n      documentation and/or other materials provided with the distribution.\r\n    * Neither the name of App vNext nor the\r\n      names of its contributors may be used to endorse or promote products\r\n      derived from this software without specific prior written permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\nDISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\r\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n"
  },
  {
    "path": "README.md",
    "content": "# Simmy\n\n\n\nSimmy is a [chaos-engineering](http://principlesofchaos.org/) and fault-injection tool, integrating with the [Polly resilience project for .NET](https://github.com/App-vNext/Polly).  It is releasing April 2019 and works with [Polly v7.0.0](https://www.nuget.org/packages/Polly/7.1.0) onwards.\n\nSimmy allows you to introduce a chaos-injection policy or policies at any location where you execute code through Polly.\n\n[![NuGet version](https://badge.fury.io/nu/Polly.Contrib.Simmy.svg)](https://badge.fury.io/nu/Polly.Contrib.Simmy) [![Build status](https://ci.appveyor.com/api/projects/status/5v3bpgjkw4snv3no?svg=true)](https://ci.appveyor.com/project/Polly-Contrib/simmy) [![Slack Status](http://www.pollytalk.org/badge.svg)](http://www.pollytalk.org)\n\n<img src=\"./Simmy_lg.png\" alt=\"Simmy\"  width=\"300\"/>\n\n# Motivation\n\nThere are a lot of questions when it comes to chaos-engineering and making sure that a system is actually ready to face the worst possible scenarios:\n\n* Is my system resilient enough?\n* Am I handling the right exceptions/scenarios?\n* How will my system behave if X happens?\n* How can I test without waiting for a handled (or even unhandled) exception to happen in my production environment?\n\nUsing Polly helps me introduce resilience to my project, but I don't want to have to wait for expected or unexpected failures to test it out. My resilience could be wrongly implemented; testing the scenarios is not straight forward; and mocking failure of some dependencies (for example a cloud SaaS or PaaS service) is not always straightforward.\n\n**What do I need, to simulate chaotic scenarios in my production environment?**\n\n* A way to mock failures of dependencies (any service dependency for example).\n* Define when to fail based on some external factors - maybe global configuration or some rule.\n* A way to revert easily, to control the blast radius.\n* Production grade, to run this in a production or near-production system with automation.\n\n# Chaos policies\n\nSimmy offers the following chaos-injection policies:\n\n|Policy| What does the policy do?|\n| ------------- |------------- |\n|**[Exception](#Inject-exception)**|Injects exceptions in your system.|\n|**[Result](#Inject-result)**|Substitute results to fake faults in your system.|\n|**[Latency](#Inject-latency)**|Injects latency into executions before the calls are made.|\n|**[Behavior](#Inject-behavior)**|Allows you to inject _any_ extra behaviour, before a call is placed. |\n\n# Usage\n## Step 1: Set up the Monkey Policy\n\n## Inject exception\n```csharp\nvar chaosPolicy = MonkeyPolicy.InjectException(Action<InjectOutcomeOptions<Exception>>);\n```\nFor example:\n```csharp\n// Following example causes the policy to throw SocketException with a probability of 5% if enabled\nvar fault = new SocketException(errorCode: 10013);\nvar chaosPolicy = MonkeyPolicy.InjectException(with =>\n\twith.Fault(fault)\n\t\t.InjectionRate(0.05)\n\t\t.Enabled()\n\t);\n```\n\n## Inject result\n```csharp\nvar chaosPolicy = MonkeyPolicy.InjectResult(Action<InjectOutcomeOptions<TResult>>);\n```\nFor example:\n```csharp\n// Following example causes the policy to return a bad request HttpResponseMessage with a probability of 5% if enabled\nvar result = new HttpResponseMessage(HttpStatusCode.BadRequest);\nvar chaosPolicy = MonkeyPolicy.InjectResult<HttpResponseMessage>(with =>\n\twith.Result(result)\n\t\t.InjectionRate(0.05)\n\t\t.Enabled()\n);\n```\n\n## Inject latency\n```csharp\nvar chaosPolicy = MonkeyPolicy.InjectLatency(Action<InjectLatencyOptions>);\n```\nFor example:\n```csharp\n// Following example causes policy to introduce an added latency of 5 seconds to a randomly-selected 10% of the calls.\nvar isEnabled = true;\nvar chaosPolicy = MonkeyPolicy.InjectLatency(with =>\n\twith.Latency(TimeSpan.FromSeconds(5))\n\t\t.InjectionRate(0.1)\n\t\t.Enabled(isEnabled)\n\t);\n```\n\n## Inject behavior\n```csharp\nvar chaosPolicy = MonkeyPolicy.InjectBehaviour(Action<InjectBehaviourOptions>);\n```\nFor example:\n```csharp\n// Following example causes policy to execute a method to restart a virtual machine; the probability that method will be executed is 1% if enabled\nvar chaosPolicy = MonkeyPolicy.InjectBehaviour(with =>\n\twith.Behaviour(() => restartRedisVM())\n\t\t.InjectionRate(0.01)\n\t\t.EnabledWhen((ctx, ct) => isEnabled(ctx, ct))\n\t);\n```\n\n## Parameters\nAll the parameters are expressed in a Fluent-builder syntax way.\n\n### Enabled\nDetermines whether the policy is enabled or not.\n\n* Configure that the monkey policy is enabled. \n```csharp\nPolicyOptions.Enabled();\n```\n\n* Receives a boolean value indicating whether the monkey policy is enabled.\n```csharp\nPolicyOptions.Enabled(bool);\n```\n\n* Receives a delegate which can be executed to determine whether the monkey policy should be enabled.\n```csharp\nPolicyOptions.EnabledWhen(Func<Context, CancellationToken, bool>);\n```\n\n### InjectionRate\nA 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. \n\n* Receives a double value between [0, 1] indicating the rate at which this monkey policy should inject chaos.\n```csharp\nPolicyOptions.InjectionRate(Double);\n```\n\n* Receives a delegate which can be executed to determine the rate at which this monkey policy should inject chaos.\n```csharp\nPolicyOptions.InjectionRate(Func<Context, CancellationToken, Double>);\n```\n\n### Fault\nThe fault to inject. The `Fault` api has overloads to build the policy in a generic way: `PolicyOptions.Fault<TResult>(...)`\n\n* Receives an exception to configure the fault to inject with the monkey policy.\n```csharp\nPolicyOptions.Fault(Exception);\n```\n\n* Receives a delegate representing the fault to inject with the monkey policy.\n```csharp\nPolicyOptions.Fault(Func<Context, CancellationToken, Exception>);\n```\n\n### Result\nThe result to inject.\n\n* Receives a generic TResult value to configure the result to inject with the monkey policy.\n```csharp\nPolicyOptions.Result<TResult>(TResult);\n```\n\n* Receives a delegate representing the result to inject with the monkey policy.\n```csharp\nPolicyOptions.Result<TResult>(Func<Context, CancellationToken, TResult>);\n```\n\n### Latency\nThe latency to inject.\n\n* Receives a TimeSpan value to configure the latency to inject with the monkey policy.\n```csharp\nPolicyOptions.Latency(TimeSpan);\n```\n\n* Receives a delegate representing the latency to inject with the monkey policy.\n```csharp\nPolicyOptions.Latency(Func<Context, CancellationToken, TimeSpan>);\n```\n\n### Behaviour\nThe behaviour to inject. \n\n* Receives an Action to configure the behaviour to inject with the monkey policy.\n```csharp\nPolicyOptions.Behaviour(Action);\n```\n\n* Receives a delegate representing the Action to inject with the monkey policy.\n```csharp\nPolicyOptions.Behaviour(Action<Context, CancellationToken>);\n```\n\n### Context-driven behaviour\n\nAll parameters are available in a `Func<Context, ...>` form.  This allows you to control the chaos injected:\n\n+ in a **dynamic** manner: by eg driving the chaos from external configuration files\n+ 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\n\nThe [example app](https://github.com/Polly-Contrib/Polly.Contrib.SimmyDemo_WebApi) demonstrates both these approaches in practice.\n\n\n## Step 2: Execute code through the Monkey Policy\n\n```csharp\n// Executes through the chaos policy directly\nchaosPolicy.Execute(() => someMethod());\n\n// Executes through the chaos policy using Context\nchaosPolicy.Execute((ctx) => someMethod(), context);\n\n// Wrap the chaos policy inside other Polly resilience policies, using PolicyWrap\nvar policyWrap = Policy\n  .Wrap(fallbackPolicy, timeoutPolicy, chaosLatencyPolicy);\npolicyWrap.Execute(() => someMethod())\n\n// All policies are also available in async forms.\nvar chaosLatencyPolicy = MonkeyPolicy.InjectLatencyAsync(with =>\n\twith.Latency(TimeSpan.FromSeconds(5))\n\t\t.InjectionRate(0.1)\n\t\t.Enabled()\n\t);\nvar policyWrap = Policy\n  .WrapAsync(fallbackPolicy, timeoutPolicy, chaosLatencyPolicy);\nvar result = await policyWrap.ExecuteAsync(token => service.GetFoo(parametersBar, token), myCancellationToken);\n\n// For general information on Polly policy syntax see: https://github.com/App-vNext/Polly\n```\n\nIt is usual to place the Simmy policy innermost in a PolicyWrap. By placing the chaos policies innermost, they subvert the usual outbound call at the last minute, substituting their fault or adding extra latency. The existing Polly policies - further out in the PolicyWrap - still apply, so you can test how the Polly resilience you have configured handles the chaos/faults injected by Simmy.\n\n**Note:** The above examples demonstrate how to execute through a Simmy policy directly, and how to include a Simmy policy in an individual PolicyWrap. If your policies are configured by .NET Core DI at StartUp, for example via HttpClientFactory, there are also patterns which can configure Simmy into your app as a whole, at StartUp. See the Simmy Sample App discussed below.\n\n## Example app: Controlling chaos via configuration and Polly.Context\n\nThis [Simmy sample app](https://github.com/Polly-Contrib/Polly.Contrib.SimmyDemo_WebApi) shows different approaches/patterns for how you can configure Simmy to introduce chaos policies in a project.  Patterns demonstrated are:\n\n* Configuring `StartUp` so that Simmy chaos policies are only introduced in builds for certain environments (for instance, Dev but not Prod).\n* Configuring Simmy chaos policies to be injected into the app without changing any existing Polly configuration code.\n* Injecting faults or chaos by modifying external configuration. \n\nThe patterns shown in the sample app are intended as starting points but are not mandatory.  Simmy is very flexible, and we would love to hear how you use it!\n\n## Wrapping up\n\nAll chaos policies (Monkey policies) are designed to inject behavior randomly (faults, latency or custom behavior), so a Monkey policy allows you to specify an injection rate between 0 and 1 (0-100%) thus, the higher is the injection rate the higher is the probability to inject them. Also it allows you to specify whether or not the random injection is enabled, that way you can release/hold (turn on/off) the monkeys regardless of injection rate you specify, it means, if you specify an injection rate of 100% but you tell to the policy that the random injection is disabled, it will do nothing.\n\n## Further information\n\nSee [Issues](https://github.com/App-vNext/Simmy/issues) for latest discussions on taking Simmy forward!\n\n## Credits\n\nSimmy was [the brainchild of](https://github.com/App-vNext/Polly/issues/499) [@mebjas](https://github.com/mebjas) and [@reisenberger](https://github.com/reisenberger). The major part of the implementation was by [@vany0114](https://github.com/vany0114) and [@mebjas](https://github.com/mebjas), with contributions also from [@reisenberger](https://github.com/reisenberger) of the Polly team.\n\n## Blogs and architecture samples around Simmy\n\n### Blog posts\n* [Simmy, the monkey for making chaos](http://elvanydev.com/chaos-injection-with-simmy/) -by [Geovanny Alzate Sandoval](https://twitter.com/geovany0114)\n* [Simmy and Azure App Configuration](http://elvanydev.com/simmy-with-azure-app-configuration/) -by [Geovanny Alzate Sandoval](https://twitter.com/geovany0114)\n* [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)\n* [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)\n* [Chaos Engineering your .NET applications using Simmy](http://josephwoodward.co.uk/2020/01/chaos-engineering-your-dot-net-application-simmy) -by [Joseph Woodward](https://twitter.com/joe_mighty)\n\n### Samples\n* [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.\n\n* [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.\n\n * [Bjørn Einar Bjartnes](https://github.com/bjartwolf) made a [red-green load-testing resilience workshop](https://github.com/bjartnes/bounded-disturbances) to understand how errors and resiliency mechanisms affect a system under load. It has been used to run workshops at for example [NDC Oslo](https://ndcoslo.com/workshops/building-and-testing-resilient-services/dbb2ed362bcc) and there is a video from the workshop at [DotNext](https://www.youtube.com/watch?v=_UFiaNlfxjI)."
  },
  {
    "path": "appveyor.yml",
    "content": "os: Visual Studio 2019\n\n# Build script\nbuild_script:\n  - ps: .\\build.ps1\n\n# Tests\ntest: off\n\nartifacts:\n  - path: artifacts\\nuget-package\\*.nupkg\n\nenvironment:\n  # Skip dotnet package caching on build servers\n  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true"
  },
  {
    "path": "build.bat",
    "content": "@ECHO OFF\nPUSHD %~dp0\nPowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command \"& './build.ps1'\"\n\nIF %errorlevel% neq 0 PAUSE\n\n"
  },
  {
    "path": "build.cake",
    "content": "﻿///////////////////////////////////////////////////////////////////////////////\n// ARGUMENTS\n///////////////////////////////////////////////////////////////////////////////\n\nvar target = Argument<string>(\"target\", \"Default\");\nvar configuration = Argument<string>(\"configuration\", \"Release\");\n\n//////////////////////////////////////////////////////////////////////\n// EXTERNAL NUGET TOOLS\n//////////////////////////////////////////////////////////////////////\n\n#tool nuget:?package=xunit.runner.console&version=2.4.1\n#tool nuget:?package=GitVersion.CommandLine&version=5.0.1\n#tool nuget:?package=Brutal.Dev.StrongNameSigner&version=2.4.0\n\n//////////////////////////////////////////////////////////////////////\n// EXTERNAL NUGET LIBRARIES\n//////////////////////////////////////////////////////////////////////\n\n#addin nuget:?package=Cake.FileHelpers&version=3.2.1\n\n///////////////////////////////////////////////////////////////////////////////\n// GLOBAL VARIABLES\n///////////////////////////////////////////////////////////////////////////////\n\nvar projectName = \"Polly.Contrib.Simmy\";\nvar keyName = \"Polly.Contrib.Simmy.snk\";\n\nvar solutions = GetFiles(\"./**/*.sln\");\nvar solutionPaths = solutions.Select(solution => solution.GetDirectory());\n\nvar srcDir = Directory(\"./src\");\nvar buildDir = Directory(\"./build\");\nvar artifactsDir = Directory(\"./artifacts\");\nvar testResultsDir = artifactsDir + Directory(\"test-results\");\n\n// NuGet\nvar nuspecFilename = projectName + \".nuspec\";\nvar nuspecSrcFile = srcDir + File(nuspecFilename);\nvar nuspecDestFile = buildDir + File(nuspecFilename);\nvar nupkgDestDir = artifactsDir + Directory(\"nuget-package\");\nvar snkFile = srcDir + File(keyName);\n\n// Gitversion\nvar gitVersionPath = ToolsExePath(\"GitVersion.exe\");\nDictionary<string, object> gitVersionOutput;\n\n// Versioning\nstring nugetVersion;\nstring appveyorBuildNumber;\nstring assemblyVersion;\nstring assemblySemver;\n\n// StrongNameSigner\nvar strongNameSignerPath = ToolsExePath(\"StrongNameSigner.Console.exe\");\n\n\n///////////////////////////////////////////////////////////////////////////////\n// SETUP / TEARDOWN\n///////////////////////////////////////////////////////////////////////////////\n\nSetup(_ =>\n{\n    Information(\"\");\n    Information(\" ███████╗██╗███╗   ███╗███╗   ███╗██╗   ██╗\");\n    Information(\" ██╔════╝██║████╗ ████║████╗ ████║╚██╗ ██╔╝\");\n    Information(\" ███████╗██║██╔████╔██║██╔████╔██║ ╚████╔╝ \");\n    Information(\" ╚════██║██║██║╚██╔╝██║██║╚██╔╝██║  ╚██╔╝  \");\n    Information(\" ███████║██║██║ ╚═╝ ██║██║ ╚═╝ ██║   ██║   \");\n    Information(\" ╚══════╝╚═╝╚═╝     ╚═╝╚═╝     ╚═╝   ╚═╝   \");\n    Information(\"\");\n});\n\nTeardown(_ =>\n{\n    Information(\"Finished running tasks.\");\n});\n\n//////////////////////////////////////////////////////////////////////\n// PRIVATE TASKS\n//////////////////////////////////////////////////////////////////////\n\nTask(\"__Clean\")\n    .Does(() =>\n{\n    DirectoryPath[] cleanDirectories = new DirectoryPath[] {\n        buildDir,\n        testResultsDir,\n        nupkgDestDir,\n        artifactsDir\n  \t};\n\n    CleanDirectories(cleanDirectories);\n\n    foreach(var path in cleanDirectories) { EnsureDirectoryExists(path); }\n\n    foreach(var path in solutionPaths)\n    {\n        Information(\"Cleaning {0}\", path);\n        CleanDirectories(path + \"/**/bin/\" + configuration);\n        CleanDirectories(path + \"/**/obj/\" + configuration);\n    }\n});\n\nTask(\"__RestoreNugetPackages\")\n    .Does(() =>\n{\n    foreach(var solution in solutions)\n    {\n        Information(\"Restoring NuGet Packages for {0}\", solution);\n        NuGetRestore(solution);\n    }\n});\n\nTask(\"__UpdateAssemblyVersionInformation\")\n    .Does(() =>\n{\n    var gitVersionSettings = new ProcessSettings()\n        .SetRedirectStandardOutput(true);\n\n    IEnumerable<string> outputLines;\n    StartProcess(gitVersionPath, gitVersionSettings, out outputLines);\n\n    var output = string.Join(\"\\n\", outputLines);\n    gitVersionOutput = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(output);\n\n    Information(\"Updated GlobalAssemblyInfo\");\n\n    Information(\"\");\n    Information(\"Obtained raw version info for package versioning:\");\n    Information(\"NuGetVersion -> {0}\", gitVersionOutput[\"NuGetVersion\"]);\n    Information(\"FullSemVer -> {0}\", gitVersionOutput[\"FullSemVer\"]);\n    Information(\"AssemblySemVer -> {0}\", gitVersionOutput[\"AssemblySemVer\"]);\n\n    appveyorBuildNumber = gitVersionOutput[\"FullSemVer\"].ToString();\n    nugetVersion = gitVersionOutput[\"NuGetVersion\"].ToString();\n    assemblyVersion = gitVersionOutput[\"Major\"].ToString() + \".0.0.0\";\n    assemblySemver = gitVersionOutput[\"AssemblySemVer\"].ToString();\n\n    Information(\"\");\n    Information(\"Mapping versioning information to:\");\n    Information(\"Appveyor build number -> {0}\", appveyorBuildNumber);\n    Information(\"Nuget package version -> {0}\", nugetVersion);\n    Information(\"AssemblyVersion -> {0}\", assemblyVersion);\n    Information(\"AssemblyFileVersion -> {0}\", assemblySemver);\n    Information(\"AssemblyInformationalVersion -> {0}\", assemblySemver);\n});\n\nTask(\"__UpdateDotNetStandardAssemblyVersionNumber\")\n    .Does(() =>\n{\n    Information(\"Updating Assembly Version Information\");\n\n    var attributeToValueMap = new Dictionary<string, string>() {\n        { \"AssemblyVersion\", assemblyVersion },\n        { \"FileVersion\", assemblySemver },\n        { \"InformationalVersion\", assemblySemver },\n        { \"Version\", nugetVersion },\n        { \"PackageVersion\", nugetVersion },\n    };\n\n    var csproj = File(\"./src/Polly.Contrib.Simmy/Polly.Contrib.Simmy.csproj\");\n\n    foreach(var attributeMap in attributeToValueMap) {\n        var attribute = attributeMap.Key;\n        var value = attributeMap.Value;\n\n        var replacedFiles = ReplaceRegexInFiles(csproj, $@\"\\<{attribute}\\>[^\\<]*\\</{attribute}\\>\", $@\"<{attribute}>{value}</{attribute}>\");\n        if (!replacedFiles.Any())\n        {\n            throw new Exception($\"{attribute} version could not be updated in {csproj}.\");\n        }\n    }\n\n});\n\nTask(\"__UpdateAppVeyorBuildNumber\")\n    .WithCriteria(() => AppVeyor.IsRunningOnAppVeyor)\n    .Does(() =>\n{\n    AppVeyor.UpdateBuildVersion(appveyorBuildNumber);\n});\n\nTask(\"__BuildSolutions\")\n    .Does(() =>\n{\n    foreach(var solution in solutions)\n    {\n        Information(\"Building {0}\", solution);\n\n        MSBuild(solution, settings =>\n            settings\n                .SetConfiguration(configuration)\n                .WithProperty(\"TreatWarningsAsErrors\", \"true\")\n                .UseToolVersion(MSBuildToolVersion.VS2019)\n                .SetVerbosity(Verbosity.Minimal)\n                .SetNodeReuse(false));\n    }\n});\n\nTask(\"__RunTests\")\n    .Does(() =>\n{\n    foreach(var specsProj in GetFiles(\"./src/**/*.Specs.csproj\")) {\n        DotNetCoreTest(specsProj.FullPath, new DotNetCoreTestSettings {\n            Configuration = configuration,\n            NoBuild = true\n        });\n    }\n});\n\nTask(\"__CopyOutputToNugetFolder\")\n    .Does(() =>\n{\n    var sourceDir = srcDir + Directory(\"Polly.Contrib.Simmy\") + Directory(\"bin\") + Directory(configuration);\n\n    var destDir = buildDir + Directory(\"lib\");\n\n    Information(\"Copying {0} -> {1}.\", sourceDir, destDir);\n    CopyDirectory(sourceDir, destDir);\n\n    CopyFile(nuspecSrcFile, nuspecDestFile);\n});\n\nTask(\"__StronglySignAssemblies\")\n    .Does(() =>\n{\n    //see: https://github.com/brutaldev/StrongNameSigner\n    var strongNameSignerSettings = new ProcessSettings()\n        .WithArguments(args => args\n            .Append(\"-in\")\n            .AppendQuoted(buildDir)\n            .Append(\"-k\")\n            .AppendQuoted(snkFile)\n            .Append(\"-l\")\n            .AppendQuoted(\"Changes\"));\n\n    StartProcess(strongNameSignerPath, strongNameSignerSettings);\n});\n\nTask(\"__CreateSignedNugetPackage\")\n    .Does(() =>\n{\n    var packageName = projectName;\n\n    Information(\"Building {0}.{1}.nupkg\", packageName, nugetVersion);\n\n    var nuGetPackSettings = new NuGetPackSettings {\n        Id = packageName,\n        Title = packageName,\n        Version = nugetVersion,\n        OutputDirectory = nupkgDestDir\n    };\n\n    NuGetPack(nuspecDestFile, nuGetPackSettings);\n});\n\n//////////////////////////////////////////////////////////////////////\n// BUILD TASKS\n//////////////////////////////////////////////////////////////////////\n\nTask(\"Build\")\n    .IsDependentOn(\"__Clean\")\n    .IsDependentOn(\"__RestoreNugetPackages\")\n    .IsDependentOn(\"__UpdateAssemblyVersionInformation\")\n    .IsDependentOn(\"__UpdateDotNetStandardAssemblyVersionNumber\")\n    .IsDependentOn(\"__UpdateAppVeyorBuildNumber\")\n    .IsDependentOn(\"__BuildSolutions\")\n    .IsDependentOn(\"__RunTests\")\n    .IsDependentOn(\"__CopyOutputToNugetFolder\")\n    .IsDependentOn(\"__StronglySignAssemblies\")\n    .IsDependentOn(\"__CreateSignedNugetPackage\");\n\n///////////////////////////////////////////////////////////////////////////////\n// PRIMARY TARGETS\n///////////////////////////////////////////////////////////////////////////////\n\nTask(\"Default\")\n    .IsDependentOn(\"Build\");\n\n///////////////////////////////////////////////////////////////////////////////\n// EXECUTION\n///////////////////////////////////////////////////////////////////////////////\n\nRunTarget(target);\n\n//////////////////////////////////////////////////////////////////////\n// HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////\n\nstring ToolsExePath(string exeFileName) {\n    var exePath = System.IO.Directory.GetFiles(@\".\\Tools\", exeFileName, SearchOption.AllDirectories).FirstOrDefault();\n    return exePath;\n}\n"
  },
  {
    "path": "build.ps1",
    "content": "<#\n\n.SYNOPSIS\nThis is a Powershell script to bootstrap a Cake build.\n\n.DESCRIPTION\nThis Powershell script will download NuGet if missing, restore NuGet tools (including Cake)\nand execute your Cake build script with the parameters you provide.\n\n.PARAMETER Script\nThe build script to execute.\n.PARAMETER Target\nThe build script target to run.\n.PARAMETER Configuration\nThe build configuration to use.\n.PARAMETER Verbosity\nSpecifies the amount of information to be displayed.\n.PARAMETER Experimental\nTells Cake to use the latest Roslyn release.\n.PARAMETER WhatIf\nPerforms a dry run of the build script.\nNo tasks will be executed.\n.PARAMETER Mono\nTells Cake to use the Mono scripting engine.\n\n.LINK\nhttp://cakebuild.net\n#>\n\nParam(\n    [string]$Script = \"build.cake\",\n    [string]$Target = \"Default\",\n    [string]$Configuration = \"Release\",\n    [ValidateSet(\"Quiet\", \"Minimal\", \"Normal\", \"Verbose\", \"Diagnostic\")]\n    [string]$Verbosity = \"Verbose\",\n    [switch]$Experimental,\n    [Alias(\"DryRun\",\"Noop\")]\n    [switch]$WhatIf,\n    [switch]$Mono,\n    [switch]$SkipToolPackageRestore,\n    [switch]$Verbose\n)\n\nWrite-Host \"Preparing to run build script...\"\n\n# Should we show verbose messages?\nif($Verbose.IsPresent)\n{\n    $VerbosePreference = \"continue\"\n}\n\n$TOOLS_DIR = Join-Path $PSScriptRoot \"tools\"\n$NUGET_EXE = Join-Path $TOOLS_DIR \"nuget.exe\"\n$CAKE_EXE = Join-Path $TOOLS_DIR \"Cake/Cake.exe\"\n$PACKAGES_CONFIG = Join-Path $TOOLS_DIR \"packages.config\"\n\n# Should we use mono?\n$UseMono = \"\";\nif($Mono.IsPresent) {\n    Write-Verbose -Message \"Using the Mono based scripting engine.\"\n    $UseMono = \"-mono\"\n}\n\n# Should we use the new Roslyn?\n$UseExperimental = \"\";\nif($Experimental.IsPresent -and !($Mono.IsPresent)) {\n    Write-Verbose -Message \"Using experimental version of Roslyn.\"\n    $UseExperimental = \"-experimental\"\n}\n\n# Is this a dry run?\n$UseDryRun = \"\";\nif($WhatIf.IsPresent) {\n    $UseDryRun = \"-dryrun\"\n}\n\n# Make sure tools folder exists\nif ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {\n    New-Item -Path $TOOLS_DIR -Type directory | out-null\n}\n\n# Try download NuGet.exe if not exists\nif (!(Test-Path $NUGET_EXE)) {\n    Write-Verbose -Message \"Downloading NuGet.exe...\"\n    Invoke-WebRequest -Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile $NUGET_EXE\n}\n\n# Make sure NuGet exists where we expect it.\nif (!(Test-Path $NUGET_EXE)) {\n    Throw \"Could not find NuGet.exe\"\n}\n\n# Save nuget.exe path to environment to be available to child processed\n$ENV:NUGET_EXE = $NUGET_EXE\n\n# Restore tools from NuGet?\nif(-Not $SkipToolPackageRestore.IsPresent)\n{\n    # Restore tools from NuGet.\n    Push-Location\n    Set-Location $TOOLS_DIR\n\n    Write-Verbose -Message \"Restoring tools from NuGet...\"\n\n    # Restore packages\n    if (Test-Path $PACKAGES_CONFIG)\n    {\n        $NuGetOutput = Invoke-Expression \"&`\"$NUGET_EXE`\" install -ExcludeVersion\"\n        Write-Verbose ($NuGetOutput | Out-String)\n    }\n    # Install just Cake if missing config\n    else\n    {\n        $NuGetOutput = Invoke-Expression \"&`\"$NUGET_EXE`\" install Cake -Version 0.35.0 -ExcludeVersion\"\n        Write-Verbose ($NuGetOutput | Out-String)\n    }\n    Pop-Location\n    if ($LASTEXITCODE -ne 0)\n    {\n        exit $LASTEXITCODE\n    }\n}\n\n# Make sure that Cake has been installed.\nif (!(Test-Path $CAKE_EXE)) {\n    Throw \"Could not find Cake.exe\"\n}\n\n# Start Cake\nWrite-Host \"Running build script...\"\nInvoke-Expression \"$CAKE_EXE `\"$Script`\" -target=`\"$Target`\" -configuration=`\"$Configuration`\" -verbosity=`\"$Verbosity`\" $UseMono $UseDryRun $UseExperimental\"\nexit $LASTEXITCODE\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/AsyncMonkeyEngine.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Utilities;\n\nnamespace Polly.Contrib.Simmy\n{\n    internal static class AsyncMonkeyEngine\n    {\n        private static async Task<bool> ShouldInjectAsync(\n            Context context, \n            CancellationToken cancellationToken, \n            Func<Context, CancellationToken, Task<double>> injectionRate, \n            Func<Context, CancellationToken, Task<bool>> enabled, \n            bool continueOnCapturedContext)\n        {\n            // to prevent execute config delegates if token is signaled before to start.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            if (!await enabled(context, cancellationToken).ConfigureAwait(continueOnCapturedContext))\n            {\n                return false;\n            }\n\n            // to prevent execute injectionRate config delegate if token is signaled on enable configuration delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            double injectionThreshold = await injectionRate(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n\n            // to prevent execute further config delegates if token is signaled on injectionRate configuration delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            injectionThreshold.EnsureInjectionThreshold();\n            return ThreadSafeRandom_LockOncePerThread.NextDouble() < injectionThreshold;\n        }\n\n        internal static async Task<TResult> InjectBehaviourImplementationAsync<TResult>(\n            Func<Context, CancellationToken, Task<TResult>> action, \n            Context context,\n            CancellationToken cancellationToken,\n            Func<Context, CancellationToken, Task> injectedBehaviour,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled,\n            bool continueOnCapturedContext)\n        {\n            if (await ShouldInjectAsync(context, cancellationToken, injectionRate, enabled, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext))\n            {\n                await injectedBehaviour(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n            }\n\n            // to prevent execute the user's action if token is signaled on injectedBehaviour delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n            return await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n        }\n\n        internal static async Task<TResult> InjectExceptionImplementationAsync<TResult>(\n            Func<Context, CancellationToken, Task<TResult>> action,\n            Context context,\n            CancellationToken cancellationToken,\n            Func<Context, CancellationToken, Task<Exception>> injectedException,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled,\n            bool continueOnCapturedContext)\n        {\n            if (await ShouldInjectAsync(context, cancellationToken, injectionRate, enabled, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext))\n            {\n                Exception exception = await injectedException(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n\n                // to prevent throws the exception if token is signaled on injectedException configuration delegate.\n                cancellationToken.ThrowIfCancellationRequested();\n\n                if (exception != null)\n                {\n                    throw exception;\n                }\n            }\n\n            return await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n        }\n\n        internal static async Task<TResult> InjectResultImplementationAsync<TResult>(\n            Func<Context, CancellationToken, Task<TResult>> action,\n            Context context,\n            CancellationToken cancellationToken,\n            Func<Context, CancellationToken, Task<TResult>> injectedResult,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled,\n            bool continueOnCapturedContext)\n        {\n            if (await ShouldInjectAsync(context, cancellationToken, injectionRate, enabled, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext))\n            {\n                return await injectedResult(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n            }\n\n            // to prevent inject the result if token is signaled on injectedResult delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n            return await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/AsyncMonkeyPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Contains common functionality for policies which intentionally disrupt async executions - which monkey around with calls.\n    /// </summary>\n    public abstract class AsyncMonkeyPolicy : AsyncPolicy, IMonkeyPolicy\n    {\n        internal Func<Context, CancellationToken, Task<Double>> InjectionRate { get; }\n        internal Func<Context, CancellationToken, Task<bool>> Enabled { get; }\n\n        internal AsyncMonkeyPolicy(Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            InjectionRate = injectionRate ?? throw new ArgumentNullException(nameof(injectionRate));\n            Enabled = enabled ?? throw new ArgumentNullException(nameof(enabled));\n        }\n    }\n\n    /// <summary>\n    /// Contains common functionality for policies which intentionally disrupt async executions returning TResult - which monkey around with calls.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    public abstract class AsyncMonkeyPolicy<TResult> : AsyncPolicy<TResult>, IMonkeyPolicy<TResult>\n    {\n        internal Func<Context, CancellationToken, Task<Double>> InjectionRate { get; }\n        internal Func<Context, CancellationToken, Task<bool>> Enabled { get; }\n\n        internal AsyncMonkeyPolicy(Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled) \n        {\n            InjectionRate = injectionRate ?? throw new ArgumentNullException(nameof(injectionRate));\n            Enabled = enabled ?? throw new ArgumentNullException(nameof(enabled));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(Action<InjectBehaviourAsyncOptions> configureOptions)\n        {\n            var options = new InjectBehaviourAsyncOptions();\n            configureOptions(options);\n\n            if (options.BehaviourInternal == null) throw new ArgumentNullException(nameof(options.BehaviourInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectBehaviourPolicy(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// A policy that injects any custom behaviour before the execution of delegates.\n    /// </summary>\n    public class AsyncInjectBehaviourPolicy : AsyncMonkeyPolicy\n    {\n        private readonly Func<Context, CancellationToken, Task> _behaviour;\n\n        [Obsolete]\n        internal AsyncInjectBehaviourPolicy(Func<Context, CancellationToken, Task> behaviour, Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _behaviour = behaviour ?? throw new ArgumentNullException(nameof(behaviour));\n        }\n\n        internal AsyncInjectBehaviourPolicy(InjectBehaviourAsyncOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _behaviour = options.BehaviourInternal ?? throw new ArgumentNullException(nameof(options.BehaviourInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,\n            bool continueOnCapturedContext)\n        {\n            return AsyncMonkeyEngine.InjectBehaviourImplementationAsync(\n                action,\n                context,\n                cancellationToken,\n                _behaviour,\n                InjectionRate,\n                Enabled,\n                continueOnCapturedContext);\n        }\n    }\n\n    /// <summary>\n    /// A policy that injects any custom behaviour before the execution of delegates returning <typeparamref name=\"TResult\"/>.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    public class AsyncInjectBehaviourPolicy<TResult> : AsyncMonkeyPolicy<TResult>\n    {\n        private readonly Func<Context, CancellationToken, Task> _behaviour;\n\n        [Obsolete]\n        internal AsyncInjectBehaviourPolicy(Func<Context, CancellationToken, Task> behaviour, Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _behaviour = behaviour ?? throw new ArgumentNullException(nameof(behaviour));\n        }\n\n        internal AsyncInjectBehaviourPolicy(InjectBehaviourAsyncOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _behaviour = options.BehaviourInternal ?? throw new ArgumentNullException(nameof(options.BehaviourInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override Task<TResult> ImplementationAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext)\n        {\n            return AsyncMonkeyEngine.InjectBehaviourImplementationAsync(\n                action,\n                context,\n                cancellationToken,\n                _behaviour,\n                InjectionRate,\n                Enabled,\n                continueOnCapturedContext);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed without context</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(\n            Func<Task> behaviour,\n            Double injectionRate,\n            Func<Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task BehaviourLambda(Context _, CancellationToken __) => behaviour();\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviourAsync(BehaviourLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(\n            Func<Context, CancellationToken, Task> behaviour,\n            Double injectionRate,\n            Func<Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviourAsync(behaviour, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(\n            Func<Context, CancellationToken, Task> behaviour,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n\n            return InjectBehaviourAsync(behaviour, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy InjectBehaviourAsync(\n            Func<Context, CancellationToken, Task> behaviour,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new AsyncInjectBehaviourPolicy(\n                    behaviour,\n                    injectionRate,\n                    enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourTResultOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectBehaviourPolicy<TResult> InjectBehaviourAsync<TResult>(Action<InjectBehaviourAsyncOptions> configureOptions)\n        {\n            var options = new InjectBehaviourAsyncOptions();\n            configureOptions(options);\n\n            if (options.BehaviourInternal == null) throw new ArgumentNullException(nameof(options.BehaviourInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectBehaviourPolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/AsyncInjectBehaviourTResultSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed without context</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy<TResult> InjectBehaviourAsync<TResult>(\n            Func<Task> behaviour,\n            Double injectionRate,\n            Func<Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task BehaviourLambda(Context _, CancellationToken __) => behaviour();\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviourAsync<TResult>(BehaviourLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy<TResult> InjectBehaviourAsync<TResult>(\n            Func<Context, CancellationToken, Task> behaviour,\n            Double injectionRate,\n            Func<Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviourAsync<TResult>(behaviour, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy<TResult> InjectBehaviourAsync<TResult>(\n            Func<Context, CancellationToken, Task> behaviour,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n\n            return InjectBehaviourAsync<TResult>(behaviour, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourAsyncOptions> instead.\")]\n        public static AsyncInjectBehaviourPolicy<TResult> InjectBehaviourAsync<TResult>(\n            Func<Context, CancellationToken, Task> behaviour,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new AsyncInjectBehaviourPolicy<TResult>(\n                    behaviour,\n                    injectionRate,\n                    enabled);\n        }\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourAsyncOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"AsyncInjectBehaviourPolicy\"/>\n    /// </summary>\n    public class InjectBehaviourAsyncOptions : InjectOptionsAsyncBase\n    {\n        /// <summary>\n        /// Behaviour Delegate to be executed\n        /// </summary>\n        internal Func<Context, CancellationToken, Task> BehaviourInternal { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourAsyncOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// Allows configuration of behaviour for asynchronous monkey behaviour-injection policies.\n    /// </summary>\n    public static class InjectBehaviourAsyncOptionsExtensions\n    {\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"behaviour\">A delegate representing the behaviour to inject.</param>\n        public static InjectBehaviourAsyncOptions Behaviour(this InjectBehaviourAsyncOptions options, Func<Task> behaviour) =>\n            Behaviour(options, (_, __) => behaviour());\n\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"behaviour\">A delegate representing the behaviour to inject.</param>\n        public static InjectBehaviourAsyncOptions Behaviour(this InjectBehaviourAsyncOptions options, Func<Context, CancellationToken, Task> behaviour)\n        {\n            options.BehaviourInternal = behaviour;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"AsyncInjectBehaviourPolicy\"/>\n    /// </summary>\n    public class InjectBehaviourOptions : InjectOptionsBase\n    {\n        /// <summary>\n        /// Behaviour Delegate to be executed\n        /// </summary>\n        internal Action<Context, CancellationToken> BehaviourInternal { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// Allows configuration of behaviour for synchronous monkey behaviour-injection policies.\n    /// </summary>\n    public static class InjectBehaviourOptionsExtensions\n    {\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"behaviour\">A delegate representing the behaviour to inject.</param>\n        public static InjectBehaviourOptions Behaviour(this InjectBehaviourOptions options, Action behaviour) =>\n            Behaviour(options, (_, __) => behaviour());\n\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"behaviour\">A delegate representing the behaviour to inject.</param>\n        public static InjectBehaviourOptions Behaviour(this InjectBehaviourOptions options, Action<Context, CancellationToken> behaviour)\n        {\n            options.BehaviourInternal = behaviour;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectBehaviourPolicy InjectBehaviour(Action<InjectBehaviourOptions> configureOptions)\n        {\n            var options = new InjectBehaviourOptions();\n            configureOptions(options);\n\n            if (options.BehaviourInternal == null) throw new ArgumentNullException(nameof(options.BehaviourInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectBehaviourPolicy(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Behavior\n{\n    /// <summary>\n    /// A policy that injects any custom behaviour before the execution of delegates.\n    /// </summary>\n    public class InjectBehaviourPolicy : Simmy.MonkeyPolicy\n    {\n        private readonly Action<Context, CancellationToken> _behaviour;\n\n        [Obsolete]\n        internal InjectBehaviourPolicy(Action<Context, CancellationToken> behaviour, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled) \n            : base(injectionRate, enabled)\n        {\n            _behaviour = behaviour ?? throw new ArgumentNullException(nameof(behaviour));\n        }\n\n        internal InjectBehaviourPolicy(InjectBehaviourOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _behaviour = options.BehaviourInternal ?? throw new ArgumentNullException(nameof(options.BehaviourInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation<TResult>(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            return MonkeyEngine.InjectBehaviourImplementation(\n                action,\n                context,\n                cancellationToken,\n                (ctx, ct) => _behaviour(ctx, ct),\n                InjectionRate,\n                Enabled);\n        }\n    }\n    /// <summary>\n    /// A policy that injects any custom behaviour before the execution of delegates returning <typeparamref name=\"TResult\"/>.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    public class InjectBehaviourPolicy<TResult> : MonkeyPolicy<TResult>\n    {\n        private readonly Action<Context, CancellationToken> _behaviour;\n\n        [Obsolete]\n        internal InjectBehaviourPolicy(Action<Context, CancellationToken> behaviour, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n            : base(injectionRate, enabled)\n        {\n            _behaviour = behaviour ?? throw new ArgumentNullException(nameof(behaviour));\n        }\n\n        internal InjectBehaviourPolicy(InjectBehaviourOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _behaviour = options.BehaviourInternal ?? throw new ArgumentNullException(nameof(options.BehaviourInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            return MonkeyEngine.InjectBehaviourImplementation(\n                action,\n                context,\n                cancellationToken,\n                (ctx, ct) => _behaviour(ctx, ct),\n                InjectionRate,\n                Enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed without context</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy InjectBehaviour(\n            Action behaviour,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            void BehaviourLambda(Context _, CancellationToken __) => behaviour();\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviour(BehaviourLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy InjectBehaviour(\n            Action<Context, CancellationToken> behaviour,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviour(behaviour, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy InjectBehaviour(\n            Action<Context, CancellationToken> behaviour,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            return InjectBehaviour(behaviour, (Func<Context, CancellationToken, Double>)InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy InjectBehaviour(\n            Action<Context, CancellationToken> behaviour,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectBehaviourPolicy(\n                    behaviour,\n                    injectionRate,\n                    enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourTResultOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectBehaviourPolicy<TResult> InjectBehaviour<TResult>(Action<InjectBehaviourOptions> configureOptions)\n        {\n            var options = new InjectBehaviourOptions();\n            configureOptions(options);\n\n            if (options.BehaviourInternal == null) throw new ArgumentNullException(nameof(options.BehaviourInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectBehaviourPolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Behavior/InjectBehaviourTResultSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Behavior;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed without context</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy<TResult> InjectBehaviour<TResult>(\n            Action behaviour,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            void BehaviourLambda(Context _, CancellationToken __) => behaviour();\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviour<TResult>(BehaviourLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free mode</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy<TResult> InjectBehaviour<TResult>(\n            Action<Context, CancellationToken> behaviour,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return InjectBehaviour<TResult>(behaviour, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy<TResult> InjectBehaviour<TResult>(\n            Action<Context, CancellationToken> behaviour,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            return InjectBehaviour<TResult>(behaviour, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"InjectBehaviourPolicy\"/> which executes a behaviour if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"behaviour\">Behaviour Delegate to be executed</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectBehaviourOptions> instead.\")]\n        public static InjectBehaviourPolicy<TResult> InjectBehaviour<TResult>(\n            Action<Context, CancellationToken> behaviour,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (behaviour == null) throw new ArgumentNullException(nameof(behaviour));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectBehaviourPolicy<TResult>(\n                    behaviour,\n                    injectionRate,\n                    enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/IMonkeyPolicy.cs",
    "content": "﻿namespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Defines properties and methods common to all Monkey policies.\n    /// </summary>\n    public interface IMonkeyPolicy : IsPolicy\n    {\n    }\n\n    /// <summary>\n    /// Defines properties and methods common to all Monkey policies generic-typed for executions returning results of type <typeparamref name=\"TResult\"/>.\n    /// </summary>\n    public interface IMonkeyPolicy<TResult> : IMonkeyPolicy\n    {\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/InjectOptionsAsyncBase.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Options used to configure a <see cref=\"MonkeyPolicy\"/>\n    /// </summary>\n    public abstract class InjectOptionsAsyncBase\n    {\n        /// <summary>\n        /// Lambda to get injection rate between [0, 1]\n        /// </summary>\n        internal Func<Context, CancellationToken, Task<Double>> InjectionRate { get; set; }\n\n        /// <summary>\n        /// Lambda to check if this policy is enabled in current context\n        /// </summary>\n        internal Func<Context, CancellationToken, Task<bool>> Enabled { get; set; }\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy/InjectOptionsAsyncBaseExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Utilities;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Allows configuration of when and how often chaos behaviour is injected, for asynchronous monkey policies.\n    /// </summary>\n    public static class InjectOptionsAsyncBaseExtensions\n    {\n        /// <summary>\n        /// Configure that this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        public static InjectOptionsAsyncBase Enabled(this InjectOptionsAsyncBase options) => Enabled(options, true);\n\n        /// <summary>\n        /// Configure whether this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"enabled\">A boolean value indicating whether the monkey policy is enabled.</param>\n        public static InjectOptionsAsyncBase Enabled(this InjectOptionsAsyncBase options, bool enabled)\n        {\n            options.Enabled = (_, __) => Task.FromResult(enabled);\n            return options;\n        }\n\n        /// <summary>\n        /// Configure when this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"enabledWhen\">A delegate which can be executed to determine whether the monkey policy should be enabled.</param>\n        public static InjectOptionsAsyncBase EnabledWhen(this InjectOptionsAsyncBase options, Func<Context, CancellationToken, Task<bool>> enabledWhen)\n        {\n            options.Enabled = enabledWhen;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure the rate at which this monkey policy should inject chaos.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        public static InjectOptionsAsyncBase InjectionRate(this InjectOptionsAsyncBase options, Double injectionRate)\n        {\n            injectionRate.EnsureInjectionThreshold();\n            options.InjectionRate = (_, __) => Task.FromResult(injectionRate);\n            return options;\n        }\n\n        /// <summary>\n        /// Configure the rate at which this monkey policy should inject chaos.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"injectionRateProvider\">A delegate returning the current rate at which this monkey policy should inject chaos, expressed as double between [0, 1]</param>\n        public static InjectOptionsAsyncBase InjectionRate(this InjectOptionsAsyncBase options, Func<Context, CancellationToken, Task<Double>> injectionRateProvider)\n        {\n            options.InjectionRate = injectionRateProvider;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/InjectOptionsBase.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Options used to configure a <see cref=\"MonkeyPolicy\"/>\n    /// </summary>\n    public abstract class InjectOptionsBase\n    {\n        /// <summary>\n        /// Lambda to get injection rate between [0, 1]\n        /// </summary>\n        internal Func<Context, CancellationToken, Double> InjectionRate { get; set; }\n\n        /// <summary>\n        /// Lambda to check if this policy is enabled in current context\n        /// </summary>\n        internal Func<Context, CancellationToken, bool> Enabled { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/InjectOptionsBaseExtensions.cs",
    "content": "﻿using Polly.Contrib.Simmy.Utilities;\nusing System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Allows configuration of when and how often chaos behaviour is injected, for synchronous monkey policies.\n    /// </summary>\n    public static class InjectOptionsBaseExtensions\n    {\n        /// <summary>\n        /// Configure that this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        public static InjectOptionsBase Enabled(this InjectOptionsBase options) => Enabled(options, true);\n\n        /// <summary>\n        /// Configure whether this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"enabled\">A boolean value indicating whether the monkey policy is enabled.</param>\n        public static InjectOptionsBase Enabled(this InjectOptionsBase options, bool enabled)\n        {\n            options.Enabled = (_, __) => enabled;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure when this monkey policy is enabled.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"enabledWhen\">A delegate which can be executed to determine whether the monkey policy should be enabled.</param>\n        public static InjectOptionsBase EnabledWhen(this InjectOptionsBase options, Func<Context, CancellationToken, bool> enabledWhen)\n        {\n            options.Enabled = enabledWhen;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure the rate at which this monkey policy should inject chaos.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"injectionRate\">The injection rate between [0, 1]</param>\n        public static InjectOptionsBase InjectionRate(this InjectOptionsBase options, Double injectionRate)\n        {\n            injectionRate.EnsureInjectionThreshold();\n            options.InjectionRate = (_, __) => injectionRate;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure the rate at which this monkey policy should inject chaos.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"injectionRateProvider\">A delegate returning the current rate at which this monkey policy should inject chaos, expressed as double between [0, 1]</param>\n        public static InjectOptionsBase InjectionRate(this InjectOptionsBase options, Func<Context, CancellationToken, Double> injectionRateProvider)\n        {\n            options.InjectionRate = injectionRateProvider;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/AsyncInjectLatencyOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Latency;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectLatencyPolicy InjectLatencyAsync(Action<InjectLatencyAsyncOptions> configureOptions)\n        {\n            var options = new InjectLatencyAsyncOptions();\n            configureOptions(options);\n\n            if (options.LatencyInternal == null) throw new ArgumentNullException(nameof(options.LatencyInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectLatencyPolicy(options);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectLatencyPolicy<TResult> InjectLatencyAsync<TResult>(Action<InjectLatencyAsyncOptions> configureOptions)\n        {\n            var options = new InjectLatencyAsyncOptions();\n            configureOptions(options);\n\n            if (options.LatencyInternal == null) throw new ArgumentNullException(nameof(options.LatencyInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectLatencyPolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/AsyncInjectLatencyPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Utilities;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// A policy that injects latency before the execution of delegates.\n    /// </summary>\n    public class AsyncInjectLatencyPolicy : AsyncMonkeyPolicy\n    {\n        private readonly Func<Context, CancellationToken, Task<TimeSpan>> _latencyProvider;\n\n        [Obsolete]\n        internal AsyncInjectLatencyPolicy(\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider,\n            Func<Context, CancellationToken, Task<Double>> injectionRate, \n            Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _latencyProvider = latencyProvider ?? throw new ArgumentNullException(nameof(latencyProvider));\n        }\n        \n        internal AsyncInjectLatencyPolicy(InjectLatencyAsyncOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _latencyProvider = options.LatencyInternal ?? throw new ArgumentNullException(nameof(options.LatencyInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override Task<TResult> ImplementationAsync<TResult>(\n            Func<Context, CancellationToken, Task<TResult>> action, \n            Context context, \n            CancellationToken cancellationToken,\n            bool continueOnCapturedContext)\n        {\n            return AsyncMonkeyEngine.InjectBehaviourImplementationAsync(\n                action,\n                context,\n                cancellationToken,\n                async (ctx, ct) =>\n                {\n                    var latency = await _latencyProvider(ctx, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n\n                    // to prevent inject latency if token was signaled on latency configuration delegate.\n                    cancellationToken.ThrowIfCancellationRequested();\n                    await SystemClock.SleepAsync(\n                            latency,\n                            cancellationToken)\n                        .ConfigureAwait(continueOnCapturedContext);\n                },\n                InjectionRate,\n                Enabled,\n                continueOnCapturedContext);\n        }\n    }\n\n    /// <summary>\n    /// A policy that injects latency before the execution of delegates.\n    /// </summary>\n    public class AsyncInjectLatencyPolicy<TResult> : AsyncMonkeyPolicy<TResult>\n    {\n        private readonly Func<Context, CancellationToken, Task<TimeSpan>> _latencyProvider;\n\n        [Obsolete]\n        internal AsyncInjectLatencyPolicy(\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _latencyProvider = latencyProvider ?? throw new ArgumentNullException(nameof(latencyProvider));\n        }\n\n        internal AsyncInjectLatencyPolicy(InjectLatencyAsyncOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _latencyProvider = options.LatencyInternal ?? throw new ArgumentNullException(nameof(options.LatencyInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override Task<TResult> ImplementationAsync(\n            Func<Context, CancellationToken, Task<TResult>> action,\n            Context context,\n            CancellationToken cancellationToken,\n            bool continueOnCapturedContext)\n        {\n            return AsyncMonkeyEngine.InjectBehaviourImplementationAsync(\n                action,\n                context,\n                cancellationToken,\n                async (ctx, ct) =>\n                {\n                    var latency = await _latencyProvider(ctx, cancellationToken).ConfigureAwait(continueOnCapturedContext);\n\n                    // to prevent inject latency if token was signaled on latency configuration delegate.\n                    cancellationToken.ThrowIfCancellationRequested();\n                    await SystemClock.SleepAsync(\n                            latency,\n                            cancellationToken)\n                        .ConfigureAwait(continueOnCapturedContext);\n                },\n                InjectionRate,\n                Enabled,\n                continueOnCapturedContext);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/AsyncInjectLatencySyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Latency;\n\nnamespace Polly.Contrib.Simmy\n{\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">The latency to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy InjectLatencyAsync(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => Task.FromResult(enabled());\n\n            return new AsyncInjectLatencyPolicy(LatencyProvider, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">The latency to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy InjectLatencyAsync(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n\n            return new AsyncInjectLatencyPolicy(LatencyProvider, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy InjectLatencyAsync(\n            TimeSpan latency,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            return new AsyncInjectLatencyPolicy(LatencyProvider, injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy InjectLatencyAsync(\n            Func<Context, CancellationToken, Task<TimeSpan>> latency,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (latency == null) throw new ArgumentNullException(nameof(latency));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new AsyncInjectLatencyPolicy(latency, injectionRate, enabled);\n        }\n    }\n\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy<TResult> InjectLatencyAsync<TResult>(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => Task.FromResult(enabled());\n\n            return new AsyncInjectLatencyPolicy<TResult>(LatencyProvider, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy<TResult> InjectLatencyAsync<TResult>(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult(injectionRate);\n\n            return new AsyncInjectLatencyPolicy<TResult>(LatencyProvider, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy<TResult> InjectLatencyAsync<TResult>(\n            TimeSpan latency,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TimeSpan> LatencyProvider(Context _, CancellationToken __) => Task.FromResult(latency);\n            return new AsyncInjectLatencyPolicy<TResult>(LatencyProvider, injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyAsyncOptions> instead.\")]\n        public static AsyncInjectLatencyPolicy<TResult> InjectLatencyAsync<TResult>(\n            Func<Context, CancellationToken, Task<TimeSpan>> latency,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (latency == null) throw new ArgumentNullException(nameof(latency));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new AsyncInjectLatencyPolicy<TResult>(latency, injectionRate, enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyAsyncOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"AsyncInjectLatencyPolicy\"/>\n    /// </summary>\n    public class InjectLatencyAsyncOptions : InjectOptionsAsyncBase\n    {\n        /// <summary>\n        /// Latency Delegate to be executed\n        /// </summary>\n        internal Func<Context, CancellationToken, Task<TimeSpan>> LatencyInternal { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyAsyncOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// Allows configuration of behaviour for asynchronous monkey behaviour-injection policies.\n    /// </summary>\n    public static class InjectLatencyAsyncOptionsExtensions\n    {\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"latency\">The latency to inject.</param>\n        public static InjectLatencyAsyncOptions Latency(this InjectLatencyAsyncOptions options, TimeSpan latency) =>\n            Latency(options, (_, __) => Task.FromResult(latency));\n\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"latency\">A delegate representing the latency to inject.</param>\n        public static InjectLatencyAsyncOptions Latency(this InjectLatencyAsyncOptions options, Func<Context, CancellationToken, Task<TimeSpan>> latency)\n        {\n            options.LatencyInternal = latency;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"AsyncInjectLatencyPolicy\"/>\n    /// </summary>\n    public class InjectLatencyOptions : InjectOptionsBase\n    {\n        /// <summary>\n        /// Latency Delegate to be executed\n        /// </summary>\n        internal Func<Context, CancellationToken, TimeSpan> LatencyInternal { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// Allows configuration of behaviour for asynchronous monkey behaviour-injection policies.\n    /// </summary>\n    public static class InjectLatencyOptionsExtensions\n    {\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"latency\">The latency to inject.</param>\n        public static InjectLatencyOptions Latency(this InjectLatencyOptions options, TimeSpan latency) =>\n            Latency(options, (_, __) => latency);\n\n        /// <summary>\n        /// Configure behaviour to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"latency\">A delegate representing the latency to inject.</param>\n        public static InjectLatencyOptions Latency(this InjectLatencyOptions options, Func<Context, CancellationToken, TimeSpan> latency)\n        {\n            options.LatencyInternal = latency;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Latency;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds a <see cref=\"InjectLatencyPolicy\"/> which injects latency if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectLatencyPolicy InjectLatency(Action<InjectLatencyOptions> configureOptions)\n        {\n            var options = new InjectLatencyOptions();\n            configureOptions(options);\n\n            if (options.LatencyInternal == null) throw new ArgumentNullException(nameof(options.LatencyInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectLatencyPolicy(options);\n        }\n\n        /// <summary>\n        /// Builds a <see cref=\"AsyncInjectLatencyPolicy\"/> which injects latency if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectLatencyPolicy<TResult> InjectLatency<TResult>(Action<InjectLatencyOptions> configureOptions)\n        {\n            var options = new InjectLatencyOptions();\n            configureOptions(options);\n\n            if (options.LatencyInternal == null) throw new ArgumentNullException(nameof(options.LatencyInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectLatencyPolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencyPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Utilities;\n\nnamespace Polly.Contrib.Simmy.Latency\n{\n    /// <summary>\n    /// A policy that injects latency before the execution of delegates.\n    /// </summary>\n    public class InjectLatencyPolicy : MonkeyPolicy\n    {\n        private readonly Func<Context, CancellationToken, TimeSpan> _latencyProvider;\n\n        [Obsolete]\n        internal InjectLatencyPolicy(\n            Func<Context, CancellationToken, TimeSpan> latencyProvider,\n            Func<Context, CancellationToken, double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n            : base(injectionRate, enabled)\n        {\n            _latencyProvider = latencyProvider ?? throw new ArgumentNullException(nameof(latencyProvider));\n        }\n\n        internal InjectLatencyPolicy(InjectLatencyOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _latencyProvider = options.LatencyInternal ?? throw new ArgumentNullException(nameof(options.LatencyInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation<TResult>(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            return MonkeyEngine.InjectBehaviourImplementation(\n                action,\n                context,\n                cancellationToken,\n                (ctx, ct) =>\n                {\n                    var latency = _latencyProvider(ctx, ct);\n\n                    // to prevent inject latency if token was signaled on latency configuration delegate.\n                    cancellationToken.ThrowIfCancellationRequested();\n                    SystemClock.Sleep(latency, cancellationToken);\n                },\n                InjectionRate,\n                Enabled);\n        }\n    }\n\n    /// <summary>\n    /// A policy that injects latency before the execution of delegates.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    public class InjectLatencyPolicy<TResult> : MonkeyPolicy<TResult>\n    {\n        private readonly Func<Context, CancellationToken, TimeSpan> _latencyProvider;\n\n        [Obsolete]\n        internal InjectLatencyPolicy(\n            Func<Context, CancellationToken, TimeSpan> latencyProvider,\n            Func<Context, CancellationToken, double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n            : base(injectionRate, enabled)\n        {\n            _latencyProvider = latencyProvider ?? throw new ArgumentNullException(nameof(latencyProvider));\n        }\n\n        internal InjectLatencyPolicy(InjectLatencyOptions options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _latencyProvider = options.LatencyInternal ?? throw new ArgumentNullException(nameof(options.LatencyInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            return MonkeyEngine.InjectBehaviourImplementation(\n                action,\n                context,\n                cancellationToken,\n                (ctx, ct) =>\n                {\n                    var latency = _latencyProvider(ctx, ct);\n\n                    // to prevent inject latency if token was signaled on latency configuration delegate.\n                    cancellationToken.ThrowIfCancellationRequested();\n                    SystemClock.Sleep(latency, cancellationToken);\n                },\n                InjectionRate,\n                Enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Latency/InjectLatencySyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Latency;\n\nnamespace Polly.Contrib.Simmy\n{\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">The latency to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy InjectLatency(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy((_, __) => latency, (_, __) => injectionRate, (_, __) => enabled());\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">The latency to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy InjectLatency(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy((_, __) => latency, (_, __) => injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy InjectLatency(\n            TimeSpan latency,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy((_, __) => latency, injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy InjectLatency(\n            Func<Context, CancellationToken, TimeSpan> latency,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (latency == null) throw new ArgumentNullException(nameof(latency));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy(latency, injectionRate, enabled);\n        }\n    }\n\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy<TResult> InjectLatency<TResult>(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy<TResult>((_, __) => latency, (_, __) => injectionRate, (_, __) => enabled());\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy<TResult> InjectLatency<TResult>(\n            TimeSpan latency,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy<TResult>((_, __) => latency, (_, __) => injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy<TResult> InjectLatency<TResult>(\n            TimeSpan latency,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy<TResult>((_, __) => latency, injectionRate, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectLatencyPolicy{TResult}\"/> which injects latency if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"latency\">lambda to get the latency object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectLatencyOptions> instead.\")]\n        public static InjectLatencyPolicy<TResult> InjectLatency<TResult>(\n            Func<Context, CancellationToken, TimeSpan> latency,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (latency == null) throw new ArgumentNullException(nameof(latency));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectLatencyPolicy<TResult>(latency, injectionRate, enabled);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/MonkeyEngine.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Utilities;\n\nnamespace Polly.Contrib.Simmy\n{\n    internal static class MonkeyEngine\n    {\n        private static bool ShouldInject(Context context, CancellationToken cancellationToken, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n        {\n            // to prevent execute config delegates if token is signaled before to start.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            if (!enabled(context, cancellationToken))\n            {\n                return false;\n            }\n\n            // to prevent execute injectionRate config delegate if token is signaled on enable configuration delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            double injectionThreshold = injectionRate(context, cancellationToken);\n\n            // to prevent execute further config delegates if token is signaled on injectionRate configuration delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n\n            injectionThreshold.EnsureInjectionThreshold();\n            return ThreadSafeRandom_LockOncePerThread.NextDouble() < injectionThreshold;\n        }\n\n        internal static TResult InjectBehaviourImplementation<TResult>(\n            Func<Context, CancellationToken, TResult> action,\n            Context context,\n            CancellationToken cancellationToken,\n            Action<Context, CancellationToken> injectedBehaviour,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (ShouldInject(context, cancellationToken, injectionRate, enabled))\n            {\n                injectedBehaviour(context, cancellationToken);\n            }\n\n            // to prevent execute the user's action if token is signaled on injectedBehaviour delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n            return action(context, cancellationToken);\n        }\n\n        internal static TResult InjectExceptionImplementation<TResult>(\n            Func<Context, CancellationToken, TResult> action,\n            Context context,\n            CancellationToken cancellationToken,\n            Func<Context, CancellationToken, Exception> injectedException,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (ShouldInject(context, cancellationToken, injectionRate, enabled))\n            {\n                Exception exception = injectedException(context, cancellationToken);\n\n                // to prevent throws the exception if token is signaled on injectedException configuration delegate.\n                cancellationToken.ThrowIfCancellationRequested();\n\n                if (exception != null)\n                {\n                    throw exception;\n                }\n            }\n\n            return action(context, cancellationToken);\n        }\n\n        internal static TResult InjectResultImplementation<TResult>(\n            Func<Context, CancellationToken, TResult> action,\n            Context context,\n            CancellationToken cancellationToken,\n            Func<Context, CancellationToken, TResult> injectedResult,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (ShouldInject(context, cancellationToken, injectionRate, enabled))\n            {\n                return injectedResult(context, cancellationToken);\n            }\n\n            // to prevent inject the result if token is signaled on injectedResult delegate.\n            cancellationToken.ThrowIfCancellationRequested();\n            return action(context, cancellationToken);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/MonkeyPolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Contains common functionality for policies which intentionally disrupt sync executions - which monkey around with calls.\n    /// </summary>\n    public abstract partial class MonkeyPolicy : Policy, IMonkeyPolicy\n    {\n        internal Func<Context, CancellationToken, Double> InjectionRate { get; }\n\n        internal Func<Context, CancellationToken, bool> Enabled { get; }\n\n        internal MonkeyPolicy(Func<Context, CancellationToken, Double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n        {\n            InjectionRate = injectionRate ?? throw new ArgumentNullException(nameof(injectionRate));\n            Enabled = enabled ?? throw new ArgumentNullException(nameof(enabled));\n        }\n    }\n\n    /// <summary>\n    /// Contains common functionality for policies which intentionally disrupt sync executions returning TResult - which monkey around with calls.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of return values this policy will handle.</typeparam>\n    public abstract class MonkeyPolicy<TResult> : Policy<TResult>, IMonkeyPolicy<TResult>\n    {\n        internal Func<Context, CancellationToken, Double> InjectionRate { get; }\n\n        internal Func<Context, CancellationToken, bool> Enabled { get; }\n\n        internal MonkeyPolicy(Func<Context, CancellationToken, Double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n        {\n            InjectionRate = injectionRate ?? throw new ArgumentNullException(nameof(injectionRate));\n            Enabled = enabled ?? throw new ArgumentNullException(nameof(enabled));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/AsyncInjectOutcomeOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Outcomes;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a fault if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectOutcomePolicy InjectExceptionAsync(Action<InjectOutcomeAsyncOptions<Exception>> configureOptions)\n        {\n            var options = new InjectOutcomeAsyncOptions<Exception>();\n            configureOptions(options);\n\n            if (options.Outcome == null) throw new ArgumentNullException(nameof(options.Outcome));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectOutcomePolicy(options);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a result if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectOutcomePolicy<TResult> InjectResultAsync<TResult>(Action<InjectOutcomeAsyncOptions<TResult>> configureOptions)\n        {\n            var options = new InjectOutcomeAsyncOptions<TResult>();\n            configureOptions(options);\n\n            if (options.Outcome == null) throw new ArgumentNullException(nameof(options.Outcome));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectOutcomePolicy<TResult>(options);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a fault as result if  <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static AsyncInjectOutcomePolicy<TResult> InjectResultAsync<TResult>(Action<InjectOutcomeAsyncOptions<Exception>> configureOptions)\n        {\n            var options = new InjectOutcomeAsyncOptions<Exception>();\n            configureOptions(options);\n\n            if (options.Outcome == null) throw new ArgumentNullException(nameof(options.Outcome));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new AsyncInjectOutcomePolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/AsyncInjectOutcomePolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// A policy that throws an exception in place of executing the passed delegate.\n    /// <remarks>The policy can also be configured to return null in place of the exception, to explicitly fake that no exception is thrown.</remarks>\n    /// </summary>\n    public class AsyncInjectOutcomePolicy : AsyncMonkeyPolicy\n    {\n        private readonly Func<Context, CancellationToken, Task<Exception>> _faultProvider;\n\n        [Obsolete]\n        internal AsyncInjectOutcomePolicy(Func<Context, CancellationToken, Task<Exception>> faultProvider, Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _faultProvider = faultProvider ?? throw new ArgumentNullException(nameof(faultProvider));\n        }\n        \n        internal AsyncInjectOutcomePolicy(InjectOutcomeAsyncOptions<Exception> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _faultProvider = options.Outcome ?? throw new ArgumentNullException(nameof(options.Outcome));\n        }\n\n        /// <inheritdoc/>\n        protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,\n            bool continueOnCapturedContext)\n        {\n             return AsyncMonkeyEngine.InjectExceptionImplementationAsync(\n                action,\n                context,\n                cancellationToken,\n                _faultProvider,\n                InjectionRate,\n                Enabled,\n                continueOnCapturedContext);\n        }\n    }\n\n    /// <summary>\n    /// A policy that injects an outcome (throws an exception or returns a specific result), in place of executing the passed delegate.\n    /// </summary>\n    public class AsyncInjectOutcomePolicy<TResult> : AsyncMonkeyPolicy<TResult>\n    {\n        private readonly Func<Context, CancellationToken, Task<Exception>> _faultProvider;\n        private readonly Func<Context, CancellationToken, Task<TResult>> _resultProvider;\n\n        [Obsolete]\n        internal AsyncInjectOutcomePolicy(Func<Context, CancellationToken, Task<Exception>> faultProvider, Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _faultProvider = faultProvider ?? throw new ArgumentNullException(nameof(faultProvider));\n        }\n\n        [Obsolete]\n        internal AsyncInjectOutcomePolicy(Func<Context, CancellationToken, Task<TResult>> resultProvider, Func<Context, CancellationToken, Task<Double>> injectionRate, Func<Context, CancellationToken, Task<bool>> enabled)\n            : base(injectionRate, enabled)\n        {\n            _resultProvider = resultProvider ?? throw new ArgumentNullException(nameof(resultProvider));\n        }\n\n        internal AsyncInjectOutcomePolicy(InjectOutcomeAsyncOptions<Exception> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _faultProvider = options.Outcome ?? throw new ArgumentNullException(nameof(options.Outcome));\n        }\n\n        internal AsyncInjectOutcomePolicy(InjectOutcomeAsyncOptions<TResult> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _resultProvider = options.Outcome ?? throw new ArgumentNullException(nameof(options.Outcome));\n        }\n\n        /// <inheritdoc/>\n        protected override async Task<TResult> ImplementationAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,\n            bool continueOnCapturedContext)\n        {\n            if (_faultProvider != null)\n            {\n                return await AsyncMonkeyEngine.InjectExceptionImplementationAsync(\n                    action,\n                    context,\n                    cancellationToken,\n                    _faultProvider,\n                    InjectionRate,\n                    Enabled,\n                    continueOnCapturedContext);\n            }\n            else if (_resultProvider != null)\n            {\n                return await AsyncMonkeyEngine.InjectResultImplementationAsync(\n                    action,\n                    context,\n                    cancellationToken,\n                    _resultProvider,\n                    InjectionRate,\n                    Enabled,\n                    continueOnCapturedContext);\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Either a fault or fake result to inject must be defined.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/AsyncInjectOutcomeSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Outcomes;\n\nnamespace Polly.Contrib.Simmy\n{\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy InjectFaultAsync(\n            Exception fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Exception> FaultLambda(Context _, CancellationToken __) => Task.FromResult<Exception>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => Task.FromResult<bool>(enabled());\n\n            return new AsyncInjectOutcomePolicy(FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy InjectFaultAsync(\n            Exception fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Exception> FaultLambda(Context _, CancellationToken __) => Task.FromResult<Exception>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n\n            return new AsyncInjectOutcomePolicy(FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"faultProvider\">lambda to get the fault exception object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy InjectFaultAsync(\n            Func<Context, CancellationToken, Task<Exception>> faultProvider,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (faultProvider == null) throw new ArgumentNullException(nameof(faultProvider));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n            \n            return new AsyncInjectOutcomePolicy(faultProvider, injectionRate, enabled);\n        }\n    }\n\n    public partial class MonkeyPolicy\n    {\n        #region Exception Based Faults\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            Exception fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Exception> FaultLambda(Context _, CancellationToken __) => Task.FromResult<Exception>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __) => Task.FromResult<bool>(enabled());\n\n            return new AsyncInjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Task<Exception>>)FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            Exception fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<Exception> FaultLambda(Context _, CancellationToken __) => Task.FromResult<Exception>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n\n            return new AsyncInjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Task<Exception>>)FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which executes a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"faultProvider\">lambda to get the fault exception object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            Func<Context, CancellationToken, Task<Exception>> faultProvider,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (faultProvider == null) throw new ArgumentNullException(nameof(faultProvider));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n            \n            return new AsyncInjectOutcomePolicy<TResult>(faultProvider, injectionRate, enabled);\n        }\n        #endregion\n\n        #region TResult based Faults\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            TResult fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TResult> FaultLambda(Context _, CancellationToken __) => Task.FromResult<TResult>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n            Task<bool> EnabledLambda(Context _, CancellationToken __)\n            {\n                return Task.FromResult<bool>(enabled());\n            }\n\n            return new AsyncInjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Task<TResult>>)FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            TResult fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Task<TResult> FaultLambda(Context _, CancellationToken __) => Task.FromResult<TResult>(fault);\n            Task<double> InjectionRateLambda(Context _, CancellationToken __) => Task.FromResult<Double>(injectionRate);\n\n            return new AsyncInjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Task<TResult>>)FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"AsyncInjectOutcomePolicy{TResult}\"/> which executes a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">lambda to get the fault exception object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultAsyncOptions> instead.\")]\n        public static AsyncInjectOutcomePolicy<TResult> InjectFaultAsync<TResult>(\n            Func<Context, CancellationToken, Task<TResult>> fault,\n            Func<Context, CancellationToken, Task<Double>> injectionRate,\n            Func<Context, CancellationToken, Task<bool>> enabled)\n        {\n            if (fault == null) throw new ArgumentNullException(nameof(fault));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new AsyncInjectOutcomePolicy<TResult>(fault, injectionRate, enabled);\n        }\n        #endregion\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeAsyncOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"InjectOutcomePolicy\"/>\n    /// </summary>\n    public class InjectOutcomeAsyncOptions<TResult> : InjectOptionsAsyncBase\n    {\n        /// <summary>\n        /// Outcome Delegate to be executed\n        /// </summary>\n        internal Func<Context, CancellationToken, Task<TResult>> Outcome { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeAsyncOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// Allows configuration of fault for asynchronous monkey fault-injection policies.\n    /// </summary>\n    public static class InjectOutcomeAsyncOptionsExtensions\n    {\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">The exception to inject.</param>\n        public static InjectOutcomeAsyncOptions<Exception> Fault(this InjectOutcomeAsyncOptions<Exception> options, Exception fault)\n            => Fault(options, (_, __) => Task.FromResult(fault));\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">A delegate representing the fault to inject.</param>\n        public static InjectOutcomeAsyncOptions<Exception> Fault(this InjectOutcomeAsyncOptions<Exception> options, Func<Context, CancellationToken, Task<Exception>> fault)\n        {\n            options.Outcome = fault;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">The result to inject</param>\n        public static InjectOutcomeAsyncOptions<Exception> Fault<TResult>(this InjectOutcomeAsyncOptions<Exception> options, Exception fault) =>\n            Fault<TResult>(options, (_, __) => Task.FromResult(fault));\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">A delegate representing the result to inject.</param>\n        public static InjectOutcomeAsyncOptions<Exception> Fault<TResult>(this InjectOutcomeAsyncOptions<Exception> options, Func<Context, CancellationToken, Task<Exception>> fault)\n        {\n            options.Outcome = fault;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure result to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"result\">The result to inject</param>\n        public static InjectOutcomeAsyncOptions<TResult> Result<TResult>(this InjectOutcomeAsyncOptions<TResult> options, TResult result) =>\n            Result(options, (_, __) => Task.FromResult(result));\n\n        /// <summary>\n        /// Configure result to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"result\">A delegate representing the result to inject.</param>\n        public static InjectOutcomeAsyncOptions<TResult> Result<TResult>(this InjectOutcomeAsyncOptions<TResult> options, Func<Context, CancellationToken, Task<TResult>> result)\n        {\n            options.Outcome = result;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeOptions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// Options used to configure an <see cref=\"InjectOutcomePolicy\"/>\n    /// </summary>\n    public class InjectOutcomeOptions<TResult> : InjectOptionsBase\n    {\n        /// <summary>\n        /// Outcome Delegate to be executed\n        /// </summary>\n        internal Func<Context, CancellationToken, TResult> OutcomeInternal { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeOptionsExtensions.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// Allows configuration of fault for synchronous monkey fault-injection policies.\n    /// </summary>\n    public static class InjectOutcomeOptionsExtensions\n    {\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">The exception to inject.</param>\n        public static InjectOutcomeOptions<Exception> Fault(this InjectOutcomeOptions<Exception> options, Exception fault)\n            => Fault(options, (_, __) => fault);\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">A delegate representing the fault to inject.</param>\n        public static InjectOutcomeOptions<Exception> Fault(this InjectOutcomeOptions<Exception> options, Func<Context, CancellationToken, Exception> fault)\n        {\n            options.OutcomeInternal = fault;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">The result to inject</param>\n        public static InjectOutcomeOptions<Exception> Fault<TResult>(this InjectOutcomeOptions<Exception> options, Exception fault) =>\n            Fault<TResult>(options, (_, __) => fault);\n\n        /// <summary>\n        /// Configure fault to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"fault\">A delegate representing the result to inject.</param>\n        public static InjectOutcomeOptions<Exception> Fault<TResult>(this InjectOutcomeOptions<Exception> options, Func<Context, CancellationToken, Exception> fault)\n        {\n            options.OutcomeInternal = fault;\n            return options;\n        }\n\n        /// <summary>\n        /// Configure result to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"result\">The result to inject</param>\n        public static InjectOutcomeOptions<TResult> Result<TResult>(this InjectOutcomeOptions<TResult> options, TResult result) =>\n            Result(options, (_, __) => result);\n\n        /// <summary>\n        /// Configure result to inject with the monkey policy.\n        /// </summary>\n        /// <param name=\"options\">The configuration object.</param>\n        /// <param name=\"result\">A delegate representing the result to inject.</param>\n        public static InjectOutcomeOptions<TResult> Result<TResult>(this InjectOutcomeOptions<TResult> options, Func<Context, CancellationToken, TResult> result)\n        {\n            options.OutcomeInternal = result;\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeOptionsSyntax.cs",
    "content": "﻿using System;\nusing Polly.Contrib.Simmy.Outcomes;\n\nnamespace Polly.Contrib.Simmy\n{\n    /// <summary>\n    /// Fluent API for defining Monkey <see cref=\"Policy\"/>. \n    /// </summary>\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectOutcomePolicy InjectException(Action<InjectOutcomeOptions<Exception>> configureOptions)\n        {\n            var options = new InjectOutcomeOptions<Exception>();\n            configureOptions(options);\n\n            if (options.OutcomeInternal == null) throw new ArgumentNullException(nameof(options.OutcomeInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectOutcomePolicy(options);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a result if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectOutcomePolicy<TResult> InjectResult<TResult>(Action<InjectOutcomeOptions<TResult>> configureOptions)\n        {\n            var options = new InjectOutcomeOptions<TResult>();\n            configureOptions(options);\n\n            if (options.OutcomeInternal == null) throw new ArgumentNullException(nameof(options.OutcomeInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectOutcomePolicy<TResult>(options);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault as result if <paramref name=\"configureOptions.Enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"configureOptions.InjectionRate\"/>.\n        /// </summary>\n        /// <param name=\"configureOptions\">A callback to configure policy options.</param>\n        /// <returns>The policy instance.</returns>\n        public static InjectOutcomePolicy<TResult> InjectResult<TResult>(Action<InjectOutcomeOptions<Exception>> configureOptions)\n        {\n            var options = new InjectOutcomeOptions<Exception>();\n            configureOptions(options);\n\n            if (options.OutcomeInternal == null) throw new ArgumentNullException(nameof(options.OutcomeInternal));\n            if (options.InjectionRate == null) throw new ArgumentNullException(nameof(options.InjectionRate));\n            if (options.Enabled == null) throw new ArgumentNullException(nameof(options.Enabled));\n\n            return new InjectOutcomePolicy<TResult>(options);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomePolicy.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Polly.Contrib.Simmy.Outcomes\n{\n    /// <summary>\n    /// A policy that throws an exception in place of executing the passed delegate.\n    /// <remarks>The policy can also be configured to return null in place of the exception, to explicitly fake that no exception is thrown.</remarks>\n    /// </summary>\n    public class InjectOutcomePolicy : MonkeyPolicy\n    {\n        private readonly Func<Context, CancellationToken, Exception> _faultProvider;\n\n        [Obsolete]\n        internal InjectOutcomePolicy(Func<Context, CancellationToken, Exception> faultProvider, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled) \n            : base(injectionRate, enabled)\n        {\n            _faultProvider = faultProvider ?? throw new ArgumentNullException(nameof(faultProvider));\n        }\n\n        internal InjectOutcomePolicy(InjectOutcomeOptions<Exception> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _faultProvider = options.OutcomeInternal ?? throw new ArgumentNullException(nameof(options.OutcomeInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation<TResult>(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            return MonkeyEngine.InjectExceptionImplementation(\n                action,\n                context,\n                cancellationToken,\n                _faultProvider,\n                InjectionRate,\n                Enabled);\n        }\n    }\n\n    /// <summary>\n    /// A policy that injects an outcome (throws an exception or returns a specific result), in place of executing the passed delegate.\n    /// </summary>\n    public class InjectOutcomePolicy<TResult> : MonkeyPolicy<TResult>\n    {\n        private readonly Func<Context, CancellationToken, Exception> _faultProvider;\n        private readonly Func<Context, CancellationToken, TResult> _resultProvider;\n\n        [Obsolete]\n        internal InjectOutcomePolicy(Func<Context, CancellationToken, Exception> faultProvider, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n            : base(injectionRate, enabled)\n        {\n            _faultProvider = faultProvider ?? throw new ArgumentNullException(nameof(faultProvider));\n        }\n\n        [Obsolete]\n        internal InjectOutcomePolicy(Func<Context, CancellationToken, TResult> resultProvider, Func<Context, CancellationToken, double> injectionRate, Func<Context, CancellationToken, bool> enabled)\n            : base(injectionRate, enabled)\n        {\n            _resultProvider = resultProvider ?? throw new ArgumentNullException(nameof(resultProvider));\n        }\n\n        internal InjectOutcomePolicy(InjectOutcomeOptions<Exception> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _faultProvider = options.OutcomeInternal ?? throw new ArgumentNullException(nameof(options.OutcomeInternal));\n        }\n\n        internal InjectOutcomePolicy(InjectOutcomeOptions<TResult> options)\n            : base(options.InjectionRate, options.Enabled)\n        {\n            _resultProvider = options.OutcomeInternal ?? throw new ArgumentNullException(nameof(options.OutcomeInternal));\n        }\n\n        /// <inheritdoc/>\n        protected override TResult Implementation(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)\n        {\n            if (_faultProvider != null)\n            {\n                return MonkeyEngine.InjectExceptionImplementation(\n                    action,\n                    context,\n                    cancellationToken,\n                    _faultProvider,\n                    InjectionRate,\n                    Enabled);\n            }\n            else if (_resultProvider != null)\n            {\n                return MonkeyEngine.InjectResultImplementation(\n                    action,\n                    context,\n                    cancellationToken,\n                    _resultProvider,\n                    InjectionRate,\n                    Enabled);\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Either a fault or fake result to inject must be defined.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Outcomes/InjectOutcomeSyntax.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Outcomes;\n\nnamespace Polly.Contrib.Simmy\n{\n    public partial class MonkeyPolicy\n    {\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy InjectFault(\n            Exception fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Exception FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return new InjectOutcomePolicy(FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy InjectFault(\n            Exception fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Exception FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n\n            return new InjectOutcomePolicy(FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"faultProvider\">lambda to get the fault exception object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy InjectFault(\n            Func<Context, CancellationToken, Exception> faultProvider,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (faultProvider == null) throw new ArgumentNullException(nameof(faultProvider));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectOutcomePolicy(faultProvider, injectionRate, enabled);\n        }\n    }\n\n    public partial class MonkeyPolicy\n    {\n        #region Exception Based Faults\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            Exception fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Exception FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return new InjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Exception>)FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault exception object to throw</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            Exception fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            Exception FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n\n            return new InjectOutcomePolicy<TResult>((Func<Context, CancellationToken, Exception>)FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which executes a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"faultProvider\">lambda to get the fault exception object</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            Func<Context, CancellationToken, Exception> faultProvider,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (faultProvider == null) throw new ArgumentNullException(nameof(faultProvider));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectOutcomePolicy<TResult>(faultProvider, injectionRate, enabled);\n        }\n\n        #endregion\n\n        #region TResult Based Faults\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault result object to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in context free fashion</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            TResult fault,\n            Double injectionRate,\n            Func<bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            TResult FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n            bool EnabledLambda(Context _, CancellationToken __) => enabled();\n\n            return new InjectOutcomePolicy<TResult>((Func<Context, CancellationToken, TResult>)FaultLambda, InjectionRateLambda, EnabledLambda);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which injects a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"fault\">The fault result object to inject</param>\n        /// <param name=\"injectionRate\">injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            TResult fault,\n            Double injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            TResult FaultLambda(Context _, CancellationToken __) => fault;\n            double InjectionRateLambda(Context _, CancellationToken __) => injectionRate;\n\n            return new InjectOutcomePolicy<TResult>((Func<Context, CancellationToken, TResult>)FaultLambda, InjectionRateLambda, enabled);\n        }\n\n        /// <summary>\n        /// Builds an <see cref=\"InjectOutcomePolicy\"/> which executes a fault if <paramref name=\"enabled\"/> returns true and\n        /// a random number is within range of <paramref name=\"injectionRate\"/>.\n        /// </summary>\n        /// <param name=\"faultProvider\">The fault result object to inject</param>\n        /// <param name=\"injectionRate\">lambda to get injection rate between [0, 1]</param>\n        /// <param name=\"enabled\">Lambda to check if this policy is enabled in current context</param>\n        /// <returns>The policy instance.</returns>\n        [Obsolete(\"This overload is going to be deprecated, use the overload which takes Action<InjectFaultOptions> instead.\")]\n        public static InjectOutcomePolicy<TResult> InjectFault<TResult>(\n            Func<Context, CancellationToken, TResult> faultProvider,\n            Func<Context, CancellationToken, Double> injectionRate,\n            Func<Context, CancellationToken, bool> enabled)\n        {\n            if (faultProvider == null) throw new ArgumentNullException(nameof(faultProvider));\n            if (injectionRate == null) throw new ArgumentNullException(nameof(injectionRate));\n            if (enabled == null) throw new ArgumentNullException(nameof(enabled));\n\n            return new InjectOutcomePolicy<TResult>(faultProvider, injectionRate, enabled);\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Polly.Contrib.Simmy.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFrameworks>netstandard1.1;netstandard2.0;netstandard2.1</TargetFrameworks>\n    <AssemblyName>Polly.Contrib.Simmy</AssemblyName>\n    <RootNamespace>Polly.Contrib.Simmy</RootNamespace>\n    <Version>0.1.0</Version>\n    <AssemblyVersion>0.0.0.0</AssemblyVersion>\n    <FileVersion>0.1.0.0</FileVersion>\n    <InformationalVersion>0.1.0.0</InformationalVersion>\n    <PackageVersion>0.1.0</PackageVersion>\n    <Company>App vNext</Company>\n    <Copyright>Copyright (c) 2019, App vNext</Copyright>\n    <Description>Simmy is a chaos-engineering and fault-injection tool, integrating with the Polly resilience project for .NET</Description>\n    <DefaultLanguage>en-US</DefaultLanguage>\n    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\n    <Authors>App vNext</Authors>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)' == 'Debug' \">\n    <DebugType>full</DebugType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)' == 'Release' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(TargetFramework)' == 'netstandard1.1' \">\n    <NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>\n  </PropertyGroup>\n  <ItemGroup>\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleToAttribute\">\n      <_Parameter1>Simmy.Specs</_Parameter1>\n    </AssemblyAttribute>\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Polly\" Version=\"7.1.0\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Utilities/GuardExtensions.cs",
    "content": "﻿using System;\n\nnamespace Polly.Contrib.Simmy.Utilities\n{\n    internal static class GuardExtensions\n    {\n        public static void EnsureInjectionThreshold(this double injectionThreshold)\n        {\n            if (injectionThreshold < 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(injectionThreshold), \"Injection rate/threshold in Monkey policies should always be a double between [0, 1]; never a negative number.\");\n            }\n            if (injectionThreshold > 1)\n            {\n                throw new ArgumentOutOfRangeException(nameof(injectionThreshold), \"Injection rate/threshold in Monkey policies should always be a double between [0, 1]; never a number greater than 1.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy/Utilities/ThreadSafeRandom_LockOncePerThread.cs",
    "content": "﻿using System;\nusing System.Threading;\n\n// Note: Given the current .NET Core (2.1) and .NET Framework (4.7.2) implementations of Random, \n// this implementation intentionally sacrifices a (marginal) degree of randomness in favour of speed, by locking only once-per-thread.\n// An implementation locking once-per-random-number-generated will generate a marginally more random sequence.\n// This implementation intentionally favours execution speed over that marginal extra degree of randomness.\n// We choose that trade-off where the random number generator is used to select executions for chaos/fault injection, where we want minimum extra drag per execution.\n// In other scenarios such as randomizing for jitter in retries, the Polly project may (with a different implementation) favour randomness at the expense of locking once-per-random-number-generated.\n\n// References:\n// - https://stackoverflow.com/a/25448166/\n// - https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netframework-4.7.2#the-systemrandom-class-and-thread-safety\n// - https://stackoverflow.com/questions/25390301/\n// - https://github.com/App-vNext/Polly/issues/530#issuecomment-439680613\n\nnamespace Polly.Contrib.Simmy.Utilities\n{\n    /// <summary>\n    /// An implementation of a Random Number Generator that is thread-safe for generating random numbers concurrently on multiple threads.\n    /// <remarks>Thread-safety without locking-per-random-number-generated is achieved simply by storing and using a ThreadStatic instance of <see cref=\"Random\"/> per thread.</remarks>\n    /// </summary>\n    public class ThreadSafeRandom_LockOncePerThread\n    {\n        /// <summary>\n        /// Initializes the static <see cref=\"ThreadSafeRandom_LockOncePerThread\"/>, setting the <see cref=\"NextDouble\"/> method to a thread-safe implementation which locks only once-per-thread.\n        /// </summary>\n        static ThreadSafeRandom_LockOncePerThread()\n        {\n            Reset();\n        }\n\n        private static readonly Random s_globalRandom = new Random();\n\n        private static readonly ThreadLocal<Random> t_threadRandom = new ThreadLocal<Random>(InitializeThreadRandom);\n\n        private static Random InitializeThreadRandom()\n        {\n            int seed;\n            // We must lock minimally once-per-thread. If the instance s_globalRandom is accessed on multiple threads concurrently, \n            // the current .NET Framework and .NET Core implementations of Random have a liability to return sequences of zeros.\n            // See the articles referenced at the head of this class.\n            lock (s_globalRandom)\n            {\n                seed = s_globalRandom.Next();\n            }\n\n            return new Random(seed);\n        }\n\n        /// <summary>\n        /// Returns a random floating point number that is greater than or equal to 0.0, and less than 1.0.\n        /// </summary>\n        public static Func<double> NextDouble;\n\n        /// <summary>\n        /// Method to reset the random generator.\n        /// </summary>\n        public static void Reset()\n        {\n            NextDouble = () => t_threadRandom.Value.NextDouble();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourAsyncSpecs.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectBehaviourAsyncSpecs : IDisposable\n    {\n        public InjectBehaviourAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.6, () => Task.FromResult(false));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.6, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.4, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(() =>\n            {\n                userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                injectedBehaviourExecuted = true;\n                return Task.CompletedTask;\n            }, 0.6, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourAsyncWithOptionsSpecs.cs",
    "content": "﻿using FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing System;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Behavior;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectBehaviourAsyncWithOptionsSpecs : IDisposable\n    {\n        public InjectBehaviourAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n                );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.4)\n                    .Enabled(false)\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() =>\n                    {\n                        userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.CompletedTask; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        #region invalid threshold on configuration and execution time\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_negative()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate(-1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_greater_than_one()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate(1.1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_is_negative()\n        {\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate((_, __) => Task.FromResult(-1d))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(() => Task.CompletedTask))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_greater_than_one()\n        {\n            var policy = MonkeyPolicy.InjectBehaviourAsync(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate((_, __) => Task.FromResult(1.1))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(() => Task.CompletedTask))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourSpecs.cs",
    "content": "﻿using System;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectBehaviourSpecs : IDisposable\n    {\n        public InjectBehaviourSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(() => { injectedBehaviourExecuted = true; }, 0.6, () => false);\n            \n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(() => { injectedBehaviourExecuted = true; }, 0.6, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(() => { injectedBehaviourExecuted = true; }, 0.4, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(() =>\n            {\n                userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                injectedBehaviourExecuted = true;\n            }, 0.6, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourTResultAsyncSpecs.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectBehaviourTResultAsyncSpecs : IDisposable\n    {\n        public InjectBehaviourTResultAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.6, () => Task.FromResult(false));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.6, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(() => { injectedBehaviourExecuted = true; return Task.CompletedTask; }, 0.4, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(() =>\n            {\n                userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                injectedBehaviourExecuted = true;\n                return Task.CompletedTask;\n            }, 0.6, () => Task.FromResult(true));\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourTResultAsyncWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Behavior;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\nusing FluentAssertions;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectBehaviourTResultAsyncWithOptionsSpecs : IDisposable\n    {\n        public InjectBehaviourTResultAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n                );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() =>\n                    {\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.4)\n                    .Enabled(false)\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() =>\n                    {\n                        userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                        injectedBehaviourExecuted = true;\n                        return Task.CompletedTask;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.ExecuteAsync(() => { userDelegateExecuted = true; return Task.FromResult(ResultPrimitive.Good); });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        #region invalid threshold on configuration and execution time\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_negative()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate(-1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_greater_than_one()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate(1.1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_is_negative()\n        {\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate((_, __) => Task.FromResult(-1d))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_greater_than_one()\n        {\n            var policy = MonkeyPolicy.InjectBehaviourAsync<ResultPrimitive>(with =>\n                with.Behaviour(() => Task.CompletedTask)\n                    .Enabled()\n                    .InjectionRate((_, __) => Task.FromResult(1.1))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourTResultSpecs.cs",
    "content": "﻿using System;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectBehaviourTResultSpecs : IDisposable\n    {\n        public InjectBehaviourTResultSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(() => { injectedBehaviourExecuted = true; }, 0.6, () => false);\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(() => { injectedBehaviourExecuted = true; }, 0.6, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(() => { injectedBehaviourExecuted = true; }, 0.4, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(() =>\n            {\n                userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                injectedBehaviourExecuted = true;\n            }, 0.6, () => true);\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourTResultWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Behavior;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectBehaviourTResultWithOptionsSpecs : IDisposable\n    {\n        public InjectBehaviourTResultWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.6)\n                    .Enabled(false));\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.6)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.4)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() =>\n                    {\n                        userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                        injectedBehaviourExecuted = true;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; return ResultPrimitive.Good; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        #region invalid threshold on configuration and execution time\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_negative()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate(-1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_greater_than_one()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate(1.1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_is_negative()\n        {\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate((_, __) => -1d)\n            );\n\n            policy.Invoking(x => x.Execute(() => ResultPrimitive.Good))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_greater_than_one()\n        {\n            var policy = MonkeyPolicy.InjectBehaviour<ResultPrimitive>(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate((_, __) => 1.1)\n            );\n\n            policy.Invoking(x => x.Execute(() => ResultPrimitive.Good))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Behavior/InjectBehaviourWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Behavior;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Behavior\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectBehaviourWithOptionsSpecs : IDisposable\n    {\n        public InjectBehaviourWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        [Fact]\n        public void Given_not_enabled_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.6)\n                    .Enabled(false));\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_within_threshold_should_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.6)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        [Fact]\n        public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_behaviour()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { injectedBehaviourExecuted = true; })\n                    .InjectionRate(0.4)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeFalse();\n        }\n\n        [Fact]\n        public void Should_inject_behaviour_before_executing_user_delegate()\n        {\n            Boolean userDelegateExecuted = false;\n            Boolean injectedBehaviourExecuted = false;\n\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() =>\n                    {\n                        userDelegateExecuted.Should().BeFalse(); // Not yet executed at the time the injected behaviour runs.\n                        injectedBehaviourExecuted = true;\n                    })\n                    .InjectionRate(0.6)\n                    .Enabled());\n\n            policy.Execute(() => { userDelegateExecuted = true; });\n\n            userDelegateExecuted.Should().BeTrue();\n            injectedBehaviourExecuted.Should().BeTrue();\n        }\n\n        #region invalid threshold on configuration and execution time\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_negative()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate(-1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_configuration_time_when_threshold_is_greater_than_one()\n        {\n            Action act = () => MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate(1.1)\n            );\n\n            act.ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_is_negative()\n        {\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate((_, __) => -1d)\n            );\n\n            policy.Invoking(x => x.Execute(() => { }))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        [Fact]\n        public void Should_throw_error_on_execution_time_when_threshold_is_greater_than_one()\n        {\n            var policy = MonkeyPolicy.InjectBehaviour(with =>\n                with.Behaviour(() => { })\n                    .Enabled()\n                    .InjectionRate((_, __) => 1.1)\n            );\n\n            policy.Invoking(x => x.Execute(() => { }))\n                .ShouldThrow<ArgumentOutOfRangeException>();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Helpers/Constants.cs",
    "content": "﻿namespace Polly.Contrib.Simmy.Specs.Helpers\n{\n    /// <summary>\n    /// Constants supporting tests.\n    /// </summary>\n    public class Constants\n    {\n        /// <summary>\n        /// Used to identify an xUnit test collection dependent on manipulating some ambient context.\n        /// <remarks>Tests in such collections are not parallelized, which prevents one test polluting another when ambient context is manipulated.</remarks>\n        /// </summary>\n        public const string AmbientContextDependentTestCollection = \"AmbientContextDependentTestCollection\";\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Helpers/ResultPrimitive.cs",
    "content": "﻿namespace Polly.Contrib.Simmy.Specs.Helpers\n{\n    /// <summary>\n    /// A helper class supporting tests on how Policy&lt;TResult&gt; policies may handle return results which are primitive types such as ints or enums.\n    /// </summary>\n    internal enum ResultPrimitive\n    {\n        Undefined,\n        Fault,\n        Good,\n        FaultAgain,\n        GoodAgain,\n        FaultYetAgain,\n        Substitute,\n        WhateverButTooLate\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyAsyncSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Timeout;\nusing Polly.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectLatencyAsyncSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.SleepAsync = async (span, ct) => _totalTimeSlept += await Task.FromResult(span.Milliseconds);\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var policy = MonkeyPolicy.InjectLatencyAsync(TimeSpan.FromMilliseconds(500), 0.6, () => false);\n            var executed = false;\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.3, () => true);\n            var executed = false;\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = false;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, 0.3, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = false;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                Func<Context, CancellationToken, Task> actionAsync = (_, ct) =>\n                {\n                    executed = true;\n                    return TaskHelper.EmptyTask;\n                };\n\n                var policy = Policy.TimeoutAsync(timeout, timeoutStrategy)\n                    .WrapAsync(MonkeyPolicy.InjectLatencyAsync(latencyProvider, injectionRate, enabled));\n\n                watch.Start();\n                policy.Awaiting(async x => { await x.ExecuteAsync(actionAsync, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyAsyncWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Latency;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\nusing Polly.Timeout;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectLatencyAsyncWithOptionsSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.SleepAsync = async (span, ct) => _totalTimeSlept += await Task.FromResult(span.Milliseconds);\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(TimeSpan.FromMilliseconds(500))\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n            );\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = false };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = false,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n            var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task> actionAsync = (_, ct) => { executed = true; return TaskHelper.EmptyTask; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                Func<Context, CancellationToken, Task> actionAsync = (_, ct) =>\n                {\n                    executed = true;\n                    return TaskHelper.EmptyTask;\n                };\n\n                var policy = Policy.TimeoutAsync(timeout, timeoutStrategy)\n                    .WrapAsync(\n                        MonkeyPolicy.InjectLatencyAsync(with =>\n                            with.Latency(latencyProvider)\n                                .InjectionRate(injectionRate)\n                                .EnabledWhen(enabled)\n                        ));\n\n                watch.Start();\n                policy.Awaiting(async x => { await x.ExecuteAsync(actionAsync, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencySpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Timeout;\nusing Polly.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectLatencySpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencySpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.Sleep = (span, ct) => _totalTimeSlept += span.Milliseconds;\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.6, () => true);\n            var executed = false;\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var policy = MonkeyPolicy.InjectLatency(TimeSpan.FromMilliseconds(500), 0.6, () => false);\n            var executed = false;\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.6, () => true);\n            var executed = false;\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.3, () => true);\n            var executed = false;\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = false;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(delay, 0.3, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = false;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"Enabled\"];\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = Policy.Timeout(timeout, timeoutStrategy)\n                    .Wrap(MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled));\n\n                watch.Start();\n                policy.Invoking(x => { x.Execute((ctx, ct) => { executed = true; }, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyTResultAsyncSpecs .cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Utilities;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Timeout;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectLatencyTResultAsyncSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyTResultAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.SleepAsync = async (span, ct) => _totalTimeSlept += await Task.FromResult(span.Milliseconds);\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(TimeSpan.FromMilliseconds(500), 0.6, () => false);\n            var executed = false;\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.3, () => true);\n            var executed = false;\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = false;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, 0.3, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = false;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) =>\n                {\n                    executed = true;\n                    return Task.FromResult(ResultPrimitive.Good);\n                };\n\n                var policy = Policy.TimeoutAsync(timeout, timeoutStrategy)\n                    .WrapAsync(MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(latencyProvider, injectionRate, enabled));\n\n                watch.Start();\n                policy.Awaiting(async x => { await x.ExecuteAsync(actionAsync, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyTResultAsyncWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Latency;\nusing Polly.Timeout;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    public class InjectLatencyTResultAsyncWithOptionsSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyTResultAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.SleepAsync = async (span, ct) => _totalTimeSlept += await Task.FromResult(span.Milliseconds);\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(TimeSpan.FromMilliseconds(500))\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n            );\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = false };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = false,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = _ => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var result = await policy.ExecuteAsync(actionAsync, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n            {\n                return await Task.FromResult((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n            var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true, [\"Enabled\"] = true, [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                }\n\n                return await Task.FromResult(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true, [\"Enabled\"] = true, [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return await Task.FromResult(delay);\n                }\n\n                return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true, [\"Enabled\"] = true, [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                var policy = MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true, [\"Enabled\"] = true, [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"Enabled\"]);\n                };\n\n                Func<Context, CancellationToken, Task<double>> injectionRate = async (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return await Task.FromResult((double)ctx[\"InjectionRate\"]);\n                    }\n\n                    return await Task.FromResult(0);\n                };\n\n                Func<Context, CancellationToken, Task<TimeSpan>> latencyProvider = async (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return await Task.FromResult(delay);\n                    }\n\n                    return await Task.FromResult(TimeSpan.FromMilliseconds(0));\n                };\n\n                Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (_, ct) =>\n                {\n                    executed = true;\n                    return Task.FromResult(ResultPrimitive.Good);\n                };\n\n                var policy = Policy.TimeoutAsync(timeout, timeoutStrategy)\n                    .WrapAsync(\n                        MonkeyPolicy.InjectLatencyAsync<ResultPrimitive>(with =>\n                            with.Latency(latencyProvider)\n                                .InjectionRate(injectionRate)\n                                .EnabledWhen(enabled)\n                        ));\n\n                watch.Start();\n                policy.Awaiting(async x => { await x.ExecuteAsync(actionAsync, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyTResultSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Utilities;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\nusing Polly.Timeout;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectLatencyTResultSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyTResultSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.Sleep = (span, ct) => _totalTimeSlept += span.Milliseconds;\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(TimeSpan.FromMilliseconds(500), 0.6, () => false);\n            var executed = false;\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.6, () => true);\n            var executed = false;\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.3, () => true);\n            var executed = false;\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = false;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.6, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, 0.3, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(delay, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = false;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.3;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(latencyProvider, injectionRate, enabled);\n            Boolean executed = false;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"Enabled\"];\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n            var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled);\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context();\n            context[\"ShouldInjectLatency\"] = true;\n            context[\"Enabled\"] = true;\n            context[\"InjectionRate\"] = 0.6;\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                var policy = Policy.Timeout(timeout, timeoutStrategy)\n                    .Wrap(MonkeyPolicy.InjectLatency(latencyProvider, injectionRate, enabled));\n\n                watch.Start();\n                policy.Invoking(x => { x.Execute(action, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyTResultWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\nusing System.Threading;\nusing Polly.Contrib.Simmy.Latency;\nusing Polly.Timeout;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    public class InjectLatencyTResultWithOptionsSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyTResultWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.Sleep = (span, ct) => _totalTimeSlept += span.Milliseconds;\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(TimeSpan.FromMilliseconds(500))\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n            );\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = false };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = false,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            result.Should().Be(ResultPrimitive.Good);\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            var result = policy.Execute(action, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"Enabled\"];\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n            var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Boolean executed = false;\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                var policy = Policy.Timeout(timeout, timeoutStrategy)\n                    .Wrap(\n                        MonkeyPolicy.InjectLatency<ResultPrimitive>(with =>\n                            with.Latency(latencyProvider)\n                                .InjectionRate(injectionRate)\n                                .EnabledWhen(enabled)\n                        ));\n\n                watch.Start();\n                policy.Invoking(x => { x.Execute(action, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Latency/InjectLatencyWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Latency;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\nusing Polly.Timeout;\n\nnamespace Polly.Contrib.Simmy.Specs.Latency\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectLatencyWithOptionsSpecs : IDisposable\n    {\n        private int _totalTimeSlept = 0;\n\n        public InjectLatencyWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n            SystemClock.Sleep = (span, ct) => _totalTimeSlept += span.Milliseconds;\n        }\n\n        public void Dispose()\n        {\n            _totalTimeSlept = 0;\n            SystemClock.Reset();\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Context Free\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_Enabled()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_Dissabled()\n        {\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(TimeSpan.FromMilliseconds(500))\n                    .InjectionRate(0.6)\n                    .Enabled(false)\n            );\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Introduce_Delay_If_InjectionRate_Is_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_Context_Free_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            policy.Execute(() => { executed = true; });\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region With Context\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = false };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Enabled_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context { [\"Enabled\"] = true };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(0.3)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_InjectionRate_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(delay)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(delay.Milliseconds);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = false,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_With_Latency_Lambda_Should_Not_Introduce_Delay_If_InjectionRate_Is_Not_Covered()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.3\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"Enabled\"]);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Execute((ctx) => { executed = true; }, context);\n\n            executed.Should().BeTrue();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"Enabled\"];\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            var policy = MonkeyPolicy.InjectLatency(with =>\n                with.Latency(latencyProvider)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n            {\n                if ((bool)ctx[\"ShouldInjectLatency\"])\n                {\n                    return delay;\n                }\n\n                return TimeSpan.FromMilliseconds(0);\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Fact]\n        public void InjectLatency_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_latency_config_delegate()\n        {\n            var delay = TimeSpan.FromMilliseconds(500);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    cts.Cancel();\n\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = MonkeyPolicy.InjectLatency(with =>\n                    with.Latency(latencyProvider)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n            _totalTimeSlept.Should().Be(0);\n        }\n\n        [Theory]\n        [InlineData(TimeoutStrategy.Optimistic)]\n        [InlineData(TimeoutStrategy.Pessimistic)]\n        public void InjectLatency_With_Context_Should_not_inject_the_whole_latency_if_user_cancelationtoken_is_signaled_from_timeout(TimeoutStrategy timeoutStrategy)\n        {\n            SystemClock.Reset();\n            var timeout = TimeSpan.FromSeconds(5);\n            var delay = TimeSpan.FromSeconds(10);\n            var context = new Context\n            {\n                [\"ShouldInjectLatency\"] = true,\n                [\"Enabled\"] = true,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Boolean executed = false;\n            Stopwatch watch = new Stopwatch();\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"Enabled\"];\n                };\n\n                Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n                {\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        return (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return 0;\n                };\n\n                Func<Context, CancellationToken, TimeSpan> latencyProvider = (ctx, ct) =>\n                {\n                    if ((bool)ctx[\"ShouldInjectLatency\"])\n                    {\n                        return delay;\n                    }\n\n                    return TimeSpan.FromMilliseconds(0);\n                };\n\n                var policy = Policy.Timeout(timeout, timeoutStrategy)\n                    .Wrap(\n                        MonkeyPolicy.InjectLatency(with =>\n                            with.Latency(latencyProvider)\n                                .InjectionRate(injectionRate)\n                                .EnabledWhen(enabled)\n                        ));\n\n                watch.Start();\n                policy.Invoking(x => { x.Execute((ctx, ct) => { executed = true; }, context, cts.Token); })\n                    .ShouldThrow<TimeoutRejectedException>();\n                watch.Stop();\n            }\n\n            executed.Should().BeFalse();\n            watch.Elapsed.Should().BeCloseTo(timeout, ((int)TimeSpan.FromSeconds(3).TotalMilliseconds));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultAsyncSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectFaultAsyncSpecs : IDisposable\n    {\n        public InjectFaultAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, 0.6, () => true);\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_async()\n        {\n            Exception fault = new Exception();\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, 0.3, () => true);\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_not_throw_if_injected_fault_is_permitted_null()\n        {\n            Exception fault = null;\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, 0.3, () => true);\n\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            var policy = MonkeyPolicy.InjectFaultAsync(\n                new Exception(\"test\"),\n                0.6,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            var policy = MonkeyPolicy.InjectFaultAsync(\n                new Exception(\"test\"),\n                0.4,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async_with_enabled_lambda_false()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            var policy = MonkeyPolicy.InjectFaultAsync(\n                new Exception(\"test\"),\n                0.6,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_low()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(-0.1);\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<ArgumentOutOfRangeException>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_high()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(1.01);\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<ArgumentOutOfRangeException>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_basic()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(0.6);\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_all_context_set()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            string failureMessage = \"Failure Message\";\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<InvalidOperationException>()\n                .WithMessage(failureMessage);\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return Task.FromResult(rate);\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return Task.FromResult(rate);\n                };\n\n                Func<Context, CancellationToken, Task<Exception>> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return Task.FromResult(ex);\n                    }\n\n                    return Task.FromResult(new Exception());\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultAsyncWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Outcomes;\nusing Polly.Contrib.Simmy.Utilities;\nusing Polly.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectFaultAsyncWithOptionsSpecs : IDisposable\n    {\n        public InjectFaultAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_async()\n        {\n            Exception fault = new Exception();\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_not_throw_if_injected_fault_is_permitted_null()\n        {\n            Exception fault = null;\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            Func<Task> actionAsync = () => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync)).ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true\n            };\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(new Exception(\"test\"))\n                    .InjectionRate(0.6)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n                );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true\n            };\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(new Exception(\"test\"))\n                    .InjectionRate(0.4)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n            );\n\n            Func<Context, Task> actionAsync = _ => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async_with_enabled_lambda_false()\n        {\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = false\n            };\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(new Exception(\"test\"))\n                    .InjectionRate(0.6)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n            );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_low()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(-0.1);\n            \n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<ArgumentOutOfRangeException>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_high()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(1.01);\n            \n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<ArgumentOutOfRangeException>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_basic()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) => Task.FromResult(0.6);\n            \n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_all_context_set()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            string failureMessage = \"Failure Message\";\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            Func<Context, Task> actionAsync = (_) => { executed = true; return TaskHelper.EmptyTask; };\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<InvalidOperationException>()\n                .WithMessage(failureMessage);\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return Task.FromResult(rate);\n                };\n\n                var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return TaskHelper.EmptyTask;\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return Task.FromResult(rate);\n                };\n\n                Func<Context, CancellationToken, Task<Exception>> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return Task.FromResult(ex);\n                    }\n\n                    return Task.FromResult(new Exception());\n                };\n\n                var policy = MonkeyPolicy.InjectExceptionAsync(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectFaultSpecs : IDisposable\n    {\n        public InjectFaultSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            var policy = MonkeyPolicy.InjectFault(fault, 0.6, () => true);\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate()\n        {\n            Exception fault = new Exception(\"test\");\n            var policy = MonkeyPolicy.InjectFault(fault, 0.3, () => true);\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_not_throw_if_injected_fault_is_permitted_null()\n        {\n            Exception fault = null;\n            var policy = MonkeyPolicy.InjectFault(fault, 0.6, () => true);\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            var policy = MonkeyPolicy.InjectFault(\n                new Exception(\"test\"),\n                0.6,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate()\n        {\n            Exception fault = new Exception(\"test\");\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            var policy = MonkeyPolicy.InjectFault(\n                new Exception(\"test\"),\n                0.4,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_with_enabled_lambda_return_false()\n        {\n            Exception fault = new Exception(\"test\");\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            var policy = MonkeyPolicy.InjectFault(\n                new Exception(\"test\"),\n                0.6,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_low()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => -0.1;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<ArgumentOutOfRangeException>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_high()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 1.01;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<ArgumentOutOfRangeException>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_with_default_context()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 0.6;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_with_all_context_set()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            string failureMessage = \"Failure Message\";\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    return new InvalidOperationException(ctx[\"Message\"].ToString());\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<InvalidOperationException>().WithMessage(failureMessage);\n\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"ShouldFail\"];\n            };\n\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return rate;\n                };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return rate;\n                };\n\n                Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return ex;\n                    }\n\n                    return new Exception();\n                };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultTResultAsyncSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectFaultTResultAsyncSpecs : IDisposable\n    {\n        public InjectFaultTResultAsyncSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.6, () => true);\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync))\n                .ShouldThrowExactly<Exception>()\n                .WithMessage(exceptionMessage);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.3, () => true);\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync))\n                .ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(\n                new Exception(),\n                0.6,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(\n                new Exception(),\n                0.4,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async_with_enabled_lambda_return_false()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(\n                new Exception(),\n                0.4,\n                async (ctx, ct) =>\n                {\n                    return await Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_default_values()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<double>> injectionRate = (ctx, ct) => Task.FromResult(0.6);\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_all_values_set()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<InvalidOperationException>();\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n\n        #region TResult Based Monkey Policies\n        [Fact]\n        public async Task InjectFault_Context_Free_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.6, () => true);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_Context_Free_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.4, () => true);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_Enabled_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.6, enabled);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_Enabled_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, 0.6, enabled);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_InjectionRate_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<ResultPrimitive>> fault = (ctx, cts) =>\n            {\n                return Task.FromResult(ResultPrimitive.Fault);\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult(true);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_InjectionRate_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.4;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<ResultPrimitive>> fault = (ctx, cts) =>\n            {\n                return Task.FromResult(ResultPrimitive.Fault);\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult(true);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return Task.FromResult(rate);\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return Task.FromResult(rate);\n                };\n\n                Func<Context, CancellationToken, Task<Exception>> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return Task.FromResult(ex);\n                    }\n\n                    return Task.FromResult(new Exception());\n                };\n\n                var policy = MonkeyPolicy.InjectFaultAsync<ResultPrimitive>(fault, injectionRate, enabled);\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultTResultAsyncWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Outcomes;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectFaultTResultAsyncWithOptionsSpecs : IDisposable\n    {\n        public InjectFaultTResultAsyncWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync))\n                .ShouldThrowExactly<Exception>()\n                .WithMessage(exceptionMessage);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_async()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () => { executed = true; return Task.FromResult(ResultPrimitive.Good); };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync))\n                .ShouldNotThrow<Exception>();\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.6)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context)).ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.4)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_async_with_enabled_lambda_return_false()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = false };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true; return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.4)\n                    .EnabledWhen(async (ctx, ct) => await Task.FromResult((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_default_values()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) => Task.FromResult(new Exception());\n            Func<Context, CancellationToken, Task<double>> injectionRate = (ctx, ct) => Task.FromResult(0.6);\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) => Task.FromResult(true);\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<Exception>();\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with_all_values_set()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context))\n                .ShouldThrowExactly<InvalidOperationException>();\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n\n        #region TResult Based Monkey Policies\n        [Fact]\n        public async Task InjectFault_Context_Free_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_Context_Free_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Func<Task<ResultPrimitive>> actionAsync = () =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.4)\n                    .Enabled()\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_Enabled_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_Enabled_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = false };\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_InjectionRate_Should_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"InjectionRate\"] = 0.6 };\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<ResultPrimitive>> fault = (ctx, cts) =>\n            {\n                return Task.FromResult(ResultPrimitive.Fault);\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult(true);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task InjectFault_With_Context_InjectionRate_Should_Not_Return_Fault_async()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.4;\n\n            Func<Context, Task<ResultPrimitive>> actionAsync = (ctx) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<ResultPrimitive>> fault = (ctx, cts) =>\n            {\n                return Task.FromResult(ResultPrimitive.Fault);\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult(true);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = await policy.ExecuteAsync(actionAsync, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n            {\n                return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return Task.FromResult(rate);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            Func<Context, CancellationToken, Task<Exception>> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return Task.FromResult(ex);\n                }\n\n                return Task.FromResult(new Exception());\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return Task.FromResult(rate);\n                };\n\n                var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, CancellationToken, Task<ResultPrimitive>> actionAsync = (ctx, ct) =>\n            {\n                executed = true;\n                return Task.FromResult(ResultPrimitive.Good);\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>\n                {\n                    return Task.FromResult((bool)ctx[\"ShouldFail\"]);\n                };\n\n                Func<Context, CancellationToken, Task<Double>> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return Task.FromResult(rate);\n                };\n\n                Func<Context, CancellationToken, Task<Exception>> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return Task.FromResult(ex);\n                    }\n\n                    return Task.FromResult(new Exception());\n                };\n\n                var policy = MonkeyPolicy.InjectResultAsync<ResultPrimitive>(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Awaiting(async x => await x.ExecuteAsync(actionAsync, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultTResultSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    [Obsolete]\n    public class InjectFaultTResultSpecs : IDisposable\n    {\n        public InjectFaultTResultSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFaultContext_Free_Enabled_Should_not_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.6, () => true);\n            policy.Invoking(x => x.Execute(action))\n                .ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultContext_Free_Enabled_Should_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.3, () => true);\n            policy.Invoking(x => x.Execute(action))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(\n                new Exception(),\n                0.6,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(\n                new Exception(),\n                0.4,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_execute_user_delegate_with_enabled_lambda_disabled()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(\n                new Exception(),\n                0.6,\n                (ctx, ct) =>\n                {\n                    return ((bool)ctx[\"ShouldFail\"]);\n                });\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate_default_context()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 0.6;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrow<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate_full_context()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    return new InvalidOperationException(ctx[\"Message\"].ToString());\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, injectionRate, enabled);\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrowExactly<InvalidOperationException>();\n\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region TResult Based Monkey Policies\n        [Fact]\n        public void InjectFaultContext_Free_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.6, () => true);\n            ResultPrimitive response = policy.Execute(action);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultContext_Free_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.4, () => true);\n            ResultPrimitive response = policy.Execute(action);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Enabled_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.6, enabled);\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Enabled_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = false;\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, 0.6, enabled);\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_InjectionRate_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            Func<Context, CancellationToken, ResultPrimitive> fault = (ctx, ct) =>\n            {\n                return ResultPrimitive.Fault;\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return true;\n            };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, injectionRate, enabled);\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_InjectionRate_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.4;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            Func<Context, CancellationToken, ResultPrimitive> fault = (ctx, ct) =>\n            {\n                return ResultPrimitive.Fault;\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return true;\n            };\n\n            var policy = MonkeyPolicy.InjectFault<ResultPrimitive>(fault, injectionRate, enabled);\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"ShouldFail\"];\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return rate;\n                };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"ShouldFail\"] = true;\n            context[\"Message\"] = failureMessage;\n            context[\"InjectionRate\"] = 0.6;\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return rate;\n                };\n\n                Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return ex;\n                    }\n\n                    return new Exception();\n                };\n\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                var policy = MonkeyPolicy.InjectFault(fault, injectionRate, enabled);\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultTResultWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Outcomes;\nusing Polly.Contrib.Simmy.Specs.Helpers;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Constants.AmbientContextDependentTestCollection)]\n    public class InjectFaultTResultWithOptionsSpecs : IDisposable\n    {\n        public InjectFaultTResultWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Result as Fault, Context Free\n        [Fact]\n        public void InjectFaultContext_Free_Enabled_Should_not_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            policy.Invoking(x => x.Execute(action))\n                .ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultContext_Free_Enabled_Should_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            policy.Invoking(x => x.Execute(action))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Basic Overload, Result as Fault, With Context\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.6)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.4)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_execute_user_delegate_with_enabled_lambda_disabled()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = false };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault(new Exception())\n                    .InjectionRate(0.6)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate_default_context()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 0.6;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault<ResultPrimitive>(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrow<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Should_not_execute_user_delegate_full_context()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    return new InvalidOperationException(ctx[\"Message\"].ToString());\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute(action, context))\n                .ShouldThrowExactly<InvalidOperationException>();\n\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region TResult Based Monkey Policies\n        [Fact]\n        public void InjectFaultContext_Free_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            ResultPrimitive response = policy.Execute(action);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultContext_Free_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Func<ResultPrimitive> action = () => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.4)\n                    .Enabled()\n            );\n\n            ResultPrimitive response = policy.Execute(action);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Enabled_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.6)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_Enabled_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = false };\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            ResultPrimitive fault = ResultPrimitive.Fault;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(0.4)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_InjectionRate_Should_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"InjectionRate\"] = 0.6 };\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            Func<Context, CancellationToken, ResultPrimitive> fault = (ctx, ct) =>\n            {\n                return ResultPrimitive.Fault;\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return true;\n            };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Fault);\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFaultWith_Context_InjectionRate_Should_Not_Return_Fault()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n            context[\"InjectionRate\"] = 0.4;\n\n            Func<Context, ResultPrimitive> action = (ctx) => { executed = true; return ResultPrimitive.Good; };\n            Func<Context, CancellationToken, ResultPrimitive> fault = (ctx, ct) =>\n            {\n                return ResultPrimitive.Fault;\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return true;\n            };\n\n            var policy = MonkeyPolicy.InjectResult<ResultPrimitive>(with =>\n                with.Result(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            ResultPrimitive response = policy.Execute(action, context);\n            response.Should().Be(ResultPrimitive.Good);\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true, [\"Message\"] = failureMessage, [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"ShouldFail\"];\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true, [\"Message\"] = failureMessage, [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true, [\"Message\"] = failureMessage, [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return rate;\n                };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true, [\"Message\"] = failureMessage, [\"InjectionRate\"] = 0.6\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return rate;\n                };\n\n                Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return ex;\n                    }\n\n                    return new Exception();\n                };\n\n                Func<Context, CancellationToken, ResultPrimitive> action = (ctx, ct) => { executed = true; return ResultPrimitive.Good; };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute(action, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Outcomes/InjectFaultWithOptionsSpecs.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing FluentAssertions;\nusing Polly.Contrib.Simmy.Outcomes;\nusing Polly.Contrib.Simmy.Utilities;\nusing Xunit;\n\nnamespace Polly.Contrib.Simmy.Specs.Outcomes\n{\n    [Collection(Helpers.Constants.AmbientContextDependentTestCollection)]\n    public class InjectFaultWithOptionsSpecs : IDisposable\n    {\n        public InjectFaultWithOptionsSpecs()\n        {\n            ThreadSafeRandom_LockOncePerThread.NextDouble = () => 0.5;\n        }\n\n        public void Dispose()\n        {\n            ThreadSafeRandom_LockOncePerThread.Reset();\n        }\n\n        #region Basic Overload, Exception, Context Free\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_not_execute_user_delegate()\n        {\n            string exceptionMessage = \"exceptionMessage\";\n            Exception fault = new Exception(exceptionMessage);\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldThrowExactly<Exception>().WithMessage(exceptionMessage);\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate()\n        {\n            Exception fault = new Exception(\"test\");\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.3)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_Context_Free_Enabled_Should_execute_user_delegate_not_throw_if_injected_fault_is_permitted_null()\n        {\n            Exception fault = null;\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.6)\n                    .Enabled()\n            );\n\n            Boolean executed = false;\n            policy.Invoking(x => x.Execute(() => { executed = true; }))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        #endregion\n\n        #region Basic Overload, Exception, With Context\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate()\n        {\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(new Exception(\"test\"))\n                    .InjectionRate(0.6)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate()\n        {\n            Exception fault = new Exception(\"test\");\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = true };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.4)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_execute_user_delegate_with_enabled_lambda_return_false()\n        {\n            Exception fault = new Exception(\"test\");\n            Boolean executed = false;\n            Context context = new Context { [\"ShouldFail\"] = false };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(0.6)\n                    .EnabledWhen((ctx, ct) => ((bool)ctx[\"ShouldFail\"]))\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldNotThrow<Exception>();\n\n            executed.Should().BeTrue();\n        }\n        #endregion\n\n        #region Overload, All based on context\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_low()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => -0.1;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<ArgumentOutOfRangeException>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_high()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 1.01;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<ArgumentOutOfRangeException>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_with_default_context()\n        {\n            Boolean executed = false;\n            Context context = new Context();\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) => new Exception();\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) => 0.6;\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) => true;\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<Exception>();\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_with_all_context_set()\n        {\n            Boolean executed = false;\n            string failureMessage = \"Failure Message\";\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    return new InvalidOperationException(ctx[\"Message\"].ToString());\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, double> injectionRate = (ctx, ct) =>\n            {\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    return (double)ctx[\"InjectionRate\"];\n                }\n\n                return 0;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return ((bool)ctx[\"ShouldFail\"]);\n            };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            policy.Invoking(x => x.Execute((ctx) => { executed = true; }, context))\n                .ShouldThrowExactly<InvalidOperationException>().WithMessage(failureMessage);\n\n            executed.Should().BeFalse();\n        }\n        #endregion\n\n        #region Cancellable scenarios\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n            {\n                return (bool)ctx[\"ShouldFail\"];\n            };\n\n            var policy = MonkeyPolicy.InjectException(with =>\n                with.Fault(fault)\n                    .InjectionRate(injectionRate)\n                    .EnabledWhen(enabled)\n            );\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                cts.Cancel();\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n            {\n                double rate = 0;\n                if (ctx[\"InjectionRate\"] != null)\n                {\n                    rate = (double)ctx[\"InjectionRate\"];\n                }\n\n                return rate;\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            Func<Context, CancellationToken, Exception> fault = (ctx, cts) =>\n            {\n                if (ctx[\"Message\"] != null)\n                {\n                    Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                    return ex;\n                }\n\n                return new Exception();\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    cts.Cancel();\n                    return rate;\n                };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        [Fact]\n        public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate()\n        {\n            string failureMessage = \"Failure Message\";\n            Boolean executed = false;\n            Context context = new Context\n            {\n                [\"ShouldFail\"] = true,\n                [\"Message\"] = failureMessage,\n                [\"InjectionRate\"] = 0.6\n            };\n\n            using (CancellationTokenSource cts = new CancellationTokenSource())\n            {\n                Func<Context, CancellationToken, bool> enabled = (ctx, ct) =>\n                {\n                    return (bool)ctx[\"ShouldFail\"];\n                };\n\n                Func<Context, CancellationToken, Double> injectionRate = (ctx, ct) =>\n                {\n                    double rate = 0;\n                    if (ctx[\"InjectionRate\"] != null)\n                    {\n                        rate = (double)ctx[\"InjectionRate\"];\n                    }\n\n                    return rate;\n                };\n\n                Func<Context, CancellationToken, Exception> fault = (ctx, ct) =>\n                {\n                    cts.Cancel();\n                    if (ctx[\"Message\"] != null)\n                    {\n                        Exception ex = new InvalidOperationException(ctx[\"Message\"].ToString());\n                        return ex;\n                    }\n\n                    return new Exception();\n                };\n\n                var policy = MonkeyPolicy.InjectException(with =>\n                    with.Fault(fault)\n                        .InjectionRate(injectionRate)\n                        .EnabledWhen(enabled)\n                );\n\n                policy.Invoking(x => x.Execute((ctx, ct) => { executed = true; }, context, cts.Token))\n                    .ShouldThrow<OperationCanceledException>();\n            }\n\n            executed.Should().BeFalse();\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.Specs/Polly.Contrib.Simmy.Specs.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp1.1;netcoreapp2.1;netcoreapp3.0;net462;net472</TargetFrameworks>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"FluentAssertions\" Version=\"4.19.3\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"15.8.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.4.0\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"2.4.0\" />\n    <DotNetCliToolReference Include=\"dotnet-xunit\" Version=\"2.3.1\" />\n  </ItemGroup>\n\n  <ItemGroup Condition=\"'$(TargetFramework)'=='net462' or '$(TargetFramework)'=='net472'\">\n    <PackageReference Include=\"Microsoft.NETFramework.ReferenceAssemblies\" Version=\"1.0.0-preview.2\" PrivateAssets=\"All\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Polly.Contrib.Simmy\\Polly.Contrib.Simmy.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.nuspec",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package>\n  <metadata>\n    <owners>App vNext</owners>\n    <authors>App vNext</authors>\n    <description>\n      Simmy is a chaos-engineering and fault-injection tool, integrating with the Polly resilience project for .NET\n    </description>\n    <language>en-US</language>\n    <license type=\"expression\">BSD-3-Clause</license>\n    <iconUrl>https://raw.github.com/App-vNext/Simmy/master/Simmy.png</iconUrl>\n    <projectUrl>https://github.com/App-vNext/Simmy</projectUrl>\n    <tags>Resilience Chaos-engineering Fault-injection</tags>\n    <copyright>Copyright © 2019, App vNext</copyright>\n    <releaseNotes>\n\t 0.3.0\n\t ---------------------\n\t - Add a new Fluent-builder syntax \n\t - Add intuitive syntax for result stubbing, for use in unit-tests or in other systems on how those systems handle faults\n\t - Compiles on mac and linux\n\t - Add support for .NET Standard 2.1\n\t - Validates constant `injectionRate` at Policy configuration time\n\t 0.2.0\n\t ---------------------\n\t - Makes InjectLatency policies cancellable (both sync and async)\n\t - Add support for cancellation on async configuration-providing delegates\n     0.1.0\n     ---------------------\n     - Initial launch\n   </releaseNotes>\n    <dependencies>\n      <group targetFramework=\"netstandard1.1\">\n        <dependency id=\"NETStandard.Library\" version=\"1.6.1\" />\n        <dependency id=\"Polly\" version=\"7.1.0\" />\n      </group>\n      <group targetFramework=\"netstandard2.0\">\n        <dependency id=\"Polly\" version=\"7.1.0\" />\n      </group>\n      <group targetFramework=\"netstandard2.1\">\n        <dependency id=\"Polly\" version=\"7.1.0\" />\n      </group>\n    </dependencies>\n  </metadata>\n  <files>\n    <file src=\"lib\\**\\*.*\" target=\"lib\" exclude=\"**\\*.unsigned\" />\n  </files>\n</package>\n"
  },
  {
    "path": "src/Polly.Contrib.Simmy.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28307.168\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Polly.Contrib.Simmy\", \"Polly.Contrib.Simmy\\Polly.Contrib.Simmy.csproj\", \"{B7730E1D-0796-4151-95C3-1C6E7DE897B9}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Polly.Contrib.Simmy.Specs\", \"Polly.Contrib.Simmy.Specs\\Polly.Contrib.Simmy.Specs.csproj\", \"{ED587F9F-BBE6-4715-9FAA-BAAEFE288A73}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B7730E1D-0796-4151-95C3-1C6E7DE897B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B7730E1D-0796-4151-95C3-1C6E7DE897B9}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B7730E1D-0796-4151-95C3-1C6E7DE897B9}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B7730E1D-0796-4151-95C3-1C6E7DE897B9}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{ED587F9F-BBE6-4715-9FAA-BAAEFE288A73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{ED587F9F-BBE6-4715-9FAA-BAAEFE288A73}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{ED587F9F-BBE6-4715-9FAA-BAAEFE288A73}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{ED587F9F-BBE6-4715-9FAA-BAAEFE288A73}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {509DA380-9907-48F4-BB77-DD6F8C4EF207}\n\tEndGlobalSection\nEndGlobal\n"
  }
]