mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-27 21:55:54 +08:00
Closes #4479 The CTT skipped a number of reference-server test cases because the sample address space, the diagnostics EnabledFlag or the CTT project settings did not provide what the scripts need. This PR fixes the sample data and the server behaviour behind those skips, updates `samples/UAReferenceServer.ctt.xml`, and records the CTT script defects that the newly running cases expose. ## Changes ### Sample address space (`ReferenceServer.NodeSet2.xml`, `ReferenceNodeManager`) | # | Skip | Fix | | --- | --- | --- | | 1 | Base Info Engineering Units `004.js`: ArrayItemType `EngineeringUnits` have an empty NamespaceUri | UNECE `mV` (12890) EUInformation, and the axis definitions use `s` (5457219) instead of UnitId 0. | | 2 | Data Access PercentDeadband `006/016/017`: `DataAccess_AnalogType_Float` EURange 0..0 | EURange 0..100 like the other analog items. | | 3 | Attribute Read `033.js` (19 nodes): second dimension of 3 | All `Scalar_Static_Arrays2D_*` are 5x5 (generated values; the Variant matrix holds scalar Int32 elements). The code-seeded Integer/Number/UInteger matrices are 5x5 too. | | 4 | View Minimum Continuation Point 01 `012.js`, View Basic 2 `018.js`: Method/View nodes need two references of their own NodeClass | `Methods_Void` HasCause/HasEffect to two methods, `Views_Operations` HasCause/HasEffect to `Views_Engineering`. | | 5 | Base Info Server Capabilities 2 `002.js`: no node without MinimumSamplingInterval | `DataAccess_DataItem_String` reports `Bad_AttributeIdInvalid` for the optional attribute (Part 3 §5.6.2). A DA item is used because Address Space WriteMask writes every attribute of the static scalars back. | | 6 | Historical Access Read Raw `Err-025.js`: no non-historizing Static Scalar | New `Scalar_Static_NonHistorizing_Boolean` (HistoryRead access, Historizing = false). See the historian change below. | | 10 | Address Space Atomicity `001.js`: no NonatomicRead node found | New `AccessRights_AccessAll_NonatomicReadWrite`. The script examines only the first 10000 variables sorted by NodeId string; the 5000 mass variables sort before `Scalar_Static_NonatomicReadWrite`. | ### Server library - **Diagnostics EnabledFlag (item 7, Base Info Diagnostics `018-1/2/3`).** `Server.ServerDiagnostics.EnabledFlag` is writable for SecurityAdmin or ConfigureAdmin over SignAndEncrypt (UserAccessLevel hook, asynchronous write handler); other users get `Bad_UserAccessDenied`. Transitions are serialized, including the node removal. Disabling returns `Bad_NotReadable` for ServerDiagnosticsSummary, its children and the diagnostics arrays, and removes the session and subscription diagnostics nodes (Part 5 §6.3.3). The server keeps the registrations: enabling restores the nodes of the live sessions and subscriptions with the same NodeIds (sessions created while disabled included) and resets the arrays to Good. Counters stay cumulative (required by `018-1.js`). Subscriptions created while diagnostics are disabled still get no diagnostics node. - `DiagnosticsNodeManager.IsDiagnosticsStructureNode` had an inverted NodeId check, so monitored diagnostics nodes never started the scan timer; `OnMonitoringModeChangedAsync` counted every node and replaced a running timer. Both fixed. - **Non-historized nodes (item 6).** `HistorianDispatcher` raw/modified, processed and at-time reads ask the resolved provider `IsHistorizingAsync` and return `Bad_HistoryOperationUnsupported` for a node it does not historize, instead of the empty result the in-memory historian gave for any node. - **Browse order (item 8).** `ReferenceDictionary.Find` returned references of a type from hash-based target maps, so a Browse filtered by ReferenceType returned references in a different order than an unfiltered Browse. It now returns them in insertion order (no extra allocation; a single match keeps the fast path). View Basic 2 `015.js` compares both lists by index. The characterization test in `NodeStateReferenceStorageTests` is updated accordingly. ### CTT project settings (`samples/UAReferenceServer.ctt.xml`) | Setting | Old | New | | --- | --- | --- | | `/Server Test/NodeIds/Static/All Profiles/Scalar/Bool` | `ns=2;s=Scalar_Static_Boolean` | `ns=2;s=Scalar_Static_NonHistorizing_Boolean` | | `/Server Test/NodeIds/References/Has References of a ReferenceType and SubType` | `ns=2;s=References_HasReferenceTypeAndSubType` | `i=2253` | | `/Server Test/NodeIds/NodeClasses/Object` | `ns=2;s=Scalar` | `i=2253` | `References_HasReferenceTypeAndSubType` loses its HasComponent/HasOrderedComponent references in the source generator; that is tracked in #4484 and not changed here. The Server object has HasComponent and HasAddIn references. ### Decisions - **Item 11, Attribute Write StatusCode & Timestamp `003/006/008` (writing ServerTimestamp): unchanged.** The stack rejects writes that contain a ServerTimestamp (`NodeState`/`BaseVariableState`), which Part 4 §5.11.4.2 allows (`Bad_WriteNotSupported`); the CTT reports it as "Not Supported", not as an error. Side finding, not changed: the StatusWrite/TimestampWrite AccessLevel bits are not enforced. - **Item 6:** Part 4 §5.11.3.4 (Table 52) specifies `Bad_HistoryOperationUnsupported`; `Err-025.js` accepts only `Bad_NotSupported`, so the case now runs and reports that as an error. Recorded as a CTT defect in `plans/ctt-issues.md`. - **Item 12:** removed the stale Historical Access `Err-012.js` entry (fixed by #4026). `plans/ctt-issues.md` adds C32 (`Err-025.js` status code), C33 (Atomicity `001.js`: 10000 cap, operator precedence, substring matching of `UaNodesToIgnore`) and C34 (View Basic 2 `015.js` index comparison), and replaces the Err-025/Err-012 configuration notes with the new settings and the EnabledFlag access requirement. Monitor Basic `039.js` is already C17. The run procedure in `plans/ctt-testing.md` is unchanged. ## Verification CTT 1.05.06, scripts 1.05.513, `ConsoleReferenceServer --ctt -a`, fresh server per conformance unit/group. "master" =5362ec5e5with the unchanged project settings. **Targeted CUs (skips before → after):** Attribute Read `033` Pass; Base Info Diagnostics `018-2`, `018-3` Pass, `018-1` Warning (*"Session diagnostics not available"* for the session the script creates while diagnostics are disabled); Base Info Engineering Units `001` Inconclusive→Pass, `004` Pass; Base Info Server Capabilities 2 `002` Pass; Data Access PercentDeadband `016`, `017` Warning→Pass; View Basic 2 `005`, `015`, `016`, `018`, `020` Pass; View Minimum Continuation Point 01 `010`, `011` Pass, `012` Warning→Pass; Address Space Atomicity `001` Pass; Monitor Value Change V2 `042` Error→Pass; Historical Access Read Raw `Err-025` runs (CTT status-code defect above); `013` fails on a varying number of results per run (1–12, also 11 on master), the documented continuation-point defect #16. Unchanged: Monitor Basic `039` (CTT script error), Monitor Value Change V2 `020` skip (`Arrays/ByteString` elements shorter than 4 bytes, not part of #4479), Historical Access Delete Value all pass. **Saved selection (1,882 cases) per group, errors:** Address Space Model 0 → 0, Aggregates 4558 → 4558 and Base Information 19 → 19 (identical messages) measured master (5362ec5e5) → this PR; after merging master (#4478) and the review fixes, Aggregates 4210 and Base Information 19; Attribute Services, Base Services, Data Access, Method Services and View Services 0 errors with this PR (0 in the recorded baseline). **Tests** (net10.0): Opc.Ua.Types.Tests 10395 passed, Opc.Ua.Server.Tests 5561 passed, Opc.Ua.InformationModel.Tests 1082 passed, Opc.Ua.History.Tests 519 passed, Opc.Ua.Client.Tests 2266 passed; no failures. New regression tests: `ReferenceServerTests` (units/ranges, 5x5 matrices, missing MinimumSamplingInterval, non-historizing HistoryRead, NodeClass references, Server object reference subtypes, both nonatomic nodes), `DiagnosticsNodeManagerTests.SetDiagnosticsEnabledAsync_Toggle_HidesAndRestoresDiagnosticsAsync`, `BaseInfoEnabledFlagToggleTests` (admin-only write, Bad_NotReadable while disabled, restore after enable), `ReferenceTableTests.FindReturnsReferencesInInsertionOrder`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>