using Omika.Diagnostics.Models;
using Omika.Diagnostics.Repositories;
namespace Omika.Diagnostics.Tests.Fakes;
///
/// Repository télémétrie in-memory (sans PostgreSQL) : reproduit le contrat
/// ITelemetryMetricRepository (upsert + purge bornée par bucket horaire).
///
public sealed class FakeTelemetryMetricRepository : ITelemetryMetricRepository
{
private readonly List _all = new();
private readonly object _sync = new();
private long _nextId = 1;
public IReadOnlyList All
{
get
{
lock (_sync)
{
return _all.ToList();
}
}
}
public Task UpsertHourlyAsync(
IReadOnlyList metrics,
CancellationToken cancellationToken = default)
{
lock (_sync)
{
foreach (TelemetryMetricHourly m in metrics)
{
m.Id = _nextId++;
_all.Add(m);
}
}
return Task.CompletedTask;
}
public Task DeleteOlderThanAsync(
DateTimeOffset cutoff,
int batchSize,
CancellationToken cancellationToken = default)
{
if (batchSize <= 0)
{
return Task.FromResult(0);
}
lock (_sync)
{
List toDelete = _all
.Where(m => m.BucketUtc < cutoff)
.OrderBy(m => m.BucketUtc)
.ThenBy(m => m.Id)
.Take(batchSize)
.ToList();
foreach (TelemetryMetricHourly m in toDelete)
{
_all.Remove(m);
}
return Task.FromResult(toDelete.Count);
}
}
}
///
/// Simule PostgreSQL DOWN pour la télémétrie : toutes les opérations lèvent.
/// La boucle de rétention doit survivre (fail-open).
///
public sealed class ThrowingTelemetryMetricRepository : ITelemetryMetricRepository
{
public Task UpsertHourlyAsync(
IReadOnlyList metrics,
CancellationToken cancellationToken = default) =>
throw new InvalidOperationException("PostgreSQL DOWN simulé");
public Task DeleteOlderThanAsync(
DateTimeOffset cutoff,
int batchSize,
CancellationToken cancellationToken = default) =>
throw new InvalidOperationException("PostgreSQL DOWN simulé");
}