docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped

Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
This commit is contained in:
Joseph Doherty
2026-05-28 08:10:17 -04:00
parent f9fc7dd2e1
commit 64e3fbe035
756 changed files with 9876 additions and 96 deletions
@@ -15,9 +15,12 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests;
[Trait("Requires", "AbServer")]
public sealed class AbCipReadSmokeTests
{
/// <summary>Gets the test profiles for the theory tests.</summary>
public static IEnumerable<object[]> Profiles =>
KnownProfiles.All.Select(p => new object[] { p });
/// <summary>Verifies that the driver can read a seeded DInt value from an AB server.</summary>
/// <param name="profile">The AB server profile to test against.</param>
[AbServerTheory]
[MemberData(nameof(Profiles))]
public async Task Driver_reads_seeded_DInt_from_ab_server(AbServerProfile profile)
@@ -31,11 +31,16 @@ public sealed class AbServerFixture : IAsyncLifetime
// 10.100.0.35 = the shared Docker host (see CLAUDE.md "Docker Workflow"). Migrated
// off this VM's 127.0.0.1 on 2026-04-28 alongside the rest of the Docker-host move.
// Override via AB_SERVER_ENDPOINT to point at a real PLC or a locally-running container.
/// <summary>Gets the host address of the AB server.</summary>
public string Host { get; } = "10.100.0.35";
/// <summary>Gets the port of the AB server.</summary>
public int Port { get; } = AbServerProfile.DefaultPort;
/// <summary>Initializes a new instance of the AbServerFixture class with the default profile.</summary>
public AbServerFixture() : this(KnownProfiles.ControlLogix) { }
/// <summary>Initializes a new instance of the AbServerFixture class with the specified profile.</summary>
/// <param name="profile">The AB server profile to use.</param>
public AbServerFixture(AbServerProfile profile)
{
Profile = profile ?? throw new ArgumentNullException(nameof(profile));
@@ -50,7 +55,9 @@ public sealed class AbServerFixture : IAsyncLifetime
}
}
/// <inheritdoc />
public ValueTask InitializeAsync() => ValueTask.CompletedTask;
/// <inheritdoc />
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
/// <summary>
@@ -92,6 +99,7 @@ public sealed class AbServerFixture : IAsyncLifetime
/// </summary>
public sealed class AbServerFactAttribute : FactAttribute
{
/// <summary>Initializes a new instance of the AbServerFactAttribute class.</summary>
public AbServerFactAttribute()
{
if (!AbServerFixture.IsServerAvailable())
@@ -109,6 +117,7 @@ public sealed class AbServerFactAttribute : FactAttribute
/// </summary>
public sealed class AbServerTheoryAttribute : TheoryAttribute
{
/// <summary>Initializes a new instance of the AbServerTheoryAttribute class.</summary>
public AbServerTheoryAttribute()
{
if (!AbServerFixture.IsServerAvailable())
@@ -26,29 +26,37 @@ public sealed record AbServerProfile(
/// <summary>Canonical profiles covering every AB CIP family shipped in PRs 912.</summary>
public static class KnownProfiles
{
/// <summary>Gets all known server profiles.</summary>
public static IReadOnlyList<AbServerProfile> All { get; } =
[ControlLogix, CompactLogix, Micro800, GuardLogix];
/// <summary>Gets the ControlLogix profile.</summary>
public static readonly AbServerProfile ControlLogix = new(
Family: AbCipPlcFamily.ControlLogix,
ComposeProfile: "controllogix",
Notes: "Widest-coverage profile — PR 9 baseline. UDTs unit-tested via golden Template Object buffers; ab_server lacks full UDT emulation.");
/// <summary>Gets the CompactLogix profile.</summary>
public static readonly AbServerProfile CompactLogix = new(
Family: AbCipPlcFamily.CompactLogix,
ComposeProfile: "compactlogix",
Notes: "ab_server doesn't enforce the narrower ConnectionSize; driver-side profile caps it per PR 10.");
/// <summary>Gets the Micro800 profile.</summary>
public static readonly AbServerProfile Micro800 = new(
Family: AbCipPlcFamily.Micro800,
ComposeProfile: "micro800",
Notes: "--plc=Micro800 mode (unconnected-only, empty path). Driver-side enforcement verified in the unit suite.");
/// <summary>Gets the GuardLogix profile.</summary>
public static readonly AbServerProfile GuardLogix = new(
Family: AbCipPlcFamily.GuardLogix,
ComposeProfile: "guardlogix",
Notes: "ab_server has no safety subsystem — _S-suffixed seed tag triggers driver-side ViewOnly classification only.");
public static IReadOnlyList<AbServerProfile> All { get; } =
[ControlLogix, CompactLogix, Micro800, GuardLogix];
/// <summary>Gets the profile for a specific family.</summary>
/// <param name="family">The AB CIP PLC family.</param>
/// <returns>The corresponding server profile.</returns>
public static AbServerProfile ForFamily(AbCipPlcFamily family) =>
All.FirstOrDefault(p => p.Family == family)
?? throw new ArgumentOutOfRangeException(nameof(family), family, "No integration profile for this family.");
@@ -39,6 +39,7 @@ public static class AbServerProfileGate
/// Skip the calling test via <c>Assert.Skip</c> when <see cref="CurrentProfile"/>
/// isn't in <paramref name="requiredProfiles"/>. Case-insensitive match.
/// </summary>
/// <param name="requiredProfiles">The list of profile names to check against the current profile.</param>
public static void SkipUnless(params string[] requiredProfiles)
{
foreach (var p in requiredProfiles)
@@ -14,6 +14,9 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests;
[Trait("Category", "Unit")]
public sealed class AbServerProfileTests
{
/// <summary>Verifies known profiles for family returns expected compose profile.</summary>
/// <param name="family">The AB CIP PLC family.</param>
/// <param name="expected">The expected Docker Compose profile name.</param>
[Theory]
[InlineData(AbCipPlcFamily.ControlLogix, "controllogix")]
[InlineData(AbCipPlcFamily.CompactLogix, "compactlogix")]
@@ -24,6 +27,7 @@ public sealed class AbServerProfileTests
KnownProfiles.ForFamily(family).ComposeProfile.ShouldBe(expected);
}
/// <summary>Verifies known profiles all covers every family.</summary>
[Fact]
public void KnownProfiles_All_Covers_Every_Family()
{
@@ -32,6 +36,7 @@ public sealed class AbServerProfileTests
covered.ShouldContain(family, $"Family {family} is missing a KnownProfiles entry.");
}
/// <summary>Verifies default port matches EtherNetIP standard.</summary>
[Fact]
public void DefaultPort_Matches_EtherNetIP_Standard()
{
@@ -39,6 +39,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests.Emulate;
[Trait("Tier", "Emulate")]
public sealed class AbCipEmulateAlmdTests
{
/// <summary>Verifies that real ALMD raise fires OnAlarmEvent through the driver projection.</summary>
[AbServerFact]
public async Task Real_ALMD_raise_fires_OnAlarmEvent_through_the_driver_projection()
{
@@ -37,6 +37,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests.Emulate;
[Trait("Tier", "Emulate")]
public sealed class AbCipEmulateUdtReadTests
{
/// <summary>Verifies that reading a whole UDT decodes each member at its template object offset.</summary>
[AbServerFact]
public async Task WholeUdt_read_decodes_each_member_at_its_Template_Object_offset()
{