docs(plans): close residual #6 (R5 merged); register row 40 (wall-clock-sleep absence-assertion test class)
This commit is contained in:
@@ -33,6 +33,7 @@ All 7 fix-now items landed via PLAN-04/05/06/07/08 (verified in review 08 round
|
|||||||
| 37 | **Two paged reads of `DeploymentRecords` with different contracts** | Found by R3 | `QueryDeploymentSummariesAsync` (CLI/ManagementActor: offset, no total, no instance join, instance-id-list scoping) and R3's `QueryDeploymentListPageAsync` (UI: total + instance join + site-id scoping) duplicate query logic. Consolidating on one contract — giving the CLI a total, both scoping by site — removes the duplication. Genuinely different contracts today, so not urgent. *(Low)* | Next time either query's shape changes |
|
| 37 | **Two paged reads of `DeploymentRecords` with different contracts** | Found by R3 | `QueryDeploymentSummariesAsync` (CLI/ManagementActor: offset, no total, no instance join, instance-id-list scoping) and R3's `QueryDeploymentListPageAsync` (UI: total + instance join + site-id scoping) duplicate query logic. Consolidating on one contract — giving the CLI a total, both scoping by site — removes the duplication. Genuinely different contracts today, so not urgent. *(Low)* | Next time either query's shape changes |
|
||||||
| 38 | **OtOpcUa: `RoslynVirtualTagEvaluatorTests` racing-clear test is load-fragile** (OtOpcUa repo, not this one) | Found by R4 during the full-suite bump verification | `Evaluate_racing_ClearCompiledScripts_never_fails_with_disposed` fails under full-solution parallel test load, passes 3/3 isolated: its design assumes at most one `ClearCompiledScripts` lands inside one evaluation (so the product's one-shot retry suffices); under contention two can. Same timing-assumption family as the R5 sweep, but lives in OtOpcUa. Test-side fix: bound clear cadence relative to observed evaluation latency, or assert on retry-exhaustion instead of zero failures. | Next OtOpcUa test session, or when it fails a run that matters |
|
| 38 | **OtOpcUa: `RoslynVirtualTagEvaluatorTests` racing-clear test is load-fragile** (OtOpcUa repo, not this one) | Found by R4 during the full-suite bump verification | `Evaluate_racing_ClearCompiledScripts_never_fails_with_disposed` fails under full-solution parallel test load, passes 3/3 isolated: its design assumes at most one `ClearCompiledScripts` lands inside one evaluation (so the product's one-shot retry suffices); under contention two can. Same timing-assumption family as the R5 sweep, but lives in OtOpcUa. Test-side fix: bound clear cadence relative to observed evaluation latency, or assert on retry-exhaustion instead of zero failures. | Next OtOpcUa test session, or when it fails a run that matters |
|
||||||
| 39 | **OtOpcUa: late-enabled replication cannot baseline pre-existing rows** (OtOpcUa repo, not this one) | Found by R4; documented in OtOpcUa's CLAUDE.md | `LocalDbSetup.OnReady` registers all four tables unconditionally on every driver node, so it can never pass `baselineExistingRows: true` (only correct when gated on replication being configured). Turning replication ON for a long-running default-OFF node converges on subsequent writes only — existing rows are never baselined. ScadaBridge closed this class with conditional registration + boot-time `DeregisterReplicated` self-heal (WP1.3/WP3.3); porting it is a behavior change beyond a pin bump (registered-set pinned by tests, deregistration must be pair-symmetric). Low current impact: site-a was enabled from fresh. | Before enabling replication on an established OtOpcUa node |
|
| 39 | **OtOpcUa: late-enabled replication cannot baseline pre-existing rows** (OtOpcUa repo, not this one) | Found by R4; documented in OtOpcUa's CLAUDE.md | `LocalDbSetup.OnReady` registers all four tables unconditionally on every driver node, so it can never pass `baselineExistingRows: true` (only correct when gated on replication being configured). Turning replication ON for a long-running default-OFF node converges on subsequent writes only — existing rows are never baselined. ScadaBridge closed this class with conditional registration + boot-time `DeregisterReplicated` self-heal (WP1.3/WP3.3); porting it is a behavior change beyond a pin bump (registered-set pinned by tests, deregistration must be pair-symmetric). Low current impact: site-a was enabled from fresh. | Before enabling replication on an established OtOpcUa node |
|
||||||
|
| 40 | **Wall-clock sleeps used as synchronization in tests (absence-assertion class)** | Found by the R5 sweep (`9fb52153`) — a different class from the one swept, deliberately left unfixed | Tests that sleep, then assert an *absence*: `ScriptDeadlineAtEnqueueTests.cs:105,128` (two `Thread.Sleep(2s)`, with `Assert.Equal(0, scheduler.DetachedThreadCount)` depending on the sleep out-racing the watchdog — worst offender), `DeploymentWarmThenGateTests.cs:117`, `SiteAlarmLiveCacheServiceTests.cs:195,216`, `DataConnectionActorTests.cs:435` (`Task.Delay(200)` to "settle" after an `AwaitCondition`). These fail toward false-pass rather than flake, so they don't trip CI — but each is a timing pin that weakens what the test proves. Fix pattern: replace the sleep with an explicit observable edge (or assert on the positive event with a bounded wait plus a negative control). | Next test-infra session, or the first time one of these areas regresses without its test catching it |
|
||||||
|
|
||||||
## Resolved (verified against the code 2026-07-10)
|
## Resolved (verified against the code 2026-07-10)
|
||||||
Rows removed from the Deferred table above once confirmed shipped. Kept here for traceability.
|
Rows removed from the Deferred table above once confirmed shipped. Kept here for traceability.
|
||||||
|
|||||||
@@ -124,8 +124,18 @@ Deliberately not fixed in this program — each has a stated reason, not an over
|
|||||||
5 places (kept at 16 as the DB read-page bound per finding F2) and documented
|
5 places (kept at 16 as the DB read-page bound per finding F2) and documented
|
||||||
`MaxBatchBytes`. Full 57-project suite green bar one unrelated pre-existing flake (register
|
`MaxBatchBytes`. Full 57-project suite green bar one unrelated pre-existing flake (register
|
||||||
row 38). Two OtOpcUa-side findings recorded as register rows 38–39.
|
row 38). Two OtOpcUa-side findings recorded as register rows 38–39.
|
||||||
6. **Fragile `SandboxTests` timing pin.** Pre-existing, unrelated to this remediation's changes;
|
6. ~~**Fragile `SandboxTests` timing pin.**~~ **RESOLVED 2026-08-15 (`ca30d17f`+`9fb52153`, R5).**
|
||||||
noted so it isn't mistaken for a regression if it flakes later.
|
Root-caused causally, not by loosening timeouts. The pin was a wall-clock
|
||||||
|
`CancellationTokenSource` (100 ms) raced against a fixed workload measured at 298 ms — fails
|
||||||
|
outright on faster hardware, and passes *vacuously* in the opposite direction because a
|
||||||
|
pre-cancelled token throws before the script body is entered. Replaced with a deterministic
|
||||||
|
same-thread cancellation edge plus a negative control; 600 ms of test sleeping removed. The
|
||||||
|
deferred sweep ran with it: 3 further instances of the `c4caebe9`/`cfa6acbf` flake class fixed
|
||||||
|
(`ScriptRunShedTests` — where `CollectReport` DRAINS the shed counter, so the fix accumulates
|
||||||
|
across polls; `SyncCallEmissionEndToEndTests`; `DebugStreamBridgeActorTests`), each with
|
||||||
|
fail-before-fix by injected delay + a suppression control; 2 ambiguous candidates cleared with
|
||||||
|
product-code evidence. Test-side only (`git diff src/` empty). A different timing-pin class
|
||||||
|
(wall-clock sleeps asserting absences) was found and registered, not fixed (register row 40).
|
||||||
7. ~~**Target-scale load test (deferred-work register #25).**~~ **RESOLVED 2026-08-15.** The
|
7. ~~**Target-scale load test (deferred-work register #25).**~~ **RESOLVED 2026-08-15.** The
|
||||||
follow-on validation ran: 10 sites x 500 instances x 75 tags = **375,000 live tag
|
follow-on validation ran: 10 sites x 500 instances x 75 tags = **375,000 live tag
|
||||||
subscriptions**, 37,518 updates/s achieved vs 37,500 nominal, **45,021,375 updates** over a
|
subscriptions**, 37,518 updates/s achieved vs 37,500 nominal, **45,021,375 updates** over a
|
||||||
|
|||||||
Reference in New Issue
Block a user