sqlinsight-pro/tests/SQLInsight.Rules.Tests/SupportLifecycleRuleTests.cs
Claude f8aa0c307b
Some checks are pending
CI / Build og unit tests (push) Waiting to run
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2019-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2022-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2025-latest) (push) Blocked by required conditions
Fase 0: solution structure, capability model, rule engine, least-privilege script
- .NET 10 solution with Core, Connectivity, Rules, Contracts, Agent, Web and Hub
- Capability model gating collectors and rules by SQL Server version (2000 and later);
  rules that cannot run are reported as not measurable, never as passed
- Connectivity via Microsoft.Data.SqlClient with ODBC fallback for legacy instances,
  hardened monitoring session settings valid back to SQL Server 2000
- Support lifecycle rule (SQLI-VER-001) with lifecycle data shipped as a rule pack
- Version-aware least-privilege permissions script, verified by integration tests
  against SQL Server in Docker (reads monitoring sources, cannot read customer data)
- Forgejo Actions CI, contributing guide, code of conduct, issue templates,
  legacy version notes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
2026-09-29 05:40:49 +00:00

93 lines
3.1 KiB
C#

using SQLInsight.Core.Findings;
using SQLInsight.Core.Instances;
using SQLInsight.Rules.Engine;
using SQLInsight.Rules.Lifecycle;
namespace SQLInsight.Rules.Tests;
public class SupportLifecycleRuleTests
{
private static readonly SupportLifecycleRule Rule = new(SupportLifecycleCatalog.LoadEmbedded());
private static readonly DateTimeOffset Today = new(2026, 9, 29, 0, 0, 0, TimeSpan.Zero);
[Theory]
[InlineData("8.00.2039")]
[InlineData("9.00.5000.00")]
[InlineData("10.50.6000.34")]
[InlineData("12.0.6024.0")]
[InlineData("13.0.6300.2")]
public void Out_of_support_releases_are_critical(string version)
{
var evaluation = Rule.Evaluate(TestInstances.Context(version, Today));
Assert.Equal(RuleOutcome.Findings, evaluation.Outcome);
Assert.Equal(Severity.Critical, Assert.Single(evaluation.Findings).Severity);
}
[Theory]
[InlineData("2026-09-29", Severity.Medium)] // 378 days left
[InlineData("2026-10-12", Severity.High)] // exactly 365 days left
[InlineData("2027-10-12", Severity.High)] // last day of support
[InlineData("2027-10-13", Severity.Critical)]
public void Sql2017_escalates_as_extended_support_ends(string date, Severity expected)
{
// SQL Server 2017 extended support ends 2027-10-12.
var now = DateTimeOffset.Parse(date + "T12:00:00Z", System.Globalization.CultureInfo.InvariantCulture);
var evaluation = Rule.Evaluate(TestInstances.Context("14.0.3456.2", now));
Assert.Equal(expected, Assert.Single(evaluation.Findings).Severity);
}
[Fact]
public void Extended_support_further_out_is_medium()
{
// SQL Server 2019 left mainstream support 2025-02-28; extended runs to 2030.
var evaluation = Rule.Evaluate(TestInstances.Context("15.0.4355.3", Today));
Assert.Equal(Severity.Medium, Assert.Single(evaluation.Findings).Severity);
}
[Fact]
public void Mainstream_support_passes()
{
var evaluation = Rule.Evaluate(TestInstances.Context("16.0.4135.4", Today));
Assert.Equal(RuleOutcome.Passed, evaluation.Outcome);
}
[Fact]
public void Release_without_published_dates_is_not_measurable()
{
var evaluation = Rule.Evaluate(TestInstances.Context("17.0.1000.7", Today));
Assert.Equal(RuleOutcome.NotMeasurable, evaluation.Outcome);
}
[Fact]
public void Unknown_future_release_is_not_measurable()
{
var evaluation = Rule.Evaluate(TestInstances.Context("18.0.100.1", Today));
Assert.Equal(RuleOutcome.NotMeasurable, evaluation.Outcome);
Assert.Contains("Opdater", evaluation.Reason, StringComparison.Ordinal);
}
[Fact]
public void Runs_on_sql2000_because_it_needs_no_capabilities()
{
Assert.Empty(Rule.RequiredCapabilities);
}
[Fact]
public void Catalog_covers_every_known_release()
{
var catalog = SupportLifecycleCatalog.LoadEmbedded();
foreach (var release in Enum.GetValues<SqlServerRelease>().Where(r => r != SqlServerRelease.Unknown))
{
Assert.NotNull(catalog.Find(release));
}
}
}