fix(cli-common): name native-driver-emitted status codes in SnapshotFormatter

Driver.FOCAS.Cli-005 follow-up: extend the SnapshotFormatter.FormatStatus
shortlist with the five Bad* codes the native-protocol mappers (FOCAS,
AbCip, AbLegacy) emit but which the shortlist previously left unnamed,
so they rendered only as severity-class 'Bad' instead of the documented
'BadDeviceFailure' / 'BadNotWritable' / ... names operators are told to
read off probe/write output.

Added entries:
  0x80020000 BadInternalError
  0x803B0000 BadNotWritable
  0x803C0000 BadOutOfRange
  0x803D0000 BadNotSupported
  0x80550000 BadDeviceFailure

(BadTimeout 0x800A0000 was already added under Driver.Cli.Common-001.)

Tests: SnapshotFormatterTests gains a new [Theory]
FormatStatus_names_native_driver_emitted_codes covering the five names,
and the existing well-known [Theory] is extended with the same entries
to enforce exact '0x... (Name)' rendering. Suite now 47 green (was 42).

Flips Driver.FOCAS.Cli-005 from Deferred to Resolved; README regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-23 15:14:08 -04:00
parent 0f8ce1cb80
commit 5a9c4591b9
4 changed files with 43 additions and 13 deletions

View File

@@ -29,12 +29,17 @@ public sealed class SnapshotFormatterTests
// Numeric codes are the canonical OPC Foundation Opc.Ua.StatusCodes values.
[InlineData(0x00000000u, "Good")]
[InlineData(0x80000000u, "Bad")]
[InlineData(0x80020000u, "BadInternalError")]
[InlineData(0x80050000u, "BadCommunicationError")]
[InlineData(0x800A0000u, "BadTimeout")]
[InlineData(0x80310000u, "BadNoCommunication")]
[InlineData(0x80320000u, "BadWaitingForInitialData")]
[InlineData(0x80340000u, "BadNodeIdUnknown")]
[InlineData(0x80330000u, "BadNodeIdInvalid")]
[InlineData(0x803B0000u, "BadNotWritable")]
[InlineData(0x803C0000u, "BadOutOfRange")]
[InlineData(0x803D0000u, "BadNotSupported")]
[InlineData(0x80550000u, "BadDeviceFailure")]
[InlineData(0x80740000u, "BadTypeMismatch")]
[InlineData(0x40000000u, "Uncertain")]
public void FormatStatus_names_well_known_status_codes(uint status, string expectedName)
@@ -42,6 +47,22 @@ public sealed class SnapshotFormatterTests
SnapshotFormatter.FormatStatus(status).ShouldBe($"0x{status:X8} ({expectedName})");
}
[Theory]
// Driver.FOCAS.Cli-005 follow-up (Driver.Cli.Common): the FOCAS / AbCip / AbLegacy mappers
// emit these five codes — they previously rendered only as severity-class "Bad" because the
// shortlist did not name them, defeating the operator workflow that docs/Driver.*.Cli.md
// promise (read the BadDeviceFailure / BadNotWritable / ... name straight off probe/write
// output). Pin them named so the docs stay accurate.
[InlineData(0x80020000u, "BadInternalError")]
[InlineData(0x803B0000u, "BadNotWritable")]
[InlineData(0x803C0000u, "BadOutOfRange")]
[InlineData(0x803D0000u, "BadNotSupported")]
[InlineData(0x80550000u, "BadDeviceFailure")]
public void FormatStatus_names_native_driver_emitted_codes(uint status, string expectedName)
{
SnapshotFormatter.FormatStatus(status).ShouldContain($"({expectedName})");
}
[Theory]
// Regression for Driver.Cli.Common-001: these codes were previously mapped to the
// wrong names. The hex values below are what the buggy shortlist used; they must