feat(siteeventlog): emit deployment + instance_lifecycle events (M1.6)
DeploymentManagerActor now fire-and-forgets a 'deployment' site operational event on deploy/enable/disable/delete outcomes (Info on success, Error on failure), source 'DeploymentManagerActor'. The disable/delete events are emitted from the existing PipeTo continuations (safe: reads only the immutable _serviceProvider and fire-and-forgets). InstanceActor now emits an 'instance_lifecycle' Info event in PreStart (started) and a new PostStop (stopped) — covering start/stop/enable/disable/redeploy/ failover transitions from the instance's own vantage point. Both actors already hold _serviceProvider; no ctor change. Resolution is optional and LogEventAsync is fire-and-forget so a logging failure never affects the deployment pipeline or instance lifecycle.
This commit is contained in:
@@ -10,6 +10,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
|
||||
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Actors;
|
||||
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Persistence;
|
||||
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
||||
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.TestSupport;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.Actors;
|
||||
@@ -58,6 +59,82 @@ public class InstanceActorTests : TestKit, IDisposable
|
||||
try { File.Delete(_dbFile); } catch { /* cleanup */ }
|
||||
}
|
||||
|
||||
// ── M1.6: site event log `instance_lifecycle` category ──────────────────
|
||||
|
||||
[Fact]
|
||||
public void InstanceActor_Start_EmitsInstanceLifecycleSiteEvent()
|
||||
{
|
||||
var siteLog = new FakeSiteEventLogger();
|
||||
var config = new FlattenedConfiguration
|
||||
{
|
||||
InstanceUniqueName = "LifecyclePump",
|
||||
Attributes = [new ResolvedAttribute { CanonicalName = "T", Value = "1", DataType = "Int32" }]
|
||||
};
|
||||
|
||||
ActorOf(Props.Create(() => new InstanceActor(
|
||||
"LifecyclePump",
|
||||
JsonSerializer.Serialize(config),
|
||||
_storage,
|
||||
_compilationService,
|
||||
_sharedScriptLibrary,
|
||||
null,
|
||||
_options,
|
||||
NullLogger<InstanceActor>.Instance,
|
||||
null,
|
||||
null,
|
||||
new SingleServiceProvider(siteLog))));
|
||||
|
||||
AwaitAssert(() =>
|
||||
{
|
||||
var rows = siteLog.OfType("instance_lifecycle");
|
||||
Assert.Contains(rows, r =>
|
||||
r.Severity == "Info" &&
|
||||
r.InstanceId == "LifecyclePump" &&
|
||||
r.Source == "InstanceActor:LifecyclePump" &&
|
||||
r.Message.Contains("started", StringComparison.OrdinalIgnoreCase));
|
||||
}, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InstanceActor_Stop_EmitsInstanceLifecycleSiteEvent()
|
||||
{
|
||||
var siteLog = new FakeSiteEventLogger();
|
||||
var config = new FlattenedConfiguration
|
||||
{
|
||||
InstanceUniqueName = "StoppedPump",
|
||||
Attributes = [new ResolvedAttribute { CanonicalName = "T", Value = "1", DataType = "Int32" }]
|
||||
};
|
||||
|
||||
var actor = ActorOf(Props.Create(() => new InstanceActor(
|
||||
"StoppedPump",
|
||||
JsonSerializer.Serialize(config),
|
||||
_storage,
|
||||
_compilationService,
|
||||
_sharedScriptLibrary,
|
||||
null,
|
||||
_options,
|
||||
NullLogger<InstanceActor>.Instance,
|
||||
null,
|
||||
null,
|
||||
new SingleServiceProvider(siteLog))));
|
||||
|
||||
// Let PreStart land its started event, then stop the actor.
|
||||
AwaitAssert(() => Assert.NotEmpty(siteLog.OfType("instance_lifecycle")),
|
||||
TimeSpan.FromSeconds(2));
|
||||
Watch(actor);
|
||||
actor.Tell(PoisonPill.Instance);
|
||||
ExpectTerminated(actor, TimeSpan.FromSeconds(5));
|
||||
|
||||
AwaitAssert(() =>
|
||||
{
|
||||
var rows = siteLog.OfType("instance_lifecycle");
|
||||
Assert.Contains(rows, r =>
|
||||
r.Severity == "Info" &&
|
||||
r.InstanceId == "StoppedPump" &&
|
||||
r.Message.Contains("stopped", StringComparison.OrdinalIgnoreCase));
|
||||
}, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InstanceActor_LoadsAttributesFromConfig()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user