fix(health): decouple AuditCentralHealthSnapshot from ActorSystem (#23 M6)
The snapshot's per-site stalled latch now lives on the snapshot itself and is fed by SiteAuditTelemetryStalledTracker via ApplyStalled, removing the chain that required ActorSystem at DI composition time. The tracker is now constructed by AkkaHostedService once ActorSystem.Create returns, with a lock-guarded auxiliary-disposable list so concurrent host start/stop in tests cannot race the enumeration.
This commit is contained in:
@@ -24,8 +24,7 @@ public class CentralAuditRedactionFailureCounterTests : TestKit
|
||||
[Fact]
|
||||
public void Increment_Routes_To_Snapshot()
|
||||
{
|
||||
using var tracker = new SiteAuditTelemetryStalledTracker(Sys);
|
||||
var snapshot = new AuditCentralHealthSnapshot(tracker);
|
||||
var snapshot = new AuditCentralHealthSnapshot();
|
||||
var counter = new CentralAuditRedactionFailureCounter(snapshot);
|
||||
|
||||
counter.Increment();
|
||||
@@ -60,10 +59,10 @@ public class CentralAuditRedactionFailureCounterTests : TestKit
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
|
||||
services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>));
|
||||
// The AuditCentralHealthSnapshot ctor takes the stalled tracker
|
||||
// which itself needs an ActorSystem — register a real system
|
||||
// (test-kit's Sys) so the DI graph composes.
|
||||
services.AddSingleton<ActorSystem>(Sys);
|
||||
// AuditCentralHealthSnapshot no longer takes a tracker dependency —
|
||||
// the tracker is constructed later by the Akka bootstrap because its
|
||||
// ctor needs an ActorSystem (not a DI-resolvable singleton). The
|
||||
// snapshot itself composes purely from primitives.
|
||||
services.AddAuditLog(config);
|
||||
services.AddAuditLogCentralMaintenance(config);
|
||||
using var provider = services.BuildServiceProvider();
|
||||
|
||||
@@ -115,9 +115,10 @@ public class CentralAuditWriteFailuresTests : TestKit
|
||||
{
|
||||
// AuditCentralHealthSnapshot implements both writer surfaces; bumping
|
||||
// through the writer interfaces is reflected on the read surface, and
|
||||
// SiteAuditTelemetryStalled is sourced from the injected tracker.
|
||||
using var tracker = new SiteAuditTelemetryStalledTracker(Sys);
|
||||
var snapshot = new AuditCentralHealthSnapshot(tracker);
|
||||
// the per-site stalled state is fed in via ApplyStalled — production
|
||||
// wires that to a SiteAuditTelemetryStalledTracker, but the snapshot
|
||||
// is testable in isolation against the same Apply surface.
|
||||
var snapshot = new AuditCentralHealthSnapshot();
|
||||
|
||||
Assert.Equal(0, snapshot.CentralAuditWriteFailures);
|
||||
Assert.Equal(0, snapshot.AuditRedactionFailure);
|
||||
@@ -127,7 +128,11 @@ public class CentralAuditWriteFailuresTests : TestKit
|
||||
((ICentralAuditWriteFailureCounter)snapshot).Increment();
|
||||
((ScadaLink.AuditLog.Payload.IAuditRedactionFailureCounter)snapshot).Increment();
|
||||
|
||||
// Publish a stalled-changed event so the tracker registers a site.
|
||||
// Wire the tracker so an EventStream publish reaches the snapshot.
|
||||
// The tracker pushes into the snapshot's ApplyStalled when given
|
||||
// the snapshot in its ctor; the tracker also keeps its own latch,
|
||||
// but the snapshot read surface is what the central UI reads.
|
||||
using var tracker = new SiteAuditTelemetryStalledTracker(Sys, snapshot);
|
||||
Sys.EventStream.Publish(new SiteAuditTelemetryStalledChanged("siteA", Stalled: true));
|
||||
AwaitAssert(() =>
|
||||
{
|
||||
@@ -143,9 +148,13 @@ public class CentralAuditWriteFailuresTests : TestKit
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuditCentralHealthSnapshot_Construction_Without_Tracker_Throws()
|
||||
public void Snapshot_Empty_OnConstruction()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(
|
||||
() => new AuditCentralHealthSnapshot(null!));
|
||||
// Sanity: the snapshot's three properties start at their zero values
|
||||
// before any writer or stalled-event publication.
|
||||
var snapshot = new AuditCentralHealthSnapshot();
|
||||
Assert.Equal(0, snapshot.CentralAuditWriteFailures);
|
||||
Assert.Equal(0, snapshot.AuditRedactionFailure);
|
||||
Assert.Empty(snapshot.SiteAuditTelemetryStalled);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user