Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Omika.Diagnostics.Configuration;
|
||||
using Omika.Diagnostics.Data;
|
||||
using Omika.Diagnostics.Import;
|
||||
using Omika.Diagnostics.Worker;
|
||||
|
||||
namespace Omika.Diagnostics.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Vérifie que le conteneur DI du Diagnostics Worker construit réellement
|
||||
/// <see cref="DiagnosticImporter"/> et les hosted services (régression de
|
||||
/// l'incident production « Unable to resolve service for type
|
||||
/// DiagnosticImportOptions »). Le host est construit avec
|
||||
/// <c>ValidateOnBuild</c> + <c>ValidateScopes</c> pour détecter ce type d'erreur
|
||||
/// à la construction (le test échouait avec l'ancien code).
|
||||
/// </summary>
|
||||
public class DiagnosticWorkerDependencyInjectionTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkerHost_ServiceProviderBuilds_WithValidation()
|
||||
{
|
||||
// Avec l'ancien constructeur (DiagnosticImportOptions concret), ce Build()
|
||||
// levait « Unable to resolve service for type DiagnosticImportOptions ».
|
||||
using IHost host = BuildWorkerHost();
|
||||
|
||||
Assert.NotNull(host.Services);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WorkerHost_DiagnosticImporter_IsResolvable()
|
||||
{
|
||||
using IHost host = BuildWorkerHost();
|
||||
|
||||
DiagnosticImporter importer = host.Services.GetRequiredService<DiagnosticImporter>();
|
||||
|
||||
Assert.NotNull(importer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WorkerHost_DiagnosticImportOptions_AreResolvedAndBound()
|
||||
{
|
||||
using IHost host = BuildWorkerHost();
|
||||
|
||||
DiagnosticImportOptions options = host.Services
|
||||
.GetRequiredService<IOptions<DiagnosticImportOptions>>()
|
||||
.Value;
|
||||
|
||||
Assert.NotNull(options);
|
||||
// La configuration in-memory prime sur les valeurs par défaut (BatchSize=100).
|
||||
Assert.Equal(50, options.BatchSize);
|
||||
Assert.Equal("import-checkpoint.json", options.CheckpointFileName);
|
||||
Assert.Equal(@"C:\Omika\Data\DiagnosticsWorker\Checkpoint", options.CheckpointDirectory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WorkerHost_DiagnosticStoreOptions_ConnectionStringOverride_Wins()
|
||||
{
|
||||
using IHost host = BuildWorkerHost();
|
||||
|
||||
DiagnosticStoreOptions store = host.Services
|
||||
.GetRequiredService<IOptions<DiagnosticStoreOptions>>()
|
||||
.Value;
|
||||
|
||||
// La surcharge standard ConnectionStrings:DiagnosticsDatabase (variable
|
||||
// d'environnement serveur) prime sur Diagnostics:ConnectionString.
|
||||
Assert.Equal(
|
||||
"Host=localhost;Database=omika_diagnostics;Username=diagnostics_worker",
|
||||
store.ConnectionString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WorkerHost_HostedServices_AreResolvable()
|
||||
{
|
||||
using IHost host = BuildWorkerHost();
|
||||
|
||||
List<IHostedService> hosted = host.Services.GetServices<IHostedService>().ToList();
|
||||
|
||||
Assert.Contains(hosted, s => s is DiagnosticImportWorker);
|
||||
Assert.Contains(hosted, s => s is DiagnosticRetentionWorker);
|
||||
Assert.Contains(hosted, s => s is DiagnosticTelemetryRetentionWorker);
|
||||
}
|
||||
|
||||
private static IHost BuildWorkerHost()
|
||||
{
|
||||
// Configuration in-memory : aucune valeur secrète. La chaîne PostgreSQL
|
||||
// est un placeholder sans mot de passe (jamais ouverte : les repositories
|
||||
// sont construits sans connexion).
|
||||
IConfiguration configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["Diagnostics:ConnectionString"] = "Host=ignored;Database=ignored",
|
||||
["Diagnostics:Import:BatchSize"] = "50",
|
||||
["Diagnostics:Import:CheckpointFileName"] = "import-checkpoint.json",
|
||||
["Diagnostics:Import:CheckpointDirectory"] = @"C:\Omika\Data\DiagnosticsWorker\Checkpoint",
|
||||
["Observability:Remote:Directory"] = @"C:\Omika\Data\Api\Diagnostics\Jsonl",
|
||||
// Surcharge standard (serveur) : prime sur Diagnostics:ConnectionString.
|
||||
["ConnectionStrings:DiagnosticsDatabase"] = "Host=localhost;Database=omika_diagnostics;Username=diagnostics_worker"
|
||||
})
|
||||
.Build();
|
||||
|
||||
// Reproduit Program.cs du Diagnostics Worker, avec validation DI stricte
|
||||
// (ValidateOnBuild + ValidateScopes) pour piéger les dépendances non
|
||||
// enregistrées.
|
||||
return new HostBuilder()
|
||||
.UseDefaultServiceProvider(options =>
|
||||
{
|
||||
options.ValidateOnBuild = true;
|
||||
options.ValidateScopes = true;
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddLogging();
|
||||
services.AddOmikaDiagnosticData(configuration);
|
||||
services.AddHostedService<DiagnosticImportWorker>();
|
||||
services.AddHostedService<DiagnosticRetentionWorker>();
|
||||
services.AddHostedService<DiagnosticTelemetryRetentionWorker>();
|
||||
})
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user