Bump Moq from 4.16.1 to 4.17.1 - #4
Closed
dependabot[bot] wants to merge 1 commit into
Closed
dependabot[bot] wants to merge 1 commit into
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps [Moq](https://github.com/moq/moq4) from 4.16.1 to 4.17.1. - [Release notes](https://github.com/moq/moq4/releases) - [Changelog](https://github.com/moq/moq4/blob/main/CHANGELOG.md) - [Commits](devlooped/moq@v4.16.1...v4.17.1) --- updated-dependencies: - dependency-name: Moq dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Author
|
Looks like Moq is no longer a dependency, so this is no longer needed. |
marcschier
added a commit
that referenced
this pull request
Jul 2, 2026
…aling, Warm/Hot client standby Plan items #3 and #4 from plans/28-distributed-ha-remaining.md (items #1/#2 are now issues OPCFoundation#3938/OPCFoundation#3939). #3: RedundantClientSessionFailoverIntegrationTests (Opc.Ua.Sessions.Tests) drives two RedundantClientSession replicas with a controllable leader election against a live ReferenceServer; asserts a follower blocks/throws BadInvalidState, then after a forced handoff the same facade reference keeps serving browse/read over the swapped-in session. Passes net10 + net48. Added a Redundancy.Client project reference. #4a: RedundantServer DNS peer discovery (HA_PEER_DISCOVERY=dns + HA_SERVICE_NAME, self-exclusion + startup retry) + docker-compose.scale.yml so 'docker compose up --scale server=N' self-configures gossip peers. Active/active eventual only; Raft dynamic scaling stays on the Kubernetes StatefulSet path. #4b: RedundantClient --standby <Cold|Warm|Hot> selects the replica-set standby mode; --suite with --replicas>1 runs the browse/read/subscribe workload through the promoted leader facade. RedundantClient AOT-publishes clean. Docs: RedundantClient/RedundantServer READMEs updated; plans/28 moves #3/#4 to Delivered.
marcschier
added a commit
that referenced
this pull request
Aug 7, 2026
…level (OPCFoundation#4180) # Description Adds a **Generators companion-specification sample** alongside the existing pump sample, and a **`SiteCompositionServer`** that composes several device servers into one OpenUSD scene at a supervisory level — demonstrating that servers can be aggregated without mirroring their address spaces. Three things, in dependency order: ### 1. `GeneratorServer` A self-contained server realising the draft Generators spec (`http://opcfoundation.org/UA/Generators/`) end to end: N simulated generating sets, DI + Machinery integration, a twelve-state operating state machine, four protection alarms per set, six control methods, and a per-set OpenUSD twin. The organising idea is that **load fraction is the only independent variable**. Everything else is a function of it: ``` V̇_f(x) = 3.67 + 100·x fuel rate [L/h] η(x) = P(x) / (V̇_f(x) · ρ · LHV) efficiency S = P / PF I = S / (√3·V_LL) f = N·p / 120 ``` This is not stylistic. When each measurement is an independent oscillator — as the pump sample's simulation once was — a server happily publishes a duty point no real machine could occupy, and no test can catch it because there is nothing for the values to be inconsistent *with*. Deriving them from one variable means `P = √3·V·I·PF` and `η = P/(V̇·ρ·LHV)` hold at every tick by construction. The published `DATASHEET.md`, the engineering ranges, the trip points and the simulation all read the same constants in `GeneratorDatasheet.cs`, so the document and the server cannot describe different machines. The machine is a fictitious **SimGen Systems GenX-500** (400 kW prime / 440 kW standby, 400/230 V, 50 Hz, four-pole). Figures are representative of a real industrial genset class; no vendor is named anywhere in the code or docs. ### 2. Cross-server composition in the connector `RemoteSessionFactory` already existed in the client library but the connector CLI never set it, so cross-server composition was unreachable. `--federate` wires it up: the connector opens a session to each server named by a component binding, discovers its representations and drives its bindings into the same stage. It is **opt-in** because the endpoint the connector dials comes from the server being rendered rather than from the operator, which makes honouring it a trust decision. Federation is best-effort per component — a subordinate that is down is logged and skipped, and the rest of the scene still renders — which is the only `src/` change in this PR. ### 3. `SiteCompositionServer` Owns no devices. It publishes a site stage plus one cross-server component binding per subordinate, carrying that server's `ComponentServerUri` and `ComponentEndpointUrl`. Nothing is mirrored, so there is no cache to invalidate and no second copy of the truth. ## Notes for reviewers **Everything interesting in this PR was found by running the servers, not by reading the code.** Six defects, none of which looked wrong in review: - `IsShutdown` and `SubsystemName` are *optional* on `GeneratorProtectionAlarmType`, so the generated factory does not materialise them. `CreateOrReplace` alone produces a child that exists, appears in `GetChildren` and holds the right value — but carries **no `ReferenceTypeId`**, so no browse can reach it. Every alarm was publishing its trip without saying whether the trip stops the machine or which subsystem to go to. `AddXxx(context)` first is what gives the child its `HasProperty` reference. - **The protections could never fire.** Every trip point sits outside the band the datasheet curves produce — that is what a datasheet *means* — so all four alarms, the shutdown class, `ResetFaults` and the whole `Fault` branch of the state machine were unreachable while the README documented them as observable. Overload was worse: the load clamp ceiling was set to exactly the trip point, making a strictly-greater-than comparison unsatisfiable. Faults are now injectable, and the first set — the one the hero camera frames — develops one on a slow rotation. - **A shutdown trip removes the condition that caused it**, because oil pressure and coolant temperature are only supervised while the engine turns. Each alarm went active for one tick and cleared, leaving an operator with a stopped machine and no indication of why. Shutdown-class alarms now latch until the set leaves the shutdown state. Every unit test that checked the *condition* passed throughout — the defect only appears when the trip and the supervision interact over time. - **`Synchronizing` and `Paralleled` were declared, drawn in the README and never entered.** The first set now energises a dead bus and closes onto it while every other set synchronises to a live one — both how a real plant parallels, and what makes the two states observable. - **The tick raced client method calls.** The simulation tick runs on a thread-pool thread while method calls arrive on request threads, and both transition sets and write the same nodes. A tick moving a set to `Cooldown` and a concurrent `EmergencyStop` could interleave the paired `CurrentState` / `CurrentState.Id` writes and leave a client with a state *name* from one transition and a state *node* from the other — the exact failure the paired write exists to prevent, reintroduced by the threading model. Both paths now take one gate. - Low oil pressure supervised from raw speed **tripped every set during cranking**, because pressure has not built yet. Now gated on `IsSpinning`, which is what a real start-up bypass does. Smaller fixes: shutdown trips are applied after the whole evaluation pass (stopping mid-loop made the remaining conditions read healthy, collapsing simultaneous trips to whichever came first in the table); `ResetFaults` reports its clears as events (a client learns of condition state changes only through events, so a silent clear leaves an alarm-list client showing it forever); the start counter moved into the transition so commanded starts are counted; the federated connector closes the remote session if the connector constructor throws between taking ownership and registering it; and `prepare_machinery_nodeset.py` now *asserts* the IA namespace is last before removing it rather than only claiming so in its docstring — removing any earlier entry would silently renumber every namespace after it and rebind their NodeIds. **A model limitation is left visible rather than papered over.** `GeneratorStateMachineType` declares an emergency stop only out of `Running`, `Loaded` and `Paralleled`, so the sample refuses `EmergencyStop` from `Starting` and `Warmup`. A real panel stops from anywhere. That is the specification's shape, not this sample's choice, so it is pinned by a test and named in the docs. **`Model/` vendors a reduced Machinery nodeset**, derived mechanically by whitelist. The full official nodeset does not survive the model source generator (`MODELGEN003`) and drags in IA through a single optional `Stacklight` member a generating set does not have. Deriving it by script keeps the provenance checkable; the whitelist is the only thing to edit when more types are needed. **Never hand-edit the generated output.** **The federated scene renders end to end.** Getting there surfaced three more defects, all of which produced a plausible-looking scene with nothing in it: the generator sample's plant aggregation was created under an already-registered `DeviceSet` and so was invisible to every client (it had *never* rendered geometry, standalone or federated); the connector's asset fetch ran on the primary session only, so composition referenced layers that were never downloaded; and both generator colour bindings wrote `primvars:displayColor` to prims that did not declare it, so the renderer rejected every update while the file still looked correct. Cross-server components compose under the subordinate's own root, so the site layer now *places* `/Plant` and `/Powerhouse` rather than leaving them stacked on the origin. **`OpenUsdRepresentation` is now mounted with `HasAddIn`, not `HasComponent`** (review feedback). The nodeset says so explicitly — *"Mounted with HasAddIn"* — but every server in the tree used plain `HasComponent`. It survived because `HasAddIn` is a *subtype* of `HasComponent`: the representation still browses, still aggregates and still drives a twin, so every functional test passed before the fix and after it, and only a conformance checker could tell. Seven mount sites corrected. `PumpDeviceIntegrationServer` and `MinimalRobotServer` had hand-rolled the mount instead of calling the shared `CreateRepresentation` helper, which is exactly how they drifted from it. Both sample E2E suites now assert the reference type across **every** discovered representation — a narrower check would have missed the plant-level representation that arrived later from master still carrying `HasComponent`. **Live colour is not achievable in the current OpenUSD viewer, and that is now documented rather than worked around.** Proven with a standalone probe: `primvars:displayColor` resolves as `color3f[]` from the `UsdGeomGprim` schema whatever the layer declares, and the `OpenUsd 0.4.0-alpha` managed API has no writer for that type. Bound `UsdPreviewSurface` materials are not shaded either, so geometry renders grey unless it also carries an explicit `displayColor` primvar. The **visibility** bindings carry no such caveat and are what the samples rely on to show state. Filed upstream as [openusd-dotnet#2](marcschier/openusd-dotnet#2), [#3](marcschier/openusd-dotnet#3) and [#4](marcschier/openusd-dotnet#4), and linked from `docs/OpenUsd.md` so a reader can check whether they have since been fixed. ## Related Issues No tracking issue — this is additive sample and documentation work with a single small, self-contained change to `src/` (per-component error isolation and session-ownership hardening in `OpenUsdConnector.Composition.cs`). Happy to open one if maintainers would prefer it tracked. ## 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. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [x] 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. ### Testing The generator fixtures live in `tests/Opc.Ua.OpenUsd.Tests/Generator` — **82 tests**, no new project. `Opc.Ua.Di.Tests` would have been the natural home next to the pump fixtures, but both device samples source-generate their own reduced `Opc.Ua.Machinery` model and expose it via `InternalsVisibleTo`, so referencing both from one assembly makes every Machinery type ambiguous (CS0433); `Opc.Ua.OpenUsd.Tests` references no other sample and already hosts `RobotAssetContractTests`. The suite runs **870** on net10.0 and net48 (784 existing + 86) and **788** on net472, where the sample does not exist and only the framework-independent asset-contract tests run — forgetting exactly that exclusion broke CI on the sibling pump PR. The tests target the things in this sample that fail *quietly*: - **Datasheet conformance** holds the model to its own claim — rated speed is `120·f/p`, rated current follows from the rating, the fuel curve reproduces the published table, and `η = P/(V̇·ρ·LHV)` reconciles at every load. Efficiency is swept across the whole simulated range to show it stays inside (0,100) and rises monotonically; a fit that goes negative somewhere in its range is a coincidence that happens to look right at the duty point, not a model. A further test reads `DATASHEET.md` and checks the document quotes the figures the server actually serves. - **Drift between the two descriptions of the state machine** — the physics' `IsLegalTransition` and the model's `GeneratorStateMap` — is checked in *both* directions. A transition the physics permits but the map lacks moves a machine without telling a client; one the map holds but the physics refuses is dead weight that looks supported. - **Reachability at run time**, not just in the declared table — the test that catches states the model declares and nothing ever enters. - **That every protection can actually fire**, which is the half of the alarm contract that "a healthy set annunciates nothing" does not cover. A **hosted end-to-end fixture** connects a real client and asserts what the address space actually exposes — the aggregation at `/Powerhouse/Generators`, its component binding, and every per-set twin. That is the only kind of test that catches the registration defect above: the node object had the right browse name, binding and asset reference, so every test that inspected objects passed while no client could see it. **Every state-machine and protection fix was checked by mutation.** Restoring the clamp ceiling, the direct `Running → Loaded` path, the old start-counter placement, or removing the alarm opt-in each makes the corresponding test fail, naming the specific defect. A test that has never been seen to fail has not been shown to work. Verified against a running plant: `Synchronizing`, `Paralleled` and `Fault` all observed on a two-set server, with `HighCoolantTemperatureAlarm` seen active on the fault subject. Method behaviour verified separately — per-set distinct `CurrentState` nodes, `EmergencyStop` → `EmergencyStopped` with `Start` then refused as `BadInvalidState`, `ResetFaults` → `Off`, `SetOperatingMode(9999)` refused with the mode unchanged, and the other sets untouched throughout. Also verified as a three-server federated stage. 0 warnings on a clean Release rebuild of both samples, the client library, the connector and the tests, across every TFM. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe608993-f3c9-4779-a6b9-9a9eabfc24ba
marcschier
pushed a commit
that referenced
this pull request
Sep 2, 2026
…PCFoundation#4377) Fixes OPCFoundation#4370. `SupportsFilteredRetain` worked for the exact shape the unit tests exercised, but was unreachable for other filter targets, wrong for branches, and kept state that outlived the filter it was derived from. This addresses all seven gaps from the issue. ### 1 — reachable only via `InstanceStateSnapshot` `CanSendFilteredAlarm` now resolves the condition through a helper that accepts either a snapshot's `Handle` or a `ConditionState` passed directly. Anything else still degrades to plain `WhereClause.Evaluate`, which is now stated in the XML docs instead of left implicit. ### 2 — the commented-out `Retain` guard Behaviour is unchanged — that is a spec call — but the dead `if` is gone and the open question is written up in place with a link to the issue, so it is tracked somewhere more durable than a bare source comment. ### 3 — branches collide on the key The key is now composed of ConditionId **and** BranchId, so a condition and its branches no longer contend for one entry. ### 4 — branches never inherit the flag `CreateBranch` copies `SupportsFilteredRetain` into the branch explicitly. ### 5 — address-space wiring I checked the spec before touching this. Part 9 §5.5.2 says the Property *"is only provided on the ConditionType"*, and `i=32060` in the standard nodeset accordingly carries no `HasModellingRule` — so the generator and nodeset are right, and making it an instance child would be the deviation. Confirmed experimentally: flipping `StandardTypes.xml` to `ModellingRule="Optional"` does generate the full property / `GetChildren` / `FindChild` / `CopyTo` wiring, and its **only** address-space effect is stamping `ModellingRule_Optional` onto `i=32060` — which the standard nodeset does not have. That change is therefore not made here. The two halves are reconciled the other way instead: the C# property is documented as the server-side per-condition switch that is deliberately *not* an address-space child (clients read the flag from the type node, which the generated address space already builds), with a test locking that in. Since nothing walks it as a child, #4 is fixed by the explicit copy rather than by `Initialize`. ### 6 — `ConditionRefresh` bypassed the bookkeeping Fixed for free by 1. Refresh queues the raw `ConditionState`, which now resolves, so refreshed conditions are evaluated against the where clause and re-prime their entries. No new API was needed — the concern in the issue about refresh mutating the set turns out to be benign: an entry means "passed the where clause at the last evaluation", so a refresh of an in-scope condition removes and re-adds the same key. ### 7 — never cleared, never persisted `ModifyAttributes` discards the state when the where clause actually changes (select clauses are ignored — they only shape the fields of an event that is being sent anyway). Persistence added via `IStoredMonitoredItem.FilteredRetainConditionIds` → `StoredMonitoredItem` → `ToStorableMonitoredItem` / restore constructor, plus encode/decode in `SharedKeyValueSubscriptionStore` behind a new definition format version 3. ## Judgment calls worth a look - **`SetMonitoringMode` deliberately keeps the state.** A disabled item never reaches `CanSendFilteredAlarm` at all, so the entries still describe what the client was last told, and the trailing event is owed to it once reporting resumes. Documented rather than changed. - **`IStoredMonitoredItem` gained a member**, which is source-breaking for anyone with a custom subscription store. `TestStoredMonitoredItem` in the test suite needed the same one-line addition. ## Tests `tests/Opc.Ua.Server.Tests/FilterRetainTests.cs` grows from 16 to 26 tests, covering branches, `ConditionState` targets, filter modification (both changed and unchanged where clause) and a durable round trip. Each new test was verified to fail against the unfixed code by reverting the corresponding change individually. The suite also drops the reflection hazard the issue flagged: a `TestableMonitoredItem` subclass exposes the protected method, so a signature change now fails the build instead of the run. Its queue factory is owned by the fixture rather than disposed inside the call that hands it to the item. ## Verification Full solution builds clean. `Opc.Ua.Server.Tests` (4801), `Opc.Ua.Core.Tests` (4371), `Opc.Ua.Redundancy.Server.Tests` (573) and `Opc.Ua.History.Tests` (506) all pass on net10.0. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Bumps Moq from 4.16.1 to 4.17.1.
Changelog
Sourced from Moq's changelog.
Commits
dcf631eUpdate version to 4.17.1759aa05Update nuget API key4d052c1Merge pull request #1234 from stakx/stubbedpropertiessetupe30183bUpdate the changelog5014bd0Switch toConcurrentDictionaryfor better thread-safetye78509bRestore LINQ to Mocks' ability to set any propertya3e41a4Add dedicated setup type forSetupAllProperties5db2a42Remove currentSetupAllPropertiesimpla0243cdProperty setups are ignored on mocks instantiated usingMock.Of611652cUpdate version to 4.17.0Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot mergewill merge this PR after your CI passes on it@dependabot squash and mergewill squash and merge this PR after your CI passes on it@dependabot cancel mergewill cancel a previously requested merge and block automerging@dependabot reopenwill reopen this PR if it is closed@dependabot closewill close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)