< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Health.ScriptProbeFactory
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Health/ScriptProbeFactory.cs
Tag: Kestrun/Kestrun@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
0%
Covered lines: 0
Uncovered lines: 44
Coverable lines: 44
Total lines: 174
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
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: 0% (0/44) Branch coverage: 0% (0/20) Total lines: 174 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e 10/13/2025 - 16:52:37 Line coverage: 0% (0/44) Branch coverage: 0% (0/20) Total lines: 174 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Create(...)0%7280%
CreatePowerShellProbe(...)100%210%
CreateCSharpProbe(...)100%210%
CreateVbProbe(...)100%210%
BuildCSharpRunner(...)0%156120%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Health/ScriptProbeFactory.cs

#LineLine coverage
 1using System.Reflection;
 2using Kestrun.Languages;
 3using Kestrun.Scripting;
 4using Microsoft.CodeAnalysis;
 5using Microsoft.CodeAnalysis.CSharp.Scripting;
 6using Microsoft.CodeAnalysis.Scripting;
 7using Microsoft.CodeAnalysis.VisualBasic;
 8using KestrunCompilationErrorException = Kestrun.Scripting.CompilationErrorException;
 9using RoslynCompilationErrorException = Microsoft.CodeAnalysis.Scripting.CompilationErrorException;
 10using SerilogLogger = Serilog.ILogger;
 11
 12namespace Kestrun.Health;
 13
 14/// <summary>
 15/// Creates <see cref="IProbe"/> implementations backed by dynamic scripts.
 16/// </summary>
 17internal static class ScriptProbeFactory
 18{
 19    internal static IProbe Create(
 20        string name,
 21        IEnumerable<string>? tags,
 22        ScriptLanguage language,
 23        string code,
 24        SerilogLogger logger,
 25        Func<KestrunRunspacePoolManager>? runspaceAccessor,
 26        IReadOnlyDictionary<string, object?>? arguments,
 27        string[]? extraImports,
 28        Assembly[]? extraRefs)
 29    {
 030        ArgumentNullException.ThrowIfNull(logger);
 031        ArgumentException.ThrowIfNullOrWhiteSpace(code);
 32
 033        return language switch
 034        {
 035            ScriptLanguage.PowerShell => CreatePowerShellProbe(name, tags, code, logger, runspaceAccessor, arguments),
 036            ScriptLanguage.CSharp => CreateCSharpProbe(name, tags, code, logger, arguments, extraImports, extraRefs),
 037            ScriptLanguage.VBNet => CreateVbProbe(name, tags, code, logger, arguments, extraImports, extraRefs),
 038            ScriptLanguage.Native => throw new NotSupportedException("Use AddProbe(Func<...>) for native probes."),
 039            ScriptLanguage.FSharp => throw new NotImplementedException("F# health probes are not yet supported."),
 040            ScriptLanguage.Python => throw new NotImplementedException("Python health probes are not yet supported."),
 041            ScriptLanguage.JavaScript => throw new NotImplementedException("JavaScript health probes are not yet support
 042            _ => throw new ArgumentOutOfRangeException(nameof(language), language, null)
 043        };
 44    }
 45
 46    /// <summary>
 47    /// Builds and returns a PowerShell script probe.
 48    /// </summary>
 49    /// <param name="name">The name of the probe.</param>
 50    /// <param name="tags">The tags associated with the probe.</param>
 51    /// <param name="code">The PowerShell code to execute.</param>
 52    /// <param name="logger">The logger to use for logging.</param>
 53    /// <param name="runspaceAccessor">Accessor for the PowerShell runspace pool manager.</param>
 54    /// <param name="arguments">Arguments to pass to the script.</param>
 55    /// <returns>A new <see cref="IProbe"/> instance representing the PowerShell script probe.</returns>
 56    private static IProbe CreatePowerShellProbe(
 57        string name,
 58        IEnumerable<string>? tags,
 59        string code,
 60        SerilogLogger logger,
 61        Func<KestrunRunspacePoolManager>? runspaceAccessor,
 62        IReadOnlyDictionary<string, object?>? arguments)
 63    {
 064        ArgumentNullException.ThrowIfNull(runspaceAccessor);
 065        return new PowerShellScriptProbe(name, tags, code, logger, runspaceAccessor, arguments);
 66    }
 67
 68    /// <summary>
 69    /// Builds and returns a C# script probe.
 70    /// </summary>
 71    /// <param name="name">The name of the probe.</param>
 72    /// <param name="tags">The tags associated with the probe.</param>
 73    /// <param name="code">The C# code to compile.</param>
 74    /// <param name="logger">The logger to use for logging.</param>
 75    /// <param name="arguments">The arguments for the script.</param>
 76    /// <param name="extraImports">Additional namespaces to import.</param>
 77    /// <param name="extraRefs">Additional assemblies to reference.</param>
 78    /// <returns>A new <see cref="IProbe"/> instance representing the C# script probe.</returns>
 79    private static IProbe CreateCSharpProbe(
 80        string name,
 81        IEnumerable<string>? tags,
 82        string code,
 83        SerilogLogger logger,
 84        IReadOnlyDictionary<string, object?>? arguments,
 85        string[]? extraImports,
 86        Assembly[]? extraRefs)
 87    {
 88        try
 89        {
 090            var runner = BuildCSharpRunner(code, extraImports, extraRefs);
 091            return new CSharpScriptProbe(name, tags, runner, arguments, logger);
 92        }
 093        catch (RoslynCompilationErrorException ex)
 94        {
 095            logger.Error(ex, "Failed to compile C# health probe {Probe}.", name);
 096            throw;
 97        }
 098    }
 99
 100    /// <summary>
 101    /// Builds and returns a VB.NET script probe.
 102    /// </summary>
 103    /// <param name="name">The name of the probe.</param>
 104    /// <param name="tags">The tags associated with the probe.</param>
 105    /// <param name="code">The VB.NET code to compile.</param>
 106    /// <param name="logger">The logger to use for logging.</param>
 107    /// <param name="arguments">The arguments for the script.</param>
 108    /// <param name="extraImports">Additional namespaces to import.</param>
 109    /// <param name="extraRefs">Additional assemblies to reference.</param>
 110    /// <returns>A new <see cref="IProbe"/> instance representing the VB.NET script probe.</returns>
 111    /// <remarks>
 112    /// This method compiles the provided VB.NET code into a script runner that can be executed asynchronously.
 113    /// It allows for additional namespaces and assemblies to be included in the compilation context.
 114    /// </remarks>
 115    private static IProbe CreateVbProbe(
 116        string name,
 117        IEnumerable<string>? tags,
 118        string code,
 119        SerilogLogger logger,
 120        IReadOnlyDictionary<string, object?>? arguments,
 121        string[]? extraImports,
 122        Assembly[]? extraRefs)
 123    {
 124        try
 125        {
 0126            var runner = VBNetDelegateBuilder.Compile<ProbeResult>(code, logger, extraImports, extraRefs, arguments, Lan
 0127            return new VbScriptProbe(name, tags, runner, arguments, logger);
 128        }
 0129        catch (KestrunCompilationErrorException ex)
 130        {
 0131            logger.Error(ex, "Failed to compile VB.NET health probe {Probe}.", name);
 0132            throw;
 133        }
 0134    }
 135
 136    /// <summary>
 137    /// Builds a C# script runner for the given code, imports, and references.
 138    /// </summary>
 139    /// <param name="code">The C# code to compile.</param>
 140    /// <param name="extraImports">Additional namespaces to import.</param>
 141    /// <param name="extraRefs">Additional assemblies to reference.</param>
 142    /// <returns>A script runner that can execute the compiled code.</returns>
 143    /// <remarks>
 144    /// This method compiles the provided C# code into a script runner that can be executed asynchronously.
 145    /// It allows for additional namespaces and assemblies to be included in the compilation context.
 146    /// </remarks>
 147    private static ScriptRunner<ProbeResult> BuildCSharpRunner(string code, string[]? extraImports, Assembly[]? extraRef
 148    {
 0149        var options = ScriptOptions.Default
 0150            .AddReferences(DelegateBuilder.BuildBaselineReferences())
 0151            .AddReferences(typeof(ProbeResult).Assembly, typeof(ScriptProbeFactory).Assembly)
 0152            .WithImports(DelegateBuilder.PlatformImports)
 0153            .AddImports("Kestrun", "Kestrun.Health", "Kestrun.SharedState");
 154
 0155        if (extraImports is { Length: > 0 })
 156        {
 0157            options = options.WithImports(options.Imports.Concat(extraImports).Distinct(StringComparer.Ordinal));
 158        }
 159
 0160        if (extraRefs is { Length: > 0 })
 161        {
 0162            var additional = extraRefs
 0163                .Where(static r => !string.IsNullOrEmpty(r.Location) && File.Exists(r.Location))
 0164                .Select(static r => MetadataReference.CreateFromFile(r.Location));
 0165            options = options.AddReferences(additional);
 166        }
 167
 0168        var script = CSharpScript.Create<ProbeResult>(code, options, typeof(CsGlobals));
 0169        var diagnostics = script.Compile();
 0170        return diagnostics.Any(static d => d.Severity == DiagnosticSeverity.Error)
 0171            ? throw new RoslynCompilationErrorException("C# health probe compilation failed.", diagnostics)
 0172            : script.CreateDelegate();
 173    }
 174}