sqlinsight-pro/tests/SQLInsight.Core.Tests/BaselineTests.cs
Claude d84cf8c2b6
Some checks are pending
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Blocked by required conditions
CI / Build og unit tests (push) Waiting to run
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 2: baselines and anomaly detection
Baselines per hour of the week (with neighbouring hours) from four weeks
of hourly aggregates, computed in C# (independent of DATEFIRST) and
refreshed by the agent each hour. SQLI-ANOM-001 compares current load
with what is normal at this time: CPU far above normal, batch requests
far above or collapsed (application down?), page life expectancy
collapse. Not measurable until enough history exists.

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

51 lines
2.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using SQLInsight.Core.Data;
namespace SQLInsight.Core.Tests;
public class BaselineTests
{
[Theory]
[InlineData("2026-09-28T00:30:00Z", 0)] // Monday
[InlineData("2026-09-29T13:10:00Z", 37)] // Tuesday 13
[InlineData("2026-10-04T23:59:00Z", 167)] // Sunday 23
public void Hour_of_week_starts_monday(string utc, int expected)
{
Assert.Equal(expected, BaselineCalculator.HourOfWeek(DateTime.Parse(utc, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal)));
}
[Fact]
public void Uses_the_same_hour_and_its_neighbours_in_earlier_weeks()
{
var now = new DateTimeOffset(2026, 9, 29, 13, 20, 0, TimeSpan.Zero); // Tuesday 13
var history = new List<HourlyValue>();
for (var week = 1; week <= 3; week++)
{
var sameHour = new DateTime(2026, 9, 29, 13, 0, 0, DateTimeKind.Utc).AddDays(-7 * week);
history.Add(new HourlyValue("cpu", sameHour.AddHours(-1), 20));
history.Add(new HourlyValue("cpu", sameHour, 30));
history.Add(new HourlyValue("cpu", sameHour.AddHours(1), 40));
history.Add(new HourlyValue("cpu", sameHour.AddHours(5), 99)); // other hour: ignored
}
history.Add(new HourlyValue("cpu", new DateTime(2026, 9, 29, 12, 0, 0, DateTimeKind.Utc), 99)); // today, too recent
var baseline = BaselineCalculator.Calculate(history, now);
var cpu = baseline.Metrics["cpu"];
Assert.Equal(37, baseline.HourOfWeek);
Assert.Equal(9, cpu.Samples);
Assert.Equal(30, cpu.Mean, 6);
Assert.Equal(Math.Sqrt(75), cpu.StandardDeviation, 6); // (3×100 + 3×0 + 3×100) / 8
}
[Fact]
public void Neighbour_hours_wrap_around_the_week()
{
var now = new DateTimeOffset(2026, 9, 28, 0, 30, 0, TimeSpan.Zero); // Monday 00
var sundayLate = new DateTime(2026, 9, 20, 23, 0, 0, DateTimeKind.Utc);
var baseline = BaselineCalculator.Calculate([new HourlyValue("cpu", sundayLate, 10)], now);
Assert.Equal(1, baseline.Metrics["cpu"].Samples);
}
}