92 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|