55ae230fa4
- v2-ci.yml: upload-artifact@v4 -> @v3 + continue-on-error (act_runner reports as GHES and v4 refuses GHES, failing every run); runner-capacity diagnostic step; AKKA_TEST_TIMEFACTOR=3 on the test step. - Runtime/ControlPlane harnesses: akka.test.timefactor from AKKA_TEST_TIMEFACTOR (TestTimeFactor), single-expect-default 15s; ControlPlane gains PresenceBudget. - Leaked spinner threads: the infinite-loop timeout tests (Calculation, Host.IntegrationTests RoslynVirtualTagEvaluator, 3x Core.Scripting) pinned a core for the rest of the test process (abandoned, never stopped). Now a bounded 5 s wall-clock spin; outer compile-inclusive bound 30 s. - Real test races fixed: ScriptedAlarmEngine push-during-drain (Inactive is also the start state + persist-before-update => wait for the Cleared save); DriverReconnectE2e (both nodes host the driver; Created[] is last-writer-wins and ForceReconnect is a no-op while Connecting); ControlPlaneStarterOrder (lost-race heal waited for a 60 s refresh tick). - Fixed sleeps -> poll-for-condition: ReconnectSupervisor LastError, Modbus deadband steps (wait for observed reads), Modbus dispose hygiene precondition, FOCAS probe-loop log. - Short presence budgets -> PresenceBudget in the Runtime/ControlPlane tests seen failing on Gitea; Calculation Settle 10 -> 30 s. No assertion removed, nothing skipped. - infra/README.md §10 CI; stale TreatWarningsAsErrors comment in Directory.Build.props. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
39 lines
2.1 KiB
C#
39 lines
2.1 KiB
C#
using System.Globalization;
|
||
|
||
namespace ZB.MOM.WW.OtOpcUa.ControlPlane.Tests.Harness;
|
||
|
||
/// <summary>
|
||
/// The Akka TestKit time-dilation factor for this run, from the <c>AKKA_TEST_TIMEFACTOR</c> environment
|
||
/// variable (unset ⇒ 1, Akka's own default).
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// <c>akka.test.timefactor</c> is Akka's sanctioned answer to "this machine is slower than the one
|
||
/// the timeouts were sized on": TestKit multiplies every <c>ExpectMsg</c> / <c>ExpectTerminated</c> /
|
||
/// <c>AwaitAssert</c> / <c>AwaitCondition</c> / <c>ExpectNoMsg</c> duration by it — explicit
|
||
/// durations included (<c>RemainingOrDilated</c>). The Gitea CI leg sets it (#606): the whole
|
||
/// solution runs there at once on the CI runner, and a long tail of 2–8 s presence budgets that
|
||
/// never fail locally each failed in roughly one run in eight, a different test each time — a
|
||
/// distribution, not a defect, the same shape Gitea #500 hit inside Runtime.Tests.
|
||
/// </para>
|
||
/// <para>
|
||
/// Dilation cannot make a broken assertion pass: a presence wait still fails, just later, and an
|
||
/// absence window only gets LONGER (a stronger check). It does not reach <c>Ask</c> timeouts or
|
||
/// plain <c>Task.WaitAsync</c> budgets — those are sized from <c>ControlPlaneActorTestBase.PresenceBudget</c> instead.
|
||
/// </para>
|
||
/// </remarks>
|
||
internal static class TestTimeFactor
|
||
{
|
||
/// <summary>The environment variable the CI workflow sets.</summary>
|
||
public const string EnvironmentVariable = "AKKA_TEST_TIMEFACTOR";
|
||
|
||
/// <summary>The factor in effect: the variable's value when it parses to a number ≥ 1, else 1.</summary>
|
||
public static double Value { get; } =
|
||
double.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariable), NumberStyles.Float,
|
||
CultureInfo.InvariantCulture, out var f) && f >= 1 ? f : 1;
|
||
|
||
/// <summary>A HOCON line setting <c>akka.test.timefactor</c>, to append to a test config.</summary>
|
||
public static string Hocon =>
|
||
"\nakka.test.timefactor = " + Value.ToString(CultureInfo.InvariantCulture) + "\n";
|
||
}
|