< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.KestrunRuntimeInfo
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/KestrunRuntimeInfo.cs
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
66%
Covered lines: 42
Uncovered lines: 21
Coverable lines: 63
Total lines: 218
Line coverage: 66.6%
Branch coverage
40%
Covered branches: 17
Total branches: 42
Branch coverage: 40.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 10/13/2025 - 16:52:37 Line coverage: 78.6% (48/61) Branch coverage: 45.2% (19/42) Total lines: 202 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e11/26/2025 - 04:09:52 Line coverage: 76.1% (48/63) Branch coverage: 45.2% (19/42) Total lines: 218 Tag: Kestrun/Kestrun@783d423774fc9827a03321203e642119023bb30012/15/2025 - 02:23:46 Line coverage: 66.6% (42/63) Branch coverage: 40.4% (17/42) Total lines: 218 Tag: Kestrun/Kestrun@7a3839f4de2254e22daae81ab8dc7cb2f40c8330 10/13/2025 - 16:52:37 Line coverage: 78.6% (48/61) Branch coverage: 45.2% (19/42) Total lines: 202 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e11/26/2025 - 04:09:52 Line coverage: 76.1% (48/63) Branch coverage: 45.2% (19/42) Total lines: 218 Tag: Kestrun/Kestrun@783d423774fc9827a03321203e642119023bb30012/15/2025 - 02:23:46 Line coverage: 66.6% (42/63) Branch coverage: 40.4% (17/42) Total lines: 218 Tag: Kestrun/Kestrun@7a3839f4de2254e22daae81ab8dc7cb2f40c8330

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_IsReleaseDistribution()100%210%
get_IsDebugBuild()100%210%
GetBuiltTargetFrameworkVersion()50%8881.81%
.cctor()50%44100%
GetKnownFeatures()100%11100%
Supports(...)50%15637.5%
Supports(...)50%24837.5%
TryGetMinVersion(...)100%22100%
IsAtLeast(...)100%11100%
CheckHttp3Runtime()0%110100%
GetBuiltTargetFrameworkName()50%44100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/KestrunRuntimeInfo.cs

#LineLine coverage
 1using System.Reflection;
 2using System.Runtime.Versioning;
 3using System.Diagnostics.CodeAnalysis;
 4
 5namespace Kestrun;
 6
 7/// <summary>
 8/// Utility class to expose information about the runtime environment
 9/// that Kestrun was built for, and to gate features by TFM and runtime.
 10/// </summary>
 11public static class KestrunRuntimeInfo
 12{
 13    /// <summary>
 14    /// Determines whether the current distribution is a release distribution.
 15    /// </summary>
 16    /// <returns> True if the current distribution is a release distribution; otherwise, false.</returns>
 17#if DEBUG
 18    public static bool IsReleaseDistribution => false;
 19#else
 020    public static bool IsReleaseDistribution => true;
 21#endif
 22
 23    /// <summary>
 24    /// Determines whether the current build is a debug build.
 25    /// </summary>
 26    /// <returns> True if the current build is a debug build; otherwise, false.</returns>
 027    public static bool IsDebugBuild => !IsReleaseDistribution;
 28
 29    /// <summary>
 30    /// Returns the target framework version this assembly was built against
 31    /// as a System.Version (e.g., 8.0, 9.0).
 32    /// </summary>
 33    public static Version GetBuiltTargetFrameworkVersion()
 34    {
 335        var asm = typeof(KestrunRuntimeInfo).Assembly;
 336        var tfm = asm.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
 337        if (string.IsNullOrEmpty(tfm))
 38        {
 039            return new Version(0, 0);
 40        }
 41
 342        var key = "Version=";
 343        var idx = tfm.IndexOf(key, StringComparison.OrdinalIgnoreCase);
 344        if (idx >= 0)
 45        {
 346            var ver = tfm[(idx + key.Length)..].TrimStart('v');
 347            if (Version.TryParse(ver, out var parsed))
 48            {
 349                return parsed;
 50            }
 51        }
 52
 053        return new Version(0, 0);
 54    }
 55
 56    // --- Feature gating ---
 57
 58    /// <summary>
 59    /// Built-in Kestrun feature keys. Add more as you gate new APIs by TFM.
 60    /// </summary>
 61    public enum KnownFeature
 62    {
 63        /// <summary>
 64        /// Kestrel HTTP/3 listener support (requires QUIC at runtime)
 65        /// </summary>
 66        Http3 = 0,
 67        /// <summary>
 68        /// Suppresses reading the antiforgery token from the form body
 69        /// </summary>
 70        SuppressReadingTokenFromFormBody = 1
 71    }
 72
 73    // Minimal TFM required for each feature.
 74    // Extend this table as you add features.
 175    private static readonly Dictionary<string, Version> FeatureMinByName =
 176        new(StringComparer.OrdinalIgnoreCase)
 177        {
 178            [nameof(KnownFeature.Http3)] = new Version(8, 0),
 179            // New in .NET 9+: Antiforgery option to suppress reading token from request form body.
 180            [nameof(KnownFeature.SuppressReadingTokenFromFormBody)] = new Version(9, 0),
 181        };
 82
 83    /// <summary>
 84    /// Returns the set of known feature identifiers (enum names) that have a
 85    /// compile-time (TFM) gate registered. This does not guarantee that
 86    /// <see cref="Supports(string)"/> will return true, only that the feature
 87    /// is recognized and has a minimum version entry.
 88    /// </summary>
 189    public static IEnumerable<string> GetKnownFeatures() => FeatureMinByName.Keys;
 90
 91    /// <summary>
 92    /// True if the loaded Kestrun assembly supports the feature,
 93    /// considering both build-time TFM and runtime requirements.
 94    /// </summary>
 95    public static bool Supports(KnownFeature feature)
 96    {
 197        var name = feature.ToString();
 198        if (!TryGetMinVersion(name, out var min) || !IsAtLeast(min))
 99        {
 1100            return false; // compile-time gate failed
 101        }
 102
 103        // runtime-sensitive checks
 0104        return feature switch
 0105        {
 0106            KnownFeature.Http3 => CheckHttp3Runtime(),
 0107            _ => true,
 0108        };
 109    }
 110
 111    /// <summary>
 112    /// True if the loaded Kestrun assembly supports the feature,
 113    /// considering both build-time TFM and runtime requirements.
 114    /// Unknown names return false.
 115    /// </summary>
 116    public static bool Supports(string featureName)
 117    {
 2118        if (string.IsNullOrWhiteSpace(featureName))
 119        {
 0120            return false;
 121        }
 122
 2123        if (!TryGetMinVersion(featureName, out var min) || !IsAtLeast(min))
 124        {
 2125            return false; // compile-time/TFM gate failed or unknown
 126        }
 127
 128        // Central runtime-sensitive feature dispatch (mirrors enum switch in Supports(KnownFeature))
 129        // Extend this map when adding new runtime-validated features.
 130        // For features with no runtime conditions, omission implies success.
 0131        var runtimeChecks = RuntimeFeatureChecks;
 0132        if (runtimeChecks.TryGetValue(featureName, out var checker))
 133        {
 0134            return checker();
 135        }
 0136        return true; // Known (by TFM table) & no runtime check required
 137    }
 138
 139    // Provides a single place to register runtime-sensitive checks by feature name.
 140    // Note: Uses StringComparer.OrdinalIgnoreCase to keep behavior consistent with FeatureMinByName.
 1141    private static readonly Dictionary<string, Func<bool>> RuntimeFeatureChecks =
 1142        new(StringComparer.OrdinalIgnoreCase)
 1143        {
 1144            [nameof(KnownFeature.Http3)] = CheckHttp3Runtime,
 1145        };
 146
 147    /// <summary>
 148    /// Returns the minimum TFM required for a feature, if known.
 149    /// </summary>
 150    /// <param name="featureName">Feature identifier (case-insensitive).</param>
 151    /// <param name="minVersion">
 152    /// When this method returns true, contains the minimum target framework version required for the feature.
 153    /// When it returns false, the value is set to <c>0.0</c> as a harmless placeholder.
 154    /// </param>
 155    /// <returns>True if the feature is known; otherwise false.</returns>
 156    public static bool TryGetMinVersion(string featureName, [NotNullWhen(true)] out Version minVersion)
 157    {
 5158        if (FeatureMinByName.TryGetValue(featureName, out var value))
 159        {
 4160            minVersion = value; // non-null by construction
 4161            return true;
 162        }
 163
 164        // Provide a non-null sentinel to satisfy non-nullable contract while indicating absence.
 1165        minVersion = new Version(0, 0);
 1166        return false;
 167    }
 168
 169    private static bool IsAtLeast(Version min)
 170    {
 2171        var built = GetBuiltTargetFrameworkVersion();
 2172        return built >= min;
 173    }
 174
 175    #region Runtime checks
 176    // ---------- Runtime-sensitive checks ----------
 177    /// <summary>
 178    /// Checks runtime support for HTTP/3 (QUIC) in addition to compile-time gating.
 179    /// </summary>
 180    private static bool CheckHttp3Runtime()
 181    {
 182        // Use cached reflection metadata to avoid repeated lookups on hot paths.
 0183        if (_quicListenerType == null)
 184        {
 0185            return false;
 186        }
 187
 0188        if (_quicIsSupportedProperty != null)
 189        {
 0190            var value = _quicIsSupportedProperty.GetValue(null);
 0191            if (value is bool supported && !supported)
 192            {
 0193                return false;
 194            }
 195        }
 196
 197        // Kestrel HTTP/3 enum field presence check
 0198        return _httpProtocolsType != null && _http3Field != null;
 199    }
 200    #endregion
 201
 202    // Cached reflection metadata for runtime checks (initialized once).
 1203    private static readonly Type? _quicListenerType = Type.GetType("System.Net.Quic.QuicListener, System.Net.Quic");
 1204    private static readonly PropertyInfo? _quicIsSupportedProperty = _quicListenerType?.GetProperty("IsSupported", Bindi
 1205    private static readonly Type? _httpProtocolsType = Type.GetType("Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtoc
 1206    private static readonly FieldInfo? _http3Field = _httpProtocolsType?.GetField("Http3", BindingFlags.Public | Binding
 207
 208    /// <summary>
 209    /// Returns the full target framework name this assembly was built against,
 210    /// e.g., ".NETCoreApp,Version=v9.0".
 211    /// </summary>
 212    public static string GetBuiltTargetFrameworkName()
 213    {
 1214        var tfm = typeof(KestrunRuntimeInfo).Assembly
 1215            .GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
 1216        return tfm ?? "Unknown";
 217    }
 218}