docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)

Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 15:05:49 -04:00
parent 0ffd4bdbea
commit 513fa1aa16
998 changed files with 17896 additions and 2395 deletions
@@ -9,7 +9,7 @@ using ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests;
/// <summary>
/// DataConnectionLayer-003: structural regression guard. RealOpcUaClient's
/// Structural regression guard. RealOpcUaClient's
/// monitored-item / callback maps are read from the OPC UA SDK's publish threads
/// concurrently with subscribe/disconnect mutations on other threads. They must be
/// concurrent collections, not plain Dictionary. This is verified structurally
@@ -18,6 +18,10 @@ namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests;
/// </summary>
public class RealOpcUaClientThreadSafetyTests
{
/// <summary>
/// Verifies that the shared dictionary fields of the OPC UA client are concurrent collections.
/// </summary>
/// <param name="fieldName">The name of the field that is inspected.</param>
[Theory]
[InlineData("_callbacks")]
[InlineData("_monitoredItems")]
@@ -40,7 +44,7 @@ public class RealOpcUaClientThreadSafetyTests
}
/// <summary>
/// DataConnectionLayer-019: <see cref="OpcUaDataConnection"/> previously kept a
/// <see cref="OpcUaDataConnection"/> previously kept a
/// dead <c>Dictionary&lt;string,string&gt; _subscriptionHandles</c> field that was
/// written and removed across thread-pool continuations but never read. Plain
/// Dictionary writes from concurrent post-await continuations are racy; the
@@ -53,6 +57,7 @@ public class RealOpcUaClientThreadSafetyTests
/// </summary>
public class OpcUaDataConnectionThreadSafetyTests
{
/// <summary>Verifies that the OPC UA data connection has no non-concurrent shared dictionary field.</summary>
[Fact]
public void DCL019_OpcUaDataConnection_HasNoNonConcurrentSharedDictionary()
{
@@ -76,14 +81,15 @@ public class OpcUaDataConnectionThreadSafetyTests
}
/// <summary>
/// DataConnectionLayer-012: secure-by-default certificate handling.
/// Secure-by-default certificate handling.
/// </summary>
public class OpcUaCertificateDefaultTests
{
/// <summary>Verifies that automatic acceptance of untrusted certificates defaults to false.</summary>
[Fact]
public void DCL012_OpcUaConnectionOptions_AutoAcceptUntrustedCerts_DefaultsToFalse()
{
// Regression test for DataConnectionLayer-012. AutoAcceptUntrustedCerts defaulted
// Regression test: AutoAcceptUntrustedCerts defaulted
// to true, accepting every server certificate unconditionally and defeating the
// Sign / SignAndEncrypt security modes against an active man-in-the-middle. A
// secure-by-default posture rejects untrusted certs unless explicitly opted in.
@@ -93,7 +99,7 @@ public class OpcUaCertificateDefaultTests
}
/// <summary>
/// DataConnectionLayer-014: the DCL-012 auto-accept-certificate security warning is
/// The auto-accept-certificate security warning is
/// only effective if RealOpcUaClient is built with a real logger. The only production
/// path that constructs one is RealOpcUaClientFactory.Create(); that factory must
/// thread a logger through, otherwise the warning sinks into NullLogger and an
@@ -109,12 +115,13 @@ public class RealOpcUaClientFactoryLoggerTests
return (ILogger<RealOpcUaClient>)field!.GetValue(client)!;
}
/// <summary>Verifies that the real OPC UA client factory creates a client with a real logger.</summary>
[Fact]
public void DCL014_RealOpcUaClientFactory_CreatesClientWithRealLogger()
{
// Regression test for DataConnectionLayer-014. RealOpcUaClientFactory.Create()
// Regression test: RealOpcUaClientFactory.Create()
// constructed `new RealOpcUaClient(_globalOptions)` with no logger, so the
// DCL-012 man-in-the-middle warning was always discarded by NullLogger in
// auto-accept man-in-the-middle warning was always discarded by NullLogger in
// production. After the fix the factory accepts an ILoggerFactory and passes a
// real ILogger<RealOpcUaClient> into every client it creates.
using var loggerFactory = LoggerFactory.Create(b => { });
@@ -126,6 +133,7 @@ public class RealOpcUaClientFactoryLoggerTests
Assert.NotSame(NullLogger<RealOpcUaClient>.Instance, logger);
}
/// <summary>Verifies that the data connection factory passes its logger through to the real OPC UA client.</summary>
[Fact]
public void DCL014_DataConnectionFactory_ThreadsLoggerToRealOpcUaClient()
{
@@ -150,14 +158,15 @@ public class RealOpcUaClientFactoryLoggerTests
}
/// <summary>
/// DataConnectionLayer-009: failover-stability tunables must be configurable.
/// Failover-stability tunables must be configurable.
/// </summary>
public class DataConnectionOptionsStabilityTests
{
/// <summary>Verifies that the stable connection threshold is configurable and defaults to sixty seconds.</summary>
[Fact]
public void DCL009_StableConnectionThreshold_IsConfigurable_WithSixtySecondDefault()
{
// Regression test for DataConnectionLayer-009. The unstable-disconnect failover
// Regression test: the unstable-disconnect failover
// path used a hard-coded 60s StableConnectionThreshold constant inside
// DataConnectionActor. It must live on DataConnectionOptions like the other
// tunables (ReconnectInterval, TagResolutionRetryInterval, WriteTimeout) so it
@@ -171,7 +180,7 @@ public class DataConnectionOptionsStabilityTests
}
/// <summary>
/// WP-7: Tests for OPC UA adapter.
/// Tests for the OPC UA adapter.
/// </summary>
public class OpcUaDataConnectionTests
{
@@ -179,6 +188,7 @@ public class OpcUaDataConnectionTests
private readonly IOpcUaClientFactory _mockFactory;
private readonly OpcUaDataConnection _adapter;
/// <summary>Initializes the mocked OPC UA client and the adapter under test.</summary>
public OpcUaDataConnectionTests()
{
_mockClient = Substitute.For<IOpcUaClient>();
@@ -187,6 +197,8 @@ public class OpcUaDataConnectionTests
_adapter = new OpcUaDataConnection(_mockFactory, NullLogger<OpcUaDataConnection>.Instance);
}
/// <summary>Verifies that connecting sets the status to connected.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_SetsStatusToConnected()
{
@@ -201,6 +213,8 @@ public class OpcUaDataConnectionTests
await _mockClient.Received(1).ConnectAsync("opc.tcp://localhost:4840", Arg.Any<OpcUaConnectionOptions?>(), Arg.Any<CancellationToken>());
}
/// <summary>Verifies that disconnecting sets the status to disconnected.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Disconnect_SetsStatusToDisconnected()
{
@@ -211,10 +225,12 @@ public class OpcUaDataConnectionTests
Assert.Equal(ConnectionHealth.Disconnected, _adapter.Status);
}
/// <summary>Verifies that concurrent connection-lost notifications raise the disconnected event exactly once.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DCL013_ConcurrentConnectionLost_RaisesDisconnectedExactlyOnce()
{
// Regression test for DataConnectionLayer-013. RaiseDisconnected used a
// Regression test: RaiseDisconnected used a
// non-atomic check-then-set on a volatile bool: two threads racing through it
// (e.g. the keep-alive thread and a ReadAsync failure path, both routed via
// OnClientConnectionLost) could both observe _disconnectFired == false and both
@@ -250,6 +266,8 @@ public class OpcUaDataConnectionTests
}
}
/// <summary>Verifies that subscribing delegates to the client and returns the subscription id.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Subscribe_DelegatesAndReturnsId()
{
@@ -263,6 +281,8 @@ public class OpcUaDataConnectionTests
Assert.Equal("sub-001", subId);
}
/// <summary>Verifies that a successful write returns a good result.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Write_Success_ReturnsGoodResult()
{
@@ -277,6 +297,8 @@ public class OpcUaDataConnectionTests
Assert.Null(result.ErrorMessage);
}
/// <summary>Verifies that a failed write returns an error result.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Write_Failure_ReturnsError()
{
@@ -291,6 +313,8 @@ public class OpcUaDataConnectionTests
Assert.Contains("0x80000000", result.ErrorMessage);
}
/// <summary>Verifies that reading a value with a bad status returns a bad result.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Read_BadStatus_ReturnsBadResult()
{
@@ -304,6 +328,8 @@ public class OpcUaDataConnectionTests
Assert.False(result.Success);
}
/// <summary>Verifies that reading a value with a good status returns the value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Read_GoodStatus_ReturnsValue()
{
@@ -320,10 +346,12 @@ public class OpcUaDataConnectionTests
Assert.Equal(QualityCode.Good, result.Value.Quality);
}
/// <summary>Verifies that a batch read returns a value for every requested tag.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ReadBatch_ReadsAllTags()
{
// WP2.1b: ReadBatchAsync is TRUE bulk — ONE client ReadValuesAsync call carrying
// ReadBatchAsync is TRUE bulk — ONE client ReadValuesAsync call carrying
// every requested node, not a per-tag loop.
_mockClient.IsConnected.Returns(true);
_mockClient.ReadValuesAsync(Arg.Any<IReadOnlyList<string>>(), Arg.Any<CancellationToken>())
@@ -340,10 +368,12 @@ public class OpcUaDataConnectionTests
Assert.Single(_mockClient.ReceivedCalls(), c => c.GetMethodInfo().Name == "ReadValuesAsync");
}
/// <summary>Verifies that a batch read returns per-tag results when one tag fails.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DCL007_ReadBatch_ReturnsPerTagResults_WhenOneTagFails()
{
// Regression test for DataConnectionLayer-007. ReadBatchAsync originally looped
// Regression test: ReadBatchAsync originally looped
// calling ReadAsync per tag; ReadAsync re-throws any non-cancellation exception, so
// a single failing tag aborted the whole batch and the caller got NO results for
// the tags that did read successfully — even though ReadResult already carries a
@@ -372,13 +402,15 @@ public class OpcUaDataConnectionTests
Assert.NotNull(results["bad"].ErrorMessage);
}
/// <summary>Verifies that a batch write returns per-tag results when some tags fail.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DCL017_WriteBatch_ReturnsPerTagResults_WhenSomeTagsFail()
{
// Regression test for DataConnectionLayer-017. WriteBatchAsync originally looped
// Regression test: WriteBatchAsync originally looped
// calling WriteAsync per tag; a mid-batch fault made the whole call throw and the
// caller lost the per-tag outcomes for the tags that already wrote. The batch is
// now ONE bulk service call (WP2.1b), and the invariant is unchanged: per-node
// now ONE bulk service call, and the invariant is unchanged: per-node
// failures are reported as failed WriteResult rows and every requested tag is
// present in the returned map.
_mockClient.IsConnected.Returns(true);
@@ -411,6 +443,8 @@ public class OpcUaDataConnectionTests
Assert.Single(_mockClient.ReceivedCalls(), c => c.GetMethodInfo().Name == "WriteValuesAsync");
}
/// <summary>Verifies that cancellation aborts the whole batch write.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DCL017_WriteBatch_CancellationAbortsWholeBatch()
{
@@ -429,6 +463,8 @@ public class OpcUaDataConnectionTests
_adapter.WriteBatchAsync(new Dictionary<string, object?> { ["tag1"] = 1 }, cts.Token));
}
/// <summary>Verifies that operations throw when the adapter is not connected.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task NotConnected_ThrowsOnOperations()
{
@@ -438,6 +474,8 @@ public class OpcUaDataConnectionTests
_adapter.ReadAsync("tag1"));
}
/// <summary>Verifies that disposing the adapter cleans up its resources.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DisposeAsync_CleansUp()
{
@@ -450,6 +488,8 @@ public class OpcUaDataConnectionTests
// --- Configuration Parsing ---
/// <summary>Verifies that connecting parses every supported configuration key.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_ParsesAllConfigurationKeys()
{
@@ -487,6 +527,8 @@ public class OpcUaDataConnectionTests
Arg.Any<CancellationToken>());
}
/// <summary>Verifies that connecting uses default values when the configuration keys are not provided.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_UsesDefaults_WhenKeysNotProvided()
{
@@ -511,6 +553,8 @@ public class OpcUaDataConnectionTests
Arg.Any<CancellationToken>());
}
/// <summary>Verifies that connecting ignores invalid numeric configuration values.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_IgnoresInvalidNumericValues()
{
@@ -535,6 +579,8 @@ public class OpcUaDataConnectionTests
Arg.Any<CancellationToken>());
}
/// <summary>Verifies that connecting parses the security mode configuration value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_ParsesSecurityMode()
{
@@ -551,6 +597,8 @@ public class OpcUaDataConnectionTests
Arg.Any<CancellationToken>());
}
/// <summary>Verifies that connecting parses the automatic certificate acceptance setting.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Connect_ParsesAutoAcceptCerts()
{
@@ -573,6 +621,8 @@ public class OpcUaDataConnectionTests
// one, leaking its session/keep-alive/socket per flap AND leaving its stale
// ConnectionLost handler wired — so a late keep-alive death on the OLD client
// flapped the NEW healthy session (after _disconnectFired was reset).
/// <summary>Verifies that reconnecting disposes the previous client and detaches its handlers.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Reconnect_DisposesAndDetachesPreviousClient()
{
@@ -593,6 +643,8 @@ public class OpcUaDataConnectionTests
await clients[1].DidNotReceive().DisposeAsync();
}
/// <summary>Verifies that a connection-lost event from a stale client does not raise a disconnect after a reconnect.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task StaleClientConnectionLost_DoesNotRaiseDisconnected_AfterReconnect()
{