fix(abcip): stride user-string arrays by the read buffer, not the built-in STRING size
Live read-only check against a production CompactLogix press: Program:UN01_Press._ModeNames (STR0016[32], 4 elements requested) returned an 80-byte buffer with libplctag.NET 1.5.2's ElementSize unset. The driver fell back to the static 88-byte STRING stride, read element 1 past the buffer, and the whole read failed (ErrorOutOfBounds -> BadCommunicationError). When the buffer divides evenly by the element count, that quotient is now the stride; the read returns [undefined, Production, Maintenance, Manual] as the controller holds.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.AbCip;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Array element stride. Seen live on a production CompactLogix: reading
|
||||
/// <c>Program:UN01_Press._ModeNames</c> (<c>STR0016[32]</c>, 4 elements requested) returned an
|
||||
/// 80-byte buffer with libplctag's <c>ElementSize</c> unset; the driver strode 88 bytes (built-in
|
||||
/// STRING) and the read failed <c>ErrorOutOfBounds</c>. The real values were
|
||||
/// "undefined" / "Production" / "Maintenance" / "Manual" at a 20-byte stride.
|
||||
/// </summary>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class AbCipArrayStrideTests
|
||||
{
|
||||
/// <summary>A user string type's stride comes from the buffer, not the built-in STRING size.</summary>
|
||||
[Fact]
|
||||
public void User_string_array_strides_by_buffer_size_over_count()
|
||||
{
|
||||
LibplctagTagRuntime.ResolveArrayStride(null, bufferSize: 80, count: 4, AbCipDataType.String).ShouldBe(20);
|
||||
}
|
||||
|
||||
/// <summary>The built-in STRING still strides 88.</summary>
|
||||
[Fact]
|
||||
public void Builtin_STRING_array_strides_88()
|
||||
{
|
||||
LibplctagTagRuntime.ResolveArrayStride(null, bufferSize: 3 * 88, count: 3, AbCipDataType.String).ShouldBe(88);
|
||||
}
|
||||
|
||||
/// <summary>libplctag's own element size wins when it is populated.</summary>
|
||||
[Fact]
|
||||
public void Reported_element_size_wins()
|
||||
{
|
||||
LibplctagTagRuntime.ResolveArrayStride(4, bufferSize: 80, count: 4, AbCipDataType.DInt).ShouldBe(4);
|
||||
}
|
||||
|
||||
/// <summary>An empty or uneven buffer falls back to the static per-type size.</summary>
|
||||
[Fact]
|
||||
public void Empty_or_uneven_buffer_falls_back_to_the_type_size()
|
||||
{
|
||||
LibplctagTagRuntime.ResolveArrayStride(null, bufferSize: 0, count: 4, AbCipDataType.Real).ShouldBe(4);
|
||||
LibplctagTagRuntime.ResolveArrayStride(null, bufferSize: 81, count: 4, AbCipDataType.String).ShouldBe(88);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user