771229b39f646cc5d4598506ae34e78dd45e0593
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
371bcb3f91 |
Resolve Worker.Tests-008..015 code-review findings
Worker.Tests-008: moved the misplaced WorkerLogRedactor test out of VariantConverterTests into Bootstrap/WorkerLogRedactorTests. Worker.Tests-009: renamed 46 snake_case alarm-test methods to PascalCase Method_Scenario_Expectation. Worker.Tests-010: replaced a weak Assert.Contains with an exact assertion against the real diagnostic message and corrected the XML doc. Worker.Tests-011: renamed and re-documented a cancellation test that overstated what it proved. Worker.Tests-012: added an oversized-frame (MessageTooLarge) test; renamed the mislabeled zero-length-payload test. Worker.Tests-013: removed the fixed-100ms ThrowIfCompletedAsync helper; the caller now races runTask deterministically. Worker.Tests-014: consolidated duplicated test fakes/helpers (FakeRuntimeSession, NoopComApartmentInitializer, NoopEventSink, frame helpers) into a shared TestSupport namespace. Worker.Tests-015: added MxAccessEventQueue coverage for drain-all (maxEvents 0), empty-queue drain, and enqueue-after-fault. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f711a55be4 |
A.2: replace AlarmClientConsumer with wnwrap-based polling consumer
Switch the worker's alarm-consumer surface from `aaAlarmManagedClient.AlarmClient` to `WNWRAPCONSUMERLib.wwAlarmConsumerClass` (CLSID 7AB52E5F-…) hosted by `wnwrapConsumer.dll`. The new path returns alarm records as a BSTR XML payload via `GetXmlCurrentAlarms2`, bypassing the FILETIME→DateTime auto-marshaling that crashed `GetHighPriAlarm` with ArgumentOutOfRangeException on every poll. Live captured 60/60 polls clean against `\DESKTOP-6JL3KKO\Galaxy!DEV` while a System Platform script flipped TestMachine_001.TestAlarm001 every 10s; the GUID, priority, state (UNACK_ALM ↔ UNACK_RTN), and ASCII-formatted timestamps arrived end-to-end. Implementation: - `Interop.WNWRAPCONSUMERLib.dll` generated via tlbimp, checked in under `lib/` so dev boxes don't need the SDK to build. - New `WnWrapAlarmConsumer` (replaces `AlarmClientConsumer`): owns a 500ms polling timer, parses `GetXmlCurrentAlarms2` output, diffs the snapshot keyed by alarm GUID, and raises one `MxAlarmTransitionEvent` per state change. Includes the Initialize→Register-before-Subscribe ordering fix found during Discovery probe runs. - New library-agnostic types `MxAlarmSnapshotRecord` / `MxAlarmStateKind` / `MxAlarmTransitionEvent` so the proto-build path is testable without an AVEVA install. - `AlarmRecordTransitionMapper` retired the COM-coupled `MapTransitionKind(eAlmTransitions)`; new pure helpers `ParseStateKind`, `MapTransition(prev, curr)`, and `ParseTransitionTimestampUtc` cover XML decode + state-delta logic. - `IMxAccessAlarmConsumer` event surface changed from `EventHandler<AlarmRecord>` to `EventHandler<MxAlarmTransitionEvent>` and `SnapshotActiveAlarms()` returns `MxAlarmSnapshotRecord` — decoupling the interface from any specific COM library. - Worker csproj drops `aaAlarmManagedClient` / `IAlarmMgrDataProvider` refs; adds `Interop.WNWRAPCONSUMERLib`. Tests: - 36 new unit tests (state-string mapping, prev/current → proto kind decision table, timestamp UTC reassembly, XML payload parser, 32-char hex GUID round-trip) covering everything that doesn't touch the live COM surface — all passing. - Skip-gated `WnWrapConsumerProbeTests.ProbeWnWrapConsumer` archives the live capture flow for regression / future probes. Docs: - `docs/AlarmClientDiscovery.md` "Option A — captured" section records sample XML payloads, the mangled `SetXmlAlarmQuery` round-trip (prefer `Subscribe` for filtering), the `GetStatistics` AccessViolationException quirk, and the worker-integration outline. Pre-existing failure noted (separate): `MxAccessInteropReference_ExistsOnlyInWorkerProject` was already failing on HEAD — the test project still references `ArchestrA.MxAccess` for the Skip-gated discovery probes. Not regressed by this change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1ac5bcafb2 |
worker: AlarmClientConsumer + transition mapper (PR A.5)
Wires the worker-side consumer for AVEVA alarm transitions over the
aaAlarmManagedClient API discovered in the prior foundation PR.
- IAlarmMgrDataProvider.dll referenced — exposes AlarmRecord +
eAlmTransitions / eQueryType / eSortFlags / eAlarmFilterState.
Both DLLs (aaAlarmManagedClient + IAlarmMgrDataProvider) load in
the worker's existing net48 x86 process; no new bitness boundary.
- IMxAccessAlarmConsumer abstraction — Subscribe / AcknowledgeByGuid
/ SnapshotActiveAlarms / AlarmRecordReceived event. Test seam.
- AlarmClientConsumer production wrapper — RegisterConsumer +
Subscribe + AlarmAckByGUID + GetStatistics-based active-alarm
walk, all delegated to AlarmClient. Uses AVEVA's managed event
surface (GetAlarmChangesCompleted on IAlarmMgrDataProvider) so
no Windows message pump is required — plain .NET events arrive
on the alarm-client's internal callback thread.
- AlarmRecordTransitionMapper — pure-function helpers:
MapTransitionKind(eAlmTransitions): ALM→Raise, ACK→Acknowledge,
RTN→Clear, others (SUB/ENB/DIS/SUP/REL/REMOVE)→Unspecified
so EventPump's decoding-failure counter records them.
ComposeFullReference(provider, group, name): Provider!Group.Name
format matching AVEVA's standard alarm-reference syntax.
Pinned during dev-rig validation (subsequent commits):
1. Confirm RegisterConsumer accepts hWnd=0 — if it requires a real
hwnd, the worker creates a hidden message-only window and
passes that handle. The managed event surface should make
this irrelevant but the AVEVA API is older than its managed
wrapper.
2. Wire AlarmClientConsumer.AlarmRecordReceived: the AVEVA
IAlarmMgrDataProvider.GetAlarmChangesCompleted event needs to
be hooked from inside the AlarmClient — find the proper
accessor (likely a property exposing the inner provider).
3. AlarmRecord field-by-field translation into the proto event
uses MxAccessAlarmEventSink.EnqueueTransition (existing
plumbing). The AlarmRecord field names (ar_OrigTime,
AlarmName, AckOperatorFullName, AckComment, etc.) are
pinned in the discovery dump preserved in
AlarmClientDiscoveryTests.
Tests: 127 pass (4 new ComposeFullReference cases + 1 Skip-gated
discovery probe). Transition-kind enum mapping is dev-rig-validated
rather than unit-tested because the AVEVA assembly is Private=false
on the reference and isn't copied to the test bin directory.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|