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

64 lines
2.8 KiB
C#

using System.Reflection;
using Omika.Core.Observability;
namespace Omika.Tests.Observability.External;
/// <summary>
/// Garde-fous d'architecture de la Phase 5 (§8/§9/§65/§66/§72) : les packages
/// OpenTelemetry sont localisés UNIQUEMENT dans le projet infrastructure dédié
/// (Omika.Observability.External), jamais dans Core ni dans le métier (App /
/// App.Local / Data). Vérifications par réflexion sur les assemblies référencées.
/// </summary>
public class ExternalArchitectureTests
{
[Fact]
public void Core_DoesNotReferenceOpenTelemetry()
{
Assembly core = typeof(OmikaEvent).Assembly;
Assert.DoesNotContain(core.GetReferencedAssemblies(), a => a.Name!.Contains("OpenTelemetry"));
Assert.DoesNotContain(
core.GetTypes(),
t => (t.FullName ?? "").Contains("OpenTelemetry", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("Otlp", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("SigNoz", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("ClickHouse", StringComparison.OrdinalIgnoreCase));
}
[Theory]
[InlineData("Omika.App")]
[InlineData("Omika.App.Local")]
[InlineData("Omika.Data")]
public void BusinessAssemblies_DoNotReferenceExternalObservabilityInfrastructure(string assemblyName)
{
Assembly asm = Assembly.Load(assemblyName);
Assert.DoesNotContain(asm.GetReferencedAssemblies(), a =>
a.Name!.Contains("OpenTelemetry")
|| a.Name!.Contains("SigNoz")
|| a.Name!.Contains("ClickHouse"));
Assert.DoesNotContain(
asm.GetTypes(),
t => (t.FullName ?? "").Contains("OpenTelemetry", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("Otlp", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("SigNoz", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("ClickHouse", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("ActivitySource", StringComparison.OrdinalIgnoreCase)
|| (t.FullName ?? "").Contains("TracerProvider", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void TrackAndLog_Path_ExposesOnlyVoidMethods_NoNetwork()
{
// Le chemin Track()/Log() du métier reste strictement void (never-throw,
// non bloquant, sans réseau) : le réseau OTel est DERRIÈRE le TelemetryWorker.
foreach (MethodInfo method in typeof(IOmikaTelemetry).GetMethods()
.Concat(typeof(IEventTracker).GetMethods())
.Concat(typeof(IDiagnosticLogger).GetMethods()))
{
Assert.Equal(typeof(void), method.ReturnType);
}
}
}