diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs index 29212664ff..9ef0755d0f 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs @@ -136,4 +136,42 @@ public class BackgroundJobManager_Tests : BackgroundJobsTestBase _dynamicBackgroundJobManager.UnregisterHandler("TestRegister").ShouldBeTrue(); _dynamicBackgroundJobManager.IsHandlerRegistered("TestRegister").ShouldBeFalse(); } + + [Fact] + public void Should_GetAllNames_From_Handler_Registry() + { + var registry = GetRequiredService(); + + registry.Register("RegistryJob1", (_, _) => Task.CompletedTask); + registry.Register("RegistryJob2", (_, _) => Task.CompletedTask); + + try + { + var names = registry.GetAllNames(); + names.ShouldContain("RegistryJob1"); + names.ShouldContain("RegistryJob2"); + } + finally + { + registry.Unregister("RegistryJob1"); + registry.Unregister("RegistryJob2"); + } + } + + [Fact] + public void Should_Clear_Handler_Registry() + { + var registry = GetRequiredService(); + + registry.Register("ClearJob1", (_, _) => Task.CompletedTask); + registry.Register("ClearJob2", (_, _) => Task.CompletedTask); + + registry.GetAllNames().ShouldContain("ClearJob1"); + registry.GetAllNames().ShouldContain("ClearJob2"); + + registry.Clear(); + + registry.IsRegistered("ClearJob1").ShouldBeFalse(); + registry.IsRegistered("ClearJob2").ShouldBeFalse(); + } } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_StopAll_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_StopAll_Tests.cs new file mode 100644 index 0000000000..e7f8ae6bc6 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_StopAll_Tests.cs @@ -0,0 +1,98 @@ +using System; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.BackgroundWorkers; +using Xunit; + +namespace Volo.Abp.BackgroundWorkers; + +/// +/// Isolated tests for . +/// Kept in a separate class so the singleton manager is fresh per test (xUnit creates +/// a new test class instance — and therefore a new ABP application — for each test method). +/// +public class DynamicBackgroundWorkerManager_StopAll_Tests : BackgroundJobsTestBase +{ + private readonly IDynamicBackgroundWorkerManager _dynamicWorkerManager; + + public DynamicBackgroundWorkerManager_StopAll_Tests() + { + _dynamicWorkerManager = GetRequiredService(); + } + + [Fact] + public async Task Should_Stop_All_Workers_And_Clear_Registry() + { + var workerName1 = "stop-all-worker-1-" + Guid.NewGuid(); + var workerName2 = "stop-all-worker-2-" + Guid.NewGuid(); + + await _dynamicWorkerManager.AddAsync( + workerName1, + new DynamicBackgroundWorkerSchedule { Period = 60000 }, + (_, _) => Task.CompletedTask + ); + await _dynamicWorkerManager.AddAsync( + workerName2, + new DynamicBackgroundWorkerSchedule { Period = 60000 }, + (_, _) => Task.CompletedTask + ); + + _dynamicWorkerManager.IsRegistered(workerName1).ShouldBeTrue(); + _dynamicWorkerManager.IsRegistered(workerName2).ShouldBeTrue(); + + await _dynamicWorkerManager.StopAllAsync(); + + _dynamicWorkerManager.IsRegistered(workerName1).ShouldBeFalse(); + _dynamicWorkerManager.IsRegistered(workerName2).ShouldBeFalse(); + } + + [Fact] + public async Task Should_Throw_ObjectDisposedException_When_AddAsync_Called_After_StopAllAsync() + { + await _dynamicWorkerManager.StopAllAsync(); + + await Assert.ThrowsAsync(() => + _dynamicWorkerManager.AddAsync( + "post-stop-worker-" + Guid.NewGuid(), + new DynamicBackgroundWorkerSchedule { Period = 1000 }, + (_, _) => Task.CompletedTask + ) + ); + } + + [Fact] + public async Task Should_Throw_ObjectDisposedException_When_UpdateScheduleAsync_Called_After_StopAllAsync() + { + var workerName = "update-after-stop-" + Guid.NewGuid(); + + await _dynamicWorkerManager.AddAsync( + workerName, + new DynamicBackgroundWorkerSchedule { Period = 60000 }, + (_, _) => Task.CompletedTask + ); + + await _dynamicWorkerManager.StopAllAsync(); + + await Assert.ThrowsAsync(() => + _dynamicWorkerManager.UpdateScheduleAsync( + workerName, + new DynamicBackgroundWorkerSchedule { Period = 1000 } + ) + ); + } + + [Fact] + public async Task Should_Be_Idempotent_When_StopAllAsync_Called_Multiple_Times() + { + await _dynamicWorkerManager.AddAsync( + "idempotent-stop-" + Guid.NewGuid(), + new DynamicBackgroundWorkerSchedule { Period = 60000 }, + (_, _) => Task.CompletedTask + ); + + // Should not throw when called multiple times + await _dynamicWorkerManager.StopAllAsync(); + await _dynamicWorkerManager.StopAllAsync(); + } +} diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs index c69b92c7ed..f7fde67b44 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/DemoAppSharedModule.cs @@ -2,9 +2,6 @@ using System; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs; using Volo.Abp.BackgroundWorkers; using Volo.Abp.Modularity;