< Summary

Line coverage
78%
Covered lines: 26
Uncovered lines: 7
Coverable lines: 33
Total lines: 88
Line coverage: 78.7%
Branch coverage
50%
Covered branches: 1
Total branches: 2
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .cctor()100%210%
File 2: .ctor(...)100%11100%
File 2: StartAsync()50%2295.65%
File 2: StopAsync(...)100%11100%

File(s)

/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs

File '/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs' does not exist (any more).

/home/runner/work/anichron/anichron/src/Anichron.Worker/Startup/DatabaseMigratorService.cs

#LineLine coverage
 1using Anichron.Worker.Settings;
 2
 3namespace Anichron.Worker.Startup;
 4
 65public sealed partial class DatabaseMigratorService(
 66    IServiceScopeFactory scopeFactory,
 67    ILogger<DatabaseMigratorService> logger) : IHostedService
 8{
 9    internal TimeSpan RetryDelay { get; init; } = TimeSpan.FromSeconds(WorkerDefaults.Migrator.RetryDelaySeconds);
 10
 11    public async Task StartAsync(CancellationToken cancellationToken)
 512    {
 6813        for (var attempt = 1; attempt <= WorkerDefaults.Migrator.MaxAttempts; attempt++)
 3414        {
 15            try
 3416            {
 3417                await using var scope = scopeFactory.CreateAsyncScope();
 3418                var migrator = scope.ServiceProvider.GetRequiredService<IDatabaseMigrator>();
 3419                await migrator.MigrateAsync(cancellationToken);
 220                Log.MigrationApplied(logger);
 221                return;
 022            }
 3223            catch (Exception ex) when (attempt < WorkerDefaults.Migrator.MaxAttempts)
 2924            {
 2925                Log.DatabaseNotReady(logger, ex, attempt, WorkerDefaults.Migrator.MaxAttempts, (int)RetryDelay.TotalSeco
 2926                await Task.Delay(RetryDelay, cancellationToken);
 2927            }
 328            catch (Exception ex)
 329            {
 330                Log.DatabaseUnavailable(logger, ex, WorkerDefaults.Migrator.MaxAttempts);
 331                throw new InvalidOperationException(
 332                    $"Database unavailable after {WorkerDefaults.Migrator.MaxAttempts} attempts. Aborting.",
 333                    ex);
 34            }
 2935        }
 236    }
 37
 138    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
 39
 40    private static partial class Log
 41    {
 42        [LoggerMessage(Level = LogLevel.Information, Message = "Database migration applied successfully.")]
 43        public static partial void MigrationApplied(ILogger logger);
 44
 45        [LoggerMessage(Level = LogLevel.Warning, Message = "Database not ready (attempt {Attempt}/{Max}). Retrying in {D
 46        public static partial void DatabaseNotReady(ILogger logger, Exception ex, int attempt, int max, int delay);
 47
 48        [LoggerMessage(Level = LogLevel.Error, Message = "Database unavailable after {Max} attempts. Aborting.")]
 49        public static partial void DatabaseUnavailable(ILogger logger, Exception ex, int max);
 50    }
 51}