code-reviews: 2026-06-18 re-review of array-write-ergonomics feature at 88915c3
Re-reviewed the 10 modules touched by the MxSparseArray / array-write ergonomics work (8df5ab3..88915c3). 16 new findings: - Server-057 (Medium): [] AddItem normalization skips AddItemBulk/AddBufferedItem - Client.Dotnet-030 (Medium): advise-supervisory missing from IsKnownGatewayCommand (dead command) - 14 Low: MxSparseArray doc/test gaps, advise-supervisory CLI gaps across clients, Client.Java-049 / Client.Python-037 version-bump consistency misses Worker.Tests and IntegrationTests clean. Worker unchanged by the feature, not re-reviewed.
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
|---|---|
|
||||
| Module | `src/ZB.MOM.WW.MxGateway.Tests` |
|
||||
| Reviewer | Claude Code |
|
||||
| Review date | 2026-06-16 |
|
||||
| Commit reviewed | `8df5ab3` |
|
||||
| Review date | 2026-06-18 |
|
||||
| Commit reviewed | `88915c3` |
|
||||
| Status | Re-reviewed |
|
||||
| Open findings | 0 |
|
||||
| Open findings | 1 |
|
||||
|
||||
## Checklist coverage
|
||||
|
||||
@@ -111,6 +111,23 @@ fakes in two test files.
|
||||
| 9 | Testing coverage | Issues found: Tests-026 (no test proves `EventStreamService` actually calls `IDashboardEventBroadcaster.Publish` for each event — the only consumers in tests are `Null` fakes). |
|
||||
| 10 | Documentation & comments | No issues found in this diff. |
|
||||
|
||||
### 2026-06-18 re-review (commit `88915c3`)
|
||||
|
||||
Re-review of the `8df5ab3..88915c3` diff. New files: `SparseArrayExpanderTests.cs`, `ArrayAddressNormalizerTests.cs`, `GatewayArrayWriteWiringTests.cs` (array-write feature tests); additions to `ConstraintEnforcerTests.cs` (bare-array-name authz fallback), `ProtobufContractRoundTripTests.cs` (ReplayGap round-trip), `GatewaySessionTests.cs` (failed-first-attach regression), `SessionEventDistributorTests.cs` (register-after-completion + DrainUntilFaultAsync fix), `GatewaySessionDashboardMirrorTests.cs` (Tests-039 release-gate fix), `GatewayOptionsValidatorTests.cs` (DetachGraceSeconds / ReplayBuffer bounds).
|
||||
|
||||
| # | Category | Result |
|
||||
|---|---|---|
|
||||
| 1 | Correctness & logic bugs | No issues found. All new tests assert the correct post-condition; `AddItem_BareArrayAddress_NormalizedOnWireAndInRegistration` correctly verifies re-normalization in `TrackCommandReply` via a bare-address `trackingCopy`; `DrainUntilFaultAsync` graceful-completion guard is correct. |
|
||||
| 2 | mxaccessgw conventions | No issues found. All new files use file-scoped namespaces, sealed classes, target-typed `new()`, PascalCase `Method_Condition_Result` names, and explicit types. |
|
||||
| 3 | Concurrency & thread safety | No issues found. `Register_AfterSourceCompletes_CompletesLateSubscriberInsteadOfHanging` correctly proves pump-completed ordering via early-subscriber drain before registering the late subscriber. The Tests-039 release-gate uses `TaskCompletionSource(RunContinuationsAsynchronously)` and `ActiveEventSubscriberCount == 1` gating. |
|
||||
| 4 | Error handling & resilience | No issues found. `SparseArrayExpanderTests` covers all six `RpcException(InvalidArgument)` paths (zero length, oversize length, out-of-range index, duplicate index, unsupported type, element-kind mismatch). |
|
||||
| 5 | Security | No issues found. The two new `ConstraintEnforcerTests` correctly pin both directions of the `[]` suffix fallback: bare array name resolves (no spurious denial); bare non-array/missing name still fails to resolve (no false positive). |
|
||||
| 6 | Performance & resource management | No issues found. `GatewayArrayWriteWiringTests.CapturingWorkerClient` implements `IAsyncDisposable` as `ValueTask.CompletedTask`; no unowned resource. `GatewaySessionTests.DetachGrace_FailedFirstAttach_DoesNotEnterGrace` uses `await using`. |
|
||||
| 7 | Design-document adherence | No issues found. Sparse-expansion and array-suffix normalization tests reflect the CLAUDE.md parity contract ("MXAccess has no partial-array write primitive"); the `ConstraintEnforcer` bare-name fallback tests match the `ArrayAddressNormalizer` contract. |
|
||||
| 8 | Code organization & conventions | No issues found. The `StubGalaxyHierarchyCache` is duplicated between `ArrayAddressNormalizerTests` and `GatewayArrayWriteWiringTests` (both in the same namespace), but both are `private sealed class` — duplication is confined and the existing Tests-007 / Tests-021 consolidation pattern applies only to test-support types shared across multiple test classes, not private fakes within a single class. Acceptable. |
|
||||
| 9 | Testing coverage | Issue found: Tests-040 (`GatewayArrayWriteWiringTests` covers `Write` and `WriteBulk` sparse expansion wiring through `GatewaySession.InvokeAsync` but omits the other six write variants — `WriteSecured`, `Write2`, `WriteSecured2`, `Write2Bulk`, `WriteSecuredBulk`, `WriteSecured2Bulk` — each of which has its own `case` arm in `NormalizeOutboundCommand` and could silently regress). |
|
||||
| 10 | Documentation & comments | No issues found. New files carry accurate class-level `<summary>` docs; test method summaries correctly describe pre/post conditions; the `DrainUntilFaultAsync` comment update precisely describes the new escape hatch. |
|
||||
|
||||
#### 2026-06-16 re-review (commit 8df5ab3)
|
||||
|
||||
Re-review of the gateway-test delta (session-resilience epic + §8). New tests are high quality (bounded async waits, FakeTimeProvider, deterministic gating, meaningful assertions). Verified the §8 FakeWorkerProcess consolidation did NOT drop the `entireProcessTree` kill assertion. Only Low coverage-gap / one latent helper footgun.
|
||||
@@ -724,3 +741,16 @@ The cancellation tests for `WorkerClient` in `WorkerClientTests` *do* exercise t
|
||||
**Recommendation:** Make the test deterministic — hold the worker stream until both the dashboard mirror and the gRPC subscriber have attached, then release, so neither subscriber can miss an event regardless of scheduling.
|
||||
|
||||
**Resolution:** 2026-06-17 — added a release-gate to the test's `FakeWorkerClient` (`HoldEventsUntilReleased()` / `ReleaseEvents()`; `ReadEventsAsync` awaits the gate before yielding, ungated by default so other tests are unaffected). The test now holds the stream, starts the gRPC reader on a background task, waits for `session.ActiveEventSubscriberCount == 1` (the internal dashboard mirror is excluded from the count, so this confirms the gRPC subscriber attached), then releases — both subscribers deterministically receive all three events. With the Server-056 production fix in place, the full `GatewaySessionDashboardMirrorTests` class now passes (5/5) instead of hanging.
|
||||
|
||||
### Tests-040
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Severity | Low |
|
||||
| Category | Testing coverage |
|
||||
| Location | `src/ZB.MOM.WW.MxGateway.Tests/Gateway/Sessions/GatewayArrayWriteWiringTests.cs` |
|
||||
| Status | Open |
|
||||
|
||||
**Description:** `GatewayArrayWriteWiringTests` covers two of eight sparse-write arms in `GatewaySession.NormalizeOutboundCommand`: `Write` (single) and `WriteBulk`. The remaining six arms — `WriteSecured`, `Write2`, `WriteSecured2`, `Write2Bulk`, `WriteSecuredBulk`, `WriteSecured2Bulk` — all call `ExpandValue(entry.Value)` through the same switch, but no wiring test exercises them through `GatewaySession.InvokeAsync`. The class summary says it covers "the single outbound choke point" and that "no sparse value is ever forwarded"; the claim is accurate for the two covered variants but unverified for the other six. A regression accidentally dropping one of the six remaining `case` arms, or shifting a brace so a case falls through to the default (no-op), would pass the entire `GatewayArrayWriteWiringTests` suite.
|
||||
|
||||
**Recommendation:** Add one wiring test per uncovered variant (or a single `[Theory]` over the six command kinds), constructing the matching command type with a `SparseArrayValue` and asserting `worker.LastCommand!.Command.<Variant>.Value.KindCase == MxValue.KindOneofCase.ArrayValue` after `session.InvokeAsync`. The `SparseArrayExpanderTests` already pin the expander logic exhaustively; the wiring tests need only check that the choke point invokes expansion for each variant, not the expansion semantics themselves. The four secured variants (`WriteSecured`, `Write2`, `WriteSecured2`, `WriteSecured2Bulk`) can reuse the same `CapturingWorkerClient` stub.
|
||||
|
||||
Reference in New Issue
Block a user