Premiere commit - Omika

This commit is contained in:
2026-10-23 18:46:50 +02:00
commit 8ea76c1b24
2155 changed files with 984301 additions and 0 deletions
@@ -0,0 +1,68 @@
using Omika.Core.Configuration;
using Omika.Core.Observability;
namespace Omika.Tests.Observability;
public class RateLimitTests
{
[Fact]
public void Storm_IdenticalEvents_IsRateLimited_AndBounded()
{
// NOTE : RateLimitPerEvent est volontairement abaissé à 100 (défaut = 1000)
// pour rendre le test de tempête rapide et lisible. La fenêtre fixe est
// de 1 seconde ; 100 000 occurrences mono-thread → ~100 acceptées, le
// reste abandonné par la protection anti-log-storm.
var options = new ObservabilityOptions { RateLimitPerEvent = 100 };
var (sink, _, counters) = ObservabilityTestHarness.CreatePipeline(options);
const long total = 100_000;
for (long i = 0; i < total; i++)
{
sink.Track(ObservabilityTestHarness.NewEvent(TelemetryEventCodes.MobileAppStarted));
}
// Tous les événements sont comptabilisés une et une seule fois.
Assert.Equal(total, counters.Accepted + counters.DroppedTotal);
// La protection rate limit a bien abandonné des occurrences.
Assert.True(counters.DroppedRateLimited > 0);
// La mémoire est bornée : on n'accepte qu'une fraction du flux.
Assert.True(counters.Accepted <= total);
}
[Fact]
public void ExactRateLimit_SingleThreaded_1000Events_RateLimit100()
{
// Fenêtre fixe = 1 s, exécution séquentielle mono-thread (aucune course).
// Le limiter accepte exactement les 100 premières occurrences puis droppe
// les 900 suivantes : le résultat est déterministe dans ce cadre.
var options = new ObservabilityOptions { RateLimitPerEvent = 100 };
var (sink, _, counters) = ObservabilityTestHarness.CreatePipeline(options);
for (int i = 0; i < 1000; i++)
{
sink.Track(ObservabilityTestHarness.NewEvent(TelemetryEventCodes.MobileAppStarted));
}
Assert.Equal(100L, counters.Accepted);
Assert.Equal(900L, counters.DroppedRateLimited);
Assert.Equal(1000L, counters.Accepted + counters.DroppedTotal);
}
[Fact]
public void ManyDistinctCodes_AreBounded_NoThrow()
{
var options = new ObservabilityOptions();
var (sink, _, counters) = ObservabilityTestHarness.CreatePipeline(options);
// Plus de codes distincts que la capacité interne de suivi (1024) : les
// codes excédentaires sont abandonnés sans exception, la mémoire reste bornée.
for (int i = 0; i < 5000; i++)
{
EventCode code = EventCode.Create("MOB", "T" + i.ToString("D7"), 1);
sink.Track(ObservabilityTestHarness.NewEvent(code));
}
Assert.Equal(5000L, counters.Accepted + counters.DroppedTotal);
Assert.True(counters.DroppedRateLimited > 0);
}
}