106 lines
3.7 KiB
C#
106 lines
3.7 KiB
C#
using System.Data;
|
|
using MBN_STOCK_WEBVIEW.Infrastructure;
|
|
using MMoneyCoderSharp.Data;
|
|
|
|
namespace MBN_STOCK_WEBVIEW.Infrastructure.Tests;
|
|
|
|
public sealed class DatabaseHealthServiceTests
|
|
{
|
|
[Fact]
|
|
public async Task CheckAsync_Unconfigured_ReturnsNotConfiguredWithoutQuery()
|
|
{
|
|
var executor = new StubDataQueryExecutor();
|
|
var service = new DatabaseHealthService(executor, new DatabaseOptions());
|
|
|
|
var status = await service.CheckAsync(DataSourceKind.Oracle);
|
|
|
|
Assert.Equal(DatabaseHealthState.NotConfigured, status.State);
|
|
Assert.Equal(DataSourceKind.Oracle, status.Source);
|
|
Assert.Equal(TimeSpan.Zero, status.Elapsed);
|
|
Assert.Equal(0, executor.CallCount);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(DataSourceKind.Oracle, "SELECT 1 FROM DUAL")]
|
|
[InlineData(DataSourceKind.MariaDb, "SELECT 1")]
|
|
public async Task CheckAsync_ConfiguredAndQuerySucceeds_ReturnsHealthy(
|
|
DataSourceKind source,
|
|
string expectedQuery)
|
|
{
|
|
var executor = new StubDataQueryExecutor
|
|
{
|
|
ExecuteAsyncHandler = (_, _, _, _) => Task.FromResult(new DataTable())
|
|
};
|
|
var service = new DatabaseHealthService(executor, TestOptions.CreateConfigured());
|
|
|
|
var status = await service.CheckAsync(source);
|
|
|
|
Assert.Equal(DatabaseHealthState.Healthy, status.State);
|
|
Assert.Equal(source, status.Source);
|
|
Assert.Equal(1, executor.CallCount);
|
|
Assert.Equal(expectedQuery, executor.LastQuery);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CheckAsync_ConfiguredAndQueryFails_ReturnsUnhealthyWithoutThrowing()
|
|
{
|
|
const string host = "health-host-sensitive-sentinel";
|
|
var executor = new StubDataQueryExecutor
|
|
{
|
|
ExecuteAsyncHandler = (_, _, _, _) => Task.FromException<DataTable>(
|
|
new DatabaseQueryException(DataSourceKind.MariaDb, isTransient: true))
|
|
};
|
|
var service = new DatabaseHealthService(executor, TestOptions.CreateConfigured());
|
|
|
|
var status = await service.CheckAsync(DataSourceKind.MariaDb);
|
|
|
|
Assert.Equal(DatabaseHealthState.Unhealthy, status.State);
|
|
Assert.Equal(DataSourceKind.MariaDb, status.Source);
|
|
Assert.DoesNotContain(host, status.UserMessage, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CheckAsync_ConfiguredAndQueryTimesOut_ReturnsTimedOut()
|
|
{
|
|
var executor = new StubDataQueryExecutor
|
|
{
|
|
ExecuteAsyncHandler = (_, _, _, _) => Task.FromException<DataTable>(
|
|
new DatabaseQueryTimeoutException(DataSourceKind.Oracle))
|
|
};
|
|
var service = new DatabaseHealthService(executor, TestOptions.CreateConfigured());
|
|
|
|
var status = await service.CheckAsync(DataSourceKind.Oracle);
|
|
|
|
Assert.Equal(DatabaseHealthState.TimedOut, status.State);
|
|
Assert.Equal(DataSourceKind.Oracle, status.Source);
|
|
}
|
|
}
|
|
|
|
internal sealed class StubDataQueryExecutor : IDataQueryExecutor
|
|
{
|
|
public Func<DataSourceKind, string, string, CancellationToken, Task<DataTable>>? ExecuteAsyncHandler
|
|
{
|
|
get;
|
|
init;
|
|
}
|
|
|
|
public int CallCount { get; private set; }
|
|
|
|
public string? LastQuery { get; private set; }
|
|
|
|
public DataTable Execute(DataSourceKind source, string tableName, string query) =>
|
|
ExecuteAsync(source, tableName, query).GetAwaiter().GetResult();
|
|
|
|
public Task<DataTable> ExecuteAsync(
|
|
DataSourceKind source,
|
|
string tableName,
|
|
string query,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
CallCount++;
|
|
LastQuery = query;
|
|
return ExecuteAsyncHandler?.Invoke(source, tableName, query, cancellationToken)
|
|
?? Task.FromResult(new DataTable());
|
|
}
|
|
}
|