184 lines
7.7 KiB
C#
184 lines
7.7 KiB
C#
using MBN_STOCK_WEBVIEW.Core.Playout;
|
|
using MBN_STOCK_WEBVIEW.Infrastructure.Diagnostics;
|
|
using MMoneyCoderSharp.Data;
|
|
|
|
namespace MBN_STOCK_WEBVIEW.Infrastructure.Tests;
|
|
|
|
public sealed class NativeOperatorLogTransitionTrackerTests
|
|
{
|
|
[Fact]
|
|
public void DatabaseMapping_CoversEveryClosedHealthState()
|
|
{
|
|
var expected = new Dictionary<DatabaseHealthState, NativeOperatorDatabaseState>
|
|
{
|
|
[DatabaseHealthState.NotConfigured] = NativeOperatorDatabaseState.NotConfigured,
|
|
[DatabaseHealthState.Healthy] = NativeOperatorDatabaseState.Healthy,
|
|
[DatabaseHealthState.Unhealthy] = NativeOperatorDatabaseState.Unhealthy,
|
|
[DatabaseHealthState.TimedOut] = NativeOperatorDatabaseState.TimedOut
|
|
};
|
|
|
|
Assert.Equal(Enum.GetValues<DatabaseHealthState>().Length, expected.Count);
|
|
foreach (var pair in expected)
|
|
{
|
|
Assert.True(NativeOperatorLogTransitionTracker.TryMapDatabaseState(
|
|
pair.Key,
|
|
out var actual));
|
|
Assert.Equal(pair.Value, actual);
|
|
}
|
|
Assert.False(NativeOperatorLogTransitionTracker.TryMapDatabaseState(
|
|
(DatabaseHealthState)int.MaxValue,
|
|
out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void TornadoMapping_CoversEveryClosedConnectionState()
|
|
{
|
|
var expected = new Dictionary<PlayoutConnectionState, NativeOperatorTornadoState>
|
|
{
|
|
[PlayoutConnectionState.Disabled] = NativeOperatorTornadoState.Disabled,
|
|
[PlayoutConnectionState.DryRunReady] = NativeOperatorTornadoState.DryRunReady,
|
|
[PlayoutConnectionState.Disconnected] = NativeOperatorTornadoState.Disconnected,
|
|
[PlayoutConnectionState.Connecting] = NativeOperatorTornadoState.Connecting,
|
|
[PlayoutConnectionState.Connected] = NativeOperatorTornadoState.Connected,
|
|
[PlayoutConnectionState.Reconnecting] = NativeOperatorTornadoState.Reconnecting,
|
|
[PlayoutConnectionState.Disconnecting] = NativeOperatorTornadoState.Disconnecting,
|
|
[PlayoutConnectionState.Faulted] = NativeOperatorTornadoState.Faulted,
|
|
[PlayoutConnectionState.OutcomeUnknown] = NativeOperatorTornadoState.OutcomeUnknown,
|
|
[PlayoutConnectionState.Disposed] = NativeOperatorTornadoState.Disposed
|
|
};
|
|
|
|
Assert.Equal(Enum.GetValues<PlayoutConnectionState>().Length, expected.Count);
|
|
foreach (var pair in expected)
|
|
{
|
|
Assert.True(NativeOperatorLogTransitionTracker.TryMapTornadoState(
|
|
pair.Key,
|
|
out var actual));
|
|
Assert.Equal(pair.Value, actual);
|
|
}
|
|
Assert.False(NativeOperatorLogTransitionTracker.TryMapTornadoState(
|
|
(PlayoutConnectionState)int.MaxValue,
|
|
out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void DatabaseTransitions_SuppressDuplicatesIndependentlyPerProvider()
|
|
{
|
|
var tracker = new NativeOperatorLogTransitionTracker();
|
|
|
|
Assert.True(tracker.TryObserveDatabaseState(
|
|
DataSourceKind.Oracle,
|
|
DatabaseHealthState.Healthy,
|
|
out var oracleHealthy));
|
|
Assert.Equal(NativeOperatorLogEvent.OracleStateChanged, oracleHealthy.Event);
|
|
Assert.Equal(NativeOperatorDatabaseState.Healthy, oracleHealthy.DatabaseState);
|
|
Assert.False(tracker.TryObserveDatabaseState(
|
|
DataSourceKind.Oracle,
|
|
DatabaseHealthState.Healthy,
|
|
out _));
|
|
|
|
Assert.True(tracker.TryObserveDatabaseState(
|
|
DataSourceKind.MariaDb,
|
|
DatabaseHealthState.Healthy,
|
|
out var mariaHealthy));
|
|
Assert.Equal(NativeOperatorLogEvent.MariaDbStateChanged, mariaHealthy.Event);
|
|
Assert.False(tracker.TryObserveDatabaseState(
|
|
DataSourceKind.MariaDb,
|
|
DatabaseHealthState.Healthy,
|
|
out _));
|
|
|
|
Assert.True(tracker.TryObserveDatabaseState(
|
|
DataSourceKind.Oracle,
|
|
DatabaseHealthState.TimedOut,
|
|
out var oracleTimedOut));
|
|
Assert.Equal(NativeOperatorDatabaseState.TimedOut, oracleTimedOut.DatabaseState);
|
|
Assert.False(tracker.TryObserveDatabaseState(
|
|
(DataSourceKind)int.MaxValue,
|
|
DatabaseHealthState.Healthy,
|
|
out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void TornadoTransitions_SuppressOnlyIdenticalConsecutiveStates()
|
|
{
|
|
var tracker = new NativeOperatorLogTransitionTracker();
|
|
|
|
Assert.True(tracker.TryObserveTornadoState(
|
|
PlayoutConnectionState.Disconnected,
|
|
out var disconnected));
|
|
Assert.Equal(NativeOperatorTornadoState.Disconnected, disconnected.TornadoState);
|
|
Assert.False(tracker.TryObserveTornadoState(
|
|
PlayoutConnectionState.Disconnected,
|
|
out _));
|
|
Assert.True(tracker.TryObserveTornadoState(
|
|
PlayoutConnectionState.Connecting,
|
|
out var connecting));
|
|
Assert.Equal(NativeOperatorTornadoState.Connecting, connecting.TornadoState);
|
|
Assert.True(tracker.TryObserveTornadoState(
|
|
PlayoutConnectionState.Disconnected,
|
|
out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void CommandTracker_EmitsOneRequestAndExactlyOneMatchingTerminalRecord()
|
|
{
|
|
var tracker = new NativeOperatorCommandLogTracker();
|
|
|
|
Assert.True(tracker.TryBegin(
|
|
NativeOperatorPlayoutCommand.Prepare,
|
|
out var requested));
|
|
Assert.Equal(NativeOperatorLogEvent.PlayoutCommandRequested, requested.Event);
|
|
Assert.Equal(NativeOperatorPlayoutCommand.Prepare, requested.Command);
|
|
Assert.False(tracker.TryComplete(
|
|
NativeOperatorPlayoutCommand.Next,
|
|
NativeOperatorPlayoutCompletion.Succeeded,
|
|
out _));
|
|
Assert.True(tracker.TryComplete(
|
|
NativeOperatorPlayoutCommand.Prepare,
|
|
NativeOperatorPlayoutCompletion.Rejected,
|
|
out var completed));
|
|
Assert.Equal(NativeOperatorLogEvent.PlayoutCommandCompleted, completed.Event);
|
|
Assert.Equal(NativeOperatorPlayoutCompletion.Rejected, completed.Completion);
|
|
Assert.False(tracker.TryComplete(
|
|
NativeOperatorPlayoutCommand.Prepare,
|
|
NativeOperatorPlayoutCompletion.Succeeded,
|
|
out _));
|
|
Assert.False(tracker.TryMarkCurrentOutcomeUnknown(out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void CommandTracker_TimeoutOutcomeWinsAndSuppressesLateCompletion()
|
|
{
|
|
var tracker = new NativeOperatorCommandLogTracker();
|
|
Assert.True(tracker.TryBegin(NativeOperatorPlayoutCommand.TakeIn, out _));
|
|
|
|
Assert.True(tracker.TryMarkCurrentOutcomeUnknown(out var unknown));
|
|
Assert.Equal(NativeOperatorLogEvent.OutcomeUnknown, unknown.Event);
|
|
Assert.Equal(NativeOperatorPlayoutCommand.TakeIn, unknown.Command);
|
|
Assert.False(tracker.TryComplete(
|
|
NativeOperatorPlayoutCommand.TakeIn,
|
|
NativeOperatorPlayoutCompletion.Succeeded,
|
|
out _));
|
|
|
|
Assert.True(tracker.TryBegin(NativeOperatorPlayoutCommand.Next, out _));
|
|
Assert.True(tracker.TryMarkOutcomeUnknown(
|
|
NativeOperatorPlayoutCommand.Next,
|
|
out var secondUnknown));
|
|
Assert.Equal(NativeOperatorLogEvent.OutcomeUnknown, secondUnknown.Event);
|
|
}
|
|
|
|
[Fact]
|
|
public void CommandTracker_UndefinedScalarsFailClosed()
|
|
{
|
|
var tracker = new NativeOperatorCommandLogTracker();
|
|
|
|
Assert.False(tracker.TryBegin((NativeOperatorPlayoutCommand)int.MaxValue, out _));
|
|
Assert.False(tracker.TryComplete(
|
|
NativeOperatorPlayoutCommand.Prepare,
|
|
(NativeOperatorPlayoutCompletion)int.MaxValue,
|
|
out _));
|
|
Assert.False(tracker.TryMarkOutcomeUnknown(
|
|
(NativeOperatorPlayoutCommand)int.MaxValue,
|
|
out _));
|
|
}
|
|
}
|