Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Extract CallPolly.Core; split tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Nov 5, 2018
1 parent ed539dd commit dbc466a
Show file tree
Hide file tree
Showing 28 changed files with 1,034 additions and 379 deletions.
30 changes: 30 additions & 0 deletions CallPolly.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CallPolly.Tests", "tests\Ca
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".project", ".project", "{6047ADD6-C48C-4583-A5C6-58FDF7A0DC10}"
ProjectSection(SolutionItems) = preProject
after.CallPolly.sln.targets = after.CallPolly.sln.targets
azure-pipelines.yml = azure-pipelines.yml
build.proj = build.proj
build.ps1 = build.ps1
Expand All @@ -19,8 +20,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".project", ".project", "{60
LICENSE = LICENSE
README.md = README.md
SECURITY.md = SECURITY.md
Directory.Build.targets = Directory.Build.targets
EndProjectSection
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CallPolly.Core", "src\CallPolly.Core\CallPolly.Core.fsproj", "{D6697E60-30D9-4E0F-8341-E99E2A00043E}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CallPolly.Core.Tests", "tests\CallPolly.Core.Tests\CallPolly.Core.Tests.fsproj", "{3827E8B1-D858-4CB9-8436-2392276E4EA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -67,6 +73,30 @@ Global
{A2263DFE-3AD1-4A07-8559-A36A7E03CBA0}.Release|x64.Build.0 = Release|Any CPU
{A2263DFE-3AD1-4A07-8559-A36A7E03CBA0}.Release|x86.ActiveCfg = Release|Any CPU
{A2263DFE-3AD1-4A07-8559-A36A7E03CBA0}.Release|x86.Build.0 = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|x64.Build.0 = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Debug|x86.Build.0 = Debug|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|Any CPU.Build.0 = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|x64.ActiveCfg = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|x64.Build.0 = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|x86.ActiveCfg = Release|Any CPU
{D6697E60-30D9-4E0F-8341-E99E2A00043E}.Release|x86.Build.0 = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|x64.ActiveCfg = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|x64.Build.0 = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|x86.ActiveCfg = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Debug|x86.Build.0 = Debug|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|Any CPU.Build.0 = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|x64.ActiveCfg = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|x64.Build.0 = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|x86.ActiveCfg = Release|Any CPU
{3827E8B1-D858-4CB9-8436-2392276E4EA3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
12 changes: 11 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project ToolsVersion="15.0">
<PropertyGroup>
<VersionPrefix>0.0.7</VersionPrefix>
<Authors>@jet @bartelink and contributors</Authors>
<Company>Jet.com</Company>
<Description>Apply systemwide resilience strategies consistently across subsystems, standing on Polly's shoulders</Description>
Expand All @@ -14,6 +15,15 @@
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<!-- disable sourcelink on mono, to workaround https://github.com/dotnet/sourcelink/issues/155 -->
<EnableSourceLink Condition=" '$(OS)' != 'Windows_NT' AND '$(MSBuildRuntimeType)' != 'Core' ">false</EnableSourceLink>
<EnableSourceControlManagerQueries>$(EnableSourceLink)</EnableSourceControlManagerQueries>
</PropertyGroup>

<!-- Workaround for https://github.com/xunit/xunit/issues/1357 -->
<PropertyGroup>
<ThisDirAbsolute>$([System.IO.Path]::GetFullPath("$(MSBuildThisFileDirectory)"))</ThisDirAbsolute>
</PropertyGroup>
<ItemGroup>
<Content Include="$(ThisDirAbsolute)tests/xunit.runner.json" Condition=" '$(OS)' != 'Windows_NT' AND '$(IsTestProject)' != 'false'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project ToolsVersion="15.0">
<!--Workaround for https://github.com/Microsoft/vstest/issues/1129 from https://dasmulli.blog/2018/01/20/make-dotnet-test-work-on-solution-files/-->
<Target Name="VSTestIfTestProject">
<CallTarget Targets="VSTest" Condition="'$(IsTestProject)' == 'true'" />
</Target>
</Project>
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,44 @@ _Please raise GitHub issues for any questions specific to CallPolly so others ca
## Goals

CallPolly wraps Polly to provide:
- parsing and validation of a suite of rules in a declarative form (presently json, but being able to maintain the inputs in YAML is on the wishlist)
- a ruleset interpreter that applies the rules in a consistent fashion
- parsing and validation of a suite of policies, composed of rules in a declarative form (presently json, but being able to maintain the inputs in YAML and other formats is a potential avenue)
- a policy interpreter that applies the rules in a consistent fashion
- carefully curated metrics and logging output so it can feed into your Distributed Tracing solution, whatever it is to understand whether it's Doing What You Mean
- the ability to iteratively refine the rules with low risk
- the ability to iteratively refine the policies with low risk

## Non-goals

- low level policy implementations should live elsewhere (see [CONTRIBUTION notes](#contribution-notes)) - _[e.g., `BulkheadMulti` needs to move out](https://github.com/App-vNext/Polly/issues/507)_
- the core CallPolly library facilitates, but should never bind _directly_ to any specific log or metrics emission sink

# Dependencies
# Elements

The library is delivered as two `net461`/`netstandard2.0` multi-targeted assemblies:-

## `CallPolly.Core`
- extends [`Polly`](https://github.com/App-vNext/Polly) with a [`BulkheadMulti`](https://github.com/jet/CallPolly/blob/master/src/CallPolly.Core/BulkheadMulti.fs) primitive
- In `CallPolly.Events`, defines Key events and metrics that are emitted to the [`Serilog`](https://github.com/serilog/serilog) logger.
- In `CallPolly.Governor`, defines how rules are applied.
- In `CallPolly.Policy`, defines policy lookups, and how live-updating policies is managed.

## `CallPolly`

The core library extends [`Polly`](https://github.com/App-vNext/Polly) and is intended to support running on `netstandard2.0` and `net461`.
- reads policies in a standardized format entitled `ServicePolicy` using `Jet.JsonNet.Converters`
- maps these inputs to `CallPolly`'s inputs

For reasons of code clarity and performance, a core secondary dependency is [`Serilog`](https://github.com/serilog/serilog); the pervasiveness and low dependency nature of Serilog and the [practical unlimited interop with other loggers/targets/sinks](https://github.com/serilog/serilog/wiki/Provided-Sinks) is considered enough of a win to make this a hard dependency _e.g., if your logger is NLog, it's 2 lines of code to [forward to it](https://www.nuget.org/packages/serilog.sinks.nlog) with minimal perf cost over CallPolly binding to that directly_.

# Dependencies

The `CallPolly.Core` library
- extends [`Polly`](https://github.com/App-vNext/Polly)
- logs to [`Serilog`](https://github.com/serilog/serilog).
- references [`Newtonsoft.Json`](https://github.com/JamesNK/Newtonsoft.Json) solely to tweak the renditions of the Policy State renditions from `DumpState` (reference is to `>= v11.0.2` is for reasons of having a clean set of dependencies for the `netstandard2.0` variant).

The `CallPolly` library:
- reads policies using [`Jet.JsonNet.Converters`](https://github.com/jet/Jet.JsonNet.Converters) and [`Newtonsoft.Json`](https://github.com/JamesNK/Newtonsoft.Json)
- feeds those into `PolicyBuilder` in `CallPolly.Core`.

Being written in F#, there's a dependency on `FSharp.Core` (v4.5 for `netstandard2.0`, or anything >= `3.1.2.5` / F# 3.1 as present in VS 2012 if you're targeting `net461`).

The tests use [`xUnit.net`](https://github.com/xunit/xunit), [`FSCheck.xUnit`](https://github.com/fscheck/FsCheck), [`Unquote`](https://github.com/SwensenSoftware/unquote) and [`Serilog.Sinks.Seq`](https://github.com/serilog/serilog-sinks-seq) (to view, see https://getseq.net, which provides a free single user license for clearer insight into log traces).
Expand Down
6 changes: 6 additions & 0 deletions after.CallPolly.sln.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project ToolsVersion="15.0">
<!--Workaround for https://github.com/Microsoft/vstest/issues/1129 from https://dasmulli.blog/2018/01/20/make-dotnet-test-work-on-solution-files/-->
<Target Name="VSTest">
<MSBuild Projects="@(ProjectReference)" Targets="VSTestIfTestProject" />
</Target>
</Project>
50 changes: 20 additions & 30 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,28 @@ jobs:
pool:
vmImage: 'vs2017-win2016'
steps:
- powershell: |
$buildId = $env:BUILD_BUILDNUMBER.PadLeft(7, '0');
$versionSuffixPR = "ci-$buildId-pr$($env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER)";
$branchName = "$env:BUILD_SOURCEBRANCHNAME".Replace("_","");
$versionSuffixBRANCH = "$branchName-$buildId";
$isTag = "$env:BUILD_SOURCEBRANCH".StartsWith('refs/tags/');
$isPR = "$env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" -ne ""
$versionSuffix = if ($isTag) { "" } else { if ($isPR) { $versionSuffixPR } else { $versionSuffixBRANCH } };
Write-Host "##vso[task.setvariable variable=VersionSuffix]$versionSuffix";
displayName: compute VersionSuffix
- script: dotnet msbuild build.proj
displayName: Test + Build
env:
VersionSuffix: '$(VersionSuffix)'
- script: dotnet test build.proj
displayName: dotnet test
- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: 'tests/**/*.trx'
condition: succeededOrFailed()
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: 'bin'
artifactName: 'nupkgs'
- script: dotnet pack build.proj
displayName: dotnet pack
- job: Linux
pool:
vmImage: 'ubuntu-16.04'
vmImage: 'ubuntu-16.04'
steps:
- script: echo "##vso[task.setvariable variable=FrameworkPathOverride]$(dirname $(which mono))/../lib/mono/4.5/"
displayName: Workaround .NET reference assemblies on linux
- script: dotnet test build.proj
displayName: dotnet test
- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: 'tests/**/*.trx'
condition: succeededOrFailed()
- powershell: |
$buildId = $env:BUILD_BUILDNUMBER.PadLeft(7, '0');
$versionSuffixPR = "ci-$buildId-pr$($env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER)";
Expand All @@ -42,14 +35,9 @@ jobs:
$isPR = "$env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" -ne ""
$versionSuffix = if ($isTag) { "" } else { if ($isPR) { $versionSuffixPR } else { $versionSuffixBRANCH } };
Write-Host "##vso[task.setvariable variable=VersionSuffix]$versionSuffix";
displayName: compute VersionSuffix
- script: dotnet msbuild build.proj
displayName: Test + Build
- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: 'tests/**/*.trx'
condition: succeededOrFailed()
displayName: compute VersionSuffix
- script: dotnet pack build.proj
displayName: dotnet pack
- task: NuGetCommand@2
condition: succeededOrFailed()
inputs:
Expand All @@ -58,17 +46,19 @@ jobs:
publishFeedCredentials: 'Jet-MyGet'
versioningScheme: byEnvVar
versionEnvVar: Version
packagesToPush: 'bin/*.nupkg;bin/*.symbols.nupkg'
packagesToPush: 'bin/*.nupkg;bin/*.symbols.nupkg'
- job: MacOS
pool:
vmImage: 'macOS-10.13'
steps:
- script: echo "##vso[task.setvariable variable=FrameworkPathOverride]$(dirname $(which mono))/../lib/mono/4.5/"
displayName: Workaround .NET reference assemblies on linux
- script: dotnet msbuild build.proj
displayName: Test + Build
- script: dotnet test build.proj
displayName: dotnet test
- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: 'tests/**/*.trx'
condition: succeededOrFailed()
- script: dotnet pack build.proj
displayName: dotnet pack
16 changes: 8 additions & 8 deletions build.proj
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<Project ToolsVersion="15.0" DefaultTargets="Test;Build">
<Project ToolsVersion="15.0">

<Import Project="Directory.Build.props" />

<PropertyGroup>

<Name>CallPolly</Name>
<Cfg>--configuration Release</Cfg>

<ThisDirAbsolute>$([System.IO.Path]::GetFullPath("$(MSBuildThisFileDirectory)"))</ThisDirAbsolute>
Expand All @@ -13,13 +11,15 @@

</PropertyGroup>

<Target Name="Build">
<Exec Command="dotnet pack src/$(Name) $(Cfg) $(PackOptions)" />
<Target Name="Pack">
<Exec Command="dotnet pack src/CallPolly.Core $(Cfg) $(PackOptions)" />
<Exec Command="dotnet pack src/CallPolly $(Cfg) $(PackOptions)" />
</Target>

<Target Name="Test">
<Exec Command="dotnet test tests/$(Name).Tests $(Cfg) $(TestOptions)" />
<Exec Command="dotnet test tests/$(Name).Acceptance $(Cfg) $(TestOptions)" />
<Target Name="VSTest">
<Exec Command="dotnet test CallPolly.sln $(Cfg) $(TestOptions)" />
</Target>

<Target Name="Build" DependsOnTargets="VSTest;Pack" />

</Project>
2 changes: 1 addition & 1 deletion build.ps1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
& dotnet msbuild build.proj @args
& dotnet build build.proj @args
File renamed without changes.
29 changes: 29 additions & 0 deletions src/CallPolly.Core/CallPolly.Core.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
</PropertyGroup>

<ItemGroup>
<Compile Include="Infrastructure.fs" />
<Compile Include="BulkheadMulti.fs" />
<Compile Include="Events.fs" />
<Compile Include="Governor.fs" />
<Compile Include="Policy.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63127-02" PrivateAssets="All" />
<PackageReference Include="FSharp.Core" Version="3.1.2.5" Condition=" '$(TargetFramework)' != 'netstandard2.0' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" Condition=" '$(TargetFramework)' == 'netstandard2.0' " />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Polly" Version="6.1.0" />
<PackageReference Include="Serilog" Version="2.7.1" />
</ItemGroup>

</Project>
File renamed without changes.
Loading

0 comments on commit dbc466a

Please sign in to comment.