예제 #1
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_new_thread()
        {
            var source  = new TaskCompletionSource <object?>();
            var watcher = new CallbackWatcher();

            var thread = new Thread(() =>
            {
                try
                {
                    using (watcher.ExpectCallback())
                        AmbientTasks.Add(Task.FromException(new Exception()));

                    source.SetResult(null);
                }
                catch (Exception ex)
                {
                    source.SetException(ex);
                }
            });

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            thread.Start();

            await source.Task;
        }
예제 #2
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_ThreadPool_QueueUserWorkItem()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            var source = new TaskCompletionSource <object?>();

            ThreadPool.QueueUserWorkItem(_ =>
            {
                try
                {
                    using (watcher.ExpectCallback())
                        AmbientTasks.Add(Task.FromException(new Exception()));

                    source.SetResult(null);
                }
                catch (Exception ex)
                {
                    source.SetException(ex);
                }
            }, null);

            await source.Task;
        }
예제 #3
0
        [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);
        }
예제 #4
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_does_not_flow_from_inner_method_back_to_outer_method_after_await()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await InnerFunction();

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
예제 #5
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_across_await()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await Task.Yield();

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
        }
예제 #6
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_is_replaced_with_next_call()
        {
            AmbientTasks.BeginContext(ex => Assert.Fail("This handler should not be called."));

            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
        }
예제 #7
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_Task_Run()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await Task.Run(() =>
            {
                using (watcher.ExpectCallback())
                    AmbientTasks.Add(Task.FromException(new Exception()));
            });
        }
예제 #8
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exception_thrown_from_func()
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (watcher.ExpectCallback())
                AmbientTasks.Add(() => throw exception);
        }
예제 #9
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exceptions_from_synchronously_faulted_tasks()
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(exception));
        }
예제 #10
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exceptions_from_asynchronously_faulted_tasks()
        {
            var source    = new TaskCompletionSource <object?>();
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            AmbientTasks.Add(source.Task);

            using (watcher.ExpectCallback())
                source.SetException(exception);
        }
예제 #11
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Exception_from_user_delegate_is_handled_by_BeginContext_handler([Values] PostOverload overload)
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke()))
            {
                using (watcher.ExpectCallback())
                    AmbientTasksPost(overload, () => throw exception);
            }
        }
예제 #12
0
        [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 });
        }