Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.Host.Tests/DeadLetterMonitorTests.cs
T
Joseph Doherty 513fa1aa16 docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)
Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
2026-10-07 15:05:49 -04:00

109 lines
4.3 KiB
C#

using System.Linq;
using Akka.Actor;
using Akka.Event;
using Akka.TestKit.Xunit2;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NSubstitute;
using ZB.MOM.WW.ScadaBridge.Host.Actors;
namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
/// <summary>
/// Tests for DeadLetterMonitorActor.
/// </summary>
public class DeadLetterMonitorTests : TestKit
{
private readonly ILogger<DeadLetterMonitorActor> _logger =
NullLoggerFactory.Instance.CreateLogger<DeadLetterMonitorActor>();
/// <summary>Verifies that a new dead-letter monitor starts with a count of zero.</summary>
[Fact]
public void DeadLetterMonitor_StartsWithZeroCount()
{
var monitor = Sys.ActorOf(Props.Create(() => new DeadLetterMonitorActor(_logger)));
monitor.Tell(GetDeadLetterCount.Instance);
var response = ExpectMsg<DeadLetterCountResponse>();
Assert.Equal(0, response.Count);
}
/// <summary>Verifies that the monitor count increments when a dead letter is published.</summary>
[Fact]
public void DeadLetterMonitor_IncrementsOnDeadLetter()
{
var monitor = Sys.ActorOf(Props.Create(() => new DeadLetterMonitorActor(_logger)));
// Ensure actor has started and subscribed by sending a message and waiting for response
monitor.Tell(GetDeadLetterCount.Instance);
ExpectMsg<DeadLetterCountResponse>();
// Now publish dead letters — actor is guaranteed to be subscribed
Sys.EventStream.Publish(new DeadLetter("test-message-1", Sys.DeadLetters, Sys.DeadLetters));
Sys.EventStream.Publish(new DeadLetter("test-message-2", Sys.DeadLetters, Sys.DeadLetters));
// Use AwaitAssert to handle async event delivery
AwaitAssert(() =>
{
monitor.Tell(GetDeadLetterCount.Instance);
var response = ExpectMsg<DeadLetterCountResponse>();
Assert.Equal(2, response.Count);
});
}
/// <summary>Verifies that a dead-letter storm logs at most the per-window warning limit while still counting every dead letter.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeadLetterStorm_LogsAtMostWindowLimit_ButCountsAll()
{
// Review 01 [Low]: a failover/undeploy storm produced one Warning per
// dead letter — unbounded log flood. Health metric counting is untouched.
var logger = Substitute.For<ILogger<DeadLetterMonitorActor>>();
var monitor = Sys.ActorOf(Props.Create(() => new DeadLetterMonitorActor(logger, null)));
// Ensure the actor has started before the storm.
monitor.Tell(GetDeadLetterCount.Instance);
ExpectMsg<DeadLetterCountResponse>();
for (var i = 0; i < 50; i++)
monitor.Tell(new DeadLetter($"m{i}", TestActor, TestActor));
var count = await monitor.Ask<DeadLetterCountResponse>(GetDeadLetterCount.Instance);
Assert.Equal(50, count.Count); // every dead letter still counted
var warnings = logger.ReceivedCalls().Count(c =>
c.GetMethodInfo().Name == "Log"
&& (Microsoft.Extensions.Logging.LogLevel)c.GetArguments()[0]!
== Microsoft.Extensions.Logging.LogLevel.Warning);
// The per-letter cap plus the one "limit reached" notice.
Assert.True(warnings <= DeadLetterMonitorActor.MaxWarningsPerWindow + 1,
$"expected <= {DeadLetterMonitorActor.MaxWarningsPerWindow + 1} warnings, got {warnings}");
}
/// <summary>Verifies that the dead-letter count accumulates across multiple dead letters.</summary>
[Fact]
public void DeadLetterMonitor_CountAccumulates()
{
var monitor = Sys.ActorOf(Props.Create(() => new DeadLetterMonitorActor(_logger)));
// Ensure actor is started and subscribed
monitor.Tell(GetDeadLetterCount.Instance);
ExpectMsg<DeadLetterCountResponse>();
// Send 5 dead letters
for (var i = 0; i < 5; i++)
{
Sys.EventStream.Publish(
new DeadLetter($"message-{i}", Sys.DeadLetters, Sys.DeadLetters));
}
AwaitAssert(() =>
{
monitor.Tell(GetDeadLetterCount.Instance);
var response = ExpectMsg<DeadLetterCountResponse>();
Assert.Equal(5, response.Count);
});
}
}