Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Omika.Core.Observability.Identity;
|
||||
using Omika.Core.Observability.Outbox;
|
||||
using Omika.Diagnostics.Data;
|
||||
using Omika.Diagnostics.Import;
|
||||
using Omika.Diagnostics.Models;
|
||||
using Omika.Diagnostics.Tests.Fakes;
|
||||
|
||||
namespace Omika.Diagnostics.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Tâche 13-E — E12 + §38 : compatibilité d'un JSONL produit par Omika.Worker avec le
|
||||
/// pipeline d'import (JsonlDiagnosticSource → DiagnosticImporter → DiagnosticEventRecord)
|
||||
/// et NON-ÉCRASEMENT du contexte du producteur par Omika.Diagnostics.Worker.
|
||||
///
|
||||
/// Un événement Worker portant <c>ServerInstance = WKR-SRV-01</c> doit arriver dans
|
||||
/// <c>DiagnosticEventRecord</c> avec EXACTEMENT <c>WKR-SRV-01</c>, jamais remplacé par
|
||||
/// le nom de machine de l'importeur. Le contexte (ClientCode/ServerInstance/Environment)
|
||||
/// représente le composant qui a PRODUIT l'événement, pas celui qui l'importe.
|
||||
/// Aucun PostgreSQL réel : FakeDiagnosticEventRepository (§51).
|
||||
/// </summary>
|
||||
public class WorkerSyncImportContextTests : IDisposable
|
||||
{
|
||||
private readonly string _dir = CreateTempDirectory();
|
||||
|
||||
public void Dispose() => DeleteDirectory(_dir);
|
||||
|
||||
// --------------------------- E12 + §38 : import complet ---------------------
|
||||
[Fact]
|
||||
public async Task WorkerJsonl_ImportsToRecord_PreservingProducerContext()
|
||||
{
|
||||
// 1. Production d'un événement Worker (format RemoteDiagnosticIngestionStore,
|
||||
// fichier omika-mobile-diagnostic-*.jsonl) avec contexte du producteur.
|
||||
Guid operationId = Guid.NewGuid();
|
||||
Guid eventId = Guid.NewGuid();
|
||||
var context = new DiagnosticDeploymentContext
|
||||
{
|
||||
ClientCode = "CLIENT-A",
|
||||
ServerInstance = "WKR-SRV-01",
|
||||
Environment = "Production"
|
||||
};
|
||||
|
||||
await WriteWorkerEventAsync(eventId, operationId, context);
|
||||
|
||||
// 2. Import par Omika.Diagnostics.Worker (JsonlDiagnosticSource + importer).
|
||||
var repository = new FakeDiagnosticEventRepository();
|
||||
var importer = new DiagnosticImporter(
|
||||
new JsonlDiagnosticSource(_dir, "import-checkpoint.json"),
|
||||
repository,
|
||||
Options.Create(new DiagnosticImportOptions { BatchSize = 100, Source = "worker" }));
|
||||
|
||||
DiagnosticImportResult result = await importer.ImportOnceAsync();
|
||||
|
||||
// 3. L'événement est lisible et importé (aucun format incompatible).
|
||||
Assert.True(result.Succeeded);
|
||||
Assert.Equal(1, result.ImportedCount);
|
||||
Assert.Equal(0, result.DroppedCount);
|
||||
|
||||
// 4. Le contexte du PRODUCTEUR est conservé, jamais remplacé par l'importeur.
|
||||
IReadOnlyList<DiagnosticEventRecord> records = await repository.GetByOperationIdAsync(operationId);
|
||||
DiagnosticEventRecord record = Assert.Single(records);
|
||||
|
||||
Assert.Equal("CLIENT-A", record.ClientCode);
|
||||
Assert.Equal("WKR-SRV-01", record.ServerInstance);
|
||||
Assert.NotEqual(Environment.MachineName, record.ServerInstance);
|
||||
Assert.Equal("Production", record.Environment);
|
||||
Assert.Equal("Omika.Worker", record.Component);
|
||||
Assert.Equal("OMK-WKR-SYNC-001", record.EventCode);
|
||||
Assert.Equal("worker", record.Source);
|
||||
Assert.Equal(operationId, record.OperationId);
|
||||
}
|
||||
|
||||
// --------------------------- Helpers -----------------------------------------
|
||||
private async Task WriteWorkerEventAsync(
|
||||
Guid eventId,
|
||||
Guid operationId,
|
||||
DiagnosticDeploymentContext context)
|
||||
{
|
||||
var store = new RemoteDiagnosticIngestionStore(new RemoteDiagnosticOptions { Directory = _dir });
|
||||
|
||||
var evt = new DiagnosticEventDto
|
||||
{
|
||||
EventId = eventId,
|
||||
EventCode = "OMK-WKR-SYNC-001",
|
||||
TimestampUtc = DateTimeOffset.UtcNow,
|
||||
Level = "Info",
|
||||
Priority = "P3",
|
||||
Component = "Omika.Worker",
|
||||
OperationId = operationId,
|
||||
AppVersion = "1.0.0.0",
|
||||
Platform = "worker",
|
||||
Source = "worker",
|
||||
EntityType = "Client",
|
||||
EntityId = Guid.NewGuid().ToString("D"),
|
||||
Success = true,
|
||||
DurationMs = 12,
|
||||
Metadata = new Dictionary<string, object?>
|
||||
{
|
||||
["operationType"] = "Create",
|
||||
["retryCount"] = 0,
|
||||
["result"] = "Success"
|
||||
}
|
||||
};
|
||||
|
||||
var batch = new DiagnosticBatchDto { Events = [evt] };
|
||||
await store.StoreAsync(batch, DiagnosticActorKey.Empty, Guid.NewGuid().ToString("D"), DateTimeOffset.UtcNow, CancellationToken.None, context);
|
||||
}
|
||||
|
||||
private static string CreateTempDirectory()
|
||||
{
|
||||
string dir = Path.Combine(Path.GetTempPath(), "omika-worker-sync-import-tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
private static void DeleteDirectory(string dir)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Directory.Delete(dir, recursive: true);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best-effort.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user