Skip to content

Cap client operation limits to MaxArrayLength and fix flaky pcap/interval tests#3910

Merged
marcschier merged 5 commits into
masterfrom
flakinessfixes
Jun 24, 2026
Merged

Cap client operation limits to MaxArrayLength and fix flaky pcap/interval tests#3910
marcschier merged 5 commits into
masterfrom
flakinessfixes

Conversation

@marcschier

@marcschier marcschier commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Description

This branch contains two independent changes.

1. Honor MaxArrayLength for service-operation arrays (Fixes #3909)

MaxArrayLength applies to every array in a decoded message, including service-operation arrays
such as nodesToRead, and a server returns BadEncodingLimitsExceeded if it is exceeded. The two
limits are independent in the spec (nothing requires MaxNodesPerRead <= MaxArrayLength), but because
the operation array is itself a decoded array, the sender must honor both bounds.

Previously the client trusted each OperationLimits value verbatim. With a server advertising, for
example, MaxNodesPerRead = 10000 and MaxArrayLength = 1000, the complex-type loader (and any other
batched service call) packed more than 1000 reads into a single request, which the server rejected. The
same happened when an operation limit was 0 (unlimited), which disables batching in
SessionClientBatched.

Session.FetchOperationLimitsAsync now:

  • clamps ServerCapabilities.MaxArrayLength by the client's configured TransportQuotas.MaxArrayLength
    (mirroring the existing MaxByteStringLength handling) to obtain an effective array length, and
  • caps every operation limit to that effective length — a limit of 0 (unlimited) or a limit larger
    than the effective length is reduced to it, while 0/unlimited on both sides leaves the limits
    unchanged.

SessionClientBatched then batches Read/Write/Browse/… calls using the capped limits, so a single
request never produces an operations array larger than the server will accept. This directly fixes the
reported scenario where the complex type system read more than MaxArrayLength nodes in one request.

No public API change; behavior remains compatible with 1.5.378. A behavior note was added to
Docs/Sessions.md, and unit tests cover the cap, the 0/unlimited case, the client-quota case, and the
no-op case.

2. Fix flaky tests

  • Tests/Opc.Ua.Core.Diagnostics.Tests/.../InProcessClientCaptureSourceTests.cs — stabilizes the
    in-process pcap capture test.
  • Tests/Opc.Ua.PubSub.Tests/IntervalRunnerTests.cs — stabilizes the interval runner timing test.

These flakiness fixes are unrelated to #3909 and are included on the same branch.

Related Issues

Checklist

Put an x in the boxes that apply. You can complete these step by step after opening the PR.

  • I have signed the CLA and read the CONTRIBUTING doc.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added all necessary documentation.
  • I have verified that my changes do not introduce (new) build or analyzer warnings.
  • I ran all tests locally using the UA.slnx solution against at least .net framework and .net 10, and all passed.
  • I fixed all failing and flaky tests in the CI pipelines and all CodeQL warnings.
  • I have addressed all PR feedback received.

FetchOperationLimitsAsync now clamps ServerCapabilities.MaxArrayLength by the client's TransportQuotas.MaxArrayLength and caps all operation limits to that effective value (treating 0 as unlimited), so SessionClientBatched never sends an operations array larger than the server accepts. Adds unit tests and a Sessions.md note.
Comment thread Docs/Sessions.md Outdated
Comment thread Docs/Sessions.md Outdated
Comment thread Libraries/Opc.Ua.Client/Session/Session.cs Outdated
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.77%. Comparing base (6a86590) to head (394537d).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3910      +/-   ##
==========================================
+ Coverage   72.75%   72.77%   +0.01%     
==========================================
  Files         917      917              
  Lines      149022   149057      +35     
  Branches    25816    25821       +5     
==========================================
+ Hits       108426   108474      +48     
+ Misses      31176    31166      -10     
+ Partials     9420     9417       -3     
Files with missing lines Coverage Δ
Libraries/Opc.Ua.Client/Session/Session.cs 73.53% <100.00%> (+0.36%) ⬆️

... and 10 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Rephrase the Sessions.md operation-limit note so the server-reported 0/over-limit cases are explicit, and simplify the TransportQuotas.MaxArrayLength int->uint cast.
@marcschier marcschier marked this pull request as ready for review June 23, 2026 17:26
Copilot AI review requested due to automatic review settings June 23, 2026 17:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the OPC UA client’s operation-limit handling to ensure batched service requests never exceed the effective MaxArrayLength (server capability clamped by client TransportQuotas), addressing scenarios where servers reject oversized operations arrays with BadEncodingLimitsExceeded. It also includes two unrelated test-stability improvements.

Changes:

  • Cap per-service OperationLimits to the effective MaxArrayLength in Session.FetchOperationLimitsAsync.
  • Add unit tests covering server cap, “0/unlimited” behavior, client-quota cap, and the no-cap case.
  • Stabilize two flaky timing/pcap-related tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Libraries/Opc.Ua.Client/Session/Session.cs Implements MaxArrayLength clamping and caps all operation limits to the effective array-length bound.
Tests/Opc.Ua.Client.Tests/Session/SessionTests.cs Adds tests validating capping behavior across server/client/unlimited cases.
Docs/Sessions.md Documents how FetchOperationLimitsAsync derives effective limits using MaxArrayLength.
Tests/Opc.Ua.Core.Diagnostics.Tests/Capture/InProcessClientCaptureSourceTests.cs Improves determinism by explicitly draining the capture worker before forced disposal.
Tests/Opc.Ua.PubSub.Tests/IntervalRunnerTests.cs Makes the polling helper more tolerant of CI thread-pool starvation and reduces spin frequency.

Comment thread Libraries/Opc.Ua.Client/Session/Session.cs Outdated
Comment thread Tests/Opc.Ua.Core.Diagnostics.Tests/Capture/InProcessClientCaptureSourceTests.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@marcschier marcschier merged commit 147c287 into master Jun 24, 2026
137 checks passed
@marcschier marcschier deleted the flakinessfixes branch June 24, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Honor MaxArrayLength for operations

3 participants