fix(r2-10): in-process resilience status store
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Hubs;
|
||||
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Covers the in-process push contract the Blazor Server driver status panel's resilience section
|
||||
/// relies on: <see cref="IDriverResilienceStatusStore.SnapshotChanged"/> fires on every
|
||||
/// <see cref="IDriverResilienceStatusStore.Upsert"/>, keyed per <c>(instance, host)</c> with
|
||||
/// last-write-wins, and <c>GetForInstance</c> returns only the queried instance's hosts. Mirrors
|
||||
/// <see cref="DriverStatusSnapshotStoreTests"/>; the panel reads this store directly (no
|
||||
/// self-targeted SignalR connection).
|
||||
/// </summary>
|
||||
public sealed class DriverResilienceStatusStoreTests
|
||||
{
|
||||
private static DriverResilienceStatusChanged Msg(
|
||||
string instance, string host, bool breakerOpen = false, int failures = 0) =>
|
||||
new(instance, host, breakerOpen, failures, 0, null,
|
||||
new DateTime(2026, 7, 13, 0, 0, 0, DateTimeKind.Utc),
|
||||
new DateTime(2026, 7, 13, 0, 0, 0, DateTimeKind.Utc));
|
||||
|
||||
[Fact]
|
||||
public void Upsert_raises_SnapshotChanged_with_the_stored_snapshot()
|
||||
{
|
||||
var store = new InMemoryDriverResilienceStatusStore();
|
||||
var received = new List<DriverResilienceStatusChanged>();
|
||||
store.SnapshotChanged += received.Add;
|
||||
|
||||
var msg = Msg("drv-1", "host-a", breakerOpen: true);
|
||||
store.Upsert(msg);
|
||||
|
||||
received.Count.ShouldBe(1);
|
||||
received[0].ShouldBeSameAs(msg);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Upsert_is_last_write_wins_per_instance_host()
|
||||
{
|
||||
var store = new InMemoryDriverResilienceStatusStore();
|
||||
store.Upsert(Msg("drv-1", "host-a", failures: 3));
|
||||
store.Upsert(Msg("drv-1", "host-a", failures: 0));
|
||||
|
||||
var hosts = store.GetForInstance("drv-1");
|
||||
hosts.Count.ShouldBe(1);
|
||||
hosts[0].ConsecutiveFailures.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetForInstance_returns_only_the_queried_instances_hosts()
|
||||
{
|
||||
var store = new InMemoryDriverResilienceStatusStore();
|
||||
store.Upsert(Msg("drv-1", "host-a"));
|
||||
store.Upsert(Msg("drv-1", "host-b"));
|
||||
store.Upsert(Msg("drv-2", "host-a"));
|
||||
|
||||
var hosts = store.GetForInstance("drv-1");
|
||||
|
||||
hosts.Count.ShouldBe(2);
|
||||
hosts.ShouldAllBe(h => h.DriverInstanceId == "drv-1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetForInstance_returns_empty_for_unknown_instance()
|
||||
{
|
||||
var store = new InMemoryDriverResilienceStatusStore();
|
||||
store.Upsert(Msg("drv-1", "host-a"));
|
||||
|
||||
store.GetForInstance("nope").ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unsubscribed_handler_stops_receiving_after_removal()
|
||||
{
|
||||
var store = new InMemoryDriverResilienceStatusStore();
|
||||
var count = 0;
|
||||
void Handler(DriverResilienceStatusChanged _) => count++;
|
||||
|
||||
store.SnapshotChanged += Handler;
|
||||
store.Upsert(Msg("drv-1", "host-a"));
|
||||
store.SnapshotChanged -= Handler;
|
||||
store.Upsert(Msg("drv-1", "host-a"));
|
||||
|
||||
count.ShouldBe(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user