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
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:
+7
@@ -18,6 +18,9 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests;
|
||||
public sealed class AddressingGrammarTests
|
||||
{
|
||||
private readonly ModbusSimulatorFixture _sim;
|
||||
|
||||
/// <summary>Initializes a new instance of the AddressingGrammarTests class.</summary>
|
||||
/// <param name="sim">The Modbus simulator fixture.</param>
|
||||
public AddressingGrammarTests(ModbusSimulatorFixture sim) => _sim = sim;
|
||||
|
||||
private async Task<ModbusDriver> NewDriverAsync(params ModbusTagDefinition[] tags)
|
||||
@@ -32,6 +35,7 @@ public sealed class AddressingGrammarTests
|
||||
return drv;
|
||||
}
|
||||
|
||||
/// <summary>Verifies that 5-digit and 6-digit Modicon formats map to the same wire offset.</summary>
|
||||
[Fact]
|
||||
public async Task Modicon_5_And_6_Digit_Both_Map_To_Same_Wire_Offset()
|
||||
{
|
||||
@@ -49,6 +53,7 @@ public sealed class AddressingGrammarTests
|
||||
await drv.ShutdownAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Float32 values roundtrip correctly with CDAB byte order.</summary>
|
||||
[Fact]
|
||||
public async Task Float32_With_CDAB_Roundtrips_Through_Wire()
|
||||
{
|
||||
@@ -70,6 +75,7 @@ public sealed class AddressingGrammarTests
|
||||
await drv.ShutdownAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Int16 array reads surface as typed arrays.</summary>
|
||||
[Fact]
|
||||
public async Task Int16_Array_Reads_Surface_As_Typed_Array()
|
||||
{
|
||||
@@ -86,6 +92,7 @@ public sealed class AddressingGrammarTests
|
||||
await drv.ShutdownAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that block read coalescing reduces PDU count end-to-end.</summary>
|
||||
[Fact]
|
||||
public async Task Block_Read_Coalescing_Reduces_PDU_Count_End_To_End()
|
||||
{
|
||||
|
||||
+1
@@ -14,6 +14,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205BcdQuirkTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies DL205 binary-coded-decimal register decodes as decimal value 1234.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_BCD16_decodes_HR1072_as_decimal_1234()
|
||||
{
|
||||
|
||||
+3
@@ -14,6 +14,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205CoilMappingTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DirectLOGIC Y0 output maps to Modbus coil 2048.</summary>
|
||||
[Fact]
|
||||
public async Task DL260_Y0_maps_to_coil_2048()
|
||||
{
|
||||
@@ -40,6 +41,7 @@ public sealed class DL205CoilMappingTests(ModbusSimulatorFixture sim)
|
||||
results[0].Value.ShouldBe(true, "dl205.json seeds coil 2048 (Y0) = ON");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that DirectLOGIC C0 relay maps to Modbus coil 3072.</summary>
|
||||
[Fact]
|
||||
public async Task DL260_C0_maps_to_coil_3072()
|
||||
{
|
||||
@@ -66,6 +68,7 @@ public sealed class DL205CoilMappingTests(ModbusSimulatorFixture sim)
|
||||
results[0].Value.ShouldBe(true, "dl205.json seeds coil 3072 (C0) = ON");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a scratch DirectLOGIC C relay supports write and read operations.</summary>
|
||||
[Fact]
|
||||
public async Task DL260_scratch_Crelay_supports_write_then_read()
|
||||
{
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205ExceptionCodeTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL205 FC03 reads at unmapped registers return BadOutOfRange status.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_FC03_at_unmapped_register_returns_BadOutOfRange()
|
||||
{
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205FloatCdabQuirkTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL205 float32 CDAB word order correctly decodes 1.5f from HR1056.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_Float32_CDAB_decodes_1_5f_from_HR1056()
|
||||
{
|
||||
|
||||
@@ -27,6 +27,10 @@ public static class DL205Profile
|
||||
/// <summary>Value the smoke test writes then reads back to assert round-trip integrity.</summary>
|
||||
public const short SmokeHoldingValue = 1234;
|
||||
|
||||
/// <summary>Builds Modbus driver options for the DL205 test profile.</summary>
|
||||
/// <param name="host">The host or IP address of the Modbus device.</param>
|
||||
/// <param name="port">The port number of the Modbus device.</param>
|
||||
/// <returns>Configured Modbus driver options for DL205.</returns>
|
||||
public static ModbusDriverOptions BuildOptions(string host, int port) => new()
|
||||
{
|
||||
Host = host,
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205SmokeTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL205 roundtrip write then read of holding register succeeds.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_roundtrip_write_then_read_of_holding_register()
|
||||
{
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205StringQuirkTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL205 low-byte-first string packing correctly decodes "Hello" from HR1040.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_string_low_byte_first_decodes_Hello_from_HR1040()
|
||||
{
|
||||
|
||||
+2
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205VMemoryQuirkTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL205 V2000 user memory octal address resolves to PDU address 0x0400.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_V2000_user_memory_resolves_to_PDU_0x0400_marker()
|
||||
{
|
||||
@@ -51,6 +52,7 @@ public sealed class DL205VMemoryQuirkTests(ModbusSimulatorFixture sim)
|
||||
results[0].Value.ShouldBe((ushort)0x2000, "dl205.json seeds HR[0x0400] with marker 0x2000 (= V2000 value)");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that DL205 V40400 system memory address resolves to PDU address 0x2100.</summary>
|
||||
[Fact]
|
||||
public async Task DL205_V40400_system_memory_resolves_to_PDU_0x2100_marker()
|
||||
{
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205;
|
||||
[Trait("Device", "DL205")]
|
||||
public sealed class DL205XInputTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that DL260 X20 octal maps to discrete input 16 and reads the ON state.</summary>
|
||||
[Fact]
|
||||
public async Task DL260_X20_octal_maps_to_DiscreteInput_16_and_reads_ON()
|
||||
{
|
||||
|
||||
+9
@@ -60,6 +60,10 @@ public sealed class ExceptionInjectionTests(ModbusSimulatorFixture sim)
|
||||
return await driver.ReadAsync([tagName], TestContext.Current.CancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Modbus FC03 reads at injected exception addresses surface the expected OPC UA status codes.</summary>
|
||||
/// <param name="address">The Modbus register address to read.</param>
|
||||
/// <param name="expectedStatus">The expected OPC UA status code.</param>
|
||||
/// <param name="scenario">Scenario description for assertion messages.</param>
|
||||
[Theory]
|
||||
[InlineData(1000, StatusBadNotSupported, "exc 0x01 (Illegal Function) -> BadNotSupported")]
|
||||
[InlineData(1001, StatusBadOutOfRange, "exc 0x02 (Illegal Data Address) -> BadOutOfRange")]
|
||||
@@ -77,6 +81,7 @@ public sealed class ExceptionInjectionTests(ModbusSimulatorFixture sim)
|
||||
results[0].StatusCode.ShouldBe(expectedStatus, scenario);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that reads at non-injected addresses return Good status.</summary>
|
||||
[Fact]
|
||||
public async Task FC03_read_at_non_injected_address_returns_Good()
|
||||
{
|
||||
@@ -89,6 +94,10 @@ public sealed class ExceptionInjectionTests(ModbusSimulatorFixture sim)
|
||||
results[0].Value.ShouldBe((ushort)5);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Modbus FC06 writes at injected exception addresses surface the expected OPC UA status codes.</summary>
|
||||
/// <param name="address">The Modbus register address to write.</param>
|
||||
/// <param name="expectedStatus">The expected OPC UA status code.</param>
|
||||
/// <param name="scenario">Scenario description for assertion messages.</param>
|
||||
[Theory]
|
||||
[InlineData(2000, StatusBadDeviceFailure, "exc 0x04 on FC06 -> BadDeviceFailure (CPU in PROGRAM mode)")]
|
||||
[InlineData(2001, StatusBadDeviceFailure, "exc 0x06 on FC06 -> BadDeviceFailure (Server Busy)")]
|
||||
|
||||
+3
@@ -23,6 +23,9 @@ public static class MitsubishiProfile
|
||||
/// <summary>Value the smoke test writes then reads back.</summary>
|
||||
public const short SmokeHoldingValue = 7890;
|
||||
|
||||
/// <summary>Builds Modbus driver options configured for the Mitsubishi profile.</summary>
|
||||
/// <param name="host">The Modbus server hostname or IP address.</param>
|
||||
/// <param name="port">The Modbus server port number.</param>
|
||||
public static ModbusDriverOptions BuildOptions(string host, int port) => new()
|
||||
{
|
||||
Host = host,
|
||||
|
||||
+7
@@ -19,6 +19,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.Mitsubishi;
|
||||
[Trait("Device", "Mitsubishi")]
|
||||
public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that Mitsubishi D0 register fingerprint reads the expected value 0x1234.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_D0_fingerprint_reads_0x1234()
|
||||
{
|
||||
@@ -34,6 +35,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
r[0].Value.ShouldBe((ushort)0x1234);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Mitsubishi Float32 with CDAB word order decodes correctly to 1.5 from D100.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_Float32_CDAB_decodes_1_5f_from_D100()
|
||||
{
|
||||
@@ -59,6 +61,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
r[1].Value.ShouldNotBe(1.5f, "same wire with BigEndian must decode to a different value");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Mitsubishi D registers store binary values, not BCD.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_D10_is_binary_not_BCD()
|
||||
{
|
||||
@@ -77,6 +80,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
r[0].Value.ShouldBe((short)1234, "MELSEC stores numeric D-register values in binary; 0x04D2 = 1234");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that reading a binary D register as BCD throws when the value contains non-decimal nibbles.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_D10_as_BCD_throws_because_nibble_is_non_decimal()
|
||||
{
|
||||
@@ -97,6 +101,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
r[0].StatusCode.ShouldNotBe(0u, "BCD decode of binary 0x04D2 must fail loudly because nibble D is non-BCD");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Mitsubishi Q/L/iQ-R X inputs use hex addressing and X210 maps correctly.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_QLiQR_X210_hex_maps_to_DI_528_reads_ON()
|
||||
{
|
||||
@@ -117,6 +122,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
r[0].Value.ShouldBe(true);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that X input address mapping differs between Mitsubishi MELSEC families (Q vs FX).</summary>
|
||||
[Fact]
|
||||
public void Mitsubishi_family_trap_X20_differs_on_Q_vs_FX()
|
||||
{
|
||||
@@ -127,6 +133,7 @@ public sealed class MitsubishiQuirkTests(ModbusSimulatorFixture sim)
|
||||
MelsecAddress.XInputToDiscrete("X20", MelsecFamily.F_iQF).ShouldBe((ushort)16);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that Mitsubishi M512 relay maps to coil address 512 and reads ON.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_M512_maps_to_coil_512_reads_ON()
|
||||
{
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.Mitsubishi;
|
||||
[Trait("Device", "Mitsubishi")]
|
||||
public sealed class MitsubishiSmokeTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies end-to-end write and read of a Mitsubishi holding register via the Modbus driver.</summary>
|
||||
[Fact]
|
||||
public async Task Mitsubishi_roundtrip_write_then_read_of_holding_register()
|
||||
{
|
||||
|
||||
+7
@@ -36,10 +36,16 @@ public sealed class ModbusSimulatorFixture : IAsyncDisposable
|
||||
private const string DefaultEndpoint = "10.100.0.35:5020";
|
||||
private const string EndpointEnvVar = "MODBUS_SIM_ENDPOINT";
|
||||
|
||||
/// <summary>Gets the host address of the Modbus simulator.</summary>
|
||||
public string Host { get; }
|
||||
|
||||
/// <summary>Gets the port of the Modbus simulator.</summary>
|
||||
public int Port { get; }
|
||||
|
||||
/// <summary>Gets the skip reason if the simulator is unreachable; otherwise null.</summary>
|
||||
public string? SkipReason { get; }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="ModbusSimulatorFixture"/> class.</summary>
|
||||
public ModbusSimulatorFixture()
|
||||
{
|
||||
var raw = Environment.GetEnvironmentVariable(EndpointEnvVar) ?? DefaultEndpoint;
|
||||
@@ -76,6 +82,7 @@ public sealed class ModbusSimulatorFixture : IAsyncDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ public static class S7_1500Profile
|
||||
/// <summary>Value the smoke test writes then reads back.</summary>
|
||||
public const short SmokeHoldingValue = 4321;
|
||||
|
||||
/// <summary>Builds Modbus driver options for the S7-1500 profile.</summary>
|
||||
/// <param name="host">The host address of the Modbus device.</param>
|
||||
/// <param name="port">The port number of the Modbus device.</param>
|
||||
/// <returns>The configured Modbus driver options.</returns>
|
||||
public static ModbusDriverOptions BuildOptions(string host, int port) => new()
|
||||
{
|
||||
Host = host,
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.S7;
|
||||
[Trait("Device", "S7")]
|
||||
public sealed class S7_1500SmokeTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that an S7-1500 roundtrip write then read of a holding register succeeds.</summary>
|
||||
[Fact]
|
||||
public async Task S7_1500_roundtrip_write_then_read_of_holding_register()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.S7;
|
||||
[Trait("Device", "S7")]
|
||||
public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
|
||||
{
|
||||
/// <summary>Verifies that S7 Float32 with ABCD byte order correctly decodes 1.5f from HR100.</summary>
|
||||
[Fact]
|
||||
public async Task S7_Float32_ABCD_decodes_1_5f_from_HR100()
|
||||
{
|
||||
@@ -61,6 +62,7 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
|
||||
results[1].Value.ShouldNotBe(1.5f, "applying CDAB swap to S7 ABCD bytes must produce a different value — confirms the flag is not a no-op and S7 profile default must be BigEndian");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that S7 Int32 with ABCD byte order correctly decodes 0x12345678 from HR300.</summary>
|
||||
[Fact]
|
||||
public async Task S7_Int32_ABCD_decodes_0x12345678_from_HR300()
|
||||
{
|
||||
@@ -95,6 +97,7 @@ public sealed class S7_ByteOrderTests(ModbusSimulatorFixture sim)
|
||||
"S7 Int32 stored as HR[300]=0x1234, HR[301]=0x5678 with ABCD order decodes to 0x12345678 — DL260 would store the reverse order");
|
||||
}
|
||||
|
||||
/// <summary>Verifies that S7 DB1 fingerprint marker reads 0xABCD from HR0.</summary>
|
||||
[Fact]
|
||||
public async Task S7_DB1_fingerprint_marker_at_HR0_reads_0xABCD()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user