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:
@@ -12,6 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
|
||||
public sealed class ClusterFormationTests
|
||||
{
|
||||
/// <summary>Verifies that two nodes form a 2-member cluster.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Two_nodes_form_a_2_member_cluster()
|
||||
{
|
||||
@@ -29,6 +30,7 @@ public sealed class ClusterFormationTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that both nodes see each other as role members.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Both_nodes_see_each_other_as_role_members()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ public sealed class DeployHappyPathTests
|
||||
private static CancellationToken Ct => TestContext.Current.CancellationToken;
|
||||
|
||||
/// <summary>Verifies that StartDeployment seals after both nodes apply.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task StartDeployment_seals_after_both_nodes_apply()
|
||||
{
|
||||
@@ -55,6 +56,7 @@ public sealed class DeployHappyPathTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that replaying dispatch to same revision is idempotent and a no-op.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Replaying_dispatch_to_same_revision_is_idempotent_no_op()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ public static class DockerFixtureAvailability
|
||||
/// <param name="host">The host to probe.</param>
|
||||
/// <param name="port">The TCP port to connect to.</param>
|
||||
/// <param name="timeoutMs">Maximum time to wait in milliseconds; defaults to 500.</param>
|
||||
/// <returns><see langword="true"/> if the TCP connection succeeded within the timeout; otherwise <see langword="false"/>.</returns>
|
||||
public static bool IsReachable(string host, int port, int timeoutMs = 500)
|
||||
{
|
||||
try
|
||||
@@ -43,6 +44,7 @@ public static class DockerFixtureAvailability
|
||||
/// </summary>
|
||||
/// <param name="endpoint">Endpoint in <c>host:port</c> format.</param>
|
||||
/// <param name="timeoutMs">Maximum time to wait in milliseconds; defaults to 500.</param>
|
||||
/// <returns><see langword="true"/> if the TCP connection succeeded within the timeout; otherwise <see langword="false"/>.</returns>
|
||||
public static bool IsReachable(string endpoint, int timeoutMs = 500)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -32,6 +32,7 @@ public sealed class DriverProbeRegistrationTests
|
||||
"Historian.Wonderware",
|
||||
];
|
||||
|
||||
/// <summary>Verifies that AddOtOpcUaDriverProbes registers a probe for every AdminUI driver type.</summary>
|
||||
[Fact]
|
||||
public void AddOtOpcUaDriverProbes_registers_a_probe_for_every_AdminUI_driver_type()
|
||||
{
|
||||
@@ -49,6 +50,7 @@ public sealed class DriverProbeRegistrationTests
|
||||
byType.ContainsKey(key).ShouldBeTrue($"No IDriverProbe registered for AdminUI driver type '{key}'.");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that AddOtOpcUaDriverProbes is idempotent when called multiple times.</summary>
|
||||
[Fact]
|
||||
public void AddOtOpcUaDriverProbes_is_idempotent()
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ public sealed class DriverReconnectE2eTests
|
||||
/// to a deployed driver, so no <c>DriverInstanceActor</c> will act on the DPS
|
||||
/// broadcast — the test is validating the command ingestion and reply path only.</para>
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Reconnect_RoundTrip_ReturnsOk()
|
||||
{
|
||||
@@ -63,6 +64,7 @@ public sealed class DriverReconnectE2eTests
|
||||
/// is also accepted (idempotent at the actor layer — the actor simply re-broadcasts
|
||||
/// to DPS and writes another <c>ConfigEdit</c> row).
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Reconnect_IsIdempotent_SecondCallAlsoReturnsOk()
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ public sealed class DriverStatusHubE2eTests
|
||||
/// to both the <see cref="IDriverStatusSnapshotStore"/> (via <c>Upsert</c>) and the
|
||||
/// mock <see cref="IHubContext{DriverStatusHub}"/> (via <c>SendAsync</c>).
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task StatusHub_BridgeActor_ForwardsHealthChanged_ToStoreAndHub()
|
||||
{
|
||||
@@ -106,6 +107,7 @@ public sealed class DriverStatusHubE2eTests
|
||||
/// for the same instance ID results in the store holding only the most recent state
|
||||
/// (last-write-wins) and both hub push calls being made.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task StatusHub_BridgeActor_LastSnapshotWins_InStore()
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ public sealed class DriverTestConnectE2eTests
|
||||
/// the <see cref="TestDriverConnectResult"/> reports <c>Ok = true</c> with a
|
||||
/// sub-5 s latency. Skipped when the Docker fixture host is unreachable.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task TestConnect_Modbus_AgainstFixture_ReportsOk()
|
||||
{
|
||||
@@ -74,6 +75,7 @@ public sealed class DriverTestConnectE2eTests
|
||||
/// containing a connection-refused indicator. Skipped when the host is unreachable
|
||||
/// (even a refused connection requires the IP to be routable).
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task TestConnect_Modbus_AgainstWrongPort_ReportsFailure()
|
||||
{
|
||||
@@ -118,6 +120,7 @@ public sealed class DriverTestConnectE2eTests
|
||||
/// <see cref="TestConnect_Modbus_AgainstFixture_ReportsOk"/> (which skips in dev).
|
||||
/// This test does NOT require any Docker fixture and always runs.</para>
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task TestConnect_Modbus_AgainstBlackHole_ReportsTimeout()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ public sealed class FailoverDuringDeployTests
|
||||
private static CancellationToken Ct => TestContext.Current.CancellationToken;
|
||||
|
||||
/// <summary>Verifies that stopping node B shrinks the cluster to one up member.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Stopping_node_b_shrinks_cluster_to_one_up_member()
|
||||
{
|
||||
@@ -34,6 +35,7 @@ public sealed class FailoverDuringDeployTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a restarted node B rejoins the cluster on the same port.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Restarted_node_b_rejoins_cluster_on_same_port()
|
||||
{
|
||||
@@ -51,6 +53,7 @@ public sealed class FailoverDuringDeployTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a deployment started with node B down seals with one-node state.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task Deployment_started_with_node_b_down_seals_with_one_node_state()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ public sealed class FleetDiagnosticsRoundTripTests
|
||||
private static CancellationToken Ct => TestContext.Current.CancellationToken;
|
||||
|
||||
/// <summary>Verifies that get diagnostics returns a snapshot with the target node ID.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task GetDiagnostics_returns_snapshot_with_target_NodeId()
|
||||
{
|
||||
@@ -41,6 +42,7 @@ public sealed class FleetDiagnosticsRoundTripTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that get diagnostics after deploy reports the current revision.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task GetDiagnostics_after_deploy_reports_current_revision()
|
||||
{
|
||||
|
||||
+8
-4
@@ -19,6 +19,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
{
|
||||
/// <summary>On success the data-plane authenticator resolves roles via the mapper from the
|
||||
/// returned Groups — not from the auth result's Roles field — and grants identity.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_LDAP_success_resolves_roles_via_mapper_from_groups()
|
||||
{
|
||||
@@ -37,6 +38,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
|
||||
/// <summary>The DevStub pre-resolved roles (Administrator) survive the move to the mapper: they are
|
||||
/// unioned with the mapper output so the dev grant still reaches the OPC UA session.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_devstub_preresolved_roles_are_unioned_with_mapper()
|
||||
{
|
||||
@@ -54,6 +56,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
|
||||
/// <summary>A mapper fault (e.g. DB outage) must not deny an authenticated session — it falls
|
||||
/// back to the pre-resolved roles, matching the login endpoint's behaviour.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_mapper_fault_falls_back_to_preresolved_roles()
|
||||
{
|
||||
@@ -68,6 +71,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that LDAP authentication failure returns Deny result with error text.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_LDAP_failure_returns_Deny_with_error_text()
|
||||
{
|
||||
@@ -82,6 +86,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that LDAP exceptions are converted to backend error denial results.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_LDAP_exception_returns_backend_error_denial()
|
||||
{
|
||||
@@ -97,6 +102,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
}
|
||||
|
||||
/// <summary>Verifies that authentication falls back to username when LDAP omits display name.</summary>
|
||||
/// <returns>A task that represents the asynchronous test operation.</returns>
|
||||
[Fact]
|
||||
public async Task Authenticate_falls_back_to_username_when_LDAP_omits_display_name()
|
||||
{
|
||||
@@ -131,10 +137,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
/// <param name="handler">The handler to invoke with the username to produce a result.</param>
|
||||
public FakeLdap(Func<string, LdapAuthResult> handler) => _handler = handler;
|
||||
|
||||
/// <summary>Authenticates a user asynchronously via the handler function.</summary>
|
||||
/// <param name="username">The username to authenticate.</param>
|
||||
/// <param name="password">The password (ignored by the fake).</param>
|
||||
/// <param name="ct">Cancellation token for the operation.</param>
|
||||
/// <inheritdoc />
|
||||
public Task<LdapAuthResult> AuthenticateAsync(string username, string password, CancellationToken ct = default)
|
||||
=> Task.FromResult(_handler(username));
|
||||
}
|
||||
@@ -145,6 +148,7 @@ public sealed class LdapOpcUaUserAuthenticatorTests
|
||||
/// <summary>Maps groups to roles via the configured delegate; Scope is always null.</summary>
|
||||
/// <param name="groups">The LDAP groups to map.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>A task that resolves to the group role mapping result.</returns>
|
||||
public Task<GroupRoleMapping<string>> MapAsync(IReadOnlyList<string> groups, CancellationToken ct)
|
||||
=> Task.FromResult(new GroupRoleMapping<string>(map(groups), Scope: null));
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ public sealed class ProdOverlayValidationTests
|
||||
return configuration.GetSection(LdapOptions.SectionName).Get<LdapOptions>() ?? new LdapOptions();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that each production overlay declares the ldaps transport.</summary>
|
||||
/// <param name="fileName">The overlay file name to validate.</param>
|
||||
[Theory]
|
||||
[InlineData("appsettings.admin.json")]
|
||||
[InlineData("appsettings.driver.json")]
|
||||
@@ -100,6 +102,8 @@ public sealed class ProdOverlayValidationTests
|
||||
options.Transport.ShouldBe(LdapTransport.Ldaps);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that each production overlay passes startup validation.</summary>
|
||||
/// <param name="fileName">The overlay file name to validate.</param>
|
||||
[Theory]
|
||||
[InlineData("appsettings.admin.json")]
|
||||
[InlineData("appsettings.driver.json")]
|
||||
@@ -114,6 +118,7 @@ public sealed class ProdOverlayValidationTests
|
||||
Sut.Validate(null, options).Succeeded.ShouldBeTrue();
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the Development overlay passes startup validation via the DevStub exemption.</summary>
|
||||
[Fact]
|
||||
public void Development_overlay_passes_startup_validation_via_devstub_exemption()
|
||||
{
|
||||
|
||||
@@ -77,6 +77,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
|
||||
/// <summary>Boots both nodes and waits up to <paramref name="formationTimeout"/> for cluster convergence.</summary>
|
||||
/// <param name="formationTimeout">Maximum time to wait for cluster formation; defaults to 20 seconds if not provided.</param>
|
||||
/// <returns>A task that resolves to the started two-node cluster harness.</returns>
|
||||
public static async Task<TwoNodeClusterHarness> StartAsync(TimeSpan? formationTimeout = null)
|
||||
{
|
||||
var harness = new TwoNodeClusterHarness();
|
||||
@@ -108,6 +109,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
/// a couple of seconds. Use this for failover scenarios; call <see cref="RestartNodeBAsync"/>
|
||||
/// to bring it back on the same Akka port.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous stop operation.</returns>
|
||||
public async Task StopNodeBAsync()
|
||||
{
|
||||
if (NodeB is null) return;
|
||||
@@ -120,6 +122,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
/// to re-converge to 2 Up members. Use after <see cref="StopNodeBAsync"/> to test rejoin.
|
||||
/// </summary>
|
||||
/// <param name="formationTimeout">The maximum time to wait for cluster formation; defaults to 20 seconds.</param>
|
||||
/// <returns>A task that represents the asynchronous restart operation.</returns>
|
||||
public async Task RestartNodeBAsync(TimeSpan? formationTimeout = null)
|
||||
{
|
||||
NodeB = await BuildNodeAsync(this, NodeRole.Joiner);
|
||||
@@ -136,6 +139,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
/// </summary>
|
||||
/// <param name="expectedUpMembers">The expected number of Up members in the cluster.</param>
|
||||
/// <param name="timeout">The maximum time to wait for the expected cluster size.</param>
|
||||
/// <returns>A task that represents the asynchronous wait operation.</returns>
|
||||
public async Task WaitForClusterSizeAsync(int expectedUpMembers, TimeSpan timeout)
|
||||
{
|
||||
var deadline = DateTime.UtcNow + timeout;
|
||||
@@ -280,6 +284,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
}
|
||||
|
||||
/// <summary>Asynchronously disposes both nodes and cleans up the SQL database if used.</summary>
|
||||
/// <returns>A value task that represents the asynchronous dispose operation.</returns>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (NodeB is not null) await NodeB.DisposeAsync();
|
||||
@@ -303,11 +308,7 @@ public sealed class TwoNodeClusterHarness : IAsyncDisposable
|
||||
|
||||
private sealed class StubLdapAuthService : ILdapAuthService
|
||||
{
|
||||
/// <summary>Asynchronously authenticates a user with the stub LDAP service.</summary>
|
||||
/// <param name="username">The username to authenticate.</param>
|
||||
/// <param name="password">The password to authenticate against.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>A task that returns the LDAP authentication result.</returns>
|
||||
/// <inheritdoc />
|
||||
public Task<LdapAuthResult> AuthenticateAsync(string username, string password, CancellationToken ct = default)
|
||||
=> Task.FromResult(new LdapAuthResult(
|
||||
Success: password == "valid-password",
|
||||
|
||||
Reference in New Issue
Block a user