Files
UA-.NETStandard/tests
romanett c7fdeb6de1 Fix stress Contract/Integration failures and run them in stress-test.yml (#4718)
## Description

`Opc.Ua.Stress.Tests` with `Category=Contract|Category=Integration` had
five failures on master. The README says these categories run on every
PR, but no workflow ran them: `get-ci-matrix.ps1` excludes the Stress
project, and `stress-test.yml` only ran `ChaosTCP`. The old
`Channels.Stress` special case in `buildandtest.yml` never matched the
project name, and #4513 removed it. So the tests rotted unseen. Two of
the five failures were real product bugs.

### Product fixes

- **Session recreate after a server restart failed forever (regression
from #4503).** User-token PolicyIds are assigned by the server and are
not stable across a restart. In the failing run the client had cached
`Anonymous|20` and the restarted server offered `Anonymous|2`. The
CreateSession check added in #4503 requires an exact match, including
PolicyId, so every `RecreateInPlace` failed with
`BadSecurityChecksFailed` ("different security policy for the selected
user identity token"). The managed session then retried without end.
- `Session.OpenCoreAsync` now adopts the server's policy when only the
PolicyId differs. TokenType, SecurityPolicyUri, IssuedTokenType and
IssuerEndpointUrl must still match, so a downgrade is still rejected.
The token is restamped with the new id.
- **A certificate rotation during a reconnect reactivated every session
twice.** `ChannelEntry.ReconnectCycleAsync` only noticed the superseded
client certificate *after* it had notified participants. It then
replaced the transport and notified them again. The check now also runs
right after the transport reconnects, before participants are notified.

### Tests updated to the #4516 contracts

- `RetryBudgetEnforcementTests`: `Session.ReconnectManagedChannelAsync`
gained an optional reverse-connection parameter, which the reflection
call must supply.
- `GateAndBypassTests`: the participant callback token is cancelled once
`OnReconnectAsync` returns. The spawned worker now runs on the test
token.
- `LeaseLifecycleTests`: releasing the last lease cancels the recovery
in progress, as documented. The reconnect caller now expects
`OperationCanceledException`.

### CI

- New `Contract and Integration` job in `stress-test.yml`, with the same
gate as Chaos TCP: nightly, manual, and PRs labelled `stress`. It takes
about 1 minute of test time.
- The README now says where these categories actually run.

### Tests

- New
`SessionIdentityReviewTests.CreateAdoptsRenumberedUserTokenPolicyIdAsync`,
covering both a renumbered id (accepted) and a changed token security
policy (rejected). It fails without the fix.
- Each of the 5 fixed tests passed 3/3 runs in isolation. The full
`Contract|Integration` filter passed 45/45 twice in Debug and once in
Release.
- Related tests also pass: Core.Tests channel tests 587/587,
Sessions.Tests channel tests 119 passed (63 skipped), Client.Tests
channel/session/reconnect tests 512/512.
- The net48 build of `UA.slnx` is clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-10-10 08:06:30 +02:00
..