Commit Graph
4 Commits
Author SHA1 Message Date
MrAlaskan 8f4087605a Fix unordered server endpoint validation (#4029)
### Summary

This PR makes `Session.ValidateServerEndpoints()` compare
`ServerEndpoints` and `UserIdentityTokens` as unordered sets and adds
regression tests that verify `OpenAsync()` no longer rejects legal
servers that return the same endpoint data in a different order.

### Problem

According to OPC UA Part 4, the client validates the endpoint set
returned by `CreateSessionResponse.ServerEndpoints` against the endpoint
set observed during discovery. The specification describes these values
as a set of endpoint descriptions filtered by the relevant transport
profile, not as an ordered array that must preserve the exact
discovery-time enumeration order.

Previously, `Session.ValidateServerEndpoints()` first checked the
endpoint count and then compared `m_discoveryServerEndpoints[ii]`
against `serverEndpoints[ii]` by index. It also compared
`UserIdentityTokens[jj]` by index within each endpoint. As a result, a
server that returned the same legal endpoints in a different order, or
returned the same token policies in a different order within an
endpoint, could be rejected with `BadSecurityChecksFailed` even though
the endpoint data itself had not changed.

### Changes

- Replace index-based `ServerEndpoints` validation with unordered
matching based on the same endpoint fields already validated by the
client.
- Compare `UserIdentityTokens` as an unordered multiset instead of
requiring the server to preserve the original token enumeration order.
- Extend the client session test scaffolding so discovery endpoints can
be supplied explicitly.
- Add regression tests that verify `OpenAsync()` accepts reordered
`ServerEndpoints` and reordered `UserIdentityTokens`.
2026-07-20 08:17:34 +02:00
MrAlaskan 12f770b3b6 Fix managed session failover target selection (#4025)
### Summary

This PR makes `ManagedSession` select failover targets relative to the
currently active endpoint after a successful failover and adds a
regression test that verifies subsequent failover decisions no longer
use the original connection target as the current server.

### Problem

According to OPC UA Part 4 redundancy semantics, once a client has
failed over to a different redundant server, subsequent target selection
must be based on the server that is currently hosting the active
session. The current server is not permanently tied to the endpoint that
was used for the initial connection.

Previously, `ManagedSession` stored the constructor-supplied
`ConfiguredEndpoint` in a read-only property and always passed that
outer value into `IServerRedundancyHandler.SelectFailoverTarget()`.
However, the inner `Session` updates its own `ConfiguredEndpoint` during
`RecreateInPlaceAsync()` when failover succeeds. After the first
failover, the outer `ManagedSession` and inner `Session` could therefore
disagree about which redundant member was currently active, causing
later failover decisions to be evaluated against the original endpoint
instead of the active one.

### Changes

- Make `ManagedSession.HandleFailoverAsync()` prefer the inner session's
current `ConfiguredEndpoint` when selecting a failover target, while
keeping the outer endpoint as a fallback before the session is
available.
- Preserve the existing failover flow and scope the fix to target
selection only.
- Add a regression test that verifies `HandleFailoverAsync()` passes the
inner session's current endpoint to
`IServerRedundancyHandler.SelectFailoverTarget()`.
2026-07-19 07:43:19 +02:00
Marc Schier 12ebfba603 Add ISA95 JobControl and ManagedSession regression coverage (#3998)
## Summary

- Adds the official ISA95 JobControl 2.0.0 NodeSet2 as a complete
source-generator regression fixture.
- Extends the lightweight generated-stack test stub with
`NamespaceMetadataState`, required by the complete model.
- Adds a deterministic ManagedSession cancellation regression proving
that a started connect attempt is stopped.

The ManagedSession cleanup implementation and Quickstarts utility
coverage now come from `master`; this PR retains the additional
deterministic cleanup regression.

## ISA95 fixture provenance and integrity

The fixture is byte-for-byte the official file:

- Source:
`OPCFoundation/UA-Nodeset@e0b5d80cfff698f0276393e28df138a7fbc4b541`
- Path: `ISA95-JOBCONTROL/opc.ua.isa95-jobcontrol.nodeset2.xml`
- Git blob: `82f008cd126ade54e5f2c737bcc116621a8c3087`
- SHA-256:
`52327e736beb604c7253a5a5393d1ad525b9ecf35b71fbacb4f429cacb334064`

The fixture test retains the OPC Foundation MIT header and verifies the
2.0.0 model/date, 258 nodes (including 134 variables), representative
late variables, and that every `ns=1` reference target resolves locally.

## Validation

- ManagedSession tests: 17 passing on net10.0; 15 passing and 2
framework-gated skips on net48.
- Quickstarts server utility tests: 3 passing on net10.0 and net48.
- ISA95 generator and fixture integrity regression: 5 passing on
net10.0.
2026-07-17 13:19:00 +02:00
Marc Schier 7cec2d614d Move repository files to the consolidated layout 2026-07-16 06:25:54 +02:00