Browse-commit parity guards overlap and one is misnamed; browser DriverType literals unguarded #558

Closed
opened 2026-08-10 02:01:35 -04:00 by dohertj2 · 1 comment
Owner

Test-hygiene residuals from #555:

  1. DriverDispatchMapParityTests.Browse_commit_falls_back_to_the_generic_address_key_for_exactly_the_non_browsable_drivers already enumerated DriverTypeNames.All over the same seam the new RawBrowseCommitMapperParityTests guards — but its NonBrowsableDriverTypes list is hand-authored AND misnamed: it really means "types that produce the generic key" (AbLegacy is genuinely non-browsable yet correctly absent because it has a typed branch). Consolidate the two classes (the new one's derivation + GenericKeyExemptions naming is the keeper) or rename/re-document the old list so the two cannot drift apart.

  2. OpcUaClientDriverBrowser.DriverType and GalaxyDriverBrowser.DriverType return string literals ("OpcUaClient", "GalaxyMxGateway") instead of DriverTypeNames constants, unlike SqlDriverBrowser/MqttDriverBrowser. Values match today; nothing guards it. Switch to the constants and/or add a reflection guard asserting every IDriverBrowser.DriverType equals a DriverTypeNames member.

Test-hygiene residuals from #555: 1. `DriverDispatchMapParityTests.Browse_commit_falls_back_to_the_generic_address_key_for_exactly_the_non_browsable_drivers` already enumerated `DriverTypeNames.All` over the same seam the new `RawBrowseCommitMapperParityTests` guards — but its `NonBrowsableDriverTypes` list is hand-authored AND misnamed: it really means "types that produce the generic key" (`AbLegacy` is genuinely non-browsable yet correctly absent because it has a typed branch). Consolidate the two classes (the new one's derivation + `GenericKeyExemptions` naming is the keeper) or rename/re-document the old list so the two cannot drift apart. 2. `OpcUaClientDriverBrowser.DriverType` and `GalaxyDriverBrowser.DriverType` return string literals (`"OpcUaClient"`, `"GalaxyMxGateway"`) instead of `DriverTypeNames` constants, unlike `SqlDriverBrowser`/`MqttDriverBrowser`. Values match today; nothing guards it. Switch to the constants and/or add a reflection guard asserting every `IDriverBrowser.DriverType` equals a `DriverTypeNames` member.
Author
Owner

Closed by merge 7482cf0c (branch fix/558-parity-guard-hygiene), verified by the 14-suite consolidated run (4,583 tests, 0 failures).

One guard per seam. The browse-commit dispatch fact moved OUT of DriverDispatchMapParityTests into RawBrowseCommitMapperParityTests (now 6 facts and the sole guard for the browse-commit seam); DriverDispatchMapParityTests is now CsvColumnMap-only. The hand-maintained NonBrowsableDriverTypes list is deleted — the browsable set derives from the real production registration (run AddAdminUI(), read back the IDriverBrowser.DriverTypes), with the non-derivable universal-DiscoveryDriverBrowser arm covered by DriverTypeNames.All enumeration + GenericKeyExemptions (Modbus, Calculation) + a fact that mechanically refutes any exemption the derived arm contradicts. Subsumption of the removed fact was proven before deletion (the moved fact reddens under the same neuters).

Ordinal, not IgnoreCase, is load-bearing in the browser-key membership guard: a case-only typo in a browser's DriverType key is exactly the drift the guard exists to catch, and IgnoreCase would wave it through.

Browser DriverType literals → constants. GalaxyDriverBrowser and OpcUaClientDriverBrowser now use DriverTypeNames.Galaxy ("GalaxyMxGateway" — exact match verified against the literal before substitution) and DriverTypeNames.OpcUaClient, closing the last string-literal drift channel into the derived guard.

Falsification: each guard neutered in turn fails exactly its own tests; the stale-comment rewrite in RawBrowseCommitMapper now states the guard's real claims instead of the retired hand-list's.

Closed by merge `7482cf0c` (branch `fix/558-parity-guard-hygiene`), verified by the 14-suite consolidated run (4,583 tests, 0 failures). **One guard per seam.** The browse-commit dispatch fact moved OUT of `DriverDispatchMapParityTests` into `RawBrowseCommitMapperParityTests` (now 6 facts and the sole guard for the browse-commit seam); `DriverDispatchMapParityTests` is now CsvColumnMap-only. The hand-maintained `NonBrowsableDriverTypes` list is deleted — the browsable set derives from the real production registration (run `AddAdminUI()`, read back the `IDriverBrowser.DriverType`s), with the non-derivable universal-`DiscoveryDriverBrowser` arm covered by `DriverTypeNames.All` enumeration + `GenericKeyExemptions` (Modbus, Calculation) + a fact that mechanically refutes any exemption the derived arm contradicts. Subsumption of the removed fact was proven before deletion (the moved fact reddens under the same neuters). **Ordinal, not IgnoreCase, is load-bearing** in the browser-key membership guard: a case-only typo in a browser's DriverType key is exactly the drift the guard exists to catch, and IgnoreCase would wave it through. **Browser DriverType literals → constants.** `GalaxyDriverBrowser` and `OpcUaClientDriverBrowser` now use `DriverTypeNames.Galaxy` ("GalaxyMxGateway" — exact match verified against the literal before substitution) and `DriverTypeNames.OpcUaClient`, closing the last string-literal drift channel into the derived guard. Falsification: each guard neutered in turn fails exactly its own tests; the stale-comment rewrite in `RawBrowseCommitMapper` now states the guard's real claims instead of the retired hand-list's.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#558