Files
2026-10-23 18:46:50 +02:00

71 lines
2.7 KiB
C#

using System.Reflection;
using Omika.Core.Observability;
using Omika.Core.Observability.Outbox;
namespace Omika.Tests.Observability.Outbox;
/// <summary>Garde-fous d'architecture (§53, §84) : isolation métier, absence d'infra externe.</summary>
public class DiagnosticArchitectureTests
{
[Fact]
public void DiagnosticOutbox_HasNoReferenceToBusinessOutboxAssembly()
{
// Le DiagnosticOutbox vit dans Omika.Core ; l'outbox métier vit dans
// Omika.App.Local. Core ne référence pas App.Local (jamais l'inverse).
Assembly core = typeof(DiagnosticOutbox).Assembly;
Assert.DoesNotContain(core.GetReferencedAssemblies(), a => a.Name == "Omika.App.Local");
}
[Fact]
public void DiagnosticOutboxStoreInterface_IsProviderAgnostic()
{
// Les signatures du store ne font référence à aucun type de l'outbox métier
// (IOutboxRepository / OutboxOperation) ni à SQLite.
foreach (MethodInfo method in typeof(IDiagnosticOutboxStore).GetMethods())
{
Assert.DoesNotContain("Business", method.Name, StringComparison.Ordinal);
foreach (Type type in method.ReturnType.GetGenericArguments()
.Concat(method.GetParameters().SelectMany(p => ParameterTypes(p.ParameterType))))
{
Assert.DoesNotContain("OutboxRepository", type.FullName ?? "", StringComparison.Ordinal);
Assert.DoesNotContain("Microsoft.Data.Sqlite", type.FullName ?? "", StringComparison.Ordinal);
}
}
}
[Fact]
public void Core_DoesNotReferenceExternalObservabilityInfrastructure()
{
Assembly core = typeof(OmikaEvent).Assembly;
string[] referenced = core.GetReferencedAssemblies().Select(a => a.Name!).ToArray();
Assert.DoesNotContain(referenced, n => n.Contains("OpenTelemetry"));
Assert.DoesNotContain(referenced, n => n.Contains("ClickHouse"));
Assert.DoesNotContain(referenced, n => n.Contains("SigNoz"));
// Aucun type OTLP / OpenTelemetry dans l'assemblage Core.
Assert.DoesNotContain(
core.GetTypes(),
t => (t.FullName ?? "").Contains("Otlp", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("OpenTelemetry", StringComparison.OrdinalIgnoreCase));
}
private static IEnumerable<Type> ParameterTypes(Type type)
{
if (type.IsGenericType)
{
foreach (Type argument in type.GetGenericArguments())
{
foreach (Type inner in ParameterTypes(argument))
{
yield return inner;
}
}
}
else
{
yield return type;
}
}
}