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
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
51 lines
2.1 KiB
C#
51 lines
2.1 KiB
C#
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);
|
||
}
|
||
}
|