Files
Omika/tests/Omika.Tests/Observability/External/RemoteDiagnosticFileForwarderSourceTests.cs
2026-10-23 18:46:50 +02:00

92 lines
3.2 KiB
C#

using System.Text;
using System.Text.Json;
using Omika.Core.Observability.External;
using Omika.Core.Observability.Outbox;
namespace Omika.Tests.Observability.External;
/// <summary>
/// §5C.1C — Le source fichier du RemoteDiagnosticForwarder applique la même
/// protection partial-line que le reader du Worker (via JsonlCompleteLineReader).
/// </summary>
public class RemoteDiagnosticFileForwarderSourceTests
{
private static readonly UTF8Encoding Utf8NoBom = new(encoderShouldEmitUTF8Identifier: false);
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
[Fact]
public void PartialFinalLine_IsNotReturned_AndDoesNotAdvance()
{
string dir = CreateTempDir();
try
{
string line1 = Serialize(NewRecord(Guid.NewGuid()));
string line2 = Serialize(NewRecord(Guid.NewGuid())); // fragment sans newline
File.WriteAllText(
Path.Combine(dir, "omika-mobile-diagnostic-20260101-001.jsonl"),
line1 + "\n" + line2,
Utf8NoBom);
var source = new RemoteDiagnosticFileForwarderSource(
new RemoteDiagnosticOptions { Directory = dir },
"forwarder-checkpoint.json");
RemoteDiagnosticForwardReadResult read = source.ReadNext(null, 10);
Assert.Single(read.Records); // seul line1 (complète)
Assert.Equal(0, read.NextPosition!.LineIndex); // fragment non checkpointé
}
finally { Directory.Delete(dir, recursive: true); }
}
[Fact]
public void CompletePoisonLine_IsSkipped_AndCursorAdvances()
{
string dir = CreateTempDir();
try
{
string line = Serialize(NewRecord(Guid.NewGuid()));
File.WriteAllText(
Path.Combine(dir, "omika-mobile-diagnostic-20260101-001.jsonl"),
"{ json invalide\n" + line + "\n",
Utf8NoBom);
var source = new RemoteDiagnosticFileForwarderSource(
new RemoteDiagnosticOptions { Directory = dir },
"forwarder-checkpoint.json");
RemoteDiagnosticForwardReadResult read = source.ReadNext(null, 10);
Assert.Single(read.Records);
Assert.Equal(1, read.NextPosition!.LineIndex); // poison (0) sautée, ligne (1)
}
finally { Directory.Delete(dir, recursive: true); }
}
private static RemoteDiagnosticRecord NewRecord(Guid eventId) => new()
{
ReceivedAtUtc = DateTimeOffset.UtcNow,
BatchId = Guid.NewGuid(),
IngestionTraceId = Guid.NewGuid().ToString("D"),
Event = new DiagnosticEventDto
{
EventId = eventId,
EventCode = "TEST",
TimestampUtc = DateTimeOffset.UtcNow,
Level = "Info",
Priority = "P2"
}
};
private static string Serialize(RemoteDiagnosticRecord record) =>
JsonSerializer.Serialize(record, JsonOptions);
private static string CreateTempDir()
{
string dir = Path.Combine(Path.GetTempPath(), "omika-fwd-test-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(dir);
return dir;
}
}