Resolve all 46 low-severity architecture review findings
This commit is contained in:
@@ -8,6 +8,15 @@ namespace ZB.MOM.WW.ScadaBridge.Communication.Tests.Grpc;
|
||||
|
||||
public class SiteStreamGrpcClientTests
|
||||
{
|
||||
[Fact]
|
||||
public void ConnectedHeaderTimeout_IsImmutablePerClient()
|
||||
{
|
||||
var property = typeof(SiteStreamGrpcClient).GetProperty("ConnectedHeaderTimeout",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static)!;
|
||||
Assert.False(property.GetMethod!.IsStatic);
|
||||
Assert.Null(property.SetMethod);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertToDomainEvent_AttributeChanged_MapsCorrectly()
|
||||
{
|
||||
@@ -436,32 +445,23 @@ public class SiteStreamGrpcClientTests
|
||||
// The bug: a header TIMEOUT used to be reported as connected. An unreachable/wedged
|
||||
// site produces exactly that shape, so the aggregator cleared _streamDown, consumed
|
||||
// its pending re-seed and fanned a full snapshot out at a site that never answered.
|
||||
var previous = SiteStreamGrpcClient.ConnectedHeaderTimeout;
|
||||
SiteStreamGrpcClient.ConnectedHeaderTimeout = TimeSpan.FromMilliseconds(50);
|
||||
try
|
||||
{
|
||||
var client = SiteStreamGrpcClient.CreateForTesting();
|
||||
var cts = new CancellationTokenSource();
|
||||
var connected = 0;
|
||||
var neverArrives = new TaskCompletionSource<Metadata>();
|
||||
var client = SiteStreamGrpcClient.CreateForTesting(new CommunicationOptions { ConnectedHeaderTimeout = TimeSpan.FromMilliseconds(50) });
|
||||
var cts = new CancellationTokenSource();
|
||||
var connected = 0;
|
||||
var neverArrives = new TaskCompletionSource<Metadata>();
|
||||
|
||||
// No headers AND no events: the site is dead. The stream ends (status OK) with
|
||||
// no connected signal ever raised.
|
||||
await client.ConsumeStreamAsync(
|
||||
"corr-dead",
|
||||
cts,
|
||||
() => FakeCall(new StubStreamReader(), neverArrives.Task),
|
||||
_ => { },
|
||||
_ => { },
|
||||
() => { },
|
||||
() => connected++);
|
||||
// No headers AND no events: the site is dead. The stream ends (status OK) with
|
||||
// no connected signal ever raised.
|
||||
await client.ConsumeStreamAsync(
|
||||
"corr-dead",
|
||||
cts,
|
||||
() => FakeCall(new StubStreamReader(), neverArrives.Task),
|
||||
_ => { },
|
||||
_ => { },
|
||||
() => { },
|
||||
() => connected++);
|
||||
|
||||
Assert.Equal(0, connected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
SiteStreamGrpcClient.ConnectedHeaderTimeout = previous;
|
||||
}
|
||||
Assert.Equal(0, connected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -470,42 +470,33 @@ public class SiteStreamGrpcClientTests
|
||||
// The case the timeout was originally added for — a peer that defers its headers
|
||||
// until the first message — is now covered by the event itself, which is real proof
|
||||
// of a live peer. Connected must precede the event's delivery and fire only once.
|
||||
var previous = SiteStreamGrpcClient.ConnectedHeaderTimeout;
|
||||
SiteStreamGrpcClient.ConnectedHeaderTimeout = TimeSpan.FromMilliseconds(50);
|
||||
try
|
||||
{
|
||||
var client = SiteStreamGrpcClient.CreateForTesting();
|
||||
var cts = new CancellationTokenSource();
|
||||
var connected = 0;
|
||||
var connectedBeforeFirstEvent = false;
|
||||
var events = 0;
|
||||
var neverArrives = new TaskCompletionSource<Metadata>();
|
||||
var client = SiteStreamGrpcClient.CreateForTesting(new CommunicationOptions { ConnectedHeaderTimeout = TimeSpan.FromMilliseconds(50) });
|
||||
var cts = new CancellationTokenSource();
|
||||
var connected = 0;
|
||||
var connectedBeforeFirstEvent = false;
|
||||
var events = 0;
|
||||
var neverArrives = new TaskCompletionSource<Metadata>();
|
||||
|
||||
await client.ConsumeStreamAsync(
|
||||
"corr-late-headers",
|
||||
cts,
|
||||
() => FakeCall(
|
||||
new StubStreamReader(
|
||||
new SiteStreamEvent { CorrelationId = "corr-late-headers" },
|
||||
new SiteStreamEvent { CorrelationId = "corr-late-headers" }),
|
||||
neverArrives.Task),
|
||||
_ =>
|
||||
{
|
||||
if (events == 0) connectedBeforeFirstEvent = connected == 1;
|
||||
events++;
|
||||
},
|
||||
_ => { },
|
||||
() => { },
|
||||
() => connected++);
|
||||
await client.ConsumeStreamAsync(
|
||||
"corr-late-headers",
|
||||
cts,
|
||||
() => FakeCall(
|
||||
new StubStreamReader(
|
||||
new SiteStreamEvent { CorrelationId = "corr-late-headers" },
|
||||
new SiteStreamEvent { CorrelationId = "corr-late-headers" }),
|
||||
neverArrives.Task),
|
||||
_ =>
|
||||
{
|
||||
if (events == 0) connectedBeforeFirstEvent = connected == 1;
|
||||
events++;
|
||||
},
|
||||
_ => { },
|
||||
() => { },
|
||||
() => connected++);
|
||||
|
||||
Assert.Equal(2, events);
|
||||
Assert.Equal(1, connected);
|
||||
Assert.True(connectedBeforeFirstEvent);
|
||||
}
|
||||
finally
|
||||
{
|
||||
SiteStreamGrpcClient.ConnectedHeaderTimeout = previous;
|
||||
}
|
||||
Assert.Equal(2, events);
|
||||
Assert.Equal(1, connected);
|
||||
Assert.True(connectedBeforeFirstEvent);
|
||||
}
|
||||
|
||||
// ── R2: batch unpacking on the client ───────────────────────────────────────
|
||||
@@ -514,12 +505,12 @@ public class SiteStreamGrpcClientTests
|
||||
{
|
||||
AttributeChanged = new AttributeValueUpdate
|
||||
{
|
||||
InstanceUniqueName = "SiteA.Pump01",
|
||||
AttributePath = "Modules.IO",
|
||||
AttributeName = "Seq",
|
||||
Value = value,
|
||||
Quality = Quality.Good,
|
||||
Timestamp = Timestamp.FromDateTimeOffset(ts)
|
||||
InstanceUniqueName = "SiteA.Pump01",
|
||||
AttributePath = "Modules.IO",
|
||||
AttributeName = "Seq",
|
||||
Value = value,
|
||||
Quality = Quality.Good,
|
||||
Timestamp = Timestamp.FromDateTimeOffset(ts)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user