public async Task Sched_Task_TaskWorkItem_CurrentScheduler() { ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; var result0 = new TaskCompletionSource <bool>(); var result1 = new TaskCompletionSource <bool>(); Task t1 = null; scheduler.QueueWorkItem(new ClosureWorkItem(() => { try { output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(activationScheduler, TaskScheduler.Current); // t1 = new Task(() => { output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" result1.SetResult(true); }); t1.Start(); result0.SetResult(true); } catch (Exception exc) { result0.SetException(exc); } }), rootContext); await result0.Task.WithTimeout(TimeSpan.FromMinutes(1)); Assert.True(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception); Assert.True(result0.Task.Result, "Task-0 completed"); Assert.NotNull(t1); // Task-1 started await result1.Task.WithTimeout(TimeSpan.FromMinutes(1)); // give a minimum extra chance to yield after result0 has been set, as it might not have finished the t1 task await t1.WithTimeout(TimeSpan.FromMilliseconds(1)); Assert.True(t1.IsCompleted, "Task-1 completed"); Assert.False(t1.IsFaulted, "Task-1 faulted: " + t1.Exception); Assert.True(result1.Task.Result, "Task-1 completed"); }
public void Sched_Task_ClosureWorkItem_SpecificScheduler() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(context); ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(context).TaskRunner; var result0 = new TaskCompletionSource <bool>(); var result1 = new TaskCompletionSource <bool>(); Task t1 = null; scheduler.QueueWorkItem(new ClosureWorkItem(() => { try { Console.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #0"); t1 = new Task(() => { Console.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.AreEqual(scheduler, TaskScheduler.Current, "TaskScheduler.Current #1"); result1.SetResult(true); }); t1.Start(scheduler); result0.SetResult(true); } catch (Exception exc) { result0.SetException(exc); } }), context); result0.Task.Wait(TimeSpan.FromSeconds(1)); Assert.IsTrue(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception); Assert.IsTrue(result0.Task.Result, "Task-0 completed"); Assert.IsNotNull(t1, "Task-1 started"); result1.Task.Wait(TimeSpan.FromSeconds(1)); Assert.IsTrue(t1.IsCompleted, "Task-1 completed"); Assert.IsFalse(t1.IsFaulted, "Task-1 faulted: " + t1.Exception); Assert.IsTrue(result1.Task.Result, "Task-1 completed"); }
public void Async_Task_Start_ActivationTaskScheduler() { ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskScheduler; int expected = 2; bool done = false; Task <int> t = new Task <int>(() => { done = true; return(expected); }); t.Start(activationScheduler); int received = t.Result; Assert.True(t.IsCompleted, "Task should have completed"); Assert.False(t.IsFaulted, "Task should not thrown exception: " + t.Exception); Assert.True(done, "Task should be done"); Assert.Equal(expected, received); }
public void Async_Task_Start_ActivationTaskScheduler() { InitSchedulerLogging(); UnitTestSchedulingContext cntx = new UnitTestSchedulingContext(); OrleansTaskScheduler masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx); ActivationTaskScheduler activationScheduler = masterScheduler.GetWorkItemGroup(cntx).TaskRunner; int expected = 2; bool done = false; Task<int> t = new Task<int>(() => { done = true; return expected; }); t.Start(activationScheduler); int received = t.Result; Assert.IsTrue(t.IsCompleted, "Task should have completed"); Assert.IsFalse(t.IsFaulted, "Task should not thrown exception: " + t.Exception); Assert.IsTrue(done, "Task should be done"); Assert.AreEqual(expected, received, "Task did not return expected value " + expected); }
public void Sched_SimpleFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskScheduler; int n = 0; // ReSharper disable AccessToModifiedClosure Action item1 = () => { n = n + 5; }; Action item2 = () => { n = n * 3; }; // ReSharper restore AccessToModifiedClosure this.scheduler.QueueAction(item1, this.rootContext); this.scheduler.QueueAction(item2, this.rootContext); // Pause to let things run Thread.Sleep(1000); // N should be 15, because the two tasks should execute in order Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(15, n); this.output.WriteLine("Test executed OK."); }
public async Task Sched_Task_TplFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskScheduler; int n = 0; // ReSharper disable AccessToModifiedClosure Task task1 = new Task(() => { Thread.Sleep(1000); n = n + 5; }); Task task2 = new Task(() => { n = n * 3; }); // ReSharper restore AccessToModifiedClosure task1.Start(activationScheduler); task2.Start(activationScheduler); await Task.WhenAll(task1, task2).WithTimeout(TimeSpan.FromSeconds(5)); // N should be 15, because the two tasks should execute in order Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(15, n); }
public void Sched_Task_SchedulingContext() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); ActivationTaskScheduler scheduler = this.orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; var result = new TaskCompletionSource <bool>(); Task endOfChain = null; int n = 0; Task wrapper = new Task(() => { CheckRuntimeContext(context); // ReSharper disable AccessToModifiedClosure Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a "); CheckRuntimeContext(context); Thread.Sleep(1000); n = n + 3; this.output.WriteLine("===> 1b"); CheckRuntimeContext(context); }); Task task2 = task1.ContinueWith(task => { this.output.WriteLine("===> 2"); CheckRuntimeContext(context); n = n * 5; }); Task task3 = task2.ContinueWith(task => { this.output.WriteLine("===> 3"); n = n / 5; CheckRuntimeContext(context); }); Task task4 = task3.ContinueWith(task => { this.output.WriteLine("===> 4"); n = n - 2; result.SetResult(true); CheckRuntimeContext(context); }); // ReSharper restore AccessToModifiedClosure endOfChain = task4.ContinueWith(task => { this.output.WriteLine("Done Faulted={0}", task.IsFaulted); CheckRuntimeContext(context); Assert.False(task.IsFaulted, "Faulted with Exception=" + task.Exception); }); }); wrapper.Start(scheduler); bool ok = wrapper.Wait(TimeSpan.FromSeconds(1)); if (!ok) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task Faulted with Exception=" + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task completed"); bool finished = result.Task.Wait(TimeSpan.FromSeconds(2)); Assert.NotNull(endOfChain); // End of chain Task created successfully Assert.False(endOfChain.IsFaulted, "Task chain Faulted with Exception=" + endOfChain.Exception); Assert.True(finished, "Wrapper Task completed ok"); Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(1, n); // "Work items executed out of order" }
public void Sched_AC_Current_TaskScheduler() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); OrleansTaskScheduler orleansTaskScheduler = orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); ActivationTaskScheduler activationScheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; // RuntimeContext.InitializeThread(masterScheduler); this.mainDone = false; var result = new TaskCompletionSource <bool>(); Task wrapper = null; Task finalPromise = null; orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting"); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #0" Log(2, "Starting wrapper Task"); wrapper = Task.Factory.StartNew(() => { Log(3, "Inside wrapper Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" Log(4, "Wrapper Task " + Task.CurrentId + " creating AC chain"); Task promise1 = Task.Factory.StartNew(() => { Log(5, "#1 Inside AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" SubProcess1(1); }); Task promise2 = promise1.ContinueWith((_) => { Log(6, "#2 Inside AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" SubProcess1(2); }); finalPromise = promise2.ContinueWith((_) => { Log(7, "#3 Inside final AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #3" SubProcess1(3); result.SetResult(true); }); finalPromise.Ignore(); Log(8, "Wrapper Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(9, "Wrapper Task Id=" + Task.CurrentId + " finished"); }); Log(10, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(11, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(12, "Finished Outer TaskWorkItem Task Id=" + wrapper.Id); this.mainDone = true; }), context); Log(13, "Waiting for ClosureWorkItem to spawn wrapper Task"); for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) { break; } Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(14, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(15, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(16, "Waiting for TaskWorkItem to complete"); for (int i = 0; i < 15 * WaitFactor; i++) { if (this.mainDone) { break; } Thread.Sleep(1000 * WaitFactor); } Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalPromise); // AC chain not created Log(18, "Waiting for final AC promise to complete"); finalPromise.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for final promise"); Assert.False(finalPromise.IsFaulted, "Final AC faulted: " + finalPromise.Exception); Assert.True(finalPromise.IsCompleted, "Final AC completed"); Assert.True(result.Task.Result, "Timeout-1"); Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" Assert.Equal(3, this.stageNum1); // "Work items executed out of order-1" }
public void Sched_Task_Turn_Execution_Order() { // A unit test that checks that any turn is indeed run till completion before any other turn? // For example, you have a long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew. // You test that no CW/StartNew runs until the main turn is fully done. And run in stress. UnitTestSchedulingContext context = new UnitTestSchedulingContext(); OrleansTaskScheduler masterScheduler = this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); WorkItemGroup workItemGroup = this.orleansTaskScheduler.GetWorkItemGroup(context); ActivationTaskScheduler activationScheduler = workItemGroup.TaskRunner; this.mainDone = false; this.stageNum1 = this.stageNum2 = 0; var result1 = new TaskCompletionSource <bool>(); var result2 = new TaskCompletionSource <bool>(); Task wrapper = null; Task finalTask1 = null; Task finalPromise2 = null; masterScheduler.QueueWorkItem(new ClosureWorkItem(() => { Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting"); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #0" Log(2, "Starting wrapper Task"); wrapper = Task.Factory.StartNew(() => { Log(3, "Inside wrapper Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" // Execution chain #1 Log(4, "Wrapper Task Id=" + Task.CurrentId + " creating Task chain"); Task task1 = Task.Factory.StartNew(() => { Log(5, "#11 Inside sub-Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #11" SubProcess1(11); }); Task task2 = task1.ContinueWith((Task task) => { Log(6, "#12 Inside continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #12" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(12); }); Task task3 = task2.ContinueWith(task => { Log(7, "#13 Inside continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #13" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(13); }); finalTask1 = task3.ContinueWith(task => { Log(8, "#14 Inside final continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #14" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(14); result1.SetResult(true); }); // Execution chain #2 Log(9, "Wrapper Task " + Task.CurrentId + " creating AC chain"); Task promise2 = Task.Factory.StartNew(() => { Log(10, "#21 Inside sub-Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #21" SubProcess2(21); }); finalPromise2 = promise2.ContinueWith((_) => { Log(11, "#22 Inside final continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #22" SubProcess2(22); result2.SetResult(true); }); finalPromise2.Ignore(); Log(12, "Wrapper Task Id=" + Task.CurrentId + " sleeping #2"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(13, "Wrapper Task Id=" + Task.CurrentId + " finished"); }); Log(14, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(15, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(16, "Finished Outer ClosureWorkItem Task Id=" + wrapper.Id); this.mainDone = true; }), context); Log(17, "Waiting for ClosureWorkItem to spawn wrapper Task"); for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) { break; } Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(18, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(20, "Waiting for TaskWorkItem to complete"); for (int i = 0; i < 15 * WaitFactor; i++) { if (this.mainDone) { break; } Thread.Sleep(1000 * WaitFactor); } Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalTask1); // Task chain #1 not created Assert.NotNull(finalPromise2); // Task chain #2 not created Log(22, "Waiting for final task #1 to complete"); bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(23, "Done waiting for final task #1 complete Ok=" + ok); if (!ok) { throw new TimeoutException(); } Assert.False(finalTask1.IsFaulted, "Final Task faulted: " + finalTask1.Exception); Assert.True(finalTask1.IsCompleted, "Final Task completed"); Assert.True(result1.Task.Result, "Timeout-1"); Log(24, "Waiting for final promise #2 to complete"); finalPromise2.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(25, "Done waiting for final promise #2"); Assert.False(finalPromise2.IsFaulted, "Final Task faulted: " + finalPromise2.Exception); Assert.True(finalPromise2.IsCompleted, "Final Task completed"); Assert.True(result2.Task.Result, "Timeout-2"); Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" Assert.Equal(14, this.stageNum1); // "Work items executed out of order-1" Assert.NotEqual(0, this.stageNum2); // "Work items did not get executed-2" Assert.Equal(22, this.stageNum2); // "Work items executed out of order-2" }