From d54c3da291f8edf6eaf66353ff08192c0ea56aa9 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 19 May 2026 05:32:06 -0400 Subject: [PATCH] test(notification-outbox): exercise per-site oldest-age reduction and Retrying status --- ...ficationOutboxRepositoryPerSiteKpiTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/ScadaLink.ConfigurationDatabase.Tests/NotificationOutboxRepositoryPerSiteKpiTests.cs b/tests/ScadaLink.ConfigurationDatabase.Tests/NotificationOutboxRepositoryPerSiteKpiTests.cs index 299a447..f88b4b9 100644 --- a/tests/ScadaLink.ConfigurationDatabase.Tests/NotificationOutboxRepositoryPerSiteKpiTests.cs +++ b/tests/ScadaLink.ConfigurationDatabase.Tests/NotificationOutboxRepositoryPerSiteKpiTests.cs @@ -39,6 +39,12 @@ public class NotificationOutboxRepositoryPerSiteKpiTests // plant-b: 1 delivered in-window, 1 pending (fresh) ctx.Notifications.Add(NewNotification("plant-b", NotificationStatus.Delivered, createdAt: now.AddHours(-2), deliveredAt: now.AddMinutes(-2))); ctx.Notifications.Add(NewNotification("plant-b", NotificationStatus.Pending, createdAt: now.AddMinutes(-1))); + // plant-c: 2 non-terminal rows of clearly different ages — pending 90m ago, + // retrying 40m ago. Both predate the 10m stuck cutoff. Exercises the + // in-memory g.Min(CreatedAt) oldest-age reduction and the Retrying branch + // of the QueueDepth/StuckCount predicates. + ctx.Notifications.Add(NewNotification("plant-c", NotificationStatus.Pending, createdAt: now.AddMinutes(-90))); + ctx.Notifications.Add(NewNotification("plant-c", NotificationStatus.Retrying, createdAt: now.AddMinutes(-40))); await ctx.SaveChangesAsync(); var repo = new NotificationOutboxRepository(ctx); @@ -56,6 +62,21 @@ public class NotificationOutboxRepositoryPerSiteKpiTests Assert.Equal(1, b.QueueDepth); Assert.Equal(0, b.StuckCount); Assert.Equal(1, b.DeliveredLastInterval); + + // plant-c: both the Pending and Retrying rows count toward QueueDepth; + // both predate the stuck cutoff so both are stuck. OldestPendingAge must + // reflect the older (90m) row, not the 10m Retrying one. + var c = result.Single(s => s.SourceSiteId == "plant-c"); + Assert.Equal(2, c.QueueDepth); + Assert.Equal(2, c.StuckCount); + Assert.Equal(0, c.ParkedCount); + Assert.NotNull(c.OldestPendingAge); + // Tolerant lower bound to absorb clock skew between seed time and the + // `now` captured inside ComputePerSiteKpisAsync. + Assert.True(c.OldestPendingAge >= TimeSpan.FromMinutes(85), + $"expected OldestPendingAge >= 85m, got {c.OldestPendingAge}"); + Assert.True(c.OldestPendingAge < TimeSpan.FromMinutes(95), + $"expected OldestPendingAge < 95m, got {c.OldestPendingAge}"); } [Fact]