Files
MBN_STOCK_WEBVIEW/tests/MBN_STOCK_WEBVIEW.Infrastructure.Tests/NativeOperatorLogTransitionTrackerTests.cs

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 _));
}
}