Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
using Omika.Core.Observability.Forwarding;
|
||||
|
||||
namespace Omika.Tests.Observability.Forwarding;
|
||||
|
||||
/// <summary>Tests du spool disque du forwarder (checkpoint, bornes, suppression, quota, rétention).</summary>
|
||||
public class DiagnosticsForwarderSpoolTests : IDisposable
|
||||
{
|
||||
private const string File001 = "omika-mobile-diagnostic-20261002-001.jsonl";
|
||||
private const string File002 = "omika-mobile-diagnostic-20261002-002.jsonl";
|
||||
private const string File003 = "omika-mobile-diagnostic-20261002-003.jsonl";
|
||||
|
||||
private readonly string _dir = ForwardingTestHarness.CreateTempDirectory();
|
||||
|
||||
private static DiagnosticsForwardingSpoolOptions DefaultSpool => new();
|
||||
|
||||
public void Dispose() => ForwardingTestHarness.DeleteDirectory(_dir);
|
||||
|
||||
private DiagnosticsForwarderSpool NewSpool(DiagnosticsForwardingSpoolOptions? options = null) =>
|
||||
new(_dir, "forwarder-checkpoint.json", options ?? DefaultSpool);
|
||||
|
||||
[Fact]
|
||||
public void ReadNext_EmptyDirectory_ReturnsReachedEnd()
|
||||
{
|
||||
var spool = NewSpool();
|
||||
|
||||
DiagnosticsForwarderBatch batch = spool.ReadNext(null, 10, 1024);
|
||||
|
||||
Assert.Empty(batch.Records);
|
||||
Assert.True(batch.ReachedEnd);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadNext_ReadsRecordsInOrder_AndResumesAcrossFiles()
|
||||
{
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File001,
|
||||
[ForwardingTestHarness.NewRecord(component: "a"), ForwardingTestHarness.NewRecord(component: "b")]);
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File002,
|
||||
[ForwardingTestHarness.NewRecord(component: "c")]);
|
||||
|
||||
var spool = NewSpool();
|
||||
|
||||
DiagnosticsForwarderBatch first = spool.ReadNext(null, 2, 1_000_000);
|
||||
Assert.Equal(2, first.Records.Count);
|
||||
Assert.Equal("a", first.Records[0].Event.Component);
|
||||
Assert.Equal("b", first.Records[1].Event.Component);
|
||||
Assert.NotNull(first.NextPosition);
|
||||
Assert.Equal(File001, first.NextPosition!.FileName);
|
||||
|
||||
DiagnosticsForwarderBatch second = spool.ReadNext(first.NextPosition, 2, 1_000_000);
|
||||
Assert.Single(second.Records);
|
||||
Assert.Equal("c", second.Records[0].Event.Component);
|
||||
Assert.Equal(File002, second.NextPosition!.FileName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadNext_RespectsMaxBytes_StillReturnsAtLeastOneRecord()
|
||||
{
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File001,
|
||||
[ForwardingTestHarness.NewRecord(), ForwardingTestHarness.NewRecord()]);
|
||||
|
||||
var spool = NewSpool();
|
||||
|
||||
DiagnosticsForwarderBatch batch = spool.ReadNext(null, 100, 10);
|
||||
|
||||
Assert.Single(batch.Records); // premier seuil (octets) : 1 seul, jamais zéro.
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Commit_ThenLoadCheckpoint_ResumesFromNextLine()
|
||||
{
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File001,
|
||||
[ForwardingTestHarness.NewRecord(component: "a"), ForwardingTestHarness.NewRecord(component: "b"), ForwardingTestHarness.NewRecord(component: "c")]);
|
||||
|
||||
var spool = NewSpool();
|
||||
|
||||
DiagnosticsForwarderBatch first = spool.ReadNext(null, 1, 1_000_000);
|
||||
Assert.Single(first.Records);
|
||||
Assert.Equal("a", first.Records[0].Event.Component);
|
||||
spool.Commit(first.NextPosition!);
|
||||
|
||||
DiagnosticsForwarderPosition? checkpoint = spool.LoadCheckpoint();
|
||||
Assert.NotNull(checkpoint);
|
||||
Assert.Equal(File001, checkpoint!.FileName);
|
||||
Assert.Equal(0, checkpoint.LineIndex);
|
||||
|
||||
DiagnosticsForwarderBatch second = spool.ReadNext(checkpoint, 10, 1_000_000);
|
||||
Assert.Equal(2, second.Records.Count);
|
||||
Assert.Equal("b", second.Records[0].Event.Component);
|
||||
Assert.Equal("c", second.Records[1].Event.Component);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PruneConsumed_DeletesOlderFiles_NeverActiveFile()
|
||||
{
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File001, [ForwardingTestHarness.NewRecord()]);
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File002, [ForwardingTestHarness.NewRecord()]);
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File003, [ForwardingTestHarness.NewRecord()]);
|
||||
|
||||
var spool = NewSpool();
|
||||
|
||||
int deleted = spool.PruneConsumed(new DiagnosticsForwarderPosition { FileName = File002, LineIndex = 0 });
|
||||
|
||||
Assert.Equal(1, deleted); // seul 001 (antérieur) est supprimé.
|
||||
Assert.False(File.Exists(Path.Combine(_dir, File001)));
|
||||
Assert.True(File.Exists(Path.Combine(_dir, File002)));
|
||||
Assert.True(File.Exists(Path.Combine(_dir, File003))); // actif préservé.
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnforceBounds_Quota_DeletesOldestFiles()
|
||||
{
|
||||
int chunk = 400 * 1024; // 3 × 400 Ko = 1.2 Mo > 1 Mo de quota.
|
||||
string padding = new string('a', chunk);
|
||||
ForwardingTestHarness.WriteRawSpoolFile(_dir, File001, padding);
|
||||
ForwardingTestHarness.WriteRawSpoolFile(_dir, File002, padding);
|
||||
ForwardingTestHarness.WriteRawSpoolFile(_dir, File003, padding);
|
||||
|
||||
var spool = NewSpool(new DiagnosticsForwardingSpoolOptions { MaxTotalSizeMb = 1 });
|
||||
|
||||
int deleted = spool.EnforceBounds(DateTimeOffset.UtcNow);
|
||||
|
||||
Assert.Equal(1, deleted); // le plus ancien est évincé, total ≤ 1 Mo.
|
||||
Assert.False(File.Exists(Path.Combine(_dir, File001)));
|
||||
Assert.True(File.Exists(Path.Combine(_dir, File002)));
|
||||
Assert.True(File.Exists(Path.Combine(_dir, File003)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnforceBounds_Retention_DeletesExpiredFiles_NotActive()
|
||||
{
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File001, [ForwardingTestHarness.NewRecord()]);
|
||||
ForwardingTestHarness.WriteSpoolFile(_dir, File002, [ForwardingTestHarness.NewRecord()]);
|
||||
|
||||
// 001 est ancien, 002 est l'actif (et récent).
|
||||
File.SetLastWriteTimeUtc(Path.Combine(_dir, File001), DateTime.UtcNow.AddDays(-2));
|
||||
File.SetLastWriteTimeUtc(Path.Combine(_dir, File002), DateTime.UtcNow);
|
||||
|
||||
var spool = NewSpool(new DiagnosticsForwardingSpoolOptions { RetentionDays = 1, MaxTotalSizeMb = 1024 });
|
||||
|
||||
int deleted = spool.EnforceBounds(DateTimeOffset.UtcNow);
|
||||
|
||||
Assert.Equal(1, deleted);
|
||||
Assert.False(File.Exists(Path.Combine(_dir, File001)));
|
||||
Assert.True(File.Exists(Path.Combine(_dir, File002)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user