mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-25 11:50:03 +08:00
WoT runtime materialization, binding execution and native source emission (#4757)
# Description - WoT registry, prepared file store, immutable content, version leases, dependency-graph sharing (advanced graph rewrite), coordinator, materialization, views and atomic refresh. - Explicit caller-context propagation (`IWotRegistryService` / versioned registry / prepared host / publication capture) and the additive `IXRegistryProjectionContextualDelete` capability. - UA/HTTP/MQTT binding execution and compilation, plus the 1.02 FileType bridge and discovery. - WoT-specific native event, source-emission and readiness integration (`MasterNodeManager.SourceEmissions`, `EventManager` identity admission, external-value monitored sources, Fluent attach/detach) and event lease conservation. - All corresponding `WotCon.*` runtime tests, WotCon sample app code, WoT docs, CI feature budgets and Samples.Tests, plus the WotCon Design NodeSet/csv/csproj and ModelSourceParity tests. - Joint model metadata: XRegistry model 0.7.0 / 2026-09-12 (NamespaceVersion 63563, NamespacePublicationDate 63564), RequiredModel date 2025-01-08. - XML-doc work from the frozen WIP, applied to G12-owned declarations only. ## Related Issues - Fixes #4751. - Part of the WoT split tracked in #4511. ## Checklist - [x] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. (Tests included, not yet run against current master.) - [ ] I have added all necessary documentation. - [ ] I have verified that my changes do not introduce (new) build or analyzer warnings. (Not run.) - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. (Not run.) - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received.
This commit is contained in:
@@ -93,6 +93,11 @@ dotnet test UA.slnx
|
||||
Conventions and requirements:
|
||||
|
||||
- **Frameworks.** Test projects use either **NUnit** (with `Assert.That` assertions and **Moq** for mocking) or **TUnit** (with its own assertions and mock helpers). Do not mix the two in one project, and do not use the classic NUnit asserts (`Assert.AreEqual`, …).
|
||||
- **Out-of-tree sample-test output.** When `--artifacts-path` places the WoT
|
||||
aggregation tests outside the checkout, set `OPCUA_TEST_REPOSITORY_ROOT` to
|
||||
the checkout containing `UA.slnx`. The sample fixtures read their original
|
||||
repository assets there; no asset or assembly copying is needed. An invalid
|
||||
configured root fails explicitly instead of falling back to another checkout.
|
||||
- **NUnit 5 async assertions.** Always await `Assert.ThrowsAsync`, `Assert.CatchAsync`, and `Assert.DoesNotThrowAsync`; these methods return tasks and no longer block until the assertion completes. The enclosing test or helper must return `Task`.
|
||||
- **Ordered NUnit fixtures.** Use `DependsOnTest` rather than the obsolete `Order` attribute. Existing sequencing-only dependencies use `AllowFailure = true` so one failed test does not suppress later tests. Filtering a dependent test also runs its prerequisites; dependency chains must not use fixture-level `Parallelizable`.
|
||||
- **Coverage.** Coverage is measured with **Coverlet** and must not regress; every non-application, non-test project should stay at or above **80 %**. Two gates enforce this in CI — see [Continuous integration](#continuous-integration).
|
||||
@@ -442,6 +447,20 @@ GitHub refuses to start a run whose matrices expand past 256 jobs, and the limit
|
||||
|
||||
The executor fails a project when its build fails, when the TRX counters report any failure, when a test fixture's setup or teardown fails, when it produces **no** TRX at all, when nothing in it actually ran, or when it outlives its per-project ceiling. A "no tests ran" outcome is a failure, not a pass — and that includes a suite whose tests were *all* skipped, which records a non-zero total while verifying nothing.
|
||||
|
||||
The WoT aggregation sample tests keep their complete companion-model corpus in a
|
||||
dedicated CI batch. That batch has a finite 240-minute combined build/test budget
|
||||
and a 65-minute inactivity limit; ordinary projects retain their 45-minute combined
|
||||
budget. The sample's full generation-replacement case includes two complete
|
||||
publications and must not be truncated to fit the ordinary project budget.
|
||||
The Server, WoT and Types integration projects also run separately, with a 90-minute
|
||||
combined budget. Server and WoT keep the 10-minute inactivity guard; Types uses
|
||||
30 minutes for complete instrumented companion-model conversions. Hosted cold builds
|
||||
have consumed 20-28 minutes before their healthy integration suites start;
|
||||
the larger finite budget prevents truncation without hiding an inactive test.
|
||||
The .NET Framework WoT profile reserves 150 combined minutes because its complete
|
||||
regeneration and server-integration run exceeded an hour after a 27-minute cold
|
||||
build. Its per-test inactivity guard remains unchanged.
|
||||
|
||||
That per-project ceiling is a **single combined budget** covering the project's build *and* its test run, measured by one stopwatch. The matrix derives each job's `timeout-minutes` from it as `20 + projectCount × perProjectTimeout`, so spending it twice per project would let a batch outlive its job: GitHub would cancel the run, and a cancelled job produces neither the executor's per-project annotation nor its results. A batch whose budgets add up past the job ceiling is an error in `get-ci-matrix.ps1` rather than a clamped `timeout-minutes`, for the same reason. `CiMatrixScriptTests` pins both halves of that arithmetic.
|
||||
|
||||
The verdict comes from the emitted TRX rather than from the `dotnet test` exit code, and lives in [`.github/scripts/get-test-verdict.ps1`](../.github/scripts/get-test-verdict.ps1) so it can be tested on its own — see [`CiTestVerdictTests`](../tests/Opc.Ua.Tools.Tests/CiTestVerdictTests.cs). A failed fixture setup or teardown, such as the assembly-level certificate leak check in a `[OneTimeTearDown]`, is not a test result, so no counter records it: the NUnit adapter writes it to the TRX as a run message (`TearDown failed for test fixture …`), and the verdict rejects it whatever the exit code says. A non-zero exit is tolerated when, and only when, the results record at least one **passing** test, no failure, error, timeout, abort or `passedButRunAborted`, and no failed fixture setup or teardown. That combination means the host died during process **exit**, after the last test and every teardown had already run; failing it would report a false red. It is not a macOS quirk — Windows hosts do it too (run 35714133848, `test-windows-net48 (5/30)`: `Opc.Ua.Client.Tests` reported 256 passed, 0 failed, host exit 1). A host that dies mid-run leaves a non-zero counter and is still rejected, and a run in which every test was skipped is rejected whatever the exit code says. Every tolerated run raises a warning annotation and is labelled in the job summary, so a host that keeps dying stays visible.
|
||||
|
||||
Reference in New Issue
Block a user