You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Resolve the open CTT findings: aggregate fixes, de-DE ApplicationName and CTT configuration - #4545
Resolves the open items of plans/ctt-issues.md (Needs clarification, Open server findings, CTT project configuration notes). Each item was checked against the OPC 10000 spec text. A server change was made only where the server was wrong, and every server change has a regression test. CTT script and oracle defects are filed in Mantis instead.
Server changes (Opc.Ua.Server)
NumberOfTransitions honours TreatUncertainAsBad.
Part 13 §5.4.3.24 does not count Bad values. §4.2.1.2 makes Uncertain values "equivalent to Bad" when TreatUncertainAsBad is True, and the aggregate definition doesn't override that.
Uncertain values are therefore no longer counted, and no longer used as the previous value, when the setting is True. The now unused TimeSlice.NonBadEarlyBound is removed.
DurationInStateZero/NonZero status follows the variable's interpolation.
§5.4.3.2.2: "A region is Uncertain if a region ends in a Bad or Uncertain value and SlopedInterpolation is used."
The calculator always built stepped status regions. So on a sloped variable, the last region stayed Good while TimeAverage2 and Total2 over the same interval were already Uncertain.
The duration value doesn't change.
AnnotationCount returns Bad_NoData and sets Partial.
Table 68 requires Bad_NoData for intervals before the start or after the end of data. §5.3.3.2 requires the Partial bit for incomplete intervals.
HistorianDispatcher now derives the start and end of data from the raw history (read with bounds) plus the annotation timestamps. It passes them to a new CalculateAnnotationCounts overload; the old overload is unchanged.
Three existing dispatcher tests change their expectations. For example, a node without any data now returns Bad_NoData instead of Good zeros.
Reference server sample and CTT configuration
de-DE ApplicationName. The server advertises de-DE in LocaleIdArray, but FindServers and GetEndpoints always returned the en-US name. The sample now keys the ApplicationName and registers en-US and de-DE translations (Part 4 §5.5.2.2 / §5.5.4.2 localeIds).
Subscription limit.Max Supported Subscriptions in samples/UAReferenceServer.ctt.xml and MaxSubscriptionCount in Ctt.ReferenceServer.Config.xml go from 100 to 200. Subscription Publish Min 05 003.js needs 190 subscriptions.
Alarm Cycle Time. The CTT template's Alarm Cycle Time is 30 s. At 60 s it equalled RequestedSessionTimeout, so a Limit/Level CU that starts a run finds its session expired (C40).
Tests only
AddNodes duplicate BrowseName test:AddNodeAsync_DuplicateBrowseNameUnderParent_ReturnsBadBrowseNameDuplicatedAsync never ran. Its items had no TypeDefinition, so its Assume always made it inconclusive. The finding it belongs to (AddNodes after a rename returning BadNodeIdExists) was already fixed by Fix server/core validation, lifecycle and protocol regressions #4477.
GDS QueryApplications/QueryServers still return records with ServerCapability NA. OPC 10000-12 §6.5.10/§6.5.11 says they "shall not", but the CTT GDS scripts expect those records. Implementing the exclusion turned 40 GDS test cases from pass to error, so it waits for the script fix (Mantis 11458).
11462 Part 13 clarification: TreatUncertainAsBad and simple bounds (DeltaBounds)
The A & C BadSubscriptionIdInvalid failures (Refresh, Refresh2, Shelving) come from CPU load: with other processes at 100 % CPU, all subscriptions of the CTT alarm session expire within one second. This happens with and without this PR (3 of 3 loaded runs, 0 of 2 idle runs).
CTT verification
CTT 1.05.06, scripts 1.05.513, compared at test-case level against a build of the starting commit:
Group
Before
After
Aggregates
4,562 error messages
4,186. NumberOfTransitions: 12 test cases go from error to pass. AnnotationCount 005-01.js/005-02.js pass. NumberOfTransitions 003-02.js/004-02.js now fail because of C1 (Mantis 11420): they request TreatUncertainAsBad = false, but the harness makes the server use its default of true.
Discovery
10 warnings
0. Find Servers Filter 003.js/006.js and Get Endpoints 002.js pass.
Subscription
–
Publish Min 05 003.js goes from warning to pass.
Historical Access, GDS, Node Management
–
no new failures
plans/ctt-issues.md is updated: resolved items leave the open sections, and the new Mantis issues are recorded.
Full CTT run (23 parts, 3,752 test cases) against origin/master + #4477,
- C48/C49: aggregate oracle lacks the Part 13 Uncertain status and
Calculated bit rules that #4477 implements for Min/Max(ActualTime)
- C14 withdrawn: Auditing Connections pass since the event queue size
fix (#4480)
- AddNodes BadNodeIdExists after a child rename (#4477 x #4486)
- Security None 007.js / Basic256Sha256 005.js fail on master too
(CloseSession latency outlasts the idle channel lifetime)
- C10 also covers A & C Confirm Test_001.js depending on alarm phase
- coverage notes for UAFX, PubSub Publisher UADP and UserDefinedCU
- ctt-testing.md section 10: how to run every group in parts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Measured with a request-arrival probe build of the reference server: the
server receives CloseSession ~520 ms after the CTT timestamps it and
completes it in 2-5 ms; the CTT stops the Session's SessionThread (~550 ms)
between stamping and sending (C50). Security None 007.js / Basic256Sha256
005.js fail because TcpTransportListener.DetectInactiveChannels closes an
idle SecureChannel after ChannelLifetime (30 s) while its SecurityToken is
valid for 60 s (Part 4 5.6.2.1); with ChannelLifetime 120000 the test passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The server closes SecureChannels without traffic after ChannelLifetime.
CTT Security None 007.js and Security Basic256Sha256 005.js keep channels
without a Session idle for about 50 s and expect the newest one to still
be open; with 120000 both pass (were BadInvalidState on close).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TcpTransportListener.DetectInactiveChannels closed every channel that had
no traffic for ChannelLifetime (30 s by default), also open channels whose
security token was still valid. OPC 10000-4 5.6.2.1 keeps a SecureChannel
until it is closed or its last token expired; unused Session-less channels
are only to be evicted before reaching the channel limit. CTT Security
None 007.js and Security Basic256Sha256 005.js failed on the close of such
a channel (60 s token, about 50 s idle).
The inactivity cleanup now skips open channels whose current or renewed
token has not expired. Channels that never opened, faulted channels and
channels without a token keep the ChannelLifetime timeout, and the
oldest-unused eviction at MaxChannelCount is unchanged. An idle open
channel now stays until its token expires.
Reverts the ChannelLifetime workaround in Ctt.ReferenceServer.Config.xml.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The reference server sends identical UserTokenPolicies (PolicyId 2, empty
SecurityPolicyUri) on all Basic256Sha256 endpoints; only the CTT's
UaEndpointDescription.FindTokenType rewrites the cached SignAndEncrypt
copies before Security User Name Password 2 015.js compares them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Opc.Ua.Sessions.Tests ClientTest.ConnectCloseSessionCloseChannelAsync
failed on CI (ubuntu, macOS): a client that detaches from a live Session
and goes silent expects the server to close the channel after the
ChannelLifetime inactivity timeout, although its token is still valid.
Only open channels without a Session are now kept while their token is
valid (OPC 10000-4 5.6.2.1 restricts closing unused Session-less
SecureChannels); a silent channel carrying a Session ends after the
inactivity timeout as before. CTT Security None 007.js and Security
Basic256Sha256 005.js still pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ReadSymmetricMessage accepts messages secured with PreviousToken until it
expires, which can be later than the current token when the lifetimes
differ. Keep a Session-less open channel while any of its current,
renewed or previous tokens is valid, and cover the lifetime mismatch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rerun of all 23 parts against origin/master plus the inactivity-cleanup
fix. Everything matches the run of 2026-09-15 except the Aggregates group,
which grew from 4,498 to 4,562 error messages: #4503 computes DeltaBounds
for Uncertain bounds, and a logged run shows server and oracle disagreeing
in both directions about which bounds are Bad and which Uncertain (U4).
Security None 007.js and Basic256Sha256 005.js pass with the default 30 s
ChannelLifetime, and Monitor Value Change V2 020.js passes again.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Link the 32 issues filed on 2026-09-24 (11420-11454), the existing
reports that already cover 12 of the drafts, and the drafts held back
for further investigation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeping idle Session-less SecureChannels open until their security token
expires lets an unauthenticated client hold a channel for up to the
SecurityTokenLifetime (one hour by default) instead of ChannelLifetime.
The CTT reference server configuration raises ChannelLifetime instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CTT Security None 007.js and Security Basic256Sha256 005.js keep
SecureChannels without a Session idle for about 51 s and expect the
newest one to still be open. With ChannelLifetime 120000 both pass
again; the default of 30000 and the server code are unchanged.
Record the validation run of 2026-09-24, the date dependency of C39 and
the %TEMP% cleanup that removed the isolated CTT PKI.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
List every failing CTT test case with a short abstract and the Mantis
link; the details live in Mantis. Keep the defects that are not filed
yet, the open questions, the open server findings and the project
configuration notes, and drop the findings the server has fixed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe setup, running, selections, result analysis, run comparison,
triage and the per-group recipes as current guidance, without references
to past runs, fixed issues or individual ctt-issues.md entries. Point to
ctt-issues.md for the known CTT defects to expect. The selection
generator now reads every profile set in a fixed order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nclusive
AddNodeAsync_DuplicateBrowseNameUnderParent_ReturnsBadBrowseNameDuplicatedAsync
added Object nodes without a TypeDefinition, so the first AddNodes returned
BadTypeDefinitionInvalid and the Assume made the test inconclusive; the
BadBrowseNameDuplicated check was never exercised. Pass BaseObjectType and
assert the first add instead of assuming it.
The AddNodes-after-rename finding itself (server-assigned NodeId colliding with
a renamed child) is already fixed on this branch by #4477: ReserveAddNodesNodeId
falls back to a counter NodeId for server-assigned ids and returns
BadNodeIdExists only for a client RequestedNewNodeId (OPC 10000-4 5.8.2.4:
"The requested node id is already used by another node."), covered by
IndexedBrowseNameReusePreservesExistingNodeIdentityAsync.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Subscription Publish Min 05 003.js creates 5 subscriptions in each of
half the Max Supported Sessions (38 sessions, 190 subscriptions). With a
limit of 100 it reduces the session count and warns. Raise both the CTT
setting Max Supported Subscriptions and the CTT server configuration's
MaxSubscriptionCount to 200 so they stay equal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The A & C collector scripts capture events for one Alarm Cycle Time on
an idle CU session before they create their subscriptions. With 60 s
the capture equals RequestedSessionTimeout (60000 ms), so a Limit/Level
CU that starts a run finds its session timed out (C40, Mantis 11448).
The reference server's alarm sources report every alarm type at most
11 s apart and the longest event chain takes about 45 s, so 30 s still
captures every type and stays below the 90 s maximum test time. This is
the value the runbook already uses for the A & C group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reference server advertises de-DE in LocaleIdArray, but FindServers and
GetEndpoints always returned the en-US ApplicationName: the server
description's ApplicationName carries no translation key, so
ResourceManager.Translate has nothing to look up. CTT Discovery Find
Servers Filter 003.js/006.js and Get Endpoints 002.js request de-DE and
warn about the en-US result.
Key the ApplicationName and register an en-US and a de-DE translation, so
the server returns the requested locale (OPC 10000-4 5.5.2.2/5.5.4.2
localeIds).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pins the shape of CTT GDS Application Directory 005.js: a Call request
with a String input argument of MaxStringLength + 10 % in two chunks.
OPC 10000-4 §5.3 requires a Bad_EncodingLimitsExceeded ServiceFault and
§7.34 says "The requestHandle in the ResponseHeader should be set to
what was provided in the RequestHeader even if these values were not
valid." The server does this since #4488; the test fails with
RequestHandle 0 when the handle is not read from the first chunk.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…AsBad is set
Part 13 §5.4.3.24 does not count Bad raw values and compares the earliest
counted value with the previous non-Bad value. §4.2.1.2 makes an Uncertain
value equivalent to Bad when TreatUncertainAsBad is True, and the
NumberOfTransitions definition does not say otherwise. The calculator
ignored the setting: it counted Uncertain values and used a preceding
Uncertain value as the previous value.
The count now skips values that are not Good under the configuration
(IsGood) and starts from the latest such value before the interval
(EarlyBound). With TreatUncertainAsBad=False the result is unchanged. The
now unused TimeSlice.NonBadEarlyBound is removed.
For the reference server's seeded pattern (index mod 10 = 7 Bad, 9
Uncertain) 24 monotonic samples give 20 transitions instead of 22, which
matches the CTT oracle (plans/ctt-issues.md U1).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 13 §5.4.3.22/.23 compute the DurationInStateZero/NonZero status with
the time-based StatusCode calculation over Simple Bounding Values.
§5.4.3.2.2 defines the regions for that calculation: "A region is
Uncertain if a region ends in a Bad or Uncertain value and
SlopedInterpolation is used. The end point has no effect on the region if
SteppedInterpolation is used."
The calculator built the status regions with stepped calculations for
every variable, so on a non-stepped variable the region ending at an
Uncertain simple end bound (for example when the raw value after the end
time is Bad) stayed Good, while TimeAverage2 and Total2 over the same
interval reported Uncertain. The status now uses GetTimeBasedStatusCode,
which follows the variable's Stepped setting as TimeAverage2, Total2 and
Minimum2 do. The duration is still summed over stepped regions that start
at a Good raw value, so the value does not change.
With TreatUncertainAsBad=True such an interval is now
Uncertain_DataSubNormal, as the CTT oracle expects (plans/ctt-issues.md
U3); with TreatUncertainAsBad=False the Uncertain region counts as Good.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 13 §5.4.3.20 (Table 68) defines the AnnotationCount status as "Good
unless the interval is before the start of data or after the end of
data", with Bad_NoData for both cases, and sets the Partial bit "If an
interval is not a complete interval" (§5.3.3.2). The dispatcher computed
every interval as Good, Calculated, including intervals of a node without
any history and the interval that overlaps the end of data.
HistorianDispatcher now determines the start and end of data from the raw
history (read with bounds over the requested window, as the other
aggregates do) together with the annotation timestamps, and passes them
to a new CalculateAnnotationCounts overload. That overload returns
Bad_NoData for intervals entirely before or after the data and sets the
Partial bit with the same edge rules as AggregateCalculator. The existing
overload keeps its behavior (unbounded data range).
Test expectations that changed:
- CountsAnnotationsPerInterval: raw data ends at 29 s, so [20 s, 30 s) is
Partial.
- ZeroIntervalReturnsSingleBucket: the only data (annotations at 1-3 s)
lies inside [0 s, 30 s), so the interval is Partial.
- WithNoAnnotationsReturnsZeros is now WithoutDataReturnsBadNoData: a node
with neither raw data nor annotations has no data, so both intervals
are Bad_NoData instead of Good zeros.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GetValueBasedStatusCode ignored TreatUncertainAsBad=False and counted
Uncertain values as neither Good nor Bad until #4503 changed it. Part 13
§5.4.3.2.1: "If TreatUncertainAsBad = False then Uncertain regions are
included with the Good regions when calculating the above ratios, if the
TreatUncertainAsBad = True then the Uncertain regions are included as Bad
regions." No test covered the value-based path, so add a Count regression
test for both settings, direct and through the historian dispatcher.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OPC 10000-4 v1.05 5.14.5.1 (Publish, Description): "When a Server
receives a new Publish request that exceeds its limit it shall de-queue
the oldest Publish request and return a response with the result set to
Bad_TooManyPublishRequests."
SessionPublishQueue.PublishAsync rejected the new request instead and
kept the older ones queued. When the admission limit is reached it now
removes the head of the request queue (new requests are added last and
requeued ones first, so the head is the oldest), fails it with
BadTooManyPublishRequests through the same retire-once completion used
by the other queue paths, and queues the new request. A requeued request
was admitted before every request still queued, so it is itself the
oldest and is still the one rejected.
The admission tests that expected the new request to be rejected now
expect the oldest live request to be returned instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OPC 10000-4 v1.05 5.14.5.1 (Publish, Description): "But a Server shall
accept more queued Publish requests than created Subscriptions. It is
expected that a Server supports several Publish requests per
Subscription."
The admission limit of SessionPublishQueue was the fixed
ServerConfiguration.MaxPublishRequestCount (20 by default), so a session
with 20 or more subscriptions got Bad_TooManyPublishRequests before it
could queue one request more than it has subscriptions. The effective
limit is now at least the number of the session's subscriptions plus
one. The queue stays bounded: the subscriptions are already limited by
ServerConfiguration.MaxSubscriptionCount.
Tests that configured a limit of one with one subscription now use two,
the lowest limit a session with one subscription can have.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
U1, U3 and the aggregate calculator findings are fixed in the server,
AddNodes after a rename was fixed by #4477, the RequestHandle echo by
#4488.
The idle SecureChannel finding is covered by the CTT configuration's
ChannelLifetime and moves to the configuration notes.
New CTT defects with drafted Mantis reports: C51 (GDS scripts expect
NA records), C52 (A & C Refresh scripts leak subscriptions on the alarm
session), C53 (StartThreadPublish.js default typos) and U2 (Minimum2
oracle on reverse reads). U4 stays open pending a Part 13 clarification.
Update the configuration notes for the new template values (Alarm Cycle
Time 30 s, 200 subscriptions) and the de-DE ApplicationName, and explain
what the remaining notes would need.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C51 11458, C52 11459, C53 11460 (CTT UA Scripts), U2 11461 (CTT UA
Binary) and the Part 13 clarification request for U4, 11462.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ Patch coverage is 87.09677% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.64%. Comparing base (b4136d8) to head (d93bbe9).
Array range slicing needs RuntimeHelpers.GetSubArray, which net472, net48 and netstandard2.0 lack (CS0656).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-value historian
HistorianDispatcher read the whole raw history of the window to find the start and end of data. Read with bounds only the first value in each direction instead. SharedKeyValueHistorianProvider computes AnnotationCount natively and still used the overload without data extents, so empty nodes returned Good zeros; pass the first and last raw and annotation timestamps (Part 13 5.4.3.20, 5.3.3.2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The annotation timestamps collected here are limited to the requested window, so they cannot establish the global annotation-data edges when no raw sample exists in the window (or when annotations extend beyond the raw history). For example, an annotation at t=0 and another at t=100 queried over [40,60) produces an empty annotation list and raw edges at only t=0, causing this code to report Bad_NoData even though the interval is inside the data range and should produce a calculated zero. Read the first/last annotation timestamps outside the request (or obtain equivalent provider metadata) before applying the boundary classification.
The data extent used only the annotations inside the requested window, so a window between two annotations without raw values was reported as Bad_NoData. Also read the nearest annotation before and after the window (one each), as for the raw edges (Part 13 5.4.3.20).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…CTT regression from #4573) (#4593)
## Description
Fixes a CTT regression introduced by #4573, found in a full CTT run of
master after the merge.
**Attribute Write Index `Err-001.js` went Pass → Error.** The test
writes a range that starts beyond the end of each array
(`1073741824:1073741824+len`), with data whose size differs from the
range by one element. It expects `Bad_IndexRangeNoData` or
`Bad_WriteNotSupported`. #4573 checked the size of the written data
before it checked whether the range lies within the target, so the
server returned `Bad_IndexRangeDataMismatch`.
Part 4 §7.27 says no data exists within such a range, so
`Bad_IndexRangeNoData` is the correct result. `NumericRange.UpdateRange`
now checks the lower bounds against the target first, for arrays,
Strings, ByteStrings and matrices. A size mismatch within the target
still returns `Bad_IndexRangeDataMismatch` (Part 4 §5.11.4.4), and the
existing mismatch tests are unchanged.
Also in this PR: `plans/ctt-issues.md` C1 now lists Aggregate –
NumberOfTransitions `003-02.js` and `004-02.js`. Since #4545,
NumberOfTransitions honours TreatUncertainAsBad, and the harness always
sends `UseServerCapabilitiesDefaults = TRUE` (Mantis 11420).
## CTT run (scripts 1.05.513, all 23 parts)
The run compared master with #4573 merged (`20c2d77d5`) against the last
recorded full run (2026-09-24, `22d07a31e`) at test-case level. It also
compared against master just before the merge (`87c35b84b`).
| Change vs recorded run | Cause |
| --- | --- |
| Attribute Write Index `Err-001.js` Pass → Error | This PR fixes it;
with the fix: Pass, 0 errors in the group |
| NumberOfTransitions: 11 cases Error → Pass; `003-02`/`004-02` Pass →
Error | #4545 (intentional), CTT defect C1 |
| Subscription Basic `Err-002.js` | Local project still claimed 100
subscriptions while #4545 raised the server to 200; passes with the
checked-in template value |
| A & C Refresh2/Shelving/Confirm: 9 cases improved | — |
Every other part is identical at test-case level, apart from the usual
"Timestamp shows a delay" warnings. All remaining errors are documented
CTT defects.
## Tests
- 3 new `NumericRangeTests` (array, String, matrix: range beyond the
target with a wrong-size slice → `Bad_IndexRangeNoData`)
- `Opc.Ua.Types.Tests` (net10.0): 11006 passed, 0 failed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
antonellaBerchesCj
added a commit
to antonellaBerchesCj/UA-.NETStandard
that referenced
this pull request
Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Resolves the open items of
plans/ctt-issues.md(Needs clarification, Open server findings, CTT project configuration notes). Each item was checked against the OPC 10000 spec text. A server change was made only where the server was wrong, and every server change has a regression test. CTT script and oracle defects are filed in Mantis instead.Server changes (
Opc.Ua.Server)TimeSlice.NonBadEarlyBoundis removed.Bad_NoDataand sets Partial.Bad_NoDatafor intervals before the start or after the end of data. §5.3.3.2 requires the Partial bit for incomplete intervals.HistorianDispatchernow derives the start and end of data from the raw history (read with bounds) plus the annotation timestamps. It passes them to a newCalculateAnnotationCountsoverload; the old overload is unchanged.Bad_NoDatainstead of Good zeros.Reference server sample and CTT configuration
de-DEApplicationName. The server advertisesde-DEin LocaleIdArray, but FindServers and GetEndpoints always returned the en-US name. The sample now keys the ApplicationName and registers en-US and de-DE translations (Part 4 §5.5.2.2 / §5.5.4.2 localeIds).Max Supported Subscriptionsinsamples/UAReferenceServer.ctt.xmlandMaxSubscriptionCountinCtt.ReferenceServer.Config.xmlgo from 100 to 200. Subscription Publish Min 05003.jsneeds 190 subscriptions.RequestedSessionTimeout, so a Limit/Level CU that starts a run finds its session expired (C40).Tests only
AddNodeAsync_DuplicateBrowseNameUnderParent_ReturnsBadBrowseNameDuplicatedAsyncnever ran. Its items had no TypeDefinition, so itsAssumealways made it inconclusive. The finding it belongs to (AddNodes after a rename returningBadNodeIdExists) was already fixed by Fix server/core validation, lifecycle and protocol regressions #4477.Not changed
NA. OPC 10000-12 §6.5.10/§6.5.11 says they "shall not", but the CTT GDS scripts expect those records. Implementing the exclusion turned 40 GDS test cases from pass to error, so it waits for the script fix (Mantis 11458).ChannelLifetime. Keeping them open would be security relevant. The CTT configuration'sChannelLifetimeof 120000 (Raise ChannelLifetime for the CTT reference server and record the full CTT run of the merged CTT PRs #4502) covers the CTT case.Mantis issues filed
StartThreadPublish.jsdefaults misspelled propertiesThe A & C
BadSubscriptionIdInvalidfailures (Refresh, Refresh2, Shelving) come from CPU load: with other processes at 100 % CPU, all subscriptions of the CTT alarm session expire within one second. This happens with and without this PR (3 of 3 loaded runs, 0 of 2 idle runs).CTT verification
CTT 1.05.06, scripts 1.05.513, compared at test-case level against a build of the starting commit:
005-01.js/005-02.jspass. NumberOfTransitions003-02.js/004-02.jsnow fail because of C1 (Mantis 11420): they request TreatUncertainAsBad = false, but the harness makes the server use its default of true.003.js/006.jsand Get Endpoints002.jspass.003.jsgoes from warning to pass.plans/ctt-issues.mdis updated: resolved items leave the open sections, and the new Mantis issues are recorded.Related Issues
Checklist
Tests run locally on net10.0 after merging master:
Opc.Ua.Server.TestsOpc.Ua.Core.TestsOpc.Ua.History.TestsOpc.Ua.Sessions.TestsBefore the merge, the whole
Opc.Ua.Sessions.TestsClientTest fixture passed (372 passed, 0 failed).🤖 Generated with Claude Code