diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs new file mode 100644 index 0000000000..196bce899c --- /dev/null +++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Web.Scheduling; + +namespace Umbraco.Tests.Scheduling +{ + [TestFixture] + public class BackgroundTaskRunnerTests + { + + + [Test] + public void Startup_And_Shutdown() + { + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.StartUp(); + } + + NUnit.Framework.Assert.IsFalse(tManager.IsRunning); + } + + [Test] + public void Startup_Starts_Automatically() + { + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.Add(new MyTask()); + NUnit.Framework.Assert.IsTrue(tManager.IsRunning); + } + } + + [Test] + public void Task_Runs() + { + var myTask = new MyTask(); + var waitHandle = new ManualResetEvent(false); + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.TaskCompleted += (sender, task) => waitHandle.Set(); + + tManager.Add(myTask); + + //wait for ITasks to complete + waitHandle.WaitOne(); + + NUnit.Framework.Assert.IsTrue(myTask.Ended != default(DateTime)); + } + } + + [Test] + public void Many_Tasks_Run() + { + var tasks = new Dictionary(); + for (var i = 0; i < 10; i++) + { + tasks.Add(new MyTask(), new ManualResetEvent(false)); + } + + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set(); + + tasks.ForEach(t => tManager.Add(t.Key)); + + //wait for all ITasks to complete + WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); + + foreach (var task in tasks) + { + NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime)); + } + } + } + + [Test] + public void Tasks_Can_Keep_Being_Added_And_Will_Execute() + { + Func> getTasks = () => + { + var newTasks = new Dictionary(); + for (var i = 0; i < 10; i++) + { + newTasks.Add(new MyTask(), new ManualResetEvent(false)); + } + return newTasks; + }; + + IDictionary tasks = getTasks(); + + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set(); + + //execute first batch + tasks.ForEach(t => tManager.Add(t.Key)); + + //wait for all ITasks to complete + WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); + + foreach (var task in tasks) + { + NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime)); + } + + //execute another batch after a bit + Thread.Sleep(2000); + + tasks = getTasks(); + tasks.ForEach(t => tManager.Add(t.Key)); + + //wait for all ITasks to complete + WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); + + foreach (var task in tasks) + { + NUnit.Framework.Assert.IsTrue(task.Key.Ended != default(DateTime)); + } + } + } + + [Test] + public void Task_Queue_Will_Be_Completed_Before_Shutdown() + { + var tasks = new Dictionary(); + for (var i = 0; i < 10; i++) + { + tasks.Add(new MyTask(), new ManualResetEvent(false)); + } + + BackgroundTaskRunner tManager; + using (tManager = new BackgroundTaskRunner(true, true)) + { + tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set(); + + tasks.ForEach(t => tManager.Add(t.Key)); + + ////wait for all ITasks to complete + //WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); + + tManager.Stop(false); + //immediate stop will block until complete - but since we are running on + // a single thread this doesn't really matter as the above will just process + // until complete. + tManager.Stop(true); + + NUnit.Framework.Assert.AreEqual(0, tManager.TaskCount); + } + } + + + + + private class MyTask : BaseTask + { + public MyTask() + { + } + + public override void Run() + { + Thread.Sleep(500); + } + + public override void Cancel() + { + + } + } + + public abstract class BaseTask : IBackgroundTask + { + public Guid UniqueId { get; protected set; } + + public abstract void Run(); + public abstract void Cancel(); + + public DateTime Queued { get; set; } + public DateTime Started { get; set; } + public DateTime Ended { get; set; } + + public virtual void Dispose() + { + Ended = DateTime.Now; + } + } + + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 6c2ee7c94d..1ce2fb7c81 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -249,6 +249,7 @@ + diff --git a/src/Umbraco.Web.UI/Global.asax b/src/Umbraco.Web.UI/Global.asax index 1627b363bc..8cb0d2d910 100644 --- a/src/Umbraco.Web.UI/Global.asax +++ b/src/Umbraco.Web.UI/Global.asax @@ -1 +1 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %> +<%@ Application Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %> diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index 5c5a33545d..eba925bcc6 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -46,7 +46,7 @@ - + @@ -64,7 +64,14 @@ xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Mvc']])"/> - + + + + + + + - + + ASPXCodeBehind + ASPXCodeBehind