[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_does_not_complete_until_async_task_added_by_user_delegate_completes([Values] PostOverload overload) { var source = new TaskCompletionSource <object?>(); var postedAction = (Action?)null; using (SynchronizationContextAssert.ExpectSinglePost(p => postedAction = p)) { AmbientTasksPost(overload, () => { AmbientTasks.Add(source.Task); }); } var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.IsCompleted.ShouldBeFalse(); postedAction.ShouldNotBeNull(); postedAction !.Invoke(); waitAllTask.IsCompleted.ShouldBeFalse(); source.SetResult(null); waitAllTask.Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Handler_should_be_called_one_additional_time_to_handle_its_own_exception() { var taskException = new Exception(); var handlerException = new Exception(); var watcher = new CallbackWatcher(); AmbientTasks.BeginContext(ex => { watcher.OnCallback(out var callCount); if (callCount == 1) { throw handlerException; } ex.ShouldBe(handlerException); }); using (watcher.ExpectCallback(count: 2)) AmbientTasks.Add(Task.FromException(taskException)); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); var aggregateException = waitAllTask.Exception !.InnerExceptions.ShouldHaveSingleItem().ShouldBeOfType <AggregateException>(); aggregateException.InnerExceptions.ShouldHaveSingleItem().ShouldBeSameAs(taskException); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_should_fault_after_adding_synchronously_failed_task_with_no_context() { Should.Throw <AggregateException>( () => AmbientTasks.Add(Task.FromException(new Exception()))); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.Faulted); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_does_not_reset_until_all_tasks_have_completed() { var source1 = new TaskCompletionSource <object?>(); var source2 = new TaskCompletionSource <object?>(); AmbientTasks.Add(source1.Task); var waitTaskSeenAfterFirstAdd = AmbientTasks.WaitAllAsync(); waitTaskSeenAfterFirstAdd.IsCompleted.ShouldBeFalse(); // Should not reset on next call AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitTaskSeenAfterFirstAdd); AmbientTasks.Add(source2.Task); AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitTaskSeenAfterFirstAdd); // Should not reset on next call AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitTaskSeenAfterFirstAdd); source1.SetResult(null); AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitTaskSeenAfterFirstAdd); // Should not reset on next call AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitTaskSeenAfterFirstAdd); source2.SetResult(null); waitTaskSeenAfterFirstAdd.Status.ShouldBe(TaskStatus.RanToCompletion); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Handled_exceptions_do_not_appear_in_a_subsequent_call_to_WaitAllAsync() { AmbientTasks.BeginContext(handler => { }); AmbientTasks.Add(Task.FromException(new Exception())); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_should_reset_after_fault_is_displayed_in_previously_returned_task() { Should.Throw <AggregateException>( () => AmbientTasks.Add(Task.FromException(new Exception()))); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.Faulted); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_should_fault_after_adding_synchronously_failed_task_with_no_context_when_on_SynchronizationContext() { using (SynchronizationContextAssert.ExpectSinglePost(postedAction => { })) { AmbientTasks.Add(Task.FromException(new Exception())); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.Faulted); } }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Func_returning_synchronously_canceled_task_is_noop() { var source = new TaskCompletionSource <object?>(); source.SetCanceled(); AmbientTasks.Add(() => source.Task); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Exception_from_user_delegate_is_not_in_task_from_next_call_to_WaitAllAsync_when_there_is_a_BeginContext_handler([Values] PostOverload overload) { AmbientTasks.BeginContext(ex => { }); using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke())) { AmbientTasksPost(overload, () => throw new Exception()); } AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void SynchronizationContext_that_throws_on_post_does_not_prevent_WaitAllAsync_completion() { var source = new TaskCompletionSource <object?>(); using (SynchronizationContextAssert.ExpectSinglePost(postedAction => throw new Exception())) { AmbientTasks.Add(source.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); source.SetException(new Exception()); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); } }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void BeginContext_handler_can_be_removed() { AmbientTasks.BeginContext(ex => Assert.Fail("This handler should not be called.")); AmbientTasks.BeginContext(); var exception = new Exception(); var aggregateException = Should.Throw <AggregateException>( () => AmbientTasks.Add(Task.FromException(exception))); aggregateException.InnerExceptions.ShouldHaveSingleItem().ShouldBeSameAs(exception); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.Faulted); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_waits_for_added_task_with_no_context_to_fault() { var source = new TaskCompletionSource <object?>(); AmbientTasks.Add(source.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.IsCompleted.ShouldBeFalse(); source.SetException(new Exception()); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static async Task WaitAllAsync_should_throw_AggregateException_when_awaited() { var source = new TaskCompletionSource <object?>(); AmbientTasks.Add(source.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); var exception = new Exception(); source.SetException(exception); var aggregateException = await Should.ThrowAsync <AggregateException>(waitAllTask); aggregateException.InnerExceptions.ShouldBe(new[] { exception }); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_resets_after_overlapping_tasks_fail() { var source1 = new TaskCompletionSource <object?>(); var source2 = new TaskCompletionSource <object?>(); AmbientTasks.Add(source1.Task); AmbientTasks.Add(source2.Task); var waitAllTaskBeforeAllExceptions = AmbientTasks.WaitAllAsync(); source1.SetException(new Exception()); source2.SetException(new Exception()); waitAllTaskBeforeAllExceptions.Status.ShouldBe(TaskStatus.Faulted); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Handled_exceptions_do_not_appear_in_task_returned_from_WaitAllAsync_while_waiting_for_task() { var source = new TaskCompletionSource <object?>(); var exception = new Exception(); AmbientTasks.BeginContext(handler => { }); AmbientTasks.Add(source.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.IsCompleted.ShouldBeFalse(); source.SetException(exception); waitAllTask.Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Exception_from_user_delegate_is_in_task_from_next_call_to_WaitAllAsync_when_there_is_no_BeginContext_handler([Values] PostOverload overload) { var exception = new Exception(); using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke())) { Should.Throw <Exception>(() => AmbientTasksPost(overload, () => throw exception)); } var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); var aggregateException = waitAllTask.Exception !.InnerExceptions.ShouldHaveSingleItem().ShouldBeOfType <AggregateException>(); aggregateException.InnerExceptions.ShouldHaveSingleItem().ShouldBeSameAs(exception); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_waits_for_SynchronizationContext_Post_to_invoke_delegate_before_completing([Values] PostOverload overload) { var postedAction = (Action?)null; using (SynchronizationContextAssert.ExpectSinglePost(p => postedAction = p)) { AmbientTasksPost(overload, () => { }); } var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.IsCompleted.ShouldBeFalse(); postedAction.ShouldNotBeNull(); postedAction !.Invoke(); waitAllTask.Status.ShouldBe(TaskStatus.RanToCompletion); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Delegate_is_abandoned_if_SynchronizationContext_post_throws_before_invoking_delegate([Values] PostOverload overload) { var postedAction = (Action?)null; using (SynchronizationContextAssert.ExpectSinglePost(p => { postedAction = p; throw new Exception(); })) { Should.Throw <Exception>(() => AmbientTasksPost(overload, () => Assert.Fail("The delegate should be abandoned."))); } AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); postedAction.ShouldNotBeNull(); postedAction !.Invoke(); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_should_have_single_AggregateException_with_all_exceptions_from_each_task_all_faulted_synchronously() { var task1Exceptions = new[] { new Exception("Task 1 exception 1"), new Exception("Task 1 exception 2") }; var task2Exceptions = new[] { new Exception("Task 2 exception 1"), new Exception("Task 2 exception 2") }; var source1 = new TaskCompletionSource <object?>(); var source2 = new TaskCompletionSource <object?>(); AmbientTasks.Add(source1.Task); AmbientTasks.Add(source2.Task); source1.SetException(task1Exceptions); source2.SetException(task2Exceptions); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); var aggregateException = waitAllTask.Exception !.InnerExceptions.ShouldHaveSingleItem().ShouldBeOfType <AggregateException>(); aggregateException.InnerExceptions.ShouldBe(task1Exceptions.Concat(task2Exceptions)); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_waits_for_added_task_with_no_context_and_throws_exception_on_current_SynchronizationContext() { var source = new TaskCompletionSource <object?>(); var exception = new Exception(); using (SynchronizationContextAssert.ExpectSinglePost(postedAction => { var aggregateException = Should.Throw <AggregateException>(postedAction); aggregateException.InnerExceptions.ShouldBe(new[] { exception }); })) { AmbientTasks.Add(source.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.IsCompleted.ShouldBeFalse(); source.SetException(exception); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); } }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_does_not_return_with_fault_from_added_test_until_last_task_completes() { var source1 = new TaskCompletionSource <object?>(); var source2 = new TaskCompletionSource <object?>(); var source3 = new TaskCompletionSource <object?>(); AmbientTasks.Add(source1.Task); AmbientTasks.Add(source2.Task); AmbientTasks.Add(source3.Task); var waitAllTask = AmbientTasks.WaitAllAsync(); source1.SetException(new Exception()); waitAllTask.IsCompleted.ShouldBeFalse(); AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitAllTask); source2.SetResult(null); waitAllTask.IsCompleted.ShouldBeFalse(); AmbientTasks.WaitAllAsync().ShouldBeSameAs(waitAllTask); source3.SetResult(null); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void WaitAllAsync_should_have_single_AggregateException_with_all_three_exceptions_when_handler_throws_exception_twice() { var taskException = new Exception(); var handlerException1 = new Exception(); var handlerException2 = new Exception(); var watcher = new CallbackWatcher(); AmbientTasks.BeginContext(ex => { watcher.OnCallback(out var callCount); throw callCount == 1 ? handlerException1 : handlerException2; }); using (watcher.ExpectCallback(count: 2)) AmbientTasks.Add(Task.FromException(taskException)); var waitAllTask = AmbientTasks.WaitAllAsync(); waitAllTask.Status.ShouldBe(TaskStatus.Faulted); var aggregateException = waitAllTask.Exception !.InnerExceptions.ShouldHaveSingleItem().ShouldBeOfType <AggregateException>(); aggregateException.InnerExceptions.ShouldBe(new[] { taskException, handlerException1, handlerException2 }); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Func_throwing_TaskCanceledException_is_noop() { AmbientTasks.Add(() => throw new TaskCanceledException()); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Func_returning_synchronously_successfully_completed_task_is_noop() { AmbientTasks.Add(() => Task.CompletedTask); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Func_returning_null_task_is_noop() { AmbientTasks.Add(() => null !); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }
[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283 public static void Adding_null_func_is_noop() { AmbientTasks.Add((Func <Task>?)null); AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion); }