fix(review): calc ReadOne reports an inputs-Bad publish; VT inputs-bad counter ticks only on a real report

This commit is contained in:
Joseph Doherty
2026-08-20 11:48:41 -04:00
parent 74794f4365
commit 886082fec7
6 changed files with 152 additions and 6 deletions
@@ -270,6 +270,38 @@ public sealed class CalculationDriverInputQualityTests
read[0].Value.ShouldBe(bad.Snapshot.Value);
}
/// <summary>
/// A tag whose ONLY publish was inputs-Bad — it never produced a value — must read back that Bad
/// status, not <c>BadWaitingForInitialData</c>. Guarding the read on "has a value" rather than
/// "has published" made a polled read say "never polled" while the subscriber on the same node had
/// been told <c>BadNoCommunication</c>: the two clients disagree, and the read is the one that
/// lies (something HAS been observed about this tag — that its input is dead).
/// </summary>
[Fact]
public async Task ReadAsync_after_an_inputs_Bad_with_no_prior_value_reports_the_bad_status()
{
var (driver, published, _) = Build(CalcTag(SumTag, SumScript));
await driver.InitializeAsync("{}", TestContext.Current.CancellationToken);
// The first thing that ever happens to this tag is a dead input — no successful evaluation, so
// there is no last value to carry.
driver.OnDependencyValue("src/a", null, StatusBadNoCommunication, DateTime.UtcNow);
driver.OnDependencyValue("src/b", 20.0, StatusGood, DateTime.UtcNow);
await Settle(driver);
published.Count.ShouldBe(1);
published.TryDequeue(out var bad).ShouldBeTrue();
bad!.Snapshot.StatusCode.ShouldBe(StatusBadNoCommunication);
bad.Snapshot.Value.ShouldBeNull();
var read = await driver.ReadAsync([SumTag], TestContext.Current.CancellationToken);
read[0].StatusCode.ShouldBe(StatusBadNoCommunication);
read[0].StatusCode.ShouldNotBe(StatusBadWaitingForInitialData,
"something HAS been observed about this tag — that its input is dead");
read[0].Value.ShouldBeNull();
}
/// <summary>A never-evaluated tag still reads BadWaitingForInitialData (regression).</summary>
[Fact]
public async Task An_unevaluated_tag_still_reads_BadWaitingForInitialData()