docs: complete XML doc comments via fixdocs (2757 to 131 findings)

Add missing <returns>/<param>/<summary>/<typeparam> tags and clean up
misused inheritdoc across 481 files so the documented API surface is
complete. Documentation-only (zero code lines changed). The 131 remaining
findings are inheritdoc-style warnings deliberately left to preserve
hand-written implementation rationale (plan-decision notes, race-condition
explanations).
This commit is contained in:
Joseph Doherty
2026-06-03 12:34:34 -04:00
parent c6d9b20d9f
commit bd6c0b4d3d
481 changed files with 2550 additions and 1668 deletions
@@ -175,10 +175,7 @@ public sealed class DriverHostActorReconcileTests : RuntimeActorTestBase
/// <param name="supportedType">The driver type this factory supports.</param>
public CountingDriverFactory(string supportedType) { _supportedType = supportedType; }
/// <summary>Attempts to create a driver if the type is supported.</summary>
/// <param name="driverType">The driver type to create.</param>
/// <param name="driverInstanceId">The unique identifier for the driver instance.</param>
/// <param name="driverConfigJson">The driver configuration in JSON format.</param>
/// <inheritdoc />
public IDriver? TryCreate(string driverType, string driverInstanceId, string driverConfigJson)
{
if (!string.Equals(driverType, _supportedType, StringComparison.Ordinal)) return null;
@@ -12,6 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
public sealed class DriverInstanceActorTests : RuntimeActorTestBase
{
/// <summary>Verifies that ApplyDelta calls ReinitializeAsync when connected and replies success.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyDelta_when_Connected_calls_ReinitializeAsync_and_replies_success()
{
@@ -48,6 +49,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that writing to a non-IWritable driver returns failure.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Write_against_non_IWritable_driver_returns_failure()
{
@@ -66,6 +68,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that writing to an IWritable driver returns success when status is Good.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Write_against_IWritable_returns_success_when_status_is_Good()
{
@@ -85,6 +88,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that write propagates status code on Bad result.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Write_propagates_status_code_on_Bad_result()
{
@@ -104,6 +108,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that subscribing to an ISubscribable driver forwards OnDataChange to parent.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Subscribe_against_ISubscribable_forwards_OnDataChange_to_parent()
{
@@ -129,6 +134,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that subscribe translates OPC UA status severity bits to OpcUaQuality.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Subscribe_translates_OPC_UA_status_severity_bits_to_OpcUaQuality()
{
@@ -153,6 +159,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that subscribing to a non-ISubscribable driver replies with failure.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Subscribe_against_non_ISubscribable_replies_with_failure()
{
@@ -170,6 +177,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that DisconnectObserved detaches subscription handler so late events are dropped.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DisconnectObserved_detaches_subscription_handler_so_late_events_are_dropped()
{
@@ -201,14 +209,12 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
/// <summary>Gets the number of times reinitialization was called.</summary>
public int ReinitializeCount;
/// <summary>Gets the driver instance ID.</summary>
/// <inheritdoc />
public string DriverInstanceId => "stub-driver-1";
/// <summary>Gets the driver type.</summary>
/// <inheritdoc />
public string DriverType => "Stub";
/// <summary>Initializes the driver with the specified configuration JSON.</summary>
/// <param name="driverConfigJson">The driver configuration JSON.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task InitializeAsync(string driverConfigJson, CancellationToken cancellationToken)
{
Interlocked.Increment(ref InitializeCount);
@@ -216,24 +222,20 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
return Task.CompletedTask;
}
/// <summary>Reinitializes the driver with the specified configuration JSON.</summary>
/// <param name="driverConfigJson">The driver configuration JSON.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task ReinitializeAsync(string driverConfigJson, CancellationToken cancellationToken)
{
Interlocked.Increment(ref ReinitializeCount);
return Task.CompletedTask;
}
/// <summary>Shuts down the driver.</summary>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task ShutdownAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <summary>Gets the health status of the driver.</summary>
/// <inheritdoc />
public DriverHealth GetHealth() => new(DriverState.Healthy, DateTime.UtcNow, null);
/// <summary>Gets the memory footprint of the driver.</summary>
/// <inheritdoc />
public long GetMemoryFootprint() => 0;
/// <summary>Flushes optional caches in the driver.</summary>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task FlushOptionalCachesAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
@@ -244,9 +246,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
/// <summary>Gets the list of write requests received.</summary>
public List<WriteRequest> Writes { get; } = new();
/// <summary>Writes the specified requests.</summary>
/// <param name="writes">The write requests.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task<IReadOnlyList<WriteResult>> WriteAsync(
IReadOnlyList<WriteRequest> writes, CancellationToken cancellationToken)
{
@@ -266,17 +266,12 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
/// <summary>Gets the number of subscribers to OnDataChange.</summary>
public int OnDataChangeSubscriberCount => OnDataChange?.GetInvocationList().Length ?? 0;
/// <summary>Subscribes to the specified full references.</summary>
/// <param name="fullReferences">The full references to subscribe to.</param>
/// <param name="publishingInterval">The publishing interval.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task<ISubscriptionHandle> SubscribeAsync(
IReadOnlyList<string> fullReferences, TimeSpan publishingInterval, CancellationToken cancellationToken)
=> Task.FromResult<ISubscriptionHandle>(_handle);
/// <summary>Unsubscribes from the specified subscription handle.</summary>
/// <param name="handle">The subscription handle.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <inheritdoc />
public Task UnsubscribeAsync(ISubscriptionHandle handle, CancellationToken cancellationToken)
=> Task.CompletedTask;
@@ -292,7 +287,7 @@ public sealed class DriverInstanceActorTests : RuntimeActorTestBase
private sealed class StubHandle : ISubscriptionHandle
{
/// <summary>Gets the diagnostic ID of the subscription.</summary>
/// <inheritdoc />
public string DiagnosticId => "stub-sub";
}
}
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Health;
public sealed class HealthProbeActorTests : RuntimeActorTestBase
{
/// <summary>Verifies that the DB health probe actor returns reachable status against an in-memory database.</summary>
/// <returns>A task that represents the asynchronous test operation.</returns>
[Fact]
public async Task DbHealthProbeActor_returns_reachable_against_in_memory_db()
{
@@ -92,6 +93,7 @@ public sealed class HealthProbeActorTests : RuntimeActorTestBase
}
/// <summary>Verifies that the historian adapter actor returns sink status via GetStatus.</summary>
/// <returns>A task that represents the asynchronous test operation.</returns>
[Fact]
public async Task HistorianAdapterActor_returns_sink_status_via_GetStatus()
{
@@ -115,16 +117,14 @@ public sealed class HealthProbeActorTests : RuntimeActorTestBase
/// <summary>Gets the list of enqueued alarm historian events.</summary>
public ConcurrentBag<AlarmHistorianEvent> Enqueued { get; } = [];
/// <summary>Enqueues an alarm historian event.</summary>
/// <param name="evt">The event to enqueue.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <inheritdoc />
public Task EnqueueAsync(AlarmHistorianEvent evt, CancellationToken cancellationToken)
{
Enqueued.Add(evt);
return Task.CompletedTask;
}
/// <summary>Gets the current status of the historian sink.</summary>
/// <inheritdoc />
public HistorianSinkStatus GetStatus() => new(
QueueDepth: Enqueued.Count,
DeadLetterDepth: 0,
@@ -128,6 +128,7 @@ public sealed class OtOpcUaTelemetryHookTests : RuntimeActorTestBase
/// <summary>Gets count of measurements with the specified tag key-value pair.</summary>
/// <param name="key">Tag key.</param>
/// <param name="value">Tag value.</param>
/// <returns>The count of matching measurements.</returns>
public int WithTag(string key, string value)
{
lock (_gate)
@@ -177,10 +178,7 @@ public sealed class OtOpcUaTelemetryHookTests : RuntimeActorTestBase
private sealed class ConstEval(object? value) : IVirtualTagEvaluator
{
/// <summary>Evaluates the virtual tag with a constant value.</summary>
/// <param name="virtualTagId">Virtual tag ID.</param>
/// <param name="expression">Expression to evaluate.</param>
/// <param name="dependencies">Dependency values.</param>
/// <inheritdoc />
public VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary<string, object?> dependencies)
=> VirtualTagEvalResult.Ok(value);
}
@@ -189,30 +187,15 @@ public sealed class OtOpcUaTelemetryHookTests : RuntimeActorTestBase
{
/// <summary>Gets the write count.</summary>
public int Writes { get; private set; }
/// <summary>Records a value write.</summary>
/// <param name="nodeId">The OPC UA node identifier.</param>
/// <param name="value">The value being written.</param>
/// <param name="quality">The OPC UA quality status.</param>
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
/// <inheritdoc />
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) => Writes++;
/// <summary>Records an alarm state write.</summary>
/// <param name="alarmNodeId">The alarm node identifier.</param>
/// <param name="active">Whether the alarm is active.</param>
/// <param name="acknowledged">Whether the alarm is acknowledged.</param>
/// <param name="occurredUtc">The time the alarm occurred in UTC.</param>
/// <inheritdoc />
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime occurredUtc) => Writes++;
/// <summary>Ensures folder exists (stub implementation).</summary>
/// <param name="folderNodeId">The folder node identifier.</param>
/// <param name="parentNodeId">The parent folder node identifier.</param>
/// <param name="displayName">The display name for the folder.</param>
/// <inheritdoc />
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
/// <summary>Ensures variable exists (stub implementation).</summary>
/// <param name="variableNodeId">The variable node identifier.</param>
/// <param name="parentFolderNodeId">The parent folder node identifier.</param>
/// <param name="displayName">The display name for the variable.</param>
/// <param name="dataType">The OPC UA built-in type name.</param>
/// <inheritdoc />
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) { }
/// <summary>Rebuilds address space (recorded via span).</summary>
/// <inheritdoc />
public void RebuildAddressSpace() { /* recorded via span */ }
}
}
@@ -160,36 +160,21 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
public List<(string AlarmNodeId, bool Active, bool Acknowledged, DateTime Ts)> Alarms =>
AlarmQueue.ToList();
/// <summary>Records a value update.</summary>
/// <param name="nodeId">The OPC UA node identifier.</param>
/// <param name="value">The attribute value.</param>
/// <param name="quality">The OPC UA quality code.</param>
/// <param name="ts">The timestamp of the update.</param>
/// <inheritdoc />
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime ts) =>
ValueQueue.Enqueue((nodeId, value, quality, ts));
/// <summary>Records an alarm state update.</summary>
/// <param name="alarmNodeId">The OPC UA alarm node identifier.</param>
/// <param name="active">Whether the alarm is active.</param>
/// <param name="acknowledged">Whether the alarm is acknowledged.</param>
/// <param name="ts">The timestamp of the update.</param>
/// <inheritdoc />
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime ts) =>
AlarmQueue.Enqueue((alarmNodeId, active, acknowledged, ts));
/// <summary>Ensures a folder exists (no-op in test).</summary>
/// <param name="folderNodeId">The OPC UA folder node identifier.</param>
/// <param name="parentNodeId">The parent folder node identifier, or null for root.</param>
/// <param name="displayName">The display name of the folder.</param>
/// <inheritdoc />
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
/// <summary>Ensures a variable exists (no-op in test).</summary>
/// <param name="variableNodeId">The OPC UA variable node identifier.</param>
/// <param name="parentFolderNodeId">The parent folder node identifier, or null for root.</param>
/// <param name="displayName">The display name of the variable.</param>
/// <param name="dataType">The OPC UA built-in type name.</param>
/// <inheritdoc />
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) { }
/// <summary>Records a rebuild call.</summary>
/// <inheritdoc />
public void RebuildAddressSpace() => Interlocked.Increment(ref RebuildCalls);
}
@@ -199,8 +184,7 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
private readonly ConcurrentQueue<byte> _q = new();
/// <summary>Gets the recorded service levels.</summary>
public byte[] Levels => _q.ToArray();
/// <summary>Records a service level publish.</summary>
/// <param name="serviceLevel">The service level value to publish.</param>
/// <inheritdoc />
public void Publish(byte serviceLevel) => _q.Enqueue(serviceLevel);
}
}
@@ -25,6 +25,7 @@ public sealed class ServiceLevelEndToEndTests : RuntimeActorTestBase
private static CancellationToken Ct => CancellationToken.None;
/// <summary>Verifies that the primary cluster leader sets Server ServiceLevel to 240.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Primary_leader_drives_Server_ServiceLevel_to_240()
{
@@ -65,6 +66,7 @@ public sealed class ServiceLevelEndToEndTests : RuntimeActorTestBase
}
/// <summary>Verifies that the secondary node sets Server ServiceLevel to 100.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Secondary_drives_Server_ServiceLevel_to_100()
{
@@ -13,6 +13,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.ScriptedAlarms;
public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
{
/// <summary>Verifies that alarm state transitions write to the state store with the correct lastAckUser value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Transition_writes_to_state_store_with_lastAckUser()
{
@@ -39,6 +40,7 @@ public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
}
/// <summary>Verifies that actor restart restores persisted state so pending acknowledgment is not dropped.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task PreStart_restores_persisted_state_so_restart_does_not_drop_pending_ack()
{
@@ -64,6 +66,7 @@ public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
}
/// <summary>Verifies that alarm boots to inactive state when no persisted state exists.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task PreStart_with_no_persisted_state_boots_inactive()
{
@@ -80,6 +83,7 @@ public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
}
/// <summary>Verifies that EF-based alarm actor state store correctly persists and restores state through the config database.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EfAlarmActorStateStore_round_trip_persists_via_ConfigDb()
{
@@ -118,6 +122,7 @@ public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
}
/// <summary>Verifies that loading an alarm state for a missing ID returns null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EfAlarmActorStateStore_load_for_missing_id_returns_null()
{
@@ -136,17 +141,11 @@ public sealed class ScriptedAlarmStatePersistenceTests : RuntimeActorTestBase
/// <summary>Gets all saved alarm state snapshots in order.</summary>
public List<AlarmActorStateSnapshot> Snapshots => _saves.ToList();
/// <summary>Loads the alarm state snapshot for the specified alarm ID.</summary>
/// <param name="alarmId">The alarm ID.</param>
/// <param name="ct">The cancellation token.</param>
/// <returns>The alarm state snapshot if found, null otherwise.</returns>
/// <inheritdoc />
public Task<AlarmActorStateSnapshot?> LoadAsync(string alarmId, CancellationToken ct)
=> Task.FromResult(_byId.TryGetValue(alarmId, out var v) ? v : null);
/// <summary>Saves the alarm state snapshot.</summary>
/// <param name="snapshot">The alarm state snapshot to save.</param>
/// <param name="ct">The cancellation token.</param>
/// <returns>A completed task.</returns>
/// <inheritdoc />
public Task SaveAsync(AlarmActorStateSnapshot snapshot, CancellationToken ct)
{
_byId[snapshot.AlarmId] = snapshot;
@@ -18,6 +18,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests;
public sealed class ServiceCollectionExtensionsTests
{
/// <summary>Verifies that WithOtOpcUaRuntimeActors spawns driver host and DB health probe actors.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WithOtOpcUaRuntimeActors_spawns_driver_host_and_db_health_probe()
{
@@ -72,6 +73,7 @@ public sealed class ServiceCollectionExtensionsTests
private sealed class InMemoryConfigDbFactory(string dbName) : IDbContextFactory<OtOpcUaConfigDbContext>
{
/// <summary>Creates a new in-memory database context.</summary>
/// <returns>A new <see cref="OtOpcUaConfigDbContext"/> instance backed by an in-memory database.</returns>
public OtOpcUaConfigDbContext CreateDbContext()
{
var opts = new DbContextOptionsBuilder<OtOpcUaConfigDbContext>()
@@ -84,22 +86,19 @@ public sealed class ServiceCollectionExtensionsTests
/// <summary>Fake cluster role information for testing.</summary>
private sealed class FakeClusterRoleInfo : IClusterRoleInfo
{
/// <summary>Gets the local node ID.</summary>
/// <inheritdoc />
public NodeId LocalNode { get; } = NodeId.Parse("test-node");
/// <summary>Gets the local roles.</summary>
/// <inheritdoc />
public IReadOnlySet<string> LocalRoles { get; } = new HashSet<string>(["driver"]);
/// <summary>Determines whether the local node has the specified role.</summary>
/// <param name="role">The role to check.</param>
/// <inheritdoc />
public bool HasRole(string role) => LocalRoles.Contains(role);
/// <summary>Gets the members with the specified role.</summary>
/// <param name="role">The role to query.</param>
/// <inheritdoc />
public IReadOnlyList<NodeId> MembersWithRole(string role) => Array.Empty<NodeId>();
/// <summary>Gets the leader node for the specified role.</summary>
/// <param name="role">The role to query.</param>
/// <inheritdoc />
public NodeId? RoleLeader(string role) => null;
/// <summary>Raised when the role leader changes.</summary>
/// <inheritdoc />
public event EventHandler<RoleLeaderChangedEventArgs>? RoleLeaderChanged
{
add { _ = value; }
@@ -155,6 +155,7 @@ public sealed class DependencyMuxActorTests : RuntimeActorTestBase
/// <param name="id">The identifier of the virtual tag.</param>
/// <param name="expression">The expression to evaluate.</param>
/// <param name="deps">A dictionary of dependency values keyed by reference.</param>
/// <returns>A <see cref="ZB.MOM.WW.OtOpcUa.Commons.Engines.VirtualTagEvalResult"/> containing the integer sum of all dependency values.</returns>
public ZB.MOM.WW.OtOpcUa.Commons.Engines.VirtualTagEvalResult Evaluate(
string id, string expression, IReadOnlyDictionary<string, object?> deps)
{
@@ -86,11 +86,7 @@ public sealed class VirtualTagActorTests : RuntimeActorTestBase
/// <summary>Test evaluator that sums integer dependency values.</summary>
private sealed class SumEvaluator : IVirtualTagEvaluator
{
/// <summary>Evaluates the expression by summing integer dependencies.</summary>
/// <param name="id">The tag identifier.</param>
/// <param name="expr">The expression string.</param>
/// <param name="deps">The dependency values.</param>
/// <returns>The sum of integer values in the dependencies.</returns>
/// <inheritdoc />
public VirtualTagEvalResult Evaluate(string id, string expr, IReadOnlyDictionary<string, object?> deps)
{
var sum = deps.Values.OfType<int>().Sum();