mirror of https://github.com/Sonarr/Sonarr
Cleaned up JobProviderFixture, should save ~20 seconds in build time.
This commit is contained in:
parent
c92e63b21a
commit
04d40575da
|
@ -124,7 +124,7 @@
|
||||||
<Compile Include="JobTests\DiskScanJobTest.cs" />
|
<Compile Include="JobTests\DiskScanJobTest.cs" />
|
||||||
<Compile Include="IndexerTests.cs" />
|
<Compile Include="IndexerTests.cs" />
|
||||||
<Compile Include="ProviderTests\InventoryProvider_QualityNeededTest.cs" />
|
<Compile Include="ProviderTests\InventoryProvider_QualityNeededTest.cs" />
|
||||||
<Compile Include="ProviderTests\JobProviderTests\JobProviderTest.cs" />
|
<Compile Include="ProviderTests\JobProviderTests\JobProviderFixture.cs" />
|
||||||
<Compile Include="QualityTest.cs" />
|
<Compile Include="QualityTest.cs" />
|
||||||
<Compile Include="ProviderTests\RootDirProviderTest.cs" />
|
<Compile Include="ProviderTests\RootDirProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
|
<Compile Include="ProviderTests\IndexerProviderTest.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<JobProvider>().Queue.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WaitForQueue()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Waiting for queue to clear.");
|
||||||
|
var stopWatch = Mocker.Resolve<JobProvider>().StopWatch;
|
||||||
|
|
||||||
|
while (stopWatch.IsRunning)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void running_scheduled_jobs_should_updates_last_execution_time()
|
||||||
|
{
|
||||||
|
IList<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { brokenJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { slowJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { brokenJob };
|
||||||
|
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> fakeJobs = new List<IJob> { slowJob, fakeJob };
|
||||||
|
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { slowJob, fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
|
||||||
|
//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<IJob> BaseFakeJobs = new List<IJob> { fakeTimer };
|
||||||
|
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
jobProvider.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
var Mocker2 = new AutoMoqer();
|
||||||
|
|
||||||
|
Mocker2.SetConstant(Db);
|
||||||
|
var assertjobProvider = Mocker2.Resolve<JobProvider>();
|
||||||
|
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<IJob> fakeJobs = new List<IJob> { disabledJob };
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
jobProvider.Initialize();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
jobProvider.All().Should().HaveCount(1);
|
||||||
|
jobProvider.All().First().Enable.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Get_Next_Execution_Time()
|
||||||
|
{
|
||||||
|
IList<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { disabledJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
jobProvider.Initialize();
|
||||||
|
jobProvider.QueueScheduled();
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
disabledJob.ExecutionCount.Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void job_with_specific_target_should_not_update_last_execution()
|
||||||
|
{
|
||||||
|
IList<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var stuckQueueItem = new JobQueueItem
|
||||||
|
{
|
||||||
|
JobType = fakeJob.GetType(),
|
||||||
|
TargetId = 12,
|
||||||
|
SecondaryTargetId = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { slowJob, disabledJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
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<IJob> BaseFakeJobs = new List<IJob> { slowJob, disabledJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobProvider>();
|
||||||
|
|
||||||
|
jobProvider.Initialize();
|
||||||
|
jobProvider.QueueJob(typeof(string));
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
ExceptionVerification.ExcpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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<IJob> BaseFakeJobs = new List<IJob> { new FakeJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { new BrokenJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { BaseFakeJob };
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { BaseFakeJob };
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { new SlowJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { brokenJob };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> fakeJobs = new List<IJob> { fakeJob };
|
|
||||||
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { slowJob, BaseFakeJob };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { fakeTimer };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { fakeTimer };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(repo);
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
timerProvider.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
var mocker2 = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker2.SetConstant(repo);
|
|
||||||
var assertTimerProvider = mocker2.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { disabledJob };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(repo);
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
timerProvider.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
var mocker2 = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker2.SetConstant(repo);
|
|
||||||
var assertTimerProvider = mocker2.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
var timers = assertTimerProvider.All();
|
|
||||||
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
timers.Should().HaveCount(1);
|
|
||||||
Assert.IsFalse(timers[0].Enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Get_Next_Execution_Time()
|
|
||||||
{
|
|
||||||
IList<IJob> BaseFakeJobs = new List<IJob> { new FakeJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { disabledJob };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(repo);
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
|
||||||
timerProvider.Initialize();
|
|
||||||
|
|
||||||
timerProvider.QueueScheduled();
|
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Assert.AreEqual(0, disabledJob.ExecutionCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void SingleId_do_not_update_last_execution()
|
|
||||||
{
|
|
||||||
IList<IJob> BaseFakeJobs = new List<IJob> { new FakeJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { new FakeJob() };
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { 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>();
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { slowJob, disabledJob };
|
|
||||||
|
|
||||||
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
|
||||||
mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
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<IJob> BaseFakeJobs = new List<IJob> { new SlowJob(), new DisabledJob() };
|
|
||||||
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
jobProvider.Initialize();
|
|
||||||
jobProvider.QueueJob(typeof(string));
|
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
ExceptionVerification.ExcpectedErrors(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -26,16 +26,18 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
private readonly IList<IJob> _jobs;
|
private readonly IList<IJob> _jobs;
|
||||||
|
|
||||||
private Thread _jobThread;
|
private Thread _jobThread;
|
||||||
private Stopwatch _jobThreadStopWatch;
|
public Stopwatch StopWatch { get; private set; }
|
||||||
|
|
||||||
private readonly object executionLock = new object();
|
private readonly object executionLock = new object();
|
||||||
private readonly List<JobQueueItem> _queue = new List<JobQueueItem>();
|
private readonly List<JobQueueItem> _queue = new List<JobQueueItem>();
|
||||||
|
|
||||||
private ProgressNotification _notification;
|
private ProgressNotification _notification;
|
||||||
|
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public JobProvider(IDatabase database, NotificationProvider notificationProvider, IList<IJob> jobs)
|
public JobProvider(IDatabase database, NotificationProvider notificationProvider, IList<IJob> jobs)
|
||||||
{
|
{
|
||||||
|
StopWatch = new Stopwatch();
|
||||||
_database = database;
|
_database = database;
|
||||||
_notificationProvider = notificationProvider;
|
_notificationProvider = notificationProvider;
|
||||||
_jobs = jobs;
|
_jobs = jobs;
|
||||||
|
@ -183,7 +185,7 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetThread();
|
ResetThread();
|
||||||
_jobThreadStopWatch = Stopwatch.StartNew();
|
StopWatch = Stopwatch.StartNew();
|
||||||
_jobThread.Start();
|
_jobThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,12 +229,7 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (Queue.Count != 0);
|
} while (Queue.Count != 0);
|
||||||
|
|
||||||
logger.Trace("Finished processing jobs in the queue.");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (ThreadAbortException e)
|
catch (ThreadAbortException e)
|
||||||
{
|
{
|
||||||
logger.Warn(e.Message);
|
logger.Warn(e.Message);
|
||||||
|
@ -243,7 +240,8 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ResetThread();
|
StopWatch.Stop();
|
||||||
|
logger.Trace("Finished processing jobs in the queue.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +299,7 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
private void VerifyThreadTime()
|
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!");
|
logger.Warn("Thread job has been running for more than an hour. fuck it!");
|
||||||
ResetThread();
|
ResetThread();
|
||||||
|
@ -317,7 +315,6 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
logger.Trace("resetting queue processor thread");
|
logger.Trace("resetting queue processor thread");
|
||||||
_jobThread = new Thread(ProcessQueue) { Name = "JobQueueThread" };
|
_jobThread = new Thread(ProcessQueue) { Name = "JobQueueThread" };
|
||||||
_jobThreadStopWatch = new Stopwatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue