< Summary

Information
Class: AmbientServices.StatusRating
Assembly: AmbientServices
File(s): /home/runner/work/AmbientServices/AmbientServices/AmbientServices/Status/StatusRating.cs
Tag: 332_35464845198
Line coverage
100%
Covered lines: 41
Uncovered lines: 0
Coverable lines: 41
Total lines: 249
Line coverage: 100%
Branch coverage
100%
Covered branches: 24
Total branches: 24
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
GetRangeSymbol(...)100%11100%
GetRangeLowerBound(...)100%22100%
GetRangeUpperBound(...)100%22100%
FindRange(...)100%88100%
GetRatingRgbForegroundColorValue(...)100%1212100%
AdjustPortion()100%11100%
GetRangeName(...)100%11100%
GetRangeName(...)100%11100%
GetRangeForegroundColor(...)100%11100%
GetRangeForegroundColor(...)100%11100%
GetRangeBackgroundColor(...)100%11100%
GetRangeBackgroundColor(...)100%11100%
GetRatingRgbForegroundColor(...)100%11100%

File(s)

/home/runner/work/AmbientServices/AmbientServices/AmbientServices/Status/StatusRating.cs

#LineLine coverage
 1namespace AmbientServices;
 2
 3/// <summary>
 4/// An enumeration of the possible ranges for status ratings.
 5/// </summary>
 6public enum StatusRatingRange
 7{
 8    /// <summary>
 9    /// A range indicating that a system status test has not yet determined the status.
 10    /// </summary>
 11    Pending,
 12    /// <summary>
 13    /// A range indicating that a system has failed.
 14    /// </summary>
 15    Fail,
 16    /// <summary>
 17    /// A range indicating that a system is alerting.
 18    /// </summary>
 19    Alert,
 20    /// <summary>
 21    /// A range indicating that a system is okay.
 22    /// </summary>
 23    Okay,
 24    /// <summary>
 25    /// A range indicating that a system is better than okay.
 26    /// </summary>
 27    Superlative,
 28}
 29/// <summary>
 30/// An enumeration of threshold status rating values.
 31/// These values are a rough determination of whether or not a system is functioning and if there is any information the
 32/// Performance is only considered if it is so bad that requests are failing.
 33/// Worse states are numerically less than better states.
 34/// </summary>
 35/// <remarks>
 36/// When a status rating is exactly equal to the specified value, it means that the corresponding system has just barely
 37/// Negative values indicate how badly the system is failing.
 38/// Values above 2.0 indicate that the system is "Superlative", ie. better than Okay.
 39/// For example, a value of 0.5 indicates that the system is alerting and is about half way towards failing but not yet 
 40/// a value of 1.5 indicates that the system is okay, but halfway towards alerting (for example, a lack of redundancy, o
 41/// When comparing status ratings, keep in mind that <see cref="StatusRating.Pending"/> has the value <see cref="float.N
 42/// If you need to check for pending statuses, either add <see cref="float.IsNaN(float)"/> logic or use the opposite log
 43/// <pitch>The shared vocabulary of the status system: a single continuous rating scale, its named range boundaries, and
 44/// <pledge>
 45/// Ratings form one continuous <see cref="float"/> scale where numerically less is worse.  The integer constants are ra
 46/// <see cref="Pending"/> is <see cref="float.NaN"/>, which compares false against everything (including itself); <see c
 47/// </pledge>
 48/// </remarks>
 49public static class StatusRating
 50{
 51    /// <summary>
 52    /// The status check has not been completed yet, even though the status system is running.
 53    /// Note that this value is <see cref="float.NaN"/> and therefore will not compare even to itself with the == operat
 54    /// Use <see cref="float.IsNaN(float)"/> to check to see if an assigned rating has this value.
 55    /// The reason for this is that this is an explicitly-assigned state, but isn't necessarily better or worse than any
 56    /// Using any other possible value would result in some use cases not working as intended.
 57    /// </summary>
 58    public const float Pending = float.NaN;
 59    /// <summary>
 60    /// The system has completely failed.  This constant defines the bottom of the bottom range.
 61    /// Although values less than this may be assigned, they are meaningless to the framework.
 62    /// Values lower than this will count as being in the same range as those between this one and the next higher const
 63    /// </summary>
 64    public const float Catastrophic = -1.0f;
 65    /// <summary>
 66    /// The value for when a system is just barely failing (and therefore also has an alert).
 67    /// </summary>
 68    public const float Fail = 0.0f;
 69    /// <summary>
 70    /// The value for when a system has not yet failed, but has just entered a state that might need work.
 71    /// </summary>
 72    public const float Alert = 1.0f;
 73    /// <summary>
 74    /// The value for when a system is almost superlative, but still just barely only okay.
 75    /// </summary>
 76    public const float Okay = 2.0f;
 77    /// <summary>
 78    /// The system is superlative and there are no alerts.  This constant defines the top of the top range.
 79    /// Although values higher than this may be assigned, they are meaningless to the framework.
 80    /// Values higher than this will count as being in the same range as those between this one and the next lower const
 81    /// </summary>
 82    public const float Superlative = 3.0f;
 83
 284    private static readonly float[] RangeValues = new float[] { float.NaN, Catastrophic, Fail, Alert, Okay, Superlative 
 285    private static readonly string[] RangeNames = new string[] { "Pending", "Fail", "Alert", "Okay", "Superlative", };
 286    private static readonly string[] RangeSymbols = new string[] { "⌛", "🛑", "⚠️", "🟢", "💙", };
 287    private static readonly string[] RangeForegroundColors = new string[] { "grey", "red", "#ffdf00", "green", "blue", }
 288    private static readonly string[] RangeBackgroundColors = new string[] { "#bfbfbf", "#ffdfdf", "#fff7df", "#dfefdf", 
 89    //private static readonly int[,] RangeRgbForegroundColorParts = new int[,] { { 0xff, 0, 0 }, { 0x7f, 0, 0 }, { 0xff,
 90    //private static readonly int[,] RangeRgbBackgroundColorParts = new int[,] { { 0xff, 0xdf, 0xdf }, { 0xef, 0xdf, 0xd
 91    internal const string StyleDefinition = @"
 92    .pending-range{background-color:#bfbfbf;color:grey;}
 93    .fail-range{background-color:#ffdfdf;color:red;}
 94    .alert-range{background-color:#fff7df;color:#ffdf00;}
 95    .okay-range{background-color:#dfefdf;color:green;}
 96    .superlative-range{background-color:#dfdfef;color:blue;}";
 97
 98    /// <summary>
 99    /// The number of ranges (as determined by the possible values of a float and the rating categories above.
 100    /// </summary>
 101    public const int Ranges = 5;
 102
 103    /// <summary>
 104    /// Gets the single-character symbol for the specified status rating range.
 105    /// </summary>
 106    /// <param name="ratingRange">A <see cref="StatusRatingRange"/> indicating the range, the same that would be returne
 107    /// <returns>A single character representing the specified rating range.</returns>
 108    public static string GetRangeSymbol(StatusRatingRange ratingRange)
 109    {
 2110        return RangeSymbols[(int)ratingRange];
 111    }
 112    /// <summary>
 113    /// Gets the <see cref="float"/> for the lower bound for the specified range.
 114    /// The returned value is the upper bound for the previous range, and passing this value to <see cref="FindRange"/> 
 115    /// </summary>
 116    /// <param name="ratingRange">The <see cref="StatusRatingRange"/> to get the lower bound for.</param>
 117    /// <returns>The lower bound for the specified range.</returns>
 118    public static float GetRangeLowerBound(StatusRatingRange ratingRange)
 119    {
 2120        return (ratingRange == 0) ? float.NaN : RangeValues[(int)ratingRange];
 121    }
 122    /// <summary>
 123    /// Gets the <see cref="float"/> for the upper bound for the specified range.
 124    /// The returned value is the lower bound for the next range.
 125    /// Passing this value to <see cref="FindRange"/> will return the specified range.
 126    /// </summary>
 127    /// <param name="ratingRange">The <see cref="StatusRatingRange"/> to get the upper bound for.</param>
 128    /// <returns>The upper bound for the specified range.</returns>
 129    public static float GetRangeUpperBound(StatusRatingRange ratingRange)
 130    {
 2131        return (ratingRange == 0) ? float.NaN : RangeValues[(int)ratingRange + 1];
 132    }
 133    /// <summary>
 134    /// Finds the range offset for the specified rating.
 135    /// </summary>
 136    /// <param name="rating">The rating whose offset is to be determined.</param>
 137    /// <returns>A <see cref="StatusRatingRange"/> indicating the range of the specified rating.</returns>
 138    public static StatusRatingRange FindRange(float rating)
 139    {
 2140        if (float.IsNaN(rating)) return StatusRatingRange.Pending;
 2141        if (rating <= Fail) return StatusRatingRange.Fail;
 2142        if (rating <= Alert) return StatusRatingRange.Alert;
 2143        if (rating <= Okay) return StatusRatingRange.Okay;
 2144        return StatusRatingRange.Superlative;
 145    }
 146    private static int GetRatingRgbForegroundColorValue(float rating)
 147    {
 148        // pending?
 2149        if (float.IsNaN(rating)) return 0x808080;
 150
 151        static float AdjustPortion(float portion)
 152        {
 2153            return 0.2f + 0.6f * portion;
 154        }
 2155        if (rating <= Catastrophic) return 0xff0000;
 2156        if (rating > Superlative) return 0x0000ff;
 157        float portionTowardsNextStatus;
 158        byte rVal;
 159        byte gVal;
 160        byte bVal;
 2161        if (rating <= Fail)
 162        {
 2163            portionTowardsNextStatus = AdjustPortion(rating - Catastrophic);
 2164            return (((byte)(0xff - 0x80 * portionTowardsNextStatus)) << 16);
 165        }
 2166        else if (rating <= Alert)
 167        {
 2168            portionTowardsNextStatus = AdjustPortion(rating - Fail);
 2169            return (((byte)(0x7f + 0x80 * portionTowardsNextStatus)) << 16) | (((byte)(0xdf * portionTowardsNextStatus))
 170        }
 2171        else if (rating <= Okay)
 172        {
 2173            portionTowardsNextStatus = AdjustPortion(rating - Alert);
 2174            rVal = ((byte)(0xff - 0xff * portionTowardsNextStatus));
 2175            gVal = ((byte)(0xdf - 0x60 * portionTowardsNextStatus));
 2176            bVal = 0;
 2177            return (rVal << 16) | (gVal << 8) | bVal;
 178
 179        }
 2180        portionTowardsNextStatus = AdjustPortion(rating - Okay);
 2181        rVal = 0;
 2182        gVal = ((byte)(0x7f - 0x7f * portionTowardsNextStatus));
 2183        bVal = ((byte)(0x00 + 0xff * portionTowardsNextStatus));
 2184        return (rVal << 16) | (gVal << 8) | bVal;
 185    }
 186    /// <summary>
 187    /// Returns a string indicating the name of the range represented by the raw status rating.
 188    /// </summary>
 189    /// <param name="rating">The raw rating number, which may have any possible value.</param>
 190    /// <returns>A string containing the name of the range the specified rating value falls into.</returns>
 191    public static string GetRangeName(float rating)
 192    {
 2193        return GetRangeName(FindRange(rating));
 194    }
 195    /// <summary>
 196    /// Returns a string indicating the name of the specified range.
 197    /// </summary>
 198    /// <param name="ratingRange">A <see cref="StatusRatingRange"/> indicating the range, presumably returned by <see cr
 199    /// <returns>A string containing the name of the specified range.</returns>
 200    public static string GetRangeName(StatusRatingRange ratingRange)
 201    {
 2202        return RangeNames[(int)ratingRange];
 203    }
 204    /// <summary>
 205    /// Returns a foreground color associated with the specified rating.
 206    /// </summary>
 207    /// <param name="rating">The raw rating number, which may have any possible value.</param>
 208    /// <returns>A string identifying the color associated with the rating.</returns>
 209    public static string GetRangeForegroundColor(float rating)
 210    {
 2211        return GetRangeForegroundColor(FindRange(rating));
 212    }
 213    /// <summary>
 214    /// Returns a foreground color associated with the specified rating range.
 215    /// </summary>
 216    /// <param name="ratingRange">A <see cref="StatusRatingRange"/> indicating the range, presumably returned by <see cr
 217    /// <returns>A string identifying the color associated with the rating range.</returns>
 218    public static string GetRangeForegroundColor(StatusRatingRange ratingRange)
 219    {
 2220        return RangeForegroundColors[(int)ratingRange];
 221    }
 222    /// <summary>
 223    /// Returns a background color associated with the specified rating.
 224    /// </summary>
 225    /// <param name="rating">The raw rating number, which may have any possible value.</param>
 226    /// <returns>A string identifying the color associated with the rating.</returns>
 227    public static string GetRangeBackgroundColor(float rating)
 228    {
 2229        return GetRangeBackgroundColor(FindRange(rating));
 230    }
 231    /// <summary>
 232    /// Returns a background color for the specified rating range.
 233    /// </summary>
 234    /// <param name="ratingRange">A <see cref="StatusRatingRange"/> indicating the range, presumably returned by <see cr
 235    /// <returns>A string identifying the color associated with the rating range.</returns>
 236    public static string GetRangeBackgroundColor(StatusRatingRange ratingRange)
 237    {
 2238        return RangeBackgroundColors[(int)ratingRange];
 239    }
 240    /// <summary>
 241    /// Returns an RGB background color associated with the specified rating.
 242    /// </summary>
 243    /// <param name="rating">The raw rating number, which may have any possible value.</param>
 244    /// <returns>A string identifying the hexadecimal RGB color associated with the rating.</returns>
 245    public static string GetRatingRgbForegroundColor(float rating)
 246    {
 2247        return "#" + GetRatingRgbForegroundColorValue(rating).ToString("x6", System.Globalization.CultureInfo.InvariantC
 248    }
 249}