feat(s7): byte-buffer codec dispatch + Int64/UInt64/LReal scalar read+write
This commit is contained in:
@@ -7,8 +7,10 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.S7.Tests;
|
||||
/// <summary>
|
||||
/// Regression tests for the remaining code-review findings closed against the S7 driver:
|
||||
/// Driver.S7-003 (Read/WriteAsync null-arg validation), Driver.S7-009 (poll-loop health
|
||||
/// update + backoff), Driver.S7-010 (Dispose without sync-over-async), and Driver.S7-013
|
||||
/// (reject not-yet-implemented S7DataType values at init).
|
||||
/// update + backoff), Driver.S7-010 (Dispose without sync-over-async), and the Phase 4d
|
||||
/// guard-(b) (wide/structured types must be byte-addressed). The wide types are no longer
|
||||
/// rejected wholesale at init — the 8-byte numerics round-trip through the byte-buffer codec
|
||||
/// (see <see cref="S7ScalarBlockTests"/>); only a wide type at a non-byte address is rejected.
|
||||
/// </summary>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class S7DriverCodeReviewFixTests2
|
||||
@@ -136,31 +138,36 @@ public sealed class S7DriverCodeReviewFixTests2
|
||||
Should.NotThrow(() => drv.Dispose());
|
||||
}
|
||||
|
||||
// ── Driver.S7-013 — Reject not-yet-implemented S7DataType values at init ─────────────
|
||||
// ── Phase 4d guard-(b) — wide/structured types must be byte-addressed ────────────────
|
||||
|
||||
/// <summary>Verifies that Initialize rejects not-yet-implemented data types with NotSupportedException.</summary>
|
||||
/// <param name="dt">The S7 data type that is not yet implemented.</param>
|
||||
/// <summary>
|
||||
/// Verifies the init guard rejects a wide/structured type authored at a non-byte address
|
||||
/// (here <c>DB1.DBD0</c>, a DWord). Phase 4d wired the 8-byte numerics (Int64/UInt64/
|
||||
/// Float64) through the byte-buffer codec — see <see cref="S7ScalarBlockTests"/> for the
|
||||
/// round-trip coverage — but they (and the still-deferred String/DateTime) decode from a
|
||||
/// byte-anchored block (<c>DBB</c>/<c>MB</c>/<c>IB</c>/<c>QB</c>). A non-byte suffix would
|
||||
/// mis-frame the value, so <c>RejectUnsupportedTagConfigs</c> guard-(b) fails the config
|
||||
/// fast at init rather than as a misleading per-read fault.
|
||||
/// </summary>
|
||||
/// <param name="dt">A wide/structured S7 data type authored at a non-byte address.</param>
|
||||
[Theory]
|
||||
[InlineData(S7DataType.Int64)]
|
||||
[InlineData(S7DataType.UInt64)]
|
||||
[InlineData(S7DataType.Float64)]
|
||||
[InlineData(S7DataType.String)]
|
||||
[InlineData(S7DataType.DateTime)]
|
||||
public async Task Initialize_rejects_not_yet_implemented_data_type_with_NotSupportedException(S7DataType dt)
|
||||
public async Task Initialize_rejects_wide_type_at_non_byte_address_with_NotSupportedException(S7DataType dt)
|
||||
{
|
||||
// A tag declared with one of the not-yet-wired data types parses cleanly and creates
|
||||
// an OPC UA node via DiscoverAsync — then every Read/Write of it returns BadNotSupported.
|
||||
// The half-implemented type must be rejected at init so a site can't deploy a config
|
||||
// that produces dead nodes (Driver.S7-013).
|
||||
var opts = new S7DriverOptions
|
||||
{
|
||||
Host = "192.0.2.1",
|
||||
Timeout = TimeSpan.FromMilliseconds(250),
|
||||
// Use a DB.DBD address — the parser accepts it for every data type. The init guard
|
||||
// must fault on the data-type rather than on the address.
|
||||
// DB1.DBD0 is a DWord (non-byte) address — guard-(b) must fault on the address shape
|
||||
// for a wide type. (At a byte address like DB1.DBB0 the 8-byte numerics round-trip;
|
||||
// see S7ScalarBlockTests.)
|
||||
Tags = [new S7TagDefinition("X", "DB1.DBD0", dt)],
|
||||
};
|
||||
using var drv = new S7Driver(opts, $"s7-bad-dt-{dt}");
|
||||
using var drv = new S7Driver(opts, $"s7-wide-nonbyte-{dt}");
|
||||
|
||||
var ex = await Should.ThrowAsync<NotSupportedException>(async () =>
|
||||
await drv.InitializeAsync("{}", TestContext.Current.CancellationToken));
|
||||
|
||||
Reference in New Issue
Block a user