fix(site-runtime): a faulted seed trigger-expression eval adopts nothing instead of replaying as a real false (review 2026-10-21 follow-up L4)

This commit is contained in:
Joseph Doherty
2026-10-22 09:50:31 -04:00
parent d646f816a4
commit 89d8568fdf
3 changed files with 51 additions and 4 deletions
@@ -589,6 +589,33 @@ public class ScriptActorTests : TestKit, IDisposable
instance.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
}
/// <summary>
/// Follow-up L4: a SEED evaluation whose task faults carries no truth value. It used to be
/// replayed as a REAL false — stopping a running WhileTrue re-fire timer (and arming a
/// spurious fire on the next true evaluation). It now adopts nothing.
/// </summary>
[Fact]
public void ScriptActor_ExpressionWhileTrue_FaultedSeedEval_DoesNotStopReFiring()
{
var triggerExpr = CompileTriggerExpression("Attributes[\"Active\"]?.ToString() == \"yes\"");
var (actor, instance) = CreateTriggeredActor(
"ExprSeedFault",
"Expression",
"{\"expression\":\"Attributes[\\\"Active\\\"]?.ToString() == \\\"yes\\\"\",\"mode\":\"WhileTrue\"}",
TimeSpan.FromMilliseconds(300),
triggerExpr);
actor.Tell(Change("Active", "yes"));
instance.ExpectMsg<SetStaticAttributeCommand>(TimeSpan.FromSeconds(2)); // edge fire
instance.ExpectMsg<SetStaticAttributeCommand>(TimeSpan.FromSeconds(2)); // tick 1
actor.Tell(new ScriptActor.ExpressionEvalFailed(new ObjectDisposedException("scheduler"), SeedOnly: true));
// The condition still holds and nothing real said otherwise: the timer keeps re-firing.
instance.ExpectMsg<SetStaticAttributeCommand>(TimeSpan.FromSeconds(2));
instance.ExpectMsg<SetStaticAttributeCommand>(TimeSpan.FromSeconds(2));
}
/// <summary>Verifies that an on-true expression trigger fires once per false-to-true edge.</summary>
[Fact]
public void ScriptActor_ExpressionOnTrue_FiresOncePerFalseToTrueEdge()