< 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@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
78%
Covered lines: 48
Uncovered lines: 13
Coverable lines: 61
Total lines: 202
Line coverage: 78.6%
Branch coverage
45%
Covered branches: 19
Total branches: 42
Branch coverage: 45.2%
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@10d476bee71c71ad215bb8ab59f219887b5b4a5e 10/13/2025 - 16:52:37 Line coverage: 78.6% (48/61) Branch coverage: 45.2% (19/42) Total lines: 202 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetBuiltTargetFrameworkVersion()50%8881.81%
.cctor()50%44100%
GetKnownFeatures()100%11100%
Supports(...)50%7675%
Supports(...)75%9875%
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    /// Returns the target framework version this assembly was built against
 15    /// as a System.Version (e.g., 8.0, 9.0).
 16    /// </summary>
 17    public static Version GetBuiltTargetFrameworkVersion()
 18    {
 319        var asm = typeof(KestrunRuntimeInfo).Assembly;
 320        var tfm = asm.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
 321        if (string.IsNullOrEmpty(tfm))
 22        {
 023            return new Version(0, 0);
 24        }
 25
 326        var key = "Version=";
 327        var idx = tfm.IndexOf(key, StringComparison.OrdinalIgnoreCase);
 328        if (idx >= 0)
 29        {
 330            var ver = tfm[(idx + key.Length)..].TrimStart('v');
 331            if (Version.TryParse(ver, out var parsed))
 32            {
 333                return parsed;
 34            }
 35        }
 36
 037        return new Version(0, 0);
 38    }
 39
 40    // --- Feature gating ---
 41
 42    /// <summary>
 43    /// Built-in Kestrun feature keys. Add more as you gate new APIs by TFM.
 44    /// </summary>
 45    public enum KnownFeature
 46    {
 47        /// <summary>
 48        /// Kestrel HTTP/3 listener support (requires QUIC at runtime)
 49        /// </summary>
 50        Http3 = 0,
 51        /// <summary>
 52        /// Suppresses reading the antiforgery token from the form body
 53        /// </summary>
 54        SuppressReadingTokenFromFormBody = 1
 55    }
 56
 57    // Minimal TFM required for each feature.
 58    // Extend this table as you add features.
 159    private static readonly Dictionary<string, Version> FeatureMinByName =
 160        new(StringComparer.OrdinalIgnoreCase)
 161        {
 162            [nameof(KnownFeature.Http3)] = new Version(8, 0),
 163            // New in .NET 9+: Antiforgery option to suppress reading token from request form body.
 164            [nameof(KnownFeature.SuppressReadingTokenFromFormBody)] = new Version(9, 0),
 165        };
 66
 67    /// <summary>
 68    /// Returns the set of known feature identifiers (enum names) that have a
 69    /// compile-time (TFM) gate registered. This does not guarantee that
 70    /// <see cref="Supports(string)"/> will return true, only that the feature
 71    /// is recognized and has a minimum version entry.
 72    /// </summary>
 173    public static IEnumerable<string> GetKnownFeatures() => FeatureMinByName.Keys;
 74
 75    /// <summary>
 76    /// True if the loaded Kestrun assembly supports the feature,
 77    /// considering both build-time TFM and runtime requirements.
 78    /// </summary>
 79    public static bool Supports(KnownFeature feature)
 80    {
 181        var name = feature.ToString();
 182        if (!TryGetMinVersion(name, out var min) || !IsAtLeast(min))
 83        {
 084            return false; // compile-time gate failed
 85        }
 86
 87        // runtime-sensitive checks
 188        return feature switch
 189        {
 090            KnownFeature.Http3 => CheckHttp3Runtime(),
 191            _ => true,
 192        };
 93    }
 94
 95    /// <summary>
 96    /// True if the loaded Kestrun assembly supports the feature,
 97    /// considering both build-time TFM and runtime requirements.
 98    /// Unknown names return false.
 99    /// </summary>
 100    public static bool Supports(string featureName)
 101    {
 2102        if (string.IsNullOrWhiteSpace(featureName))
 103        {
 0104            return false;
 105        }
 106
 2107        if (!TryGetMinVersion(featureName, out var min) || !IsAtLeast(min))
 108        {
 1109            return false; // compile-time/TFM gate failed or unknown
 110        }
 111
 112        // Central runtime-sensitive feature dispatch (mirrors enum switch in Supports(KnownFeature))
 113        // Extend this map when adding new runtime-validated features.
 114        // For features with no runtime conditions, omission implies success.
 1115        var runtimeChecks = RuntimeFeatureChecks;
 1116        if (runtimeChecks.TryGetValue(featureName, out var checker))
 117        {
 0118            return checker();
 119        }
 1120        return true; // Known (by TFM table) & no runtime check required
 121    }
 122
 123    // Provides a single place to register runtime-sensitive checks by feature name.
 124    // Note: Uses StringComparer.OrdinalIgnoreCase to keep behavior consistent with FeatureMinByName.
 1125    private static readonly Dictionary<string, Func<bool>> RuntimeFeatureChecks =
 1126        new(StringComparer.OrdinalIgnoreCase)
 1127        {
 1128            [nameof(KnownFeature.Http3)] = CheckHttp3Runtime,
 1129        };
 130
 131    /// <summary>
 132    /// Returns the minimum TFM required for a feature, if known.
 133    /// </summary>
 134    /// <param name="featureName">Feature identifier (case-insensitive).</param>
 135    /// <param name="minVersion">
 136    /// When this method returns true, contains the minimum target framework version required for the feature.
 137    /// When it returns false, the value is set to <c>0.0</c> as a harmless placeholder.
 138    /// </param>
 139    /// <returns>True if the feature is known; otherwise false.</returns>
 140    public static bool TryGetMinVersion(string featureName, [NotNullWhen(true)] out Version minVersion)
 141    {
 5142        if (FeatureMinByName.TryGetValue(featureName, out var value))
 143        {
 4144            minVersion = value; // non-null by construction
 4145            return true;
 146        }
 147
 148        // Provide a non-null sentinel to satisfy non-nullable contract while indicating absence.
 1149        minVersion = new Version(0, 0);
 1150        return false;
 151    }
 152
 153    private static bool IsAtLeast(Version min)
 154    {
 2155        var built = GetBuiltTargetFrameworkVersion();
 2156        return built >= min;
 157    }
 158
 159    #region Runtime checks
 160    // ---------- Runtime-sensitive checks ----------
 161    /// <summary>
 162    /// Checks runtime support for HTTP/3 (QUIC) in addition to compile-time gating.
 163    /// </summary>
 164    private static bool CheckHttp3Runtime()
 165    {
 166        // Use cached reflection metadata to avoid repeated lookups on hot paths.
 0167        if (_quicListenerType == null)
 168        {
 0169            return false;
 170        }
 171
 0172        if (_quicIsSupportedProperty != null)
 173        {
 0174            var value = _quicIsSupportedProperty.GetValue(null);
 0175            if (value is bool supported && !supported)
 176            {
 0177                return false;
 178            }
 179        }
 180
 181        // Kestrel HTTP/3 enum field presence check
 0182        return _httpProtocolsType != null && _http3Field != null;
 183    }
 184    #endregion
 185
 186    // Cached reflection metadata for runtime checks (initialized once).
 1187    private static readonly Type? _quicListenerType = Type.GetType("System.Net.Quic.QuicListener, System.Net.Quic");
 1188    private static readonly PropertyInfo? _quicIsSupportedProperty = _quicListenerType?.GetProperty("IsSupported", Bindi
 1189    private static readonly Type? _httpProtocolsType = Type.GetType("Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtoc
 1190    private static readonly FieldInfo? _http3Field = _httpProtocolsType?.GetField("Http3", BindingFlags.Public | Binding
 191
 192    /// <summary>
 193    /// Returns the full target framework name this assembly was built against,
 194    /// e.g., ".NETCoreApp,Version=v9.0".
 195    /// </summary>
 196    public static string GetBuiltTargetFrameworkName()
 197    {
 1198        var tfm = typeof(KestrunRuntimeInfo).Assembly
 1199            .GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
 1200        return tfm ?? "Unknown";
 201    }
 202}