feat: complete Oracle and MariaDB WebView data layer
This commit is contained in:
132
tools/MBN_STOCK_WEBVIEW.DbSmoke/Program.cs
Normal file
132
tools/MBN_STOCK_WEBVIEW.DbSmoke/Program.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using MBN_STOCK_WEBVIEW.Infrastructure;
|
||||
using MMoneyCoderSharp.Data;
|
||||
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
using var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(3));
|
||||
Console.CancelKeyPress += (_, eventArgs) =>
|
||||
{
|
||||
eventArgs.Cancel = true;
|
||||
cancellation.Cancel();
|
||||
};
|
||||
|
||||
var configurationPath = GetConfigurationPath(args);
|
||||
|
||||
try
|
||||
{
|
||||
var runtime = DatabaseRuntime.CreateDefault(configurationPath);
|
||||
var statuses = await runtime.HealthService.CheckAllAsync(cancellation.Token);
|
||||
|
||||
foreach (var status in statuses)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"{status.Source}: {status.State} ({status.Elapsed.TotalMilliseconds:F0} ms) - {status.UserMessage}");
|
||||
}
|
||||
|
||||
if (statuses.Any(status => status.State != DatabaseHealthState.Healthy))
|
||||
{
|
||||
Console.Error.WriteLine("Smoke test stopped because both database health probes must be healthy.");
|
||||
return 2;
|
||||
}
|
||||
|
||||
await VerifyOracleServerVersionAsync(runtime.Executor, cancellation.Token);
|
||||
|
||||
var service = new LegacyMarketDataService(runtime.Executor);
|
||||
await VerifySnapshotAsync(service, MarketDataView.Kospi, cancellation.Token);
|
||||
await VerifySnapshotAsync(service, MarketDataView.Kosdaq, cancellation.Token);
|
||||
await VerifySnapshotAsync(service, MarketDataView.Index, cancellation.Token);
|
||||
await VerifySnapshotAsync(service, MarketDataView.Overseas, cancellation.Token);
|
||||
|
||||
Console.WriteLine("REAL_DB_SMOKE: PASS");
|
||||
return 0;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.Error.WriteLine("REAL_DB_SMOKE: CANCELED_OR_TIMED_OUT");
|
||||
return 3;
|
||||
}
|
||||
catch (DatabaseInfrastructureException exception)
|
||||
{
|
||||
Console.Error.WriteLine($"REAL_DB_SMOKE: FAIL - {exception.Message}");
|
||||
return 1;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.Error.WriteLine("REAL_DB_SMOKE: FAIL - An unexpected error occurred. No provider details were printed.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static string? GetConfigurationPath(string[] arguments)
|
||||
{
|
||||
if (arguments.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (arguments.Length == 2 && arguments[0].Equals("--config", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return arguments[1];
|
||||
}
|
||||
|
||||
throw new DatabaseConfigurationException("Usage: MBN_STOCK_WEBVIEW.DbSmoke [--config <path>]");
|
||||
}
|
||||
|
||||
static async Task VerifyOracleServerVersionAsync(
|
||||
IDataQueryExecutor executor,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
const string query =
|
||||
"SELECT VERSION FROM PRODUCT_COMPONENT_VERSION " +
|
||||
"WHERE PRODUCT LIKE 'Oracle Database%' FETCH FIRST 1 ROWS ONLY";
|
||||
|
||||
var table = await executor.ExecuteAsync(
|
||||
DataSourceKind.Oracle,
|
||||
"OracleVersion",
|
||||
query,
|
||||
cancellationToken);
|
||||
|
||||
if (table.Rows.Count == 0 || table.Columns.Count == 0)
|
||||
{
|
||||
throw new DatabaseConfigurationException("Oracle 서버 버전을 확인할 수 없습니다.");
|
||||
}
|
||||
|
||||
var version = Convert.ToString(table.Rows[0][0], CultureInfo.InvariantCulture) ?? string.Empty;
|
||||
var match = Regex.Match(version, @"(?<!\d)(?<major>\d{2})(?:\.\d+)", RegexOptions.CultureInvariant);
|
||||
if (!match.Success ||
|
||||
!int.TryParse(match.Groups["major"].Value, NumberStyles.None, CultureInfo.InvariantCulture, out var major))
|
||||
{
|
||||
throw new DatabaseConfigurationException("Oracle 서버 주 버전을 판별할 수 없습니다.");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Oracle server major version: {major}");
|
||||
if (major < 19)
|
||||
{
|
||||
throw new DatabaseConfigurationException(
|
||||
"Oracle.ManagedDataAccess.Core 23.26.200은 Oracle Database 19c 이상이 필요합니다.");
|
||||
}
|
||||
}
|
||||
|
||||
static async Task VerifySnapshotAsync(
|
||||
IMarketDataService service,
|
||||
MarketDataView view,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var snapshot = await service.GetAsync(view, maximumRowsPerTable: 5, cancellationToken);
|
||||
if (snapshot.Tables.Count == 0)
|
||||
{
|
||||
throw new DatabaseConfigurationException($"{view} 조회 결과에 데이터셋이 없습니다.");
|
||||
}
|
||||
|
||||
foreach (var table in snapshot.Tables)
|
||||
{
|
||||
if (table.Columns.Count == 0)
|
||||
{
|
||||
throw new DatabaseConfigurationException($"{view}/{table.Name} 결과 열이 없습니다.");
|
||||
}
|
||||
|
||||
Console.WriteLine(
|
||||
$"{view}/{table.Source}/{table.Name}: {table.TotalRowCount.ToString(CultureInfo.InvariantCulture)} rows");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user