using Tiku.Worker; namespace Tiku.UnitTests.Worker; public sealed class PeriodicWorkerExecutionModeTests { [Fact] public async Task Multi_instance_mode_does_not_request_global_lock() { var processorLock = new RecordingProcessorLock(null); await using var lease = await PeriodicWorker.TryAcquireExecutionLeaseAsync( PeriodicWorkerExecutionMode.MultiInstance, processorLock, "background-jobs", CancellationToken.None); Assert.NotNull(lease); Assert.Equal(0, processorLock.Attempts); } [Fact] public async Task Singleton_mode_skips_iteration_when_global_lock_is_unavailable() { var processorLock = new RecordingProcessorLock(null); var lease = await PeriodicWorker.TryAcquireExecutionLeaseAsync( PeriodicWorkerExecutionMode.Singleton, processorLock, "commercial-billing", CancellationToken.None); Assert.Null(lease); Assert.Equal(1, processorLock.Attempts); } [Fact] public async Task Singleton_mode_returns_acquired_global_lock_lease() { var expected = new RecordingLease(); var processorLock = new RecordingProcessorLock(expected); var lease = await PeriodicWorker.TryAcquireExecutionLeaseAsync( PeriodicWorkerExecutionMode.Singleton, processorLock, "platform-approvals", CancellationToken.None); Assert.Same(expected, lease); Assert.Equal(1, processorLock.Attempts); await lease!.DisposeAsync(); Assert.True(expected.Disposed); } private sealed class RecordingProcessorLock(IAsyncDisposable? lease) : IPeriodicProcessorLock { public int Attempts { get; private set; } public Task TryAcquireAsync(string processor, CancellationToken cancellationToken) { Attempts++; return Task.FromResult(lease); } } private sealed class RecordingLease : IAsyncDisposable { public bool Disposed { get; private set; } public ValueTask DisposeAsync() { Disposed = true; return ValueTask.CompletedTask; } } }