Assurance 1.1.3

dotnet add package Assurance --version 1.1.3                
NuGet\Install-Package Assurance -Version 1.1.3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Assurance" Version="1.1.3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Assurance --version 1.1.3                
#r "nuget: Assurance, 1.1.3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Assurance as a Cake Addin
#addin nuget:?package=Assurance&version=1.1.3

// Install Assurance as a Cake Tool
#tool nuget:?package=Assurance&version=1.1.3                

Overview

Assurance is a library to boost confidence when making code changes.

image

Status

build

Package Latest Release
Assurance NuGet version

Getting Started

dotnet add package Assurance

OR

PM> Install-Package Assurance

NOTE: This package uses Spiffy logging.

Example

Imagine discovering some legacy code:

    int i;
    for (i = 0; i < 1000000; i++) ;
    return i;

Naturally, you consider replacing this code with:

    return 1000000;

Since the first code is "legacy", changing it is "scary" because it has been running that way for a long time and might have side-effects that others couple to.

The Assurance library allows you to evaluate 2 implementations side-by-side and switch to better implementations with confidence.

    var result = (await Runner.RunInParallel(
        "CountToOneMillion",
        () =>
        {
            int i;
            for (i = 0; i < 1000000; i++) ;
            return i;
        },
        () =>
        {
            return 1000000;
        }))
        .UseExisting();
        // .UseReplacement();

When the above code is run, log entries are created, e.g.

[2021-07-28 21:33:32.144Z] Level=Info Component=Assurance Operation=CountToOneMillion
TimeElapsed=24.6 Result=same TimeElapsed_Existing=24.1 TimeElapsed_Replacement=0.2
Use=existing

Result=same gives us confidence that we haven't regressed behavior.

TimeElapsed_Replacement < TimeElapsed_Existing gives us confidence that we haven't regressed performance.

The returned object makes it easy to toggle implementations (i.e. choose which is the authority).

Generally you'd defer to the existing implementation for some evaluation period, then cutover to the replacement.

Different Results

Imagine we weren't so lucky with our drop-in replacement and observed that 1% of the time, the replacement implementation computed a different result. In these cases, Result=different can be found in the logs along with Existing and Replacement fields, e.g.

[2021-07-28 21:33:32.242Z] Level=Info Component=Assurance
Operation=ComputeResult TimeElapsed=500 Result=different Existing=1000001 Replacement=1000000
TimeElapsed_Existing=500 TimeElapsed_Replacement=100

Sometimes, you might be willing to accept different behavior if, for example, the new code is substantially faster.

Other times, you might find out that the existing system is wrong and you prefer the results from the new implementation.

Exception Behavior

An exception that occurs in the existing implementation will be logged and re-thrown.

An exception that occurs in the replacement implementation will be logged only (i.e. not re-thrown).

Cutting Over

Once you are satisified with the replacement implementation, cutting over is a simple code change, from UseExisting to UseReplacement, e.g.

    var result = (await Runner.RunInParallel(
        "CountToOneMillion",
        () =>
        {
            int i;
            for (i = 0; i < 1000000; i++) ;
            return i;
        },
        () =>
        {
            return 1000000;
        }))
        // .UseExisting();
        .UseReplacement();

After an evaluation period, the old implementation (and the Assurance scaffolding) can be removed, e.g.


    var result = CountToOneMillion();

    int CountToOneMillion()
    {
        return 1000000;
    }
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.3 413 2/8/2023
1.1.2 261 2/8/2023
1.1.1 271 2/8/2023
1.1.0 297 2/7/2023
1.0.3 496 3/1/2022
1.0.2 356 8/20/2021
1.0.1 370 8/9/2021
0.1.0 427 7/28/2021
0.0.1 357 3/17/2021

Include release notes in package