using SQLInsight.Core.Data; namespace SQLInsight.Core.Tests; public class ErrorLogTests { private static readonly DateTimeOffset T = new(2026, 10, 2, 8, 0, 0, TimeSpan.Zero); [Fact] public void Number_lines_are_joined_to_the_message_that_follows() { var entries = ErrorLogAnalysis.ParseLines( [ (T, "Error: 824, Severity: 24, State: 2."), (T, "SQL Server detected a logical consistency-based I/O error: incorrect checksum."), (T.AddSeconds(1), "SQL Server has encountered 3 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [D:\\Data\\AX.mdf]"), (T.AddSeconds(2), "Login failed for user 'sa'. Reason: Password did not match. [CLIENT: 10.0.0.9]"), (T.AddSeconds(3), "Error: 17310, Severity: 20, State: 1."), ]); Assert.Equal(4, entries.Count); Assert.Equal((824, 24), (entries[0].Error, entries[0].Severity)); Assert.Contains("checksum", entries[0].Message, StringComparison.Ordinal); Assert.Equal(833, entries[1].Error); Assert.Equal(18456, entries[2].Error); Assert.Equal(17310, entries[3].Error); } [Theory] [InlineData(825, 10, null, ErrorLogCategory.Corruption)] [InlineData(833, 10, null, ErrorLogCategory.SlowIo)] [InlineData(18456, 14, null, ErrorLogCategory.LoginFailed)] [InlineData(35206, 16, null, ErrorLogCategory.AvailabilityGroup)] [InlineData(null, null, "***Stack Dump being sent to C:\\…\\SQLDump0001.txt", ErrorLogCategory.StackDump)] [InlineData(701, 17, null, ErrorLogCategory.Severe)] [InlineData(5701, 10, "Changed database context to 'master'.", ErrorLogCategory.Other)] public void Entries_are_categorized(int? error, int? severity, string? message, ErrorLogCategory expected) => Assert.Equal(expected, ErrorLogAnalysis.Categorize(new ErrorLogEntry(T, error, severity, message))); [Fact] public void Repetitions_are_summed_and_kept_for_a_day() { var first = ErrorLogAnalysis.Group(Enumerable.Range(0, 30).Select(i => new ErrorLogEntry(T.AddSeconds(i), 18456, 14, "Login failed for user 'x'."))); var later = ErrorLogAnalysis.Group([new ErrorLogEntry(T.AddHours(2), 18456, 14, "Login failed for user 'y'.")]); var login = Assert.Single(first); Assert.Equal((30, T, T.AddSeconds(29)), (login.Count, login.FirstAt, login.LastAt)); var recent = Assert.Single(ErrorLogAnalysis.Recent(first, later, T.AddHours(2))); Assert.Equal(31, recent.Count); Assert.Contains("'y'", recent.Sample, StringComparison.Ordinal); Assert.Single(ErrorLogAnalysis.Recent(first, later, T.AddHours(25))); // the first batch has expired Assert.Equal(1, ErrorLogAnalysis.Recent(first, later, T.AddHours(25))[0].Count); } }