feat(sitecall-audit): add SourceNode to SiteCallOperational + SiteCall entity
This commit is contained in:
@@ -72,6 +72,7 @@ public class CachedCallCombinedTelemetryTests : TestKit, IClassFixture<MsSqlMigr
|
||||
Channel: "ApiOutbound",
|
||||
Target: target,
|
||||
SourceSite: siteId,
|
||||
SourceNode: null,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
|
||||
@@ -61,6 +61,7 @@ public class CachedWriteCombinedTelemetryTests : TestKit, IClassFixture<MsSqlMig
|
||||
Channel: "DbOutbound",
|
||||
Target: target,
|
||||
SourceSite: siteId,
|
||||
SourceNode: null,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
|
||||
@@ -51,6 +51,7 @@ public class CachedCallTelemetryForwarderTests
|
||||
Channel: "ApiOutbound",
|
||||
Target: "ERP.GetOrder",
|
||||
SourceSite: "site-1",
|
||||
SourceNode: null,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
@@ -80,6 +81,7 @@ public class CachedCallTelemetryForwarderTests
|
||||
Channel: "ApiOutbound",
|
||||
Target: "ERP.GetOrder",
|
||||
SourceSite: "site-1",
|
||||
SourceNode: null,
|
||||
Status: "Attempted",
|
||||
RetryCount: retryCount,
|
||||
LastError: lastError,
|
||||
@@ -107,6 +109,7 @@ public class CachedCallTelemetryForwarderTests
|
||||
Channel: "ApiOutbound",
|
||||
Target: "ERP.GetOrder",
|
||||
SourceSite: "site-1",
|
||||
SourceNode: null,
|
||||
Status: status,
|
||||
RetryCount: 2,
|
||||
LastError: null,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using ScadaLink.Commons.Entities.Audit;
|
||||
using ScadaLink.Commons.Types;
|
||||
|
||||
namespace ScadaLink.Commons.Tests.Entities.Audit;
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the <see cref="SiteCall"/> central operational entity carries the
|
||||
/// SourceNode column (additive, nullable) through init-only construction and
|
||||
/// <c>with</c> expressions. Sibling to <see cref="AuditEventTests"/>.
|
||||
/// </summary>
|
||||
public class SiteCallTests
|
||||
{
|
||||
private static SiteCall MinimalRow() => new()
|
||||
{
|
||||
TrackedOperationId = TrackedOperationId.New(),
|
||||
Channel = "ApiOutbound",
|
||||
Target = "ERP.GetOrder",
|
||||
SourceSite = "site-01",
|
||||
Status = "Submitted",
|
||||
RetryCount = 0,
|
||||
CreatedAtUtc = new DateTime(2026, 5, 23, 12, 0, 0, DateTimeKind.Utc),
|
||||
UpdatedAtUtc = new DateTime(2026, 5, 23, 12, 0, 0, DateTimeKind.Utc),
|
||||
IngestedAtUtc = new DateTime(2026, 5, 23, 12, 0, 1, DateTimeKind.Utc),
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void SiteCall_carries_SourceNode()
|
||||
{
|
||||
// SourceNode identifies the cluster node that emitted the cached call
|
||||
// (site node-a/node-b or central-a/central-b). Additive nullable init
|
||||
// property — defaults to null on rows ingested before the column
|
||||
// existed, and round-trips its value via `with` expressions.
|
||||
var row = MinimalRow();
|
||||
Assert.Null(row.SourceNode);
|
||||
|
||||
var stamped = row with { SourceNode = "node-b" };
|
||||
Assert.Equal("node-b", stamped.SourceNode);
|
||||
Assert.Null(row.SourceNode);
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,10 @@ public class CachedCallTelemetryTests
|
||||
Channel: nameof(AuditChannel.ApiOutbound),
|
||||
Target: "ERP.GetOrder",
|
||||
SourceSite: SiteId,
|
||||
// SourceNode: actual stamping arrives with Task 14; for now the
|
||||
// packet builder leaves the column null so existing assertions on
|
||||
// the packet's other fields stay intact.
|
||||
SourceNode: null,
|
||||
Status: status.ToString(),
|
||||
RetryCount: retryCount,
|
||||
LastError: lastError,
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using ScadaLink.Commons.Types;
|
||||
|
||||
namespace ScadaLink.Commons.Tests.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Verifies <see cref="SiteCallOperational"/> — the positional record carried on
|
||||
/// the combined <c>CachedCallTelemetry</c> packet — round-trips the SourceNode
|
||||
/// field through positional construction (where the parameter sits between
|
||||
/// <c>SourceSite</c> and <c>Status</c>, mirroring the central <c>SiteCalls</c>
|
||||
/// table column order).
|
||||
/// </summary>
|
||||
public class SiteCallOperationalTests
|
||||
{
|
||||
[Fact]
|
||||
public void SiteCallOperational_carries_SourceNode()
|
||||
{
|
||||
// SourceNode identifies the cluster node that emitted the cached call
|
||||
// (site node-a/node-b or central-a/central-b). Nullable — callsites
|
||||
// pass null until INodeIdentityProvider stamping arrives in Task 14.
|
||||
var trackedId = TrackedOperationId.New();
|
||||
var nowUtc = new DateTime(2026, 5, 23, 12, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
var defaulted = new SiteCallOperational(
|
||||
TrackedOperationId: trackedId,
|
||||
Channel: "ApiOutbound",
|
||||
Target: "ERP.GetOrder",
|
||||
SourceSite: "site-01",
|
||||
SourceNode: null,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
HttpStatus: null,
|
||||
CreatedAtUtc: nowUtc,
|
||||
UpdatedAtUtc: nowUtc,
|
||||
TerminalAtUtc: null);
|
||||
Assert.Null(defaulted.SourceNode);
|
||||
|
||||
var stamped = defaulted with { SourceNode = "node-a" };
|
||||
Assert.Equal("node-a", stamped.SourceNode);
|
||||
Assert.Null(defaulted.SourceNode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user