mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
splited jobprovider into jobrepo, jobcontroller, moved to object db.
This commit is contained in:
parent
97398f604b
commit
40f3a8663d
@ -16,9 +16,9 @@ namespace NzbDrone.Api.Series
|
|||||||
public class SeriesModule : NzbDroneApiModule
|
public class SeriesModule : NzbDroneApiModule
|
||||||
{
|
{
|
||||||
private readonly SeriesProvider _seriesProvider;
|
private readonly SeriesProvider _seriesProvider;
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
|
|
||||||
public SeriesModule(SeriesProvider seriesProvider, JobProvider jobProvider)
|
public SeriesModule(SeriesProvider seriesProvider, JobController jobProvider)
|
||||||
: base("/Series")
|
: base("/Series")
|
||||||
{
|
{
|
||||||
_seriesProvider = seriesProvider;
|
_seriesProvider = seriesProvider;
|
||||||
|
@ -104,7 +104,7 @@ public void All_metadata_clients_should_be_registered()
|
|||||||
[Test]
|
[Test]
|
||||||
public void jobs_are_initialized()
|
public void jobs_are_initialized()
|
||||||
{
|
{
|
||||||
kernel.Resolve<JobProvider>().All().Should().HaveSameCount(jobs);
|
kernel.Resolve<IJobRepository>().All().Should().HaveSameCount(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -134,8 +134,8 @@ public void quality_profile_initialized()
|
|||||||
[Test]
|
[Test]
|
||||||
public void JobProvider_should_be_singletone()
|
public void JobProvider_should_be_singletone()
|
||||||
{
|
{
|
||||||
var first = kernel.Resolve<JobProvider>();
|
var first = kernel.Resolve<JobController>();
|
||||||
var second = kernel.Resolve<JobProvider>();
|
var second = kernel.Resolve<JobController>();
|
||||||
|
|
||||||
first.Should().BeSameAs(second);
|
first.Should().BeSameAs(second);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@ -215,7 +216,7 @@ public void Truncate_should_truncate_strings_to_max_specified_number_of_bytes()
|
|||||||
var resultString = str.Truncate(1000);
|
var resultString = str.Truncate(1000);
|
||||||
|
|
||||||
//Resolve
|
//Resolve
|
||||||
var result = new System.Text.UTF8Encoding().GetBytes(resultString);
|
var result = new UTF8Encoding().GetBytes(resultString);
|
||||||
result.Length.Should().BeLessOrEqualTo(1000);
|
result.Length.Should().BeLessOrEqualTo(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +230,7 @@ public void Truncate_should_not_truncate_string_shorter_than_max_bytes()
|
|||||||
var resultString = str.Truncate(1000);
|
var resultString = str.Truncate(1000);
|
||||||
|
|
||||||
//Resolve
|
//Resolve
|
||||||
var result = new System.Text.UTF8Encoding().GetBytes(resultString);
|
var result = new UTF8Encoding().GetBytes(resultString);
|
||||||
result.Length.Should().Be(11);
|
result.Length.Should().Be(11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,14 +28,28 @@ protected FileStream OpenRead(params string[] path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class CoreTest<TSubject> : CoreTest
|
public abstract class CoreTest<TSubject> : CoreTest where TSubject: class
|
||||||
{
|
{
|
||||||
|
private TSubject _subject;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void CoreTestSetup()
|
public void CoreTestSetup()
|
||||||
{
|
{
|
||||||
Subject = Mocker.Resolve<TSubject>();
|
_subject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TSubject Subject { get; set; }
|
protected TSubject Subject
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_subject == null)
|
||||||
|
{
|
||||||
|
_subject = Mocker.Resolve<TSubject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,23 @@
|
|||||||
namespace NzbDrone.Core.Test.Framework
|
namespace NzbDrone.Core.Test.Framework
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class RepositoryTest<TRepository, TModel> : ObjectDbTest<TRepository>
|
||||||
|
where TRepository : class, IBasicRepository<TModel>
|
||||||
|
where TModel : ModelBase, new()
|
||||||
|
{
|
||||||
|
|
||||||
|
protected BasicRepository<TModel> Storage { get; private set; }
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void RepositoryTestSetup()
|
||||||
|
{
|
||||||
|
WithObjectDb();
|
||||||
|
Storage = Mocker.Resolve<BasicRepository<TModel>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class ObjectDbTest<TSubject> : ObjectDbTest where TSubject : class
|
public abstract class ObjectDbTest<TSubject> : ObjectDbTest where TSubject : class
|
||||||
{
|
{
|
||||||
private TSubject _subject;
|
private TSubject _subject;
|
||||||
@ -56,7 +73,7 @@ protected void WithObjectDb(bool memory = true)
|
|||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
_db = new SiaqoDbFactory(new DiskProvider(),new EnvironmentProvider()).Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Guid.NewGuid().ToString()));
|
_db = new SiaqoDbFactory(new DiskProvider(), new EnvironmentProvider()).Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Guid.NewGuid().ToString()));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Mocker.SetConstant(Db);
|
Mocker.SetConstant(Db);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Providers.Core;
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
228
NzbDrone.Core.Test/JobTests/JobControllerFixture.cs
Normal file
228
NzbDrone.Core.Test/JobTests/JobControllerFixture.cs
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NCrunch.Framework;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.JobTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
[ExclusivelyUses("JOB_PROVIDER")]
|
||||||
|
public class JobControllerFixture : CoreTest<JobController>
|
||||||
|
{
|
||||||
|
|
||||||
|
FakeJob _fakeJob;
|
||||||
|
SlowJob _slowJob;
|
||||||
|
BrokenJob _brokenJob;
|
||||||
|
DisabledJob _disabledJob;
|
||||||
|
|
||||||
|
|
||||||
|
private JobDefinition _updatedJob = null;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_fakeJob = new FakeJob();
|
||||||
|
_slowJob = new SlowJob();
|
||||||
|
_brokenJob = new BrokenJob();
|
||||||
|
_disabledJob = new DisabledJob();
|
||||||
|
_updatedJob = null;
|
||||||
|
|
||||||
|
IEnumerable<IJob> jobs = new List<IJob> { _fakeJob, _slowJob, _brokenJob, _disabledJob };
|
||||||
|
|
||||||
|
Mocker.SetConstant(jobs);
|
||||||
|
|
||||||
|
Mocker.GetMock<IJobRepository>()
|
||||||
|
.Setup(c => c.Update(It.IsAny<JobDefinition>()))
|
||||||
|
.Callback<JobDefinition>(c => _updatedJob = c);
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<IJobRepository>()
|
||||||
|
.Setup(c => c.GetDefinition(It.IsAny<Type>()))
|
||||||
|
.Returns(new JobDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void GivenPendingJob(IList<JobDefinition> jobDefinition)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IJobRepository>().Setup(c => c.GetPendingJobs()).Returns(jobDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
Subject.Queue.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WaitForQueue()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Waiting for queue to clear.");
|
||||||
|
var stopWatch = Mocker.Resolve<JobController>().StopWatch;
|
||||||
|
|
||||||
|
while (stopWatch.IsRunning)
|
||||||
|
{
|
||||||
|
Thread.Sleep(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void running_scheduled_jobs_should_updates_last_execution_time()
|
||||||
|
{
|
||||||
|
GivenPendingJob(new List<JobDefinition> { new JobDefinition { TypeName = _fakeJob.GetType().FullName } });
|
||||||
|
|
||||||
|
Subject.QueueScheduled();
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
_updatedJob.LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10));
|
||||||
|
_updatedJob.LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10));
|
||||||
|
_fakeJob.ExecutionCount.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void failing_scheduled_job_should_mark_job_as_failed()
|
||||||
|
{
|
||||||
|
GivenPendingJob(new List<JobDefinition> { new JobDefinition { TypeName = _brokenJob.GetType().FullName } });
|
||||||
|
|
||||||
|
Subject.QueueScheduled();
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
_updatedJob.LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10));
|
||||||
|
_updatedJob.Success.Should().BeFalse();
|
||||||
|
_brokenJob.ExecutionCount.Should().Be(1);
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void can_run_async_job_again()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(FakeJob));
|
||||||
|
WaitForQueue();
|
||||||
|
Subject.QueueJob(typeof(FakeJob));
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
Subject.Queue.Should().BeEmpty();
|
||||||
|
_fakeJob.ExecutionCount.Should().Be(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void no_concurent_jobs()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(SlowJob), 1);
|
||||||
|
Subject.QueueJob(typeof(SlowJob), 2);
|
||||||
|
Subject.QueueJob(typeof(SlowJob), 3);
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
Subject.Queue.Should().BeEmpty();
|
||||||
|
_slowJob.ExecutionCount.Should().Be(3);
|
||||||
|
ExceptionVerification.AssertNoUnexcpectedLogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void can_run_broken_job_again()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(BrokenJob));
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
Subject.QueueJob(typeof(BrokenJob));
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
|
||||||
|
_brokenJob.ExecutionCount.Should().Be(2);
|
||||||
|
ExceptionVerification.ExpectedErrors(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void schedule_hit_should_be_ignored_if_queue_is_running()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(SlowJob));
|
||||||
|
Subject.QueueScheduled();
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
_slowJob.ExecutionCount.Should().Be(1);
|
||||||
|
_fakeJob.ExecutionCount.Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void can_queue_jobs_at_the_same_time()
|
||||||
|
{
|
||||||
|
|
||||||
|
Subject.QueueJob(typeof(SlowJob));
|
||||||
|
var thread1 = new Thread(() => Subject.QueueJob(typeof(FakeJob)));
|
||||||
|
var thread2 = new Thread(() => Subject.QueueJob(typeof(FakeJob)));
|
||||||
|
|
||||||
|
thread1.Start();
|
||||||
|
thread2.Start();
|
||||||
|
|
||||||
|
thread1.Join();
|
||||||
|
thread2.Join();
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
_fakeJob.ExecutionCount.Should().Be(1);
|
||||||
|
_slowJob.ExecutionCount.Should().Be(1);
|
||||||
|
Subject.Queue.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void job_with_specific_target_should_not_update_status()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(FakeJob), 10);
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
Mocker.GetMock<IJobRepository>().Verify(c=>c.Update(It.IsAny<JobDefinition>()),Times.Never());
|
||||||
|
_updatedJob.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Item_added_to_queue_while_scheduler_runs_should_be_executed()
|
||||||
|
{
|
||||||
|
GivenPendingJob(new List<JobDefinition> { new JobDefinition { TypeName = _slowJob.GetType().FullName } });
|
||||||
|
|
||||||
|
var jobThread = new Thread(Subject.QueueScheduled);
|
||||||
|
jobThread.Start();
|
||||||
|
|
||||||
|
Thread.Sleep(200);
|
||||||
|
|
||||||
|
Subject.QueueJob(typeof(DisabledJob), 12);
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
_slowJob.ExecutionCount.Should().Be(1);
|
||||||
|
_disabledJob.ExecutionCount.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void trygin_to_queue_unregistered_job_should_fail()
|
||||||
|
{
|
||||||
|
Subject.QueueJob(typeof(UpdateInfoJob));
|
||||||
|
WaitForQueue();
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void scheduled_job_should_have_scheduler_as_source()
|
||||||
|
{
|
||||||
|
GivenPendingJob(new List<JobDefinition> { new JobDefinition { TypeName = _slowJob.GetType().FullName }, new JobDefinition { TypeName = _slowJob.GetType().FullName } });
|
||||||
|
Subject.QueueScheduled();
|
||||||
|
|
||||||
|
Subject.Queue.Should().OnlyContain(c => c.Source == JobQueueItem.JobSourceType.Scheduler);
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
161
NzbDrone.Core.Test/JobTests/JobRepositoryFixture.cs
Normal file
161
NzbDrone.Core.Test/JobTests/JobRepositoryFixture.cs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// ReSharper disable RedundantUsingDirective
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NCrunch.Framework;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.JobTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class JobRepositoryFixture : RepositoryTest<JobRepository, JobDefinition>
|
||||||
|
{
|
||||||
|
FakeJob _fakeJob;
|
||||||
|
DisabledJob _disabledJob;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_fakeJob = new FakeJob();
|
||||||
|
_disabledJob = new DisabledJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Init_should_add_defintaions()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> baseFakeJobs = new List<IJob> { _fakeJob };
|
||||||
|
Mocker.SetConstant(baseFakeJobs);
|
||||||
|
|
||||||
|
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
Storage.All().Should().HaveCount(1);
|
||||||
|
Storage.All()[0].Interval.Should().Be((Int32)_fakeJob.DefaultInterval.TotalMinutes);
|
||||||
|
Storage.All()[0].Name.Should().Be(_fakeJob.Name);
|
||||||
|
Storage.All()[0].TypeName.Should().Be(_fakeJob.GetType().ToString());
|
||||||
|
Storage.All()[0].LastExecution.Should().HaveYear(DateTime.Now.Year);
|
||||||
|
Storage.All()[0].LastExecution.Should().HaveMonth(DateTime.Now.Month);
|
||||||
|
Storage.All()[0].LastExecution.Should().HaveDay(DateTime.Today.Day);
|
||||||
|
Storage.All()[0].Enable.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void inti_should_removed_jobs_that_no_longer_exist()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> fakeJobs = new List<IJob> { _fakeJob };
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
var deletedJob = Builder<JobDefinition>.CreateNew()
|
||||||
|
.With(c => c.OID = 0)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Db.Insert(deletedJob);
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
var registeredJobs = Storage.All();
|
||||||
|
registeredJobs.Should().HaveCount(1);
|
||||||
|
registeredJobs.Should().NotContain(c => c.TypeName == deletedJob.TypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void inti_should_removed_jobs_that_no_longer_exist_even_with_same_name()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> fakeJobs = new List<IJob> { _fakeJob };
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
var deletedJob = Builder<JobDefinition>.CreateNew()
|
||||||
|
.With(c => c.Name = _fakeJob.Name)
|
||||||
|
.With(c => c.OID = 0)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
Db.Insert(deletedJob);
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var registeredJobs = Storage.All();
|
||||||
|
registeredJobs.Should().HaveCount(1);
|
||||||
|
registeredJobs.Should().NotContain(c => c.TypeName == deletedJob.TypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void init_should_update_existing_job()
|
||||||
|
{
|
||||||
|
|
||||||
|
var oldJob = Builder<JobDefinition>.CreateNew()
|
||||||
|
.With(c => c.OID = 0)
|
||||||
|
.With(c => c.Name = "OldName")
|
||||||
|
.With(c => c.TypeName = typeof(FakeJob).ToString())
|
||||||
|
.With(c => c.Interval = 0)
|
||||||
|
.With(c => c.Enable = true)
|
||||||
|
.With(c => c.Success = true)
|
||||||
|
.With(c => c.LastExecution = DateTime.Now.AddDays(-7).Date)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Storage.Add(oldJob);
|
||||||
|
|
||||||
|
var newJob = new FakeJob();
|
||||||
|
|
||||||
|
IEnumerable<IJob> fakeJobs = new List<IJob> { newJob };
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
|
||||||
|
var registeredJobs = Storage.All();
|
||||||
|
registeredJobs.Should().HaveCount(1);
|
||||||
|
registeredJobs.First().TypeName.Should().Be(newJob.GetType().FullName);
|
||||||
|
registeredJobs.First().Name.Should().Be(newJob.Name);
|
||||||
|
registeredJobs.First().Interval.Should().Be((int)newJob.DefaultInterval.TotalMinutes);
|
||||||
|
|
||||||
|
registeredJobs.First().Enable.Should().Be(true);
|
||||||
|
registeredJobs.First().Success.Should().Be(oldJob.Success);
|
||||||
|
registeredJobs.First().LastExecution.Should().Be(oldJob.LastExecution);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void jobs_with_zero_interval_are_registered_as_disabled()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> fakeJobs = new List<IJob> { _disabledJob };
|
||||||
|
Mocker.SetConstant(fakeJobs);
|
||||||
|
|
||||||
|
Subject.Init();
|
||||||
|
|
||||||
|
|
||||||
|
Storage.All().Should().HaveCount(1);
|
||||||
|
Storage.All().First().Enable.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [Test]
|
||||||
|
public void disabled_jobs_arent_run_by_scheduler()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { disabledJob };
|
||||||
|
Mocker.SetConstant(BaseFakeJobs);
|
||||||
|
|
||||||
|
var jobProvider = Mocker.Resolve<JobController>();
|
||||||
|
jobProvider.QueueScheduled();
|
||||||
|
|
||||||
|
WaitForQueue();
|
||||||
|
|
||||||
|
|
||||||
|
disabledJob.ExecutionCount.Should().Be(0);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests.JobProviderTests
|
namespace NzbDrone.Core.Test.JobTests
|
||||||
{
|
{
|
||||||
|
|
||||||
public class FakeJob : IJob
|
public class FakeJob : IJob
|
@ -141,6 +141,7 @@
|
|||||||
<Compile Include="Framework\ObjectDbTest.cs" />
|
<Compile Include="Framework\ObjectDbTest.cs" />
|
||||||
<Compile Include="HelperTests\XElementHelperTests\ConvertToTFixture.cs" />
|
<Compile Include="HelperTests\XElementHelperTests\ConvertToTFixture.cs" />
|
||||||
<Compile Include="IndexerTests\NzbxFixture.cs" />
|
<Compile Include="IndexerTests\NzbxFixture.cs" />
|
||||||
|
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
||||||
<Compile Include="JobTests\RenameSeasonJobFixture.cs" />
|
<Compile Include="JobTests\RenameSeasonJobFixture.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
||||||
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
|
<Compile Include="ProviderTests\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
|
||||||
@ -212,7 +213,7 @@
|
|||||||
<Compile Include="ProviderTests\PostDownloadProviderTests\GetFolderNameWithStatusFixture.cs" />
|
<Compile Include="ProviderTests\PostDownloadProviderTests\GetFolderNameWithStatusFixture.cs" />
|
||||||
<Compile Include="JobTests\EpisodeSearchJobTest.cs" />
|
<Compile Include="JobTests\EpisodeSearchJobTest.cs" />
|
||||||
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDownloadFixture.cs" />
|
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDownloadFixture.cs" />
|
||||||
<Compile Include="ProviderTests\JobProviderTests\TestJobs.cs" />
|
<Compile Include="JobTests\TestJobs.cs" />
|
||||||
<Compile Include="JobTests\AppUpdateJobFixture.cs" />
|
<Compile Include="JobTests\AppUpdateJobFixture.cs" />
|
||||||
<Compile Include="ProviderTests\UpdateProviderTests\GetUpdateLogFixture.cs" />
|
<Compile Include="ProviderTests\UpdateProviderTests\GetUpdateLogFixture.cs" />
|
||||||
<Compile Include="ProviderTests\UpdateProviderTests\GetAvilableUpdateFixture.cs" />
|
<Compile Include="ProviderTests\UpdateProviderTests\GetAvilableUpdateFixture.cs" />
|
||||||
@ -245,7 +246,7 @@
|
|||||||
<Compile Include="JobTests\DiskScanJobTest.cs" />
|
<Compile Include="JobTests\DiskScanJobTest.cs" />
|
||||||
<Compile Include="IndexerTests\IndexerFixture.cs" />
|
<Compile Include="IndexerTests\IndexerFixture.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\AllowedDownloadSpecificationFixture.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\AllowedDownloadSpecificationFixture.cs" />
|
||||||
<Compile Include="ProviderTests\JobProviderTests\JobProviderFixture.cs" />
|
<Compile Include="JobTests\JobControllerFixture.cs" />
|
||||||
<Compile Include="QualityTest.cs" />
|
<Compile Include="QualityTest.cs" />
|
||||||
<Compile Include="RootFolderTests\RootFolderServiceFixture.cs" />
|
<Compile Include="RootFolderTests\RootFolderServiceFixture.cs" />
|
||||||
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
|
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
|
||||||
|
@ -1,463 +0,0 @@
|
|||||||
// ReSharper disable RedundantUsingDirective
|
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NCrunch.Framework;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Core.Jobs;
|
|
||||||
using NzbDrone.Core.Model;
|
|
||||||
using NzbDrone.Core.Repository;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
using NzbDrone.Test.Common.AutoMoq;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests.JobProviderTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
[ExclusivelyUses("JOB_PROVIDER")]
|
|
||||||
public class JobProviderFixture : SqlCeTest
|
|
||||||
{
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
if(!EnvironmentProvider.IsMono)
|
|
||||||
{
|
|
||||||
Mocker.Resolve<JobProvider>().Queue.Should().BeEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetLastExecution()
|
|
||||||
{
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
var jobs = jobProvider.All();
|
|
||||||
foreach (var jobDefinition in jobs)
|
|
||||||
{
|
|
||||||
jobDefinition.LastExecution = new DateTime(2000, 1, 1);
|
|
||||||
jobProvider.SaveDefinition(jobDefinition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WaitForQueue()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Waiting for queue to clear.");
|
|
||||||
var stopWatch = Mocker.Resolve<JobProvider>().StopWatch;
|
|
||||||
|
|
||||||
while (stopWatch.IsRunning)
|
|
||||||
{
|
|
||||||
Thread.Sleep(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void running_scheduled_jobs_should_updates_last_execution_time()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
|
|
||||||
ResetLastExecution();
|
|
||||||
Mocker.Resolve<JobProvider>().QueueScheduled();
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
var settings = Mocker.Resolve<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()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { brokenJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
|
|
||||||
ResetLastExecution();
|
|
||||||
Mocker.Resolve<JobProvider>().QueueScheduled();
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
var settings = Mocker.Resolve<JobProvider>().All();
|
|
||||||
settings.First().LastExecution.Should().BeWithin(TimeSpan.FromSeconds(10));
|
|
||||||
settings.First().Success.Should().BeFalse();
|
|
||||||
brokenJob.ExecutionCount.Should().Be(1);
|
|
||||||
ExceptionVerification.ExpectedErrors(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void scheduler_skips_jobs_that_arent_mature_yet()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
|
|
||||||
ResetLastExecution();
|
|
||||||
|
|
||||||
Mocker.Resolve<JobProvider>().QueueScheduled();
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
Mocker.Resolve<JobProvider>().QueueScheduled();
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.QueueJob(typeof(FakeJob));
|
|
||||||
WaitForQueue();
|
|
||||||
jobProvider.QueueJob(typeof(FakeJob));
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.Queue.Should().BeEmpty();
|
|
||||||
fakeJob.ExecutionCount.Should().Be(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void no_concurent_jobs()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { slowJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { brokenJob };
|
|
||||||
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.QueueJob(typeof(BrokenJob));
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
jobProvider.QueueJob(typeof(BrokenJob));
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
brokenJob.ExecutionCount.Should().Be(2);
|
|
||||||
ExceptionVerification.ExpectedErrors(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void schedule_hit_should_be_ignored_if_queue_is_running()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> fakeJobs = new List<IJob> { slowJob, fakeJob };
|
|
||||||
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.QueueJob(typeof(SlowJob));
|
|
||||||
jobProvider.QueueScheduled();
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
slowJob.ExecutionCount.Should().Be(1);
|
|
||||||
fakeJob.ExecutionCount.Should().Be(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void can_queue_jobs_at_the_same_time()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { slowJob, fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var timers = jobProvider.All();
|
|
||||||
timers.Should().HaveCount(1);
|
|
||||||
timers[0].Interval.Should().Be((Int32)fakeJob.DefaultInterval.TotalMinutes);
|
|
||||||
timers[0].Name.Should().Be(fakeJob.Name);
|
|
||||||
timers[0].TypeName.Should().Be(fakeJob.GetType().ToString());
|
|
||||||
timers[0].LastExecution.Should().HaveYear(DateTime.Now.Year);
|
|
||||||
timers[0].LastExecution.Should().HaveMonth(DateTime.Now.Month);
|
|
||||||
timers[0].LastExecution.Should().HaveDay(DateTime.Today.Day);
|
|
||||||
timers[0].Enable.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void inti_should_removed_jobs_that_no_longer_exist()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> fakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
WithRealDb();
|
|
||||||
var deletedJob = Builder<JobDefinition>.CreateNew().Build();
|
|
||||||
Db.Insert(deletedJob);
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
var registeredJobs = Db.Fetch<JobDefinition>();
|
|
||||||
registeredJobs.Should().HaveCount(1);
|
|
||||||
registeredJobs.Should().NotContain(c => c.TypeName == deletedJob.TypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void inti_should_removed_jobs_that_no_longer_exist_even_with_same_name()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> fakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
WithRealDb();
|
|
||||||
var deletedJob = Builder<JobDefinition>.CreateNew()
|
|
||||||
.With(c => c.Name = fakeJob.Name).Build();
|
|
||||||
|
|
||||||
Db.Insert(deletedJob);
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
var registeredJobs = Db.Fetch<JobDefinition>();
|
|
||||||
registeredJobs.Should().HaveCount(1);
|
|
||||||
registeredJobs.Should().NotContain(c => c.TypeName == deletedJob.TypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void init_should_update_existing_job()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> fakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
WithRealDb();
|
|
||||||
var initialFakeJob = Builder<JobDefinition>.CreateNew()
|
|
||||||
.With(c => c.Name = "NewName")
|
|
||||||
.With(c => c.TypeName = fakeJob.GetType().ToString())
|
|
||||||
.With(c => c.Interval = 0)
|
|
||||||
.With(c => c.Enable = false)
|
|
||||||
.With(c => c.Success = true)
|
|
||||||
.With(c => c.LastExecution = DateTime.Now.AddDays(-7).Date)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var id = Convert.ToInt32(Db.Insert(initialFakeJob));
|
|
||||||
|
|
||||||
Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var registeredJobs = Db.Fetch<JobDefinition>();
|
|
||||||
registeredJobs.Should().HaveCount(1);
|
|
||||||
registeredJobs.First().TypeName.Should().Be(fakeJob.GetType().ToString());
|
|
||||||
registeredJobs.First().Name.Should().Be(fakeJob.Name);
|
|
||||||
registeredJobs.First().Interval.Should().Be((Int32)fakeJob.DefaultInterval.TotalMinutes);
|
|
||||||
|
|
||||||
registeredJobs.First().Enable.Should().Be(true);
|
|
||||||
registeredJobs.First().Success.Should().Be(initialFakeJob.Success);
|
|
||||||
registeredJobs.First().LastExecution.Should().Be(initialFakeJob.LastExecution);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void jobs_with_zero_interval_are_registered_as_disabled()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> fakeJobs = new List<IJob> { disabledJob };
|
|
||||||
Mocker.SetConstant(fakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.All().Should().HaveCount(1);
|
|
||||||
jobProvider.All().First().Enable.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void disabled_jobs_arent_run_by_scheduler()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { disabledJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
jobProvider.QueueScheduled();
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
disabledJob.ExecutionCount.Should().Be(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void job_with_specific_target_should_not_update_last_execution()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
ResetLastExecution();
|
|
||||||
jobProvider.QueueJob(typeof(FakeJob), 10);
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.All().First().LastExecution.Should().HaveYear(2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void job_with_specific_target_should_not_set_success_flag()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
jobProvider.QueueJob(typeof(FakeJob), 10);
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
jobProvider.All().First().Success.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void duplicated_queue_item_should_start_queue_if_its_not_running()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { fakeJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var stuckQueueItem = new JobQueueItem
|
|
||||||
{
|
|
||||||
JobType = fakeJob.GetType(),
|
|
||||||
Options = new { TargetId = 12 }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
jobProvider.Queue.Add(stuckQueueItem);
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
jobProvider.QueueJob(stuckQueueItem.JobType, stuckQueueItem.Options);
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
fakeJob.ExecutionCount.Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Item_added_to_queue_while_scheduler_runs_should_be_executed()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { slowJob, disabledJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
ResetLastExecution();
|
|
||||||
var _jobThread = new Thread(Mocker.Resolve<JobProvider>().QueueScheduled);
|
|
||||||
_jobThread.Start();
|
|
||||||
|
|
||||||
Thread.Sleep(200);
|
|
||||||
|
|
||||||
Mocker.Resolve<JobProvider>().QueueJob(typeof(DisabledJob), 12);
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
|
|
||||||
|
|
||||||
slowJob.ExecutionCount.Should().Be(1);
|
|
||||||
disabledJob.ExecutionCount.Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void trygin_to_queue_unregistered_job_should_fail()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { slowJob, disabledJob };
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
|
|
||||||
jobProvider.QueueJob(typeof(string));
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
ExceptionVerification.ExpectedErrors(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void scheduled_job_should_have_scheduler_as_source()
|
|
||||||
{
|
|
||||||
IEnumerable<IJob> BaseFakeJobs = new List<IJob> { slowJob, fakeJob};
|
|
||||||
Mocker.SetConstant(BaseFakeJobs);
|
|
||||||
|
|
||||||
var jobProvider = Mocker.Resolve<JobProvider>();
|
|
||||||
ResetLastExecution();
|
|
||||||
jobProvider.QueueScheduled();
|
|
||||||
|
|
||||||
jobProvider.Queue.Should().OnlyContain(c => c.Source == JobQueueItem.JobSourceType.Scheduler);
|
|
||||||
|
|
||||||
WaitForQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,6 +8,8 @@ public interface IBasicRepository<TModel>
|
|||||||
List<TModel> All();
|
List<TModel> All();
|
||||||
TModel Get(int id);
|
TModel Get(int id);
|
||||||
TModel Add(TModel model);
|
TModel Add(TModel model);
|
||||||
|
TModel Update(TModel model);
|
||||||
|
TModel Upsert(TModel model);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ public BasicRepository(IObjectDatabase objectDatabase)
|
|||||||
ObjectDatabase = objectDatabase;
|
ObjectDatabase = objectDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IObjectDatabase ObjectDatabase { get; private set; }
|
public IObjectDatabase ObjectDatabase { get; private set; }
|
||||||
|
|
||||||
protected IEnumerable<TModel> Queryable { get { return ObjectDatabase.AsQueryable<TModel>(); } }
|
protected IEnumerable<TModel> Queryable { get { return ObjectDatabase.AsQueryable<TModel>(); } }
|
||||||
|
|
||||||
@ -37,6 +39,20 @@ public TModel Add(TModel model)
|
|||||||
return ObjectDatabase.Insert(model);
|
return ObjectDatabase.Insert(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TModel Update(TModel model)
|
||||||
|
{
|
||||||
|
return ObjectDatabase.Update(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TModel Upsert(TModel model)
|
||||||
|
{
|
||||||
|
if(model.OID == 0)
|
||||||
|
{
|
||||||
|
return ObjectDatabase.Insert(model);
|
||||||
|
}
|
||||||
|
return ObjectDatabase.Update(model);
|
||||||
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var itemToDelete = Get(id);
|
var itemToDelete = Get(id);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using NLog;
|
using NLog;
|
||||||
@ -21,7 +22,7 @@ static ConnectionFactory()
|
|||||||
|
|
||||||
if (EnvironmentProvider.IsMono) return;
|
if (EnvironmentProvider.IsMono) return;
|
||||||
|
|
||||||
var dataSet = (System.Data.DataSet)ConfigurationManager.GetSection("system.data");
|
var dataSet = (DataSet)ConfigurationManager.GetSection("system.data");
|
||||||
dataSet.Tables[0].Rows.Add("Microsoft SQL Server Compact Data Provider 4.0"
|
dataSet.Tables[0].Rows.Add("Microsoft SQL Server Compact Data Provider 4.0"
|
||||||
, "System.Data.SqlServerCe.4.0"
|
, "System.Data.SqlServerCe.4.0"
|
||||||
, ".NET Framework Data Provider for Microsoft SQL Server Compact"
|
, ".NET Framework Data Provider for Microsoft SQL Server Compact"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
|
// ReSharper disable CheckNamespace
|
||||||
namespace PetaPoco
|
namespace PetaPoco
|
||||||
{
|
{
|
||||||
public class EpisodeSeasonRelator
|
public class EpisodeSeasonRelator
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Instrumentation;
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Jobs
|
namespace NzbDrone.Core.Instrumentation
|
||||||
{
|
{
|
||||||
public class TrimLogsJob : IJob
|
public class TrimLogsJob : IJob
|
||||||
{
|
{
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -8,21 +7,24 @@
|
|||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Repository;
|
|
||||||
using PetaPoco;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Jobs
|
namespace NzbDrone.Core.Jobs
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IJobController
|
||||||
/// Provides a background task runner, tasks could be queue either by the scheduler using QueueScheduled()
|
{
|
||||||
/// or by explicitly calling QueueJob(type,int)
|
Stopwatch StopWatch { get; }
|
||||||
/// </summary>
|
List<JobQueueItem> Queue { get; }
|
||||||
public class JobProvider
|
void QueueScheduled();
|
||||||
|
void QueueJob(Type jobType, dynamic options = null, JobQueueItem.JobSourceType source = JobQueueItem.JobSourceType.User);
|
||||||
|
bool QueueJob(string jobTypeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JobController : IJobController
|
||||||
{
|
{
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
||||||
private readonly IDatabase _database;
|
|
||||||
private readonly NotificationProvider _notificationProvider;
|
private readonly NotificationProvider _notificationProvider;
|
||||||
private readonly IEnumerable<IJob> _jobs;
|
private readonly IEnumerable<IJob> _jobs;
|
||||||
|
private readonly IJobRepository _jobRepository;
|
||||||
|
private readonly Logger logger;
|
||||||
|
|
||||||
private Thread _jobThread;
|
private Thread _jobThread;
|
||||||
public Stopwatch StopWatch { get; private set; }
|
public Stopwatch StopWatch { get; private set; }
|
||||||
@ -33,26 +35,16 @@ public class JobProvider
|
|||||||
private ProgressNotification _notification;
|
private ProgressNotification _notification;
|
||||||
|
|
||||||
|
|
||||||
public JobProvider(IDatabase database, NotificationProvider notificationProvider, IEnumerable<IJob> jobs)
|
public JobController(NotificationProvider notificationProvider, IEnumerable<IJob> jobs, IJobRepository jobRepository, Logger logger)
|
||||||
{
|
{
|
||||||
StopWatch = new Stopwatch();
|
StopWatch = new Stopwatch();
|
||||||
_database = database;
|
|
||||||
_notificationProvider = notificationProvider;
|
_notificationProvider = notificationProvider;
|
||||||
_jobs = jobs;
|
_jobs = jobs;
|
||||||
|
_jobRepository = jobRepository;
|
||||||
|
this.logger = logger;
|
||||||
ResetThread();
|
ResetThread();
|
||||||
Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="JobProvider"/> class. by AutoMoq
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Should only be used by AutoMoq</remarks>
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public JobProvider() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the active queue.
|
|
||||||
/// </summary>
|
|
||||||
public List<JobQueueItem> Queue
|
public List<JobQueueItem> Queue
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -61,62 +53,6 @@ public List<JobQueueItem> Queue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<JobDefinition> All()
|
|
||||||
{
|
|
||||||
return _database.Fetch<JobDefinition>().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
var currentJobs = All();
|
|
||||||
logger.Debug("Initializing jobs. Available: {0} Existing:{1}", _jobs.Count(), currentJobs.Count);
|
|
||||||
|
|
||||||
foreach (var currentJob in currentJobs)
|
|
||||||
{
|
|
||||||
if (!_jobs.Any(c => c.GetType().ToString() == currentJob.TypeName))
|
|
||||||
{
|
|
||||||
logger.Debug("Removing job from database '{0}'", currentJob.Name);
|
|
||||||
_database.Delete(currentJob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var job in _jobs)
|
|
||||||
{
|
|
||||||
var jobDefinition = currentJobs.SingleOrDefault(c => c.TypeName == job.GetType().ToString());
|
|
||||||
|
|
||||||
if (jobDefinition == null)
|
|
||||||
{
|
|
||||||
jobDefinition = new JobDefinition();
|
|
||||||
jobDefinition.TypeName = job.GetType().ToString();
|
|
||||||
jobDefinition.LastExecution = DateTime.Now;
|
|
||||||
}
|
|
||||||
|
|
||||||
jobDefinition.Enable = job.DefaultInterval.TotalSeconds > 0;
|
|
||||||
jobDefinition.Name = job.Name;
|
|
||||||
|
|
||||||
jobDefinition.Interval = Convert.ToInt32(job.DefaultInterval.TotalMinutes);
|
|
||||||
|
|
||||||
SaveDefinition(jobDefinition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds/Updates definitions for a job
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="definitions">Settings to be added/updated</param>
|
|
||||||
public virtual void SaveDefinition(JobDefinition definitions)
|
|
||||||
{
|
|
||||||
if (definitions.Id == 0)
|
|
||||||
{
|
|
||||||
logger.Trace("Adding job definitions for {0}", definitions.Name);
|
|
||||||
_database.Insert(definitions);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Trace("Updating job definitions for {0}", definitions.Name);
|
|
||||||
_database.Update(definitions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void QueueScheduled()
|
public virtual void QueueScheduled()
|
||||||
{
|
{
|
||||||
@ -131,14 +67,13 @@ public virtual void QueueScheduled()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pendingJobTypes = All().Where(
|
var pendingJobs = _jobRepository.GetPendingJobs()
|
||||||
t => t.Enable &&
|
.Select(c => _jobs.Single(t => t.GetType().ToString() == c.TypeName)
|
||||||
(DateTime.Now - t.LastExecution) > TimeSpan.FromMinutes(t.Interval)
|
.GetType()).ToList();
|
||||||
).Select(c => _jobs.Single(t => t.GetType().ToString() == c.TypeName).GetType()).ToList();
|
|
||||||
|
|
||||||
|
|
||||||
pendingJobTypes.ForEach(jobType => QueueJob(jobType, source: JobQueueItem.JobSourceType.Scheduler));
|
pendingJobs.ForEach(jobType => QueueJob(jobType, source: JobQueueItem.JobSourceType.Scheduler));
|
||||||
logger.Trace("{0} Scheduled tasks have been added to the queue", pendingJobTypes.Count);
|
logger.Trace("{0} Scheduled tasks have been added to the queue", pendingJobs.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void QueueJob(Type jobType, dynamic options = null, JobQueueItem.JobSourceType source = JobQueueItem.JobSourceType.User)
|
public virtual void QueueJob(Type jobType, dynamic options = null, JobQueueItem.JobSourceType source = JobQueueItem.JobSourceType.User)
|
||||||
@ -193,11 +128,6 @@ public virtual bool QueueJob(string jobTypeString)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual JobDefinition GetDefinition(Type type)
|
|
||||||
{
|
|
||||||
return _database.Single<JobDefinition>("WHERE TypeName = @0", type.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessQueue()
|
private void ProcessQueue()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -261,13 +191,12 @@ private void Execute(JobQueueItem queueItem)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings = All().Single(j => j.TypeName == queueItem.JobType.ToString());
|
var jobDefinition = _jobRepository.GetDefinition(queueItem.JobType);
|
||||||
|
|
||||||
using (_notification = new ProgressNotification(jobImplementation.Name))
|
using (_notification = new ProgressNotification(jobImplementation.Name))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.Debug("Starting {0}. Last execution {1}", queueItem, settings.LastExecution);
|
logger.Debug("Starting {0}. Last execution {1}", queueItem, jobDefinition.LastExecution);
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
@ -275,8 +204,8 @@ private void Execute(JobQueueItem queueItem)
|
|||||||
jobImplementation.Start(_notification, queueItem.Options);
|
jobImplementation.Start(_notification, queueItem.Options);
|
||||||
_notification.Status = ProgressNotificationStatus.Completed;
|
_notification.Status = ProgressNotificationStatus.Completed;
|
||||||
|
|
||||||
settings.LastExecution = DateTime.Now;
|
jobDefinition.LastExecution = DateTime.Now;
|
||||||
settings.Success = true;
|
jobDefinition.Success = true;
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
logger.Debug("Job {0} successfully completed in {1:0}.{2} seconds.", queueItem, sw.Elapsed.TotalSeconds, sw.Elapsed.Milliseconds / 100,
|
logger.Debug("Job {0} successfully completed in {1:0}.{2} seconds.", queueItem, sw.Elapsed.TotalSeconds, sw.Elapsed.Milliseconds / 100,
|
||||||
@ -292,15 +221,15 @@ private void Execute(JobQueueItem queueItem)
|
|||||||
_notification.Status = ProgressNotificationStatus.Failed;
|
_notification.Status = ProgressNotificationStatus.Failed;
|
||||||
_notification.CurrentMessage = jobImplementation.Name + " Failed.";
|
_notification.CurrentMessage = jobImplementation.Name + " Failed.";
|
||||||
|
|
||||||
settings.LastExecution = DateTime.Now;
|
jobDefinition.LastExecution = DateTime.Now;
|
||||||
settings.Success = false;
|
jobDefinition.Success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only update last execution status if was triggered by the scheduler
|
//Only update last execution status if was triggered by the scheduler
|
||||||
if (queueItem.Options == null)
|
if (queueItem.Options == null)
|
||||||
{
|
{
|
||||||
SaveDefinition(settings);
|
_jobRepository.Update(jobDefinition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using PetaPoco;
|
using System;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Repository
|
namespace NzbDrone.Core.Jobs
|
||||||
{
|
{
|
||||||
[TableName("JobDefinitions")]
|
public class JobDefinition : ModelBase
|
||||||
[PrimaryKey("Id", autoIncrement = true)]
|
|
||||||
public class JobDefinition
|
|
||||||
{
|
{
|
||||||
public Int32 Id { get; set; }
|
|
||||||
|
|
||||||
public Boolean Enable { get; set; }
|
public Boolean Enable { get; set; }
|
||||||
|
|
||||||
public String TypeName { get; set; }
|
public String TypeName { get; set; }
|
75
NzbDrone.Core/Jobs/JobRepository.cs
Normal file
75
NzbDrone.Core/Jobs/JobRepository.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Jobs
|
||||||
|
{
|
||||||
|
public interface IJobRepository : IInitializable, IBasicRepository<JobDefinition>
|
||||||
|
{
|
||||||
|
IList<JobDefinition> GetPendingJobs();
|
||||||
|
JobDefinition GetDefinition(Type type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JobRepository : BasicRepository<JobDefinition>, IJobRepository
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<IJob> _jobs;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public JobRepository(IObjectDatabase objectDatabase, IEnumerable<IJob> jobs, Logger logger)
|
||||||
|
: base(objectDatabase)
|
||||||
|
{
|
||||||
|
_jobs = jobs;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JobDefinition GetDefinition(Type type)
|
||||||
|
{
|
||||||
|
return Queryable.Single(c => c.TypeName == type.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IList<JobDefinition> GetPendingJobs()
|
||||||
|
{
|
||||||
|
return Queryable.Where(c => c.Enable && c.LastExecution < DateTime.UtcNow.AddMinutes(c.Interval)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
var currentJobs = All();
|
||||||
|
_logger.Debug("Initializing jobs. Available: {0} Existing:{1}", _jobs.Count(), currentJobs.Count);
|
||||||
|
|
||||||
|
foreach (var currentJob in currentJobs)
|
||||||
|
{
|
||||||
|
if (_jobs.All(c => c.GetType().ToString() != currentJob.TypeName))
|
||||||
|
{
|
||||||
|
_logger.Debug("Removing job from database '{0}'", currentJob.Name);
|
||||||
|
Delete(currentJob.OID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var job in _jobs)
|
||||||
|
{
|
||||||
|
var jobDefinition = currentJobs.SingleOrDefault(c => c.TypeName == job.GetType().ToString());
|
||||||
|
|
||||||
|
if (jobDefinition == null)
|
||||||
|
{
|
||||||
|
jobDefinition = new JobDefinition
|
||||||
|
{
|
||||||
|
TypeName = job.GetType().ToString(),
|
||||||
|
LastExecution = DateTime.Now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
jobDefinition.Enable = job.DefaultInterval.TotalSeconds > 0;
|
||||||
|
jobDefinition.Name = job.Name;
|
||||||
|
|
||||||
|
jobDefinition.Interval = Convert.ToInt32(job.DefaultInterval.TotalMinutes);
|
||||||
|
|
||||||
|
Upsert(jobDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,10 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Jobs
|
namespace NzbDrone.Core.Lifecycle
|
||||||
{
|
{
|
||||||
public class AppRestartJob : IJob
|
public class AppRestartJob : IJob
|
||||||
{
|
{
|
@ -1,12 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Jobs
|
namespace NzbDrone.Core.Lifecycle
|
||||||
{
|
{
|
||||||
public class AppShutdownJob : IJob
|
public class AppShutdownJob : IJob
|
||||||
{
|
{
|
@ -4,11 +4,12 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Providers.Core;
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Jobs
|
namespace NzbDrone.Core.Lifecycle
|
||||||
{
|
{
|
||||||
public class AppUpdateJob : IJob
|
public class AppUpdateJob : IJob
|
||||||
{
|
{
|
7
NzbDrone.Core/Lifecycle/IInitilizable.cs
Normal file
7
NzbDrone.Core/Lifecycle/IInitilizable.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace NzbDrone.Core.Lifecycle
|
||||||
|
{
|
||||||
|
public interface IInitializable
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
}
|
||||||
|
}
|
@ -270,13 +270,15 @@
|
|||||||
<Compile Include="Helpers\XElementHelper.cs" />
|
<Compile Include="Helpers\XElementHelper.cs" />
|
||||||
<Compile Include="Instrumentation\LogInjectionModule.cs" />
|
<Compile Include="Instrumentation\LogInjectionModule.cs" />
|
||||||
<Compile Include="Jobs\CleanupRecycleBinJob.cs" />
|
<Compile Include="Jobs\CleanupRecycleBinJob.cs" />
|
||||||
<Compile Include="Jobs\AppShutdownJob.cs" />
|
<Compile Include="Jobs\JobRepository.cs" />
|
||||||
<Compile Include="Jobs\AppRestartJob.cs" />
|
<Compile Include="Lifecycle\AppShutdownJob.cs" />
|
||||||
|
<Compile Include="Lifecycle\AppRestartJob.cs" />
|
||||||
<Compile Include="Jobs\XemUpdateJob.cs" />
|
<Compile Include="Jobs\XemUpdateJob.cs" />
|
||||||
<Compile Include="Jobs\EmptyRecycleBinJob.cs" />
|
<Compile Include="Jobs\EmptyRecycleBinJob.cs" />
|
||||||
<Compile Include="Jobs\RefreshEpsiodeMetadata.cs" />
|
<Compile Include="Jobs\RefreshEpsiodeMetadata.cs" />
|
||||||
<Compile Include="Jobs\PastWeekBacklogSearchJob.cs" />
|
<Compile Include="Jobs\PastWeekBacklogSearchJob.cs" />
|
||||||
<Compile Include="Jobs\SearchHistoryCleanupJob.cs" />
|
<Compile Include="Jobs\SearchHistoryCleanupJob.cs" />
|
||||||
|
<Compile Include="Lifecycle\IInitilizable.cs" />
|
||||||
<Compile Include="Model\HistoryQueryModel.cs" />
|
<Compile Include="Model\HistoryQueryModel.cs" />
|
||||||
<Compile Include="Model\DownloadClientType.cs" />
|
<Compile Include="Model\DownloadClientType.cs" />
|
||||||
<Compile Include="Instrumentation\LogProvider.cs" />
|
<Compile Include="Instrumentation\LogProvider.cs" />
|
||||||
@ -353,11 +355,11 @@
|
|||||||
<Compile Include="Providers\Search\SearchBase.cs" />
|
<Compile Include="Providers\Search\SearchBase.cs" />
|
||||||
<Compile Include="Providers\SeasonProvider.cs" />
|
<Compile Include="Providers\SeasonProvider.cs" />
|
||||||
<Compile Include="Jobs\RecentBacklogSearchJob.cs" />
|
<Compile Include="Jobs\RecentBacklogSearchJob.cs" />
|
||||||
<Compile Include="Jobs\TrimLogsJob.cs" />
|
<Compile Include="Instrumentation\TrimLogsJob.cs" />
|
||||||
<Compile Include="Jobs\JobProvider.cs" />
|
<Compile Include="Jobs\JobController.cs" />
|
||||||
<Compile Include="Jobs\RenameSeasonJob.cs" />
|
<Compile Include="Jobs\RenameSeasonJob.cs" />
|
||||||
<Compile Include="Jobs\RenameSeriesJob.cs" />
|
<Compile Include="Jobs\RenameSeriesJob.cs" />
|
||||||
<Compile Include="Jobs\AppUpdateJob.cs" />
|
<Compile Include="Lifecycle\AppUpdateJob.cs" />
|
||||||
<Compile Include="Jobs\BacklogSearchJob.cs" />
|
<Compile Include="Jobs\BacklogSearchJob.cs" />
|
||||||
<Compile Include="Jobs\BannerDownloadJob.cs" />
|
<Compile Include="Jobs\BannerDownloadJob.cs" />
|
||||||
<Compile Include="Jobs\ConvertEpisodeJob.cs" />
|
<Compile Include="Jobs\ConvertEpisodeJob.cs" />
|
||||||
@ -570,7 +572,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Repository\NewznabDefinition.cs" />
|
<Compile Include="Repository\NewznabDefinition.cs" />
|
||||||
<Compile Include="Repository\ExternalNotificationDefinition.cs" />
|
<Compile Include="Repository\ExternalNotificationDefinition.cs" />
|
||||||
<Compile Include="Repository\JobDefinition.cs" />
|
<Compile Include="Jobs\JobDefinition.cs" />
|
||||||
<Compile Include="Repository\IndexerDefinition.cs" />
|
<Compile Include="Repository\IndexerDefinition.cs" />
|
||||||
<Compile Include="Model\EpisodeParseResult.cs" />
|
<Compile Include="Model\EpisodeParseResult.cs" />
|
||||||
<Compile Include="Model\EpisodeSortingType.cs" />
|
<Compile Include="Model\EpisodeSortingType.cs" />
|
||||||
|
@ -29,7 +29,7 @@ public virtual bool RunAtomicParsley(Episode episode, string outputFile)
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
var atomicParsleyLocation = _configProvider.GetValue("AtomicParsleyLocation", "");
|
var atomicParsleyLocation = _configProvider.GetValue("AtomicParsleyLocation", "");
|
||||||
var atomicParsleyTitleType = (AtomicParsleyTitleType) System.Convert.ToInt32(_configProvider.GetValue("AtomicParsley", 0));
|
var atomicParsleyTitleType = (AtomicParsleyTitleType) Convert.ToInt32(_configProvider.GetValue("AtomicParsley", 0));
|
||||||
|
|
||||||
var atomicParsleyCommand = String.Format("\"{0}\" --overWrite --title \"{1}\" --genre \"TV Shows\" --stik \"TV Show\" --TVShowName \"{2}\" --TVEpisodeNum \"{3}\" --TVSeason \"{4}\"",
|
var atomicParsleyCommand = String.Format("\"{0}\" --overWrite --title \"{1}\" --genre \"TV Shows\" --stik \"TV Show\" --TVShowName \"{2}\" --TVEpisodeNum \"{3}\" --TVSeason \"{4}\"",
|
||||||
outputFile, episode.Title, episode.Series.Title, episode.EpisodeNumber, episode.SeasonNumber);
|
outputFile, episode.Title, episode.Series.Title, episode.EpisodeNumber, episode.SeasonNumber);
|
||||||
|
@ -81,7 +81,7 @@ private void HandBrakeOutputDataReceived(object obj, DataReceivedEventArgs args)
|
|||||||
_currentEpisode.SeasonNumber,
|
_currentEpisode.SeasonNumber,
|
||||||
_currentEpisode.EpisodeNumber);
|
_currentEpisode.EpisodeNumber);
|
||||||
|
|
||||||
var percent = System.Convert.ToDecimal(match[0].Groups["percent"].Value);
|
var percent = Convert.ToDecimal(match[0].Groups["percent"].Value);
|
||||||
int hours;
|
int hours;
|
||||||
int minutes;
|
int minutes;
|
||||||
int seconds;
|
int seconds;
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
namespace NzbDrone.Core.Providers.Xbmc
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers.Xbmc
|
||||||
{
|
{
|
||||||
public class ResourceManager
|
public class ResourceManager
|
||||||
{
|
{
|
||||||
public static System.Drawing.Icon GetIcon(string Name)
|
public static Icon GetIcon(string Name)
|
||||||
{
|
{
|
||||||
System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name));
|
Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name));
|
||||||
if (stm == null) return null;
|
if (stm == null) return null;
|
||||||
return new System.Drawing.Icon(stm);
|
return new Icon(stm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] GetRawData(string Name)
|
public static byte[] GetRawData(string Name)
|
||||||
{
|
{
|
||||||
byte[] data;
|
byte[] data;
|
||||||
using (System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name)))
|
using (Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name)))
|
||||||
{
|
{
|
||||||
if (stm == null) return null;
|
if (stm == null) return null;
|
||||||
data = new byte[stm.Length];
|
data = new byte[stm.Length];
|
||||||
@ -25,7 +28,7 @@ public static byte[] GetRawData(string Name)
|
|||||||
public static byte[] GetRawLogo(string Name)
|
public static byte[] GetRawLogo(string Name)
|
||||||
{
|
{
|
||||||
byte[] data;
|
byte[] data;
|
||||||
using (System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}", Name)))
|
using (Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}", Name)))
|
||||||
{
|
{
|
||||||
if (stm == null) return null;
|
if (stm == null) return null;
|
||||||
data = new byte[stm.Length];
|
data = new byte[stm.Length];
|
||||||
@ -35,15 +38,15 @@ public static byte[] GetRawLogo(string Name)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static System.Drawing.Bitmap GetIconAsImage(string Name)
|
public static Bitmap GetIconAsImage(string Name)
|
||||||
{
|
{
|
||||||
System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name));
|
Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name));
|
||||||
if (stm == null) return null;
|
if (stm == null) return null;
|
||||||
System.Drawing.Bitmap bmp;
|
Bitmap bmp;
|
||||||
using (System.Drawing.Icon ico = new System.Drawing.Icon(stm))
|
using (Icon ico = new Icon(stm))
|
||||||
{
|
{
|
||||||
bmp = new System.Drawing.Bitmap(ico.Width, ico.Height);
|
bmp = new Bitmap(ico.Width, ico.Height);
|
||||||
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
{
|
{
|
||||||
g.DrawIcon(ico, 0, 0);
|
g.DrawIcon(ico, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace NzbDrone.Core
|
|||||||
{
|
{
|
||||||
public class WebTimer
|
public class WebTimer
|
||||||
{
|
{
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
|
|
||||||
private static CacheItemRemovedCallback _onCacheRemove;
|
private static CacheItemRemovedCallback _onCacheRemove;
|
||||||
private static bool _stop;
|
private static bool _stop;
|
||||||
@ -17,7 +17,7 @@ public class WebTimer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public WebTimer(JobProvider jobProvider)
|
public WebTimer(JobController jobProvider)
|
||||||
{
|
{
|
||||||
_jobProvider = jobProvider;
|
_jobProvider = jobProvider;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using NLog;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Test.Common.AutoMoq;
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
@ -45,6 +46,8 @@ private string VirtualPath
|
|||||||
public void TestBaseSetup()
|
public void TestBaseSetup()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Mocker.SetConstant(LogManager.GetLogger("TestLogger"));
|
||||||
|
|
||||||
TempFolder = Path.Combine(Directory.GetCurrentDirectory(), "_temp_" + DateTime.Now.Ticks);
|
TempFolder = Path.Combine(Directory.GetCurrentDirectory(), "_temp_" + DateTime.Now.Ticks);
|
||||||
|
|
||||||
MockedRestProvider = new Mock<RestProvider>();
|
MockedRestProvider = new Mock<RestProvider>();
|
||||||
|
@ -11,7 +11,7 @@ namespace NzbDrone.Web.Controllers
|
|||||||
{
|
{
|
||||||
public class CommandController : Controller
|
public class CommandController : Controller
|
||||||
{
|
{
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly SabProvider _sabProvider;
|
private readonly SabProvider _sabProvider;
|
||||||
private readonly SmtpProvider _smtpProvider;
|
private readonly SmtpProvider _smtpProvider;
|
||||||
private readonly TwitterProvider _twitterProvider;
|
private readonly TwitterProvider _twitterProvider;
|
||||||
@ -25,7 +25,7 @@ public class CommandController : Controller
|
|||||||
|
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public CommandController(JobProvider jobProvider, SabProvider sabProvider,
|
public CommandController(JobController jobProvider, SabProvider sabProvider,
|
||||||
SmtpProvider smtpProvider, TwitterProvider twitterProvider,
|
SmtpProvider smtpProvider, TwitterProvider twitterProvider,
|
||||||
EpisodeProvider episodeProvider, GrowlProvider growlProvider,
|
EpisodeProvider episodeProvider, GrowlProvider growlProvider,
|
||||||
SeasonProvider seasonProvider, ProwlProvider prowlProvider,
|
SeasonProvider seasonProvider, ProwlProvider prowlProvider,
|
||||||
|
@ -9,10 +9,10 @@ namespace NzbDrone.Web.Controllers
|
|||||||
{
|
{
|
||||||
public class EpisodeController : Controller
|
public class EpisodeController : Controller
|
||||||
{
|
{
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly MediaFileProvider _mediaFileProvider;
|
private readonly MediaFileProvider _mediaFileProvider;
|
||||||
|
|
||||||
public EpisodeController(JobProvider jobProvider, MediaFileProvider mediaFileProvider)
|
public EpisodeController(JobController jobProvider, MediaFileProvider mediaFileProvider)
|
||||||
{
|
{
|
||||||
_jobProvider = jobProvider;
|
_jobProvider = jobProvider;
|
||||||
_mediaFileProvider = mediaFileProvider;
|
_mediaFileProvider = mediaFileProvider;
|
||||||
|
@ -16,10 +16,10 @@ namespace NzbDrone.Web.Controllers
|
|||||||
public class HistoryController : Controller
|
public class HistoryController : Controller
|
||||||
{
|
{
|
||||||
private readonly HistoryProvider _historyProvider;
|
private readonly HistoryProvider _historyProvider;
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly ConfigProvider _configProvider;
|
private readonly ConfigProvider _configProvider;
|
||||||
|
|
||||||
public HistoryController(HistoryProvider historyProvider, JobProvider jobProvider,
|
public HistoryController(HistoryProvider historyProvider, JobController jobProvider,
|
||||||
ConfigProvider configProvider)
|
ConfigProvider configProvider)
|
||||||
{
|
{
|
||||||
_historyProvider = historyProvider;
|
_historyProvider = historyProvider;
|
||||||
|
@ -24,14 +24,14 @@ public class SeriesController : Controller
|
|||||||
{
|
{
|
||||||
private readonly QualityProvider _qualityProvider;
|
private readonly QualityProvider _qualityProvider;
|
||||||
private readonly SeriesProvider _seriesProvider;
|
private readonly SeriesProvider _seriesProvider;
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly SeasonProvider _seasonProvider;
|
private readonly SeasonProvider _seasonProvider;
|
||||||
private readonly ConfigProvider _configProvider;
|
private readonly ConfigProvider _configProvider;
|
||||||
//
|
//
|
||||||
// GET: /Series/
|
// GET: /Series/
|
||||||
|
|
||||||
public SeriesController(SeriesProvider seriesProvider, QualityProvider qualityProvider,
|
public SeriesController(SeriesProvider seriesProvider, QualityProvider qualityProvider,
|
||||||
JobProvider jobProvider, SeasonProvider seasonProvider,
|
JobController jobProvider, SeasonProvider seasonProvider,
|
||||||
ConfigProvider configProvider)
|
ConfigProvider configProvider)
|
||||||
{
|
{
|
||||||
_seriesProvider = seriesProvider;
|
_seriesProvider = seriesProvider;
|
||||||
|
@ -34,7 +34,7 @@ public class SettingsController : Controller
|
|||||||
private readonly ConfigFileProvider _configFileProvider;
|
private readonly ConfigFileProvider _configFileProvider;
|
||||||
private readonly NewznabProvider _newznabProvider;
|
private readonly NewznabProvider _newznabProvider;
|
||||||
private readonly MetadataProvider _metadataProvider;
|
private readonly MetadataProvider _metadataProvider;
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public SettingsController(ConfigProvider configProvider, IndexerProvider indexer
|
|||||||
SeriesProvider seriesProvider, ExternalNotificationProvider externalNotificationProvider,
|
SeriesProvider seriesProvider, ExternalNotificationProvider externalNotificationProvider,
|
||||||
QualityTypeProvider qualityTypeProvider, ConfigFileProvider configFileProvider,
|
QualityTypeProvider qualityTypeProvider, ConfigFileProvider configFileProvider,
|
||||||
NewznabProvider newznabProvider, MetadataProvider metadataProvider,
|
NewznabProvider newznabProvider, MetadataProvider metadataProvider,
|
||||||
JobProvider jobProvider)
|
JobController jobProvider)
|
||||||
{
|
{
|
||||||
_externalNotificationProvider = externalNotificationProvider;
|
_externalNotificationProvider = externalNotificationProvider;
|
||||||
_qualityTypeProvider = qualityTypeProvider;
|
_qualityTypeProvider = qualityTypeProvider;
|
||||||
@ -439,9 +439,9 @@ public JsonResult SaveIndexers(IndexerSettingsModel data)
|
|||||||
//Save the interval to config and immediately apply it the the job (to avoid a restart)
|
//Save the interval to config and immediately apply it the the job (to avoid a restart)
|
||||||
_configProvider.RssSyncInterval = data.RssSyncInterval;
|
_configProvider.RssSyncInterval = data.RssSyncInterval;
|
||||||
|
|
||||||
var rssSyncJob = _jobProvider.GetDefinition(typeof(RssSyncJob));
|
/* var rssSyncJob = _jobProvider.GetDefinition(typeof(RssSyncJob));
|
||||||
rssSyncJob.Interval = data.RssSyncInterval;
|
rssSyncJob.Interval = data.RssSyncInterval;
|
||||||
_jobProvider.SaveDefinition(rssSyncJob);
|
_jobProvider.SaveDefinition(rssSyncJob);*/
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
using NzbDrone.Core;
|
using NzbDrone.Core;
|
||||||
using NzbDrone.Core.Helpers;
|
using NzbDrone.Core.Helpers;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Providers.Core;
|
using NzbDrone.Core.Providers.Core;
|
||||||
using NzbDrone.Core.Providers.DownloadClients;
|
using NzbDrone.Core.Providers.DownloadClients;
|
||||||
@ -17,16 +18,17 @@ namespace NzbDrone.Web.Controllers
|
|||||||
{
|
{
|
||||||
public class SystemController : Controller
|
public class SystemController : Controller
|
||||||
{
|
{
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly IndexerProvider _indexerProvider;
|
private readonly IndexerProvider _indexerProvider;
|
||||||
private readonly ConfigProvider _configProvider;
|
private readonly ConfigProvider _configProvider;
|
||||||
private readonly DiskProvider _diskProvider;
|
private readonly DiskProvider _diskProvider;
|
||||||
private readonly BackupProvider _backupProvider;
|
private readonly BackupProvider _backupProvider;
|
||||||
private readonly StatsProvider _statsProvider;
|
private readonly StatsProvider _statsProvider;
|
||||||
|
private readonly IJobRepository _jobRepository;
|
||||||
|
|
||||||
public SystemController(JobProvider jobProvider, IndexerProvider indexerProvider,
|
public SystemController(JobController jobProvider, IndexerProvider indexerProvider,
|
||||||
ConfigProvider configProvider, DiskProvider diskProvider,
|
ConfigProvider configProvider, DiskProvider diskProvider,
|
||||||
BackupProvider backupProvider, StatsProvider statsProvider)
|
BackupProvider backupProvider, StatsProvider statsProvider,IJobRepository jobRepository)
|
||||||
{
|
{
|
||||||
_jobProvider = jobProvider;
|
_jobProvider = jobProvider;
|
||||||
_indexerProvider = indexerProvider;
|
_indexerProvider = indexerProvider;
|
||||||
@ -34,6 +36,7 @@ public SystemController(JobProvider jobProvider, IndexerProvider indexerProvider
|
|||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_backupProvider = backupProvider;
|
_backupProvider = backupProvider;
|
||||||
_statsProvider = statsProvider;
|
_statsProvider = statsProvider;
|
||||||
|
_jobRepository = jobRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
@ -58,9 +61,9 @@ public ActionResult Jobs()
|
|||||||
|
|
||||||
ViewData["Queue"] = serializedQueue;
|
ViewData["Queue"] = serializedQueue;
|
||||||
|
|
||||||
var jobs = _jobProvider.All().Select(j => new JobModel
|
var jobs = _jobRepository.All().Select(j => new JobModel
|
||||||
{
|
{
|
||||||
Id = j.Id,
|
Id = j.OID,
|
||||||
Enable = j.Enable,
|
Enable = j.Enable,
|
||||||
TypeName = j.TypeName,
|
TypeName = j.TypeName,
|
||||||
Name = j.Name,
|
Name = j.Name,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Web.Models;
|
using NzbDrone.Web.Models;
|
||||||
|
|
||||||
@ -11,11 +12,11 @@ namespace NzbDrone.Web.Controllers
|
|||||||
public class UpdateController : Controller
|
public class UpdateController : Controller
|
||||||
{
|
{
|
||||||
private readonly UpdateProvider _updateProvider;
|
private readonly UpdateProvider _updateProvider;
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobController _jobProvider;
|
||||||
private readonly EnvironmentProvider _environmentProvider;
|
private readonly EnvironmentProvider _environmentProvider;
|
||||||
private readonly DiskProvider _diskProvider;
|
private readonly DiskProvider _diskProvider;
|
||||||
|
|
||||||
public UpdateController(UpdateProvider updateProvider, JobProvider jobProvider,
|
public UpdateController(UpdateProvider updateProvider, JobController jobProvider,
|
||||||
EnvironmentProvider environmentProvider, DiskProvider diskProvider)
|
EnvironmentProvider environmentProvider, DiskProvider diskProvider)
|
||||||
{
|
{
|
||||||
_updateProvider = updateProvider;
|
_updateProvider = updateProvider;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<SolutionConfiguration>
|
<SolutionConfiguration>
|
||||||
<FileVersion>1</FileVersion>
|
<FileVersion>1</FileVersion>
|
||||||
<AutoEnableOnStartup>False</AutoEnableOnStartup>
|
<AutoEnableOnStartup>True</AutoEnableOnStartup>
|
||||||
<AllowParallelTestExecution>true</AllowParallelTestExecution>
|
<AllowParallelTestExecution>true</AllowParallelTestExecution>
|
||||||
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
|
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
|
||||||
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
|
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">ERROR</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||||
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>
|
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>
|
||||||
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Style/@EntryValue">OUTLINE</s:String>
|
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Style/@EntryValue">OUTLINE</s:String>
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user