Skip to content

fix: don't return continuation points on BadNoContinuationPoints - #4022

Merged
marcschier merged 4 commits into
OPCFoundation:masterfrom
MrAlaskan:fix/browse-continuationpoint-no-continuationpoints
Jul 20, 2026
Merged

fix: don't return continuation points on BadNoContinuationPoints#4022
marcschier merged 4 commits into
OPCFoundation:masterfrom
MrAlaskan:fix/browse-continuationpoint-no-continuationpoints

Conversation

@MrAlaskan

Copy link
Copy Markdown
Contributor

Summary

This PR fixes Browse and BrowseNext so they do not return a usable continuation point when the server reports BadNoContinuationPoints, and adds regression tests that cover both code paths.

Problem

According to OPC UA Part 4, if the server cannot allocate another continuation point for a Browse or BrowseNext operation, the result should be Bad_NoContinuationPoints. In that case, the server must not also return a continuation point that the client can continue to use.

Previously, MasterNodeManager.FetchReferencesAsync() could return BadNoContinuationPoints while still passing a live continuation point object back to its callers. BrowseAsync() then copied that continuation point into the result, producing a contradictory response with StatusCode = BadNoContinuationPoints and a non-empty ContinuationPoint. BrowseNextAsync() went further and overwrote the error with Good whenever a continuation point object was still present. That behavior hides continuation-point quota exhaustion and breaks the expected paging semantics.

Changes

  • Dispose and clear the continuation point when FetchReferencesAsync() hits the no-continuation-points path.
  • Only copy a continuation point into Browse and BrowseNext results when the operation completed successfully.
  • Add deterministic regression tests that verify both Browse and BrowseNext return BadNoContinuationPoints without a continuation point when the continuation-point quota is exhausted.

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.53%. Comparing base (84fa8e8) to head (ecb0836).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4022      +/-   ##
==========================================
- Coverage   73.85%   73.53%   -0.33%     
==========================================
  Files        1345     1345              
  Lines      179988   180039      +51     
  Branches    31668    31678      +10     
==========================================
- Hits       132938   132390     -548     
- Misses      36299    36943     +644     
+ Partials    10751    10706      -45     
Files with missing lines Coverage Δ
src/Opc.Ua.Server/NodeManager/MasterNodeManager.cs 72.26% <100.00%> (+0.01%) ⬆️

... and 54 files with indirect coverage changes

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

@marcschier
marcschier requested a review from Copilot July 18, 2026 15:37
@marcschier

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

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

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes OPC UA Browse/BrowseNext behavior to avoid returning usable continuation points when the server reports BadNoContinuationPoints, and adds deterministic regression tests to lock in the correct semantics.

Changes:

  • Prevent Browse/BrowseNext from copying/returning continuation points when the operation result is not Good.
  • Dispose and clear continuation points when allocation fails with BadNoContinuationPoints.
  • Add regression tests covering Browse and BrowseNext for continuation-point quota exhaustion.

Reviewed changes

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

File Description
tests/Opc.Ua.Server.Tests/NodeManager/MasterNodeManagerDeterministicTests.cs Adds deterministic tests and helpers to simulate continuation-point persistence and quota exhaustion.
src/Opc.Ua.Server/NodeManager/MasterNodeManager.cs Ensures continuation points are only returned on success and are disposed/cleared on BadNoContinuationPoints.

@marcschier marcschier added the ready Ready to merge once CI Passes label Jul 18, 2026
@marcschier

Copy link
Copy Markdown
Collaborator

@MrAlaskan thanks for all the great contributions, we really appreciate it!!! Could you take a look at the server test which seem to be failing in this PR?

@MrAlaskan

Copy link
Copy Markdown
Contributor Author

Thank you for recognizing my work. I’ll take a look at the failing server tests and start working on resolving them.

@marcschier
marcschier merged commit 399747f into OPCFoundation:master Jul 20, 2026
162 of 164 checks passed
marcschier pushed a commit that referenced this pull request Aug 18, 2026
…) [backport to master378] (#4268)

### Summary

Backport of commit 399747f (#4022) from `master` to `master378`.

Fixes `Browse` and `BrowseNext` so they do not return a usable
continuation point when the server reports `BadNoContinuationPoints`,
and adds regression tests covering both code paths.

### Problem

Per OPC UA Part 4, if the server cannot allocate another continuation
point for a `Browse`/`BrowseNext` operation, the result should be
`Bad_NoContinuationPoints` and the server must not also return a usable
continuation point. Previously `FetchReferences` could return
`BadNoContinuationPoints` while still passing a live continuation point
back to its callers, producing a contradictory response
(`BadNoContinuationPoints` with a non-empty `ContinuationPoint`), and
`BrowseNext` could overwrite the error with `Good`.

### Changes

- Dispose and clear the continuation point when `FetchReferences` hits
the no-continuation-points path.
- Only copy a continuation point into `Browse` and `BrowseNext` results
when the operation completed successfully
(`ServiceResult.IsGood(error)`).
- Add deterministic regression tests for both `Browse` and `BrowseNext`,
adapted to the `master378` server API.

### Notes

The upstream commit targets the v2.0 APIs (`ArrayOf`/`ByteString`); the
source fix and tests here were adapted to the `master378` API (`byte[]`
continuation points, `BrowseResultCollection`/`ByteStringCollection`,
4-arg `OperationContext` constructor). Both new tests pass.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready Ready to merge once CI Passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants