From a71c1df99221c9ac8c1031b0953f283e2b302494 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Wed, 16 Nov 2011 17:40:55 -0800 Subject: [PATCH 1/2] Commented out IISProviderFixutre. Diagnosing slow tests --- NzbDrone.App.Test/IISProviderFixture.cs | 104 ++++++++++++------------ 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/NzbDrone.App.Test/IISProviderFixture.cs b/NzbDrone.App.Test/IISProviderFixture.cs index 65c11abce..197386d96 100644 --- a/NzbDrone.App.Test/IISProviderFixture.cs +++ b/NzbDrone.App.Test/IISProviderFixture.cs @@ -1,64 +1,64 @@ -using System; -using System.Diagnostics; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using Ninject; -using NzbDrone.Common; -using NzbDrone.Common.Model; -using NzbDrone.Providers; -using NzbDrone.Test.Common; -using NzbDrone.Test.Dummy; +//using System; +//using System.Diagnostics; +//using FluentAssertions; +//using Moq; +//using NUnit.Framework; +//using Ninject; +//using NzbDrone.Common; +//using NzbDrone.Common.Model; +//using NzbDrone.Providers; +//using NzbDrone.Test.Common; +//using NzbDrone.Test.Dummy; -namespace NzbDrone.App.Test -{ - [TestFixture] - public class IISProviderFixture : TestBase - { - [Test] - public void should_update_pid_env_varibles() - { - WithTempAsAppPath(); +//namespace NzbDrone.App.Test +//{ +// [TestFixture] +// public class IISProviderFixture : TestBase +// { +// [Test] +// public void should_update_pid_env_varibles() +// { +// WithTempAsAppPath(); - var dummy = StartDummyProcess(); +// var dummy = StartDummyProcess(); - Environment.SetEnvironmentVariable(EnviromentProvider.NZBDRONE_PID, "0"); - Environment.SetEnvironmentVariable(EnviromentProvider.NZBDRONE_PATH, "Test"); +// Environment.SetEnvironmentVariable(EnviromentProvider.NZBDRONE_PID, "0"); +// Environment.SetEnvironmentVariable(EnviromentProvider.NZBDRONE_PATH, "Test"); - Mocker.GetMock() - .Setup(c => c.Start(It.IsAny())) - .Returns(dummy); +// Mocker.GetMock() +// .Setup(c => c.Start(It.IsAny())) +// .Returns(dummy); - Mocker.Resolve().StartServer(); - } +// Mocker.Resolve().StartServer(); +// } - [Test] - public void should_set_iis_procces_id() - { - WithTempAsAppPath(); - var dummy = StartDummyProcess(); +// [Test] +// public void should_set_iis_procces_id() +// { +// WithTempAsAppPath(); +// var dummy = StartDummyProcess(); - Mocker.GetMock() - .Setup(c => c.Start(It.IsAny())) - .Returns(dummy); +// Mocker.GetMock() +// .Setup(c => c.Start(It.IsAny())) +// .Returns(dummy); - //act - Mocker.Resolve().StartServer(); +// //act +// Mocker.Resolve().StartServer(); - //assert - Mocker.Resolve().IISProcessId.Should().Be(dummy.Id); - } +// //assert +// Mocker.Resolve().IISProcessId.Should().Be(dummy.Id); +// } - public Process StartDummyProcess() - { - var startInfo = new ProcessStartInfo(DummyApp.DUMMY_PROCCESS_NAME + ".exe"); - startInfo.UseShellExecute = false; - startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError = true; - startInfo.CreateNoWindow = true; - return new ProcessProvider().Start(startInfo); - } +// public Process StartDummyProcess() +// { +// var startInfo = new ProcessStartInfo(DummyApp.DUMMY_PROCCESS_NAME + ".exe"); +// startInfo.UseShellExecute = false; +// startInfo.RedirectStandardOutput = true; +// startInfo.RedirectStandardError = true; +// startInfo.CreateNoWindow = true; +// return new ProcessProvider().Start(startInfo); +// } - } -} +// } +//} From 04d40575da698cea3c7195cdab23aea0b99906db Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Wed, 16 Nov 2011 22:23:35 -0800 Subject: [PATCH 2/2] Cleaned up JobProviderFixture, should save ~20 seconds in build time. --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 2 +- .../JobProviderTests/JobProviderFixture.cs | 422 ++++++++++++++++ .../JobProviderTests/JobProviderTest.cs | 471 ------------------ NzbDrone.Core/Providers/Jobs/JobProvider.cs | 17 +- 4 files changed, 430 insertions(+), 482 deletions(-) create mode 100644 NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderFixture.cs delete mode 100644 NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderTest.cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index ebfa4a2c6..54c46d44f 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -124,7 +124,7 @@ - + diff --git a/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderFixture.cs new file mode 100644 index 000000000..4ff401b36 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderFixture.cs @@ -0,0 +1,422 @@ +// ReSharper disable RedundantUsingDirective + +using System.Linq; +using System; +using System.Collections.Generic; +using System.Threading; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers.Jobs; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.JobProviderTests +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class JobProviderFixture : CoreTest + { + + FakeJob fakeJob; + SlowJob slowJob; + BrokenJob brokenJob; + DisabledJob disabledJob; + + [SetUp] + public void Setup() + { + WithRealDb(); + fakeJob = new FakeJob(); + slowJob = new SlowJob(); + brokenJob = new BrokenJob(); + disabledJob = new DisabledJob(); + } + + [TearDown] + public void TearDown() + { + Mocker.Resolve().Queue.Should().BeEmpty(); + } + + private void WaitForQueue() + { + Console.WriteLine("Waiting for queue to clear."); + var stopWatch = Mocker.Resolve().StopWatch; + + while (stopWatch.IsRunning) + { + Thread.Sleep(100); + } + } + + [Test] + public void running_scheduled_jobs_should_updates_last_execution_time() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueScheduled(); + + //Assert + WaitForQueue(); + var settings = jobProvider.All(); + settings.First().LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10)); + fakeJob.ExecutionCount.Should().Be(1); + } + + [Test] + public void failing_scheduled_job_should_mark_job_as_failed() + { + IList BaseFakeJobs = new List { brokenJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueScheduled(); + + //Assert + WaitForQueue(); + var settings = jobProvider.All(); + settings.First().LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10)); + settings.First().Success.Should().BeFalse(); + brokenJob.ExecutionCount.Should().Be(1); + ExceptionVerification.ExcpectedErrors(1); + } + + [Test] + public void scheduler_skips_jobs_that_arent_mature_yet() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueScheduled(); + WaitForQueue(); + jobProvider.QueueScheduled(); + WaitForQueue(); + + //Assert + fakeJob.ExecutionCount.Should().Be(1); + } + + [Test] + //This test will confirm that the concurrency checks are rest + //after execution so the job can successfully run. + public void can_run_async_job_again() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + //Act + jobProvider.QueueJob(typeof(FakeJob)); + WaitForQueue(); + jobProvider.QueueJob(typeof(FakeJob)); + WaitForQueue(); + + //Assert + jobProvider.Queue.Should().BeEmpty(); + fakeJob.ExecutionCount.Should().Be(2); + } + + [Test] + public void no_concurent_jobs() + { + IList BaseFakeJobs = new List { slowJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueJob(typeof(SlowJob), 1); + jobProvider.QueueJob(typeof(SlowJob), 2); + jobProvider.QueueJob(typeof(SlowJob), 3); + + WaitForQueue(); + + jobProvider.Queue.Should().BeEmpty(); + slowJob.ExecutionCount.Should().Be(3); + ExceptionVerification.AssertNoUnexcpectedLogs(); + } + + + [Test] + public void can_run_broken_job_again() + { + IList BaseFakeJobs = new List { brokenJob }; + + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + //Act + jobProvider.QueueJob(typeof(BrokenJob)); + WaitForQueue(); + + jobProvider.QueueJob(typeof(BrokenJob)); + WaitForQueue(); + + //Assert + brokenJob.ExecutionCount.Should().Be(2); + ExceptionVerification.ExcpectedErrors(2); + } + + [Test] + public void schedule_hit_should_be_ignored_if_queue_is_running() + { + IList fakeJobs = new List { slowJob, fakeJob }; + + Mocker.SetConstant(fakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + + //Act + jobProvider.QueueJob(typeof(SlowJob)); + jobProvider.QueueScheduled(); + WaitForQueue(); + + //Assert + slowJob.ExecutionCount.Should().Be(1); + fakeJob.ExecutionCount.Should().Be(0); + } + + + [Test] + public void can_queue_jobs_at_the_same_time() + { + + IList BaseFakeJobs = new List { slowJob, fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + + jobProvider.QueueJob(typeof(SlowJob)); + var thread1 = new Thread(() => jobProvider.QueueJob(typeof(FakeJob))); + var thread2 = new Thread(() => jobProvider.QueueJob(typeof(FakeJob))); + + thread1.Start(); + thread2.Start(); + + thread1.Join(); + thread2.Join(); + + WaitForQueue(); + + fakeJob.ExecutionCount.Should().Be(1); + slowJob.ExecutionCount.Should().Be(1); + jobProvider.Queue.Should().BeEmpty(); + } + + [Test] + public void Init_Jobs() + { + IList BaseFakeJobs = new List { fakeJob }; + + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + + //Act + jobProvider.Initialize(); + + //assert + var timers = jobProvider.All(); + timers.Should().HaveCount(1); + timers[0].Interval.Should().Be(fakeJob.DefaultInterval); + timers[0].Name.Should().Be(fakeJob.Name); + timers[0].TypeName.Should().Be(fakeJob.GetType().ToString()); + timers[0].LastExecution.Should().HaveYear(2000); + timers[0].Enable.Should().BeTrue(); + } + + [Test] + public void Init_Timers_only_registers_once() + { + for (int i = 0; i < 2; i++) + { + var fakeTimer = new FakeJob(); + IList BaseFakeJobs = new List { fakeTimer }; + + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + } + + var Mocker2 = new AutoMoqer(); + + Mocker2.SetConstant(Db); + var assertjobProvider = Mocker2.Resolve(); + var timers = assertjobProvider.All(); + + //Assert + timers.Should().HaveCount(1); + timers[0].Enable.Should().BeTrue(); + } + + [Test] + public void jobs_with_zero_interval_are_registered_as_disabled() + { + IList fakeJobs = new List { disabledJob }; + Mocker.SetConstant(fakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + //Assert + jobProvider.All().Should().HaveCount(1); + jobProvider.All().First().Enable.Should().BeFalse(); + } + + [Test] + public void Get_Next_Execution_Time() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueScheduled(); + WaitForQueue(); + + //Assert + var next = jobProvider.NextScheduledRun(typeof(FakeJob)); + jobProvider.All().Should().HaveCount(1); + jobProvider.All().First().LastExecution.Should().Be(next.AddMinutes(-fakeJob.DefaultInterval)); + } + + [Test] + public void disabled_jobs_arent_run_by_scheduler() + { + IList BaseFakeJobs = new List { disabledJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueScheduled(); + + WaitForQueue(); + + //Assert + disabledJob.ExecutionCount.Should().Be(0); + } + + [Test] + public void job_with_specific_target_should_not_update_last_execution() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueJob(typeof(FakeJob), 10); + + WaitForQueue(); + + //Assert + jobProvider.All().First().LastExecution.Should().HaveYear(2000); + } + + [Test] + public void job_with_specific_target_should_not_set_success_flag() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.QueueJob(typeof(FakeJob), 10); + + WaitForQueue(); + + //Assert + jobProvider.All().First().Success.Should().BeFalse(); + } + + + [Test] + public void duplicated_queue_item_should_start_queue_if_its_not_running() + { + IList BaseFakeJobs = new List { fakeJob }; + Mocker.SetConstant(BaseFakeJobs); + + var stuckQueueItem = new JobQueueItem + { + JobType = fakeJob.GetType(), + TargetId = 12, + SecondaryTargetId = 0 + }; + + //Act + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + jobProvider.Queue.Add(stuckQueueItem); + + WaitForQueue(); + jobProvider.QueueJob(stuckQueueItem.JobType, stuckQueueItem.TargetId, stuckQueueItem.SecondaryTargetId); + WaitForQueue(); + + //Assert + fakeJob.ExecutionCount.Should().Be(1); + } + + + [Test] + public void Item_added_to_queue_while_scheduler_runs_should_be_executed() + { + IList BaseFakeJobs = new List { slowJob, disabledJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + jobProvider.Initialize(); + + var _jobThread = new Thread(jobProvider.QueueScheduled); + _jobThread.Start(); + + Thread.Sleep(200); + + jobProvider.QueueJob(typeof(DisabledJob), 12); + + WaitForQueue(); + + //Assert + slowJob.ExecutionCount.Should().Be(1); + disabledJob.ExecutionCount.Should().Be(1); + } + + [Test] + public void trygin_to_queue_unregistered_job_should_fail() + { + IList BaseFakeJobs = new List { slowJob, disabledJob }; + Mocker.SetConstant(BaseFakeJobs); + + var jobProvider = Mocker.Resolve(); + + jobProvider.Initialize(); + jobProvider.QueueJob(typeof(string)); + + WaitForQueue(); + ExceptionVerification.ExcpectedErrors(1); + } + + } + + +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderTest.cs deleted file mode 100644 index 38c6169f2..000000000 --- a/NzbDrone.Core.Test/ProviderTests/JobProviderTests/JobProviderTest.cs +++ /dev/null @@ -1,471 +0,0 @@ -// ReSharper disable RedundantUsingDirective - -using System.Linq; -using System; -using System.Collections.Generic; -using System.Threading; - -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.Model; -using NzbDrone.Core.Providers.Jobs; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common; -using NzbDrone.Test.Common.AutoMoq; - -namespace NzbDrone.Core.Test.ProviderTests.JobProviderTests -{ - [TestFixture] - // ReSharper disable InconsistentNaming - public class JobProviderTest : CoreTest - { - [Test] - public void Run_Jobs_Updates_Last_Execution() - { - IList BaseFakeJobs = new List { new FakeJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - //Act - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - timerProvider.QueueScheduled(); - - //Assert - var settings = timerProvider.All(); - - Assert.AreNotEqual(DateTime.MinValue, settings[0].LastExecution); - } - - [Test] - public void Run_Jobs_Updates_Last_Execution_Mark_as_unsuccesful() - { - - IList BaseFakeJobs = new List { new BrokenJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - //Act - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - timerProvider.QueueScheduled(); - - Thread.Sleep(1000); - - //Assert - var settings = timerProvider.All(); - Assert.AreNotEqual(DateTime.MinValue, settings[0].LastExecution); - settings[0].Success.Should().BeFalse(); - ExceptionVerification.ExcpectedErrors(1); - } - - [Test] - public void scheduler_skips_jobs_that_arent_mature_yet() - { - var BaseFakeJob = new FakeJob(); - var mocker = new AutoMoqer(); - - IList BaseFakeJobs = new List { BaseFakeJob }; - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - timerProvider.QueueScheduled(); - Thread.Sleep(500); - timerProvider.QueueScheduled(); - Thread.Sleep(500); - - BaseFakeJob.ExecutionCount.Should().Be(1); - } - - [Test] - //This test will confirm that the concurrency checks are rest - //after execution so the job can successfully run. - public void can_run_async_job_again() - { - var BaseFakeJob = new FakeJob(); - var mocker = new AutoMoqer(); - - IList BaseFakeJobs = new List { BaseFakeJob }; - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(FakeJob)); - Thread.Sleep(1000); - jobProvider.QueueJob(typeof(FakeJob)); - Thread.Sleep(2000); - jobProvider.Queue.Should().BeEmpty(); - BaseFakeJob.ExecutionCount.Should().Be(2); - } - - [Test] - public void no_concurent_jobs() - { - IList BaseFakeJobs = new List { new SlowJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(SlowJob), 1); - jobProvider.QueueJob(typeof(SlowJob), 2); - jobProvider.QueueJob(typeof(SlowJob), 3); - - - Thread.Sleep(5000); - jobProvider.Queue.Should().BeEmpty(); - //Asserts are done in ExceptionVerification - } - - - [Test] - //This test will confirm that the concurrency checks are rest - //after execution so the job can successfully run. - public void can_run_broken_async_job_again() - { - var brokenJob = new BrokenJob(); - IList BaseFakeJobs = new List { brokenJob }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(BrokenJob)); - Thread.Sleep(2000); - jobProvider.QueueJob(typeof(BrokenJob)); - - - Thread.Sleep(2000); - jobProvider.Queue.Should().BeEmpty(); - brokenJob.ExecutionCount.Should().Be(2); - ExceptionVerification.ExcpectedErrors(2); - } - - [Test] - public void can_run_two_jobs_at_the_same_time() - { - WithRealDb(); - - var fakeJob = new FakeJob(); - IList fakeJobs = new List { fakeJob }; - - Mocker.SetConstant(fakeJobs); - - var jobProvider = Mocker.Resolve(); - jobProvider.Initialize(); - - - jobProvider.QueueScheduled(); - jobProvider.QueueScheduled(); - - - Thread.Sleep(2000); - - fakeJob.ExecutionCount.Should().Be(1); - } - - - [Test] - public void can_queue_jobs_at_the_same_time() - { - var slowJob = new SlowJob(); - var BaseFakeJob = new FakeJob(); - - IList BaseFakeJobs = new List { slowJob, BaseFakeJob }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - - - jobProvider.QueueJob(typeof(SlowJob)); - var thread1 = new Thread(() => jobProvider.QueueJob(typeof(FakeJob))); - var thread2 = new Thread(() => jobProvider.QueueJob(typeof(FakeJob))); - - thread1.Start(); - thread2.Start(); - - thread1.Join(); - thread2.Join(); - - Thread.Sleep(5000); - - BaseFakeJob.ExecutionCount.Should().Be(1); - jobProvider.Queue.Should().BeEmpty(); - } - - [Test] - public void Init_Jobs() - { - var fakeTimer = new FakeJob(); - IList BaseFakeJobs = new List { fakeTimer }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - - var timers = timerProvider.All(); - - - //Assert - - timers.Should().HaveCount(1); - timers[0].Interval.Should().Be(fakeTimer.DefaultInterval); - timers[0].Name.Should().Be(fakeTimer.Name); - timers[0].TypeName.Should().Be(fakeTimer.GetType().ToString()); - timers[0].LastExecution.Should().HaveYear(2000); - timers[0].Enable.Should().BeTrue(); - } - - [Test] - public void Init_Timers_only_registers_once() - { - var repo = MockLib.GetEmptyDatabase(); - - for (int i = 0; i < 2; i++) - { - var fakeTimer = new FakeJob(); - IList BaseFakeJobs = new List { fakeTimer }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(repo); - mocker.SetConstant(BaseFakeJobs); - - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - } - - var mocker2 = new AutoMoqer(); - - mocker2.SetConstant(repo); - var assertTimerProvider = mocker2.Resolve(); - - var timers = assertTimerProvider.All(); - - - //Assert - timers.Should().HaveCount(1); - timers[0].Enable.Should().BeTrue(); - } - - [Test] - public void Init_Timers_sets_interval_0_to_disabled() - { - var repo = MockLib.GetEmptyDatabase(); - - for (int i = 0; i < 2; i++) - { - var disabledJob = new DisabledJob(); - IList BaseFakeJobs = new List { disabledJob }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(repo); - mocker.SetConstant(BaseFakeJobs); - - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - } - - var mocker2 = new AutoMoqer(); - - mocker2.SetConstant(repo); - var assertTimerProvider = mocker2.Resolve(); - - var timers = assertTimerProvider.All(); - - - //Assert - timers.Should().HaveCount(1); - Assert.IsFalse(timers[0].Enable); - } - - [Test] - public void Get_Next_Execution_Time() - { - IList BaseFakeJobs = new List { new FakeJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - //Act - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - timerProvider.QueueScheduled(); - var next = timerProvider.NextScheduledRun(typeof(FakeJob)); - - //Assert - var settings = timerProvider.All(); - Assert.IsNotEmpty(settings); - Assert.AreEqual(next, settings[0].LastExecution.AddMinutes(15)); - } - - [Test] - public void Disabled_isnt_run_by_scheduler() - { - var repo = MockLib.GetEmptyDatabase(); - - - var disabledJob = new DisabledJob(); - IList BaseFakeJobs = new List { disabledJob }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(repo); - mocker.SetConstant(BaseFakeJobs); - - var timerProvider = mocker.Resolve(); - timerProvider.Initialize(); - - timerProvider.QueueScheduled(); - - Thread.Sleep(1000); - - - //Assert - Assert.AreEqual(0, disabledJob.ExecutionCount); - } - - [Test] - public void SingleId_do_not_update_last_execution() - { - IList BaseFakeJobs = new List { new FakeJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - //Act - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(FakeJob), 10); - Thread.Sleep(1000); - - //Assert - var settings = jobProvider.All(); - settings.Should().NotBeEmpty(); - settings[0].LastExecution.Should().HaveYear(2000); - jobProvider.Queue.Should().BeEmpty(); - } - - [Test] - public void SingleId_do_not_set_success() - { - IList BaseFakeJobs = new List { new FakeJob() }; - var mocker = new AutoMoqer(); - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - //Act - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(FakeJob), 10); - Thread.Sleep(1000); - - //Assert - var settings = jobProvider.All(); - Assert.IsNotEmpty(settings); - Assert.IsFalse(settings[0].Success); - } - - - [Test] - public void existing_queue_should_start_queue_if_not_running() - { - var mocker = new AutoMoqer(); - - var BaseFakeJob = new FakeJob(); - IList BaseFakeJobs = new List { BaseFakeJob }; - - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var fakeQueueItem = new JobQueueItem - { - JobType = BaseFakeJob.GetType(), - TargetId = 12, - SecondaryTargetId = 0 - }; - - //Act - var jobProvider = mocker.Resolve(); - jobProvider.Initialize(); - jobProvider.Queue.Add(fakeQueueItem); - jobProvider.QueueJob(BaseFakeJob.GetType(), 12); - Thread.Sleep(1000); - - //Assert - BaseFakeJob.ExecutionCount.Should().Be(1); - } - - - [Test] - public void Item_added_to_queue_while_scheduler_runs_is_executed() - { - var mocker = new AutoMoqer(); - - var slowJob = new SlowJob(); - var disabledJob = new DisabledJob(); - IList BaseFakeJobs = new List { slowJob, disabledJob }; - - mocker.SetConstant(MockLib.GetEmptyDatabase()); - mocker.SetConstant(BaseFakeJobs); - - var jobProvider = mocker.Resolve(); - - jobProvider.Initialize(); - - var _jobThread = new Thread(jobProvider.QueueScheduled); - _jobThread.Start(); - - Thread.Sleep(200); - - jobProvider.QueueJob(typeof(DisabledJob), 12); - - Thread.Sleep(3000); - - //Assert - jobProvider.Queue.Should().BeEmpty(); - slowJob.ExecutionCount.Should().Be(1); - disabledJob.ExecutionCount.Should().Be(1); - } - - [Test] - public void trygin_to_queue_unregistered_job_should_fail() - { - WithRealDb(); - - IList BaseFakeJobs = new List { new SlowJob(), new DisabledJob() }; - - Mocker.SetConstant(BaseFakeJobs); - - var jobProvider = Mocker.Resolve(); - - jobProvider.Initialize(); - jobProvider.QueueJob(typeof(string)); - - Thread.Sleep(1000); - ExceptionVerification.ExcpectedErrors(1); - } - } - - -} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Jobs/JobProvider.cs b/NzbDrone.Core/Providers/Jobs/JobProvider.cs index 97690a4eb..0ff1b4642 100644 --- a/NzbDrone.Core/Providers/Jobs/JobProvider.cs +++ b/NzbDrone.Core/Providers/Jobs/JobProvider.cs @@ -26,16 +26,18 @@ public class JobProvider private readonly IList _jobs; private Thread _jobThread; - private Stopwatch _jobThreadStopWatch; + public Stopwatch StopWatch { get; private set; } private readonly object executionLock = new object(); private readonly List _queue = new List(); private ProgressNotification _notification; + [Inject] public JobProvider(IDatabase database, NotificationProvider notificationProvider, IList jobs) { + StopWatch = new Stopwatch(); _database = database; _notificationProvider = notificationProvider; _jobs = jobs; @@ -183,7 +185,7 @@ public virtual void QueueJob(Type jobType, int targetId = 0, int secondaryTarget } ResetThread(); - _jobThreadStopWatch = Stopwatch.StartNew(); + StopWatch = Stopwatch.StartNew(); _jobThread.Start(); } @@ -227,12 +229,7 @@ private void ProcessQueue() } } while (Queue.Count != 0); - - logger.Trace("Finished processing jobs in the queue."); - - return; } - catch (ThreadAbortException e) { logger.Warn(e.Message); @@ -243,7 +240,8 @@ private void ProcessQueue() } finally { - ResetThread(); + StopWatch.Stop(); + logger.Trace("Finished processing jobs in the queue."); } } @@ -301,7 +299,7 @@ private void Execute(JobQueueItem queueItem) private void VerifyThreadTime() { - if (_jobThreadStopWatch.Elapsed.TotalHours > 1) + if (StopWatch.Elapsed.TotalHours > 1) { logger.Warn("Thread job has been running for more than an hour. fuck it!"); ResetThread(); @@ -317,7 +315,6 @@ private void ResetThread() logger.Trace("resetting queue processor thread"); _jobThread = new Thread(ProcessQueue) { Name = "JobQueueThread" }; - _jobThreadStopWatch = new Stopwatch(); }