47 lines
1.4 KiB
C#
47 lines
1.4 KiB
C#
using Omika.Core.Observability;
|
|
using Omika.Core.Observability.Outbox;
|
|
|
|
namespace Omika.Tests.Observability.Outbox;
|
|
|
|
/// <summary>Tests du fan-out : l'échec d'un exporteur n'empêche jamais les autres (§16).</summary>
|
|
public class CompositeTelemetryExporterTests
|
|
{
|
|
private sealed class RecordingExporter : ITelemetryExporter
|
|
{
|
|
public int Calls { get; private set; }
|
|
|
|
public bool Throw { get; set; }
|
|
|
|
public Task ExportAsync(IReadOnlyList<OmikaEvent> events, CancellationToken cancellationToken = default)
|
|
{
|
|
Calls++;
|
|
if (Throw)
|
|
{
|
|
throw new InvalidOperationException("exporter down");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task OneExporterFails_OtherStillRuns()
|
|
{
|
|
var broken = new RecordingExporter { Throw = true };
|
|
var healthy = new RecordingExporter();
|
|
var composite = new CompositeTelemetryExporter([broken, healthy]);
|
|
|
|
await composite.ExportAsync([OutboxTestHarness.NewEvent()], CancellationToken.None);
|
|
|
|
Assert.Equal(1, broken.Calls);
|
|
Assert.Equal(1, healthy.Calls);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task EmptyExporterList_NoOp()
|
|
{
|
|
var composite = new CompositeTelemetryExporter([]);
|
|
await composite.ExportAsync([OutboxTestHarness.NewEvent()], CancellationToken.None);
|
|
}
|
|
}
|