chore(gates): close adminui-followups by audit; R2-03 T11/T12 + reconfigure Task 3 PASSED, R2-10 re-diagnosed
The two items deferment.md §0.1 named as the remaining untracked engineering. adminui-followups (19 pending / 0 completed) — CLOSED by the overlap audit the plan itself asks for first, with no code written. All 19 tasks are shipped, superseded by v3, or moot. WS1's premise had also expired: it assumed driver-embedded tag lists in DriverConfig are the runtime source of truth, which v3 ended (the artifact populates RawTags). Its capability shipped in the v3 shape — TagConfigEditorMap + DeviceFormMap, both verified reachable from RawTagModal/DeviceModal rather than merely present. Live gates on docker-dev (image rebuilt: the rig was running a build 3 h older than the last code commit; parity asserted per container plus a positive check that the symbols under test are in the shipped DLLs): - R2-03 T11 PASSED — build 0 errors, Runtime.Tests 555/555, RoslynVirtualTagEvaluator 20/20. - R2-03 T12 PASSED — VT 42 -> 0x80020000 -> 42, staged WITHOUT a deployment (a Modbus register flipped on the fixture) so the VT child survived; a deploy-driven trip creates a fresh child with no last value, which is correct-by-design and masked the result twice. P7 confirmed: two byte-identical redeploys, zero disturbance. - driver-reconfigure Task 3 PASSED — a faulted driver adopted a corrected config and connected with the node's startedAt unchanged and RestartCount=0. - R2-10 T10 still OPEN, but the recorded cause was wrong. Not ConnectionBackoff throttling (the breaker opens on 2 failures / 30 s): the dead-endpoint failure mode never enters the resilience pipeline. IDriver.InitializeAsync is not invoker-wrapped (DriverInstanceActor.cs:707) and ModbusDriver swallows per-tag failures in BOTH directions, so even the plan's fallback trigger cannot work. Live-proven: a driver timing out every read against a blackhole reported ConsecutiveFailures=0 while the panel read "All targets healthy." Finding from T12: the Bad publish's documented "carrying the last-known value" is unobservable by any client — subscription and a raw Read service call both return NULL. The actor is correct; every existing failure assertion checked StatusCode alone, so the value half was asserted nowhere. Adds VirtualTagActorTests.The_Bad_result_carries_the_last_known_value, which proves the actor emits it. The documentation is what overstates.
This commit is contained in:
@@ -128,6 +128,31 @@ public sealed class VirtualTagActorTests : RuntimeActorTestBase
|
||||
recovered.Value.ShouldBe(42);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 02/S13: the Bad result must <b>carry the last-known value</b>, not just the Bad status.
|
||||
/// <para>Every other failure assertion in this file checks <c>StatusCode</c> alone, so the
|
||||
/// "carrying the last-known value" half of the S13 contract — stated in
|
||||
/// <c>VirtualTagActor</c>'s own xmldoc and in the R2-03 STATUS.md row — was asserted nowhere.
|
||||
/// Added while live-gating R2-03 T12, where a client observed the VT go Bad with a NULL value
|
||||
/// and there was no test to say whether the actor or the OPC UA layer dropped it.</para>
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void The_Bad_result_carries_the_last_known_value()
|
||||
{
|
||||
var parent = CreateTestProbe();
|
||||
var evaluator = new QueuedEvaluator(
|
||||
VirtualTagEvalResult.Ok(42), VirtualTagEvalResult.Failure("boom"));
|
||||
var actor = parent.ChildActorOf(VirtualTagActor.Props("vt-1", "expr", evaluator: evaluator));
|
||||
|
||||
actor.Tell(new VirtualTagActor.DependencyValueChanged("a", 1, DateTime.UtcNow));
|
||||
parent.ExpectMsg<VirtualTagActor.EvaluationResult>().Value.ShouldBe(42);
|
||||
|
||||
actor.Tell(new VirtualTagActor.DependencyValueChanged("a", 2, DateTime.UtcNow));
|
||||
var bad = parent.ExpectMsg<VirtualTagActor.EvaluationResult>();
|
||||
bad.StatusCode.ShouldBe(OpcUaStatus.BadInternalError);
|
||||
bad.Value.ShouldBe(42);
|
||||
}
|
||||
|
||||
/// <summary>02/S13: an evaluator that THROWS (not just returns Failure) also degrades quality —
|
||||
/// the try/catch path publishes a Bad EvaluationResult too.</summary>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user