104 lines
3.8 KiB
C#
104 lines
3.8 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>
|
|
/// WP-15: Tests for DeadLetterMonitorActor.
|
|
/// </summary>
|
|
public class DeadLetterMonitorTests : TestKit
|
|
{
|
|
private readonly ILogger<DeadLetterMonitorActor> _logger =
|
|
NullLoggerFactory.Instance.CreateLogger<DeadLetterMonitorActor>();
|
|
|
|
[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);
|
|
}
|
|
|
|
[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);
|
|
});
|
|
}
|
|
|
|
[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}");
|
|
}
|
|
|
|
[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);
|
|
});
|
|
}
|
|
}
|