feat: consolidate legacy parity migration baseline
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
|
||||
|
||||
public sealed class LegacyDatabaseHealthMonitorNativeContractTests
|
||||
{
|
||||
private static readonly string RepositoryRoot = FindRepositoryRoot();
|
||||
private static readonly string AppRoot = Path.Combine(
|
||||
RepositoryRoot,
|
||||
"src",
|
||||
"MBN_STOCK_WEBVIEW.LegacyParityApp");
|
||||
private static readonly string Window = File.ReadAllText(
|
||||
Path.Combine(AppRoot, "MainWindow.xaml.cs"));
|
||||
private static readonly string Monitor = File.ReadAllText(
|
||||
Path.Combine(AppRoot, "MainWindow.DatabaseHealth.cs"));
|
||||
private static readonly string Playout = File.ReadAllText(
|
||||
Path.Combine(AppRoot, "MainWindow.Playout.cs"));
|
||||
|
||||
[Fact]
|
||||
public void LegacyTenSecondMonitorStartsAndStopsWithTheActiveWindow()
|
||||
{
|
||||
Assert.Contains(
|
||||
"TimeSpan.FromSeconds(10)",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"await Task.Delay(DatabaseHealthPollingInterval, cancellationToken)",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"StartDatabaseHealthMonitor();",
|
||||
Window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_lifetimeCancellation.Cancel();\n CancelActiveDatabaseHealthCheck();",
|
||||
Normalize(Window),
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MonitorUsesBothConfiguredProvidersAndLogsOnlyClosedTransitions()
|
||||
{
|
||||
Assert.Contains(
|
||||
".HealthService\n .CheckAllAsync(healthCancellation.Token)",
|
||||
Normalize(Monitor),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"foreach (var status in statuses)",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"ObserveDatabaseHealthState(status.Source, status.State);",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_databaseHealthTransitions.TryObserveDatabaseState(",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_databaseHealthLogWriter.TryWrite(record)",
|
||||
Monitor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("status.UserMessage", Monitor, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("exception.Message", Monitor, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OperatorAndRefreshWorkCancelAndSerializeAgainstHealthProbes()
|
||||
{
|
||||
var dispatch = Slice(
|
||||
Window,
|
||||
"private async Task ProcessIntentAsync(",
|
||||
"private static bool IsNamedPlaylistModalIntent(");
|
||||
var databaseWait = RequiredIndex(
|
||||
dispatch,
|
||||
"await AcquirePriorityDatabaseActivityAsync(_lifetimeCancellation.Token)");
|
||||
var handle = RequiredIndex(dispatch, "await HandleIntentAsync(");
|
||||
Assert.True(databaseWait < handle);
|
||||
Assert.Contains("_databaseActivityGate.Release();", dispatch,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
var refresh = Slice(
|
||||
Playout,
|
||||
"private async Task RunRefreshLoopAsync(",
|
||||
"private bool TrySetRefreshFault(");
|
||||
databaseWait = RequiredIndex(
|
||||
refresh,
|
||||
"await AcquirePriorityDatabaseActivityAsync(token)");
|
||||
var refreshCall = RequiredIndex(refresh, "workflow.RefreshOnAirAsync");
|
||||
Assert.True(databaseWait < refreshCall);
|
||||
Assert.Contains("_databaseActivityGate.Release();", refresh,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OperatorPriorityClosesTheHealthProbeCancellationPublishRace()
|
||||
{
|
||||
var acquire = Slice(
|
||||
Monitor,
|
||||
"private async Task AcquirePriorityDatabaseActivityAsync(",
|
||||
"private void CancelActiveDatabaseHealthCheck()");
|
||||
var waiterIncrement = RequiredIndex(
|
||||
acquire,
|
||||
"Interlocked.Increment(ref _databaseActivityPriorityWaiterCount);");
|
||||
var cancel = RequiredIndex(acquire, "CancelActiveDatabaseHealthCheck();");
|
||||
var gateWait = RequiredIndex(
|
||||
acquire,
|
||||
"await _databaseActivityGate.WaitAsync(cancellationToken)");
|
||||
var waiterDecrement = RequiredIndex(
|
||||
acquire,
|
||||
"Interlocked.Decrement(ref _databaseActivityPriorityWaiterCount);");
|
||||
Assert.True(waiterIncrement < cancel);
|
||||
Assert.True(cancel < gateWait);
|
||||
Assert.True(gateWait < waiterDecrement);
|
||||
|
||||
var probe = Slice(
|
||||
Monitor,
|
||||
"private async Task CheckAndLogDatabaseHealthAsync(",
|
||||
"private async Task AcquirePriorityDatabaseActivityAsync(");
|
||||
var preAcquirePriorityCheck = RequiredIndex(
|
||||
probe,
|
||||
"Volatile.Read(ref _databaseActivityPriorityWaiterCount) != 0");
|
||||
var healthCancellationPublish = RequiredIndex(
|
||||
probe,
|
||||
"Interlocked.Exchange(\n ref _databaseHealthCheckCancellation,\n healthCancellation);");
|
||||
var postPublishPriorityCheck = RequiredIndex(
|
||||
probe,
|
||||
"Volatile.Read(ref _databaseActivityPriorityWaiterCount) != 0",
|
||||
healthCancellationPublish);
|
||||
var providerProbe = RequiredIndex(probe, ".CheckAllAsync(healthCancellation.Token)");
|
||||
Assert.True(preAcquirePriorityCheck < healthCancellationPublish);
|
||||
Assert.True(healthCancellationPublish < postPublishPriorityCheck);
|
||||
Assert.True(postPublishPriorityCheck < providerProbe);
|
||||
}
|
||||
|
||||
private static string Normalize(string value) =>
|
||||
value.Replace("\r\n", "\n", StringComparison.Ordinal);
|
||||
|
||||
private static string Slice(string value, string start, string end)
|
||||
{
|
||||
var startIndex = RequiredIndex(value, start);
|
||||
var endIndex = RequiredIndex(value, end, startIndex + start.Length);
|
||||
return value[startIndex..endIndex];
|
||||
}
|
||||
|
||||
private static int RequiredIndex(string value, string needle, int startIndex = 0)
|
||||
{
|
||||
var index = value.IndexOf(needle, startIndex, StringComparison.Ordinal);
|
||||
Assert.True(index >= 0, $"Required marker was not found: {needle}");
|
||||
return index;
|
||||
}
|
||||
|
||||
private static string FindRepositoryRoot()
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
if (File.Exists(Path.Combine(directory.FullName, "MBN_STOCK_WEBVIEW.sln")))
|
||||
{
|
||||
return directory.FullName;
|
||||
}
|
||||
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new DirectoryNotFoundException("Repository root was not found.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user