using System.Diagnostics;
using Akka.Actor;
using Akka.TestKit.Xunit2;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.Extensions.Logging.Abstractions;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.ScriptExecution;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Streaming;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Actors;
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.Actors;
///
/// Test groups 1 and 2 — the regression pin for the trigger-evaluation starvation finding.
///
/// The finding. Trigger-expression evaluation used to be queued onto the same
/// fixed 8-thread that runs blocking script bodies. Eight
/// scripts blocked in synchronous I/O therefore stalled EVERY Expression trigger on the node —
/// scripts and alarms alike — for an unbounded time. Worse, the evaluation's 2 s timeout was
/// constructed INSIDE the queued body, so it did not start until the evaluation was dequeued:
/// the operator saw neither a raise nor a timeout, just silence.
///
/// The fix these tests pin. Evaluations are non-blocking by construction
/// ( exposes only reads over an in-memory snapshot, and
/// the trust gate has already denied I/O), so they run as plain async work on the shared .NET
/// thread pool behind — never on the blocking pool. And their
/// deadline is armed at ENQUEUE, so gate-wait time burns the same budget.
///
public class TriggerEvalStarvationTests : TestKit, IDisposable
{
private readonly SharedScriptLibrary _sharedLibrary;
/// Initializes a new instance of the TriggerEvalStarvationTests class.
public TriggerEvalStarvationTests()
{
var compilationService = new ScriptCompilationService(
NullLogger.Instance);
_sharedLibrary = new SharedScriptLibrary(
compilationService, NullLogger.Instance);
StarvationHooks.Gate = new SemaphoreSlim(0);
}
///
void IDisposable.Dispose()
{
StarvationHooks.Gate.Release(32);
Shutdown();
}
private static Script