88 lines
3.0 KiB
C#
88 lines
3.0 KiB
C#
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);
|
|
}
|
|
}
|