Пример #1
0
        public static async Task Invoke(this Func <Task> action, ExceptionAggregator aggregator, ExecutionTimer timer)
        {
            var oldSyncContext = SynchronizationContext.Current;

            try
            {
                var asyncSyncContext = new AsyncTestSyncContext(oldSyncContext);
                SetSynchronizationContext(asyncSyncContext);

                await aggregator?.RunAsync(
                    () => timer.AggregateAsync(
                        async() =>
                {
                    await action();
                    var ex = await asyncSyncContext.WaitForCompletionAsync();
                    if (ex != null)
                    {
                        aggregator.Add(ex);
                    }
                }));
            }
            finally
            {
                SetSynchronizationContext(oldSyncContext);
            }
        }
Пример #2
0
        public void Dispose()
        {
            var aggregator = new ExceptionAggregator();
            var tasks      = _collectionFixtureMappings.Values.OfType <IAsyncLifetime>()
                             .Select(asyncFixture => aggregator.RunAsync(asyncFixture.DisposeAsync))
                             .Concat(_assemblyFixtureMappings.Values.OfType <IAsyncLifetime>()
                                     .Select(asyncFixture => aggregator.RunAsync(asyncFixture.DisposeAsync)))
                             .ToArray();

            foreach (var disposable in _assemblyFixtureMappings.Values.OfType <IDisposable>()
                     .Concat(_collectionFixtureMappings.Values.OfType <IDisposable>()))
            {
                aggregator.Run(disposable.Dispose);
            }

            Trace.Listeners.Clear();
            Constants.Tracer.Listeners.Clear();

            Task.WaitAll(tasks);
        }
Пример #3
0
        public async Task <RunSummary> RunAsync()
        {
            if (!string.IsNullOrEmpty(this.skipReason))
            {
                this.messageBus.Queue(
                    this.scenario, test => new TestSkipped(test, this.skipReason), this.cancellationTokenSource);

                return(new RunSummary {
                    Total = 1, Skipped = 1
                });
            }
            else
            {
                var summary         = new RunSummary();
                var output          = string.Empty;
                var childAggregator = new ExceptionAggregator(this.parentAggregator);
                if (!childAggregator.HasExceptions)
                {
                    var tuple = await childAggregator.RunAsync(() => this.InvokeScenarioAsync(childAggregator));

                    summary.Aggregate(tuple.Item1);
                    output = tuple.Item2;
                }

                var exception = childAggregator.ToException();
                if (exception != null)
                {
                    summary.Total++;
                    summary.Failed++;
                    this.messageBus.Queue(
                        this.scenario,
                        test => new TestFailed(test, summary.Time, output, exception),
                        this.cancellationTokenSource);
                }
                else if (summary.Total == 0)
                {
                    summary.Total++;
                    this.messageBus.Queue(
                        this.scenario, test => new TestPassed(test, summary.Time, output), this.cancellationTokenSource);
                }

                return(summary);
            }
        }
        /// <inheritdoc/>
        protected override async Task <RunSummary> RunTestAsync()
        {
            if (dataDiscoveryException != null)
            {
                return(RunTest_DataDiscoveryException());
            }

            var runSummary = new RunSummary();

            foreach (var testRunner in testRunners)
            {
                runSummary.Aggregate(await testRunner.RunAsync());
            }

            // Run the cleanup here so we can include cleanup time in the run summary,
            // but save any exceptions so we can surface them during the cleanup phase,
            // so they get properly reported as test case cleanup failures.
            var timer = new ExecutionTimer();

            foreach (var trackedObject in disposalTracker.TrackedObjects)
            {
                if (trackedObject is IAsyncDisposable asyncDisposable)
                {
                    await timer.AggregateAsync(() => cleanupAggregator.RunAsync(asyncDisposable.DisposeAsync));
                }
                if (trackedObject is IDisposable disposable)
                {
                    timer.Aggregate(() => cleanupAggregator.Run(disposable.Dispose));
                }
            }

            disposalTracker.Clear();

            runSummary.Time += timer.Total;
            return(runSummary);
        }
Пример #5
0
        public async Task <RunSummary> RunScenarioAsync()
        {
            var runSummary = new RunSummary {
                Total = 1
            };
            var output = string.Empty;

            if (!MessageBus.QueueMessage(new TestStarting(Test)))
            {
                CancellationTokenSource.Cancel();
            }
            else
            {
                AfterTestStarting();

                if (!string.IsNullOrEmpty(SkipReason))
                {
                    runSummary.Skipped++;

                    if (!MessageBus.QueueMessage(new TestSkipped(Test, SkipReason)))
                    {
                        CancellationTokenSource.Cancel();
                    }
                }
                else
                {
                    var aggregator = new ExceptionAggregator(Aggregator);

                    if (!aggregator.HasExceptions)
                    {
                        var tuple = await aggregator.RunAsync(() => InvokeTestAsync(aggregator));

                        runSummary.Time = tuple.Item1;
                        output          = tuple.Item2;
                    }

                    var exception = aggregator.ToException();
                    TestResultMessage testResult;

                    if (exception == null)
                    {
                        testResult = new TestPassed(Test, runSummary.Time, output);
                    }
                    else if (exception is IgnoreException)
                    {
                        testResult = new TestSkipped(Test, exception.Message);
                        runSummary.Skipped++;
                    }
                    else
                    {
                        testResult = new TestFailed(Test, runSummary.Time, output, exception);
                        runSummary.Failed++;
                    }

                    if (!CancellationTokenSource.IsCancellationRequested)
                    {
                        if (!MessageBus.QueueMessage(testResult))
                        {
                            CancellationTokenSource.Cancel();
                        }
                    }
                }

                Aggregator.Clear();
                BeforeTestFinished();

                if (Aggregator.HasExceptions)
                {
                    if (!MessageBus.QueueMessage(new TestCleanupFailure(Test, Aggregator.ToException())))
                    {
                        CancellationTokenSource.Cancel();
                    }
                }
            }

            if (!MessageBus.QueueMessage(new TestFinished(Test, runSummary.Time, output)))
            {
                CancellationTokenSource.Cancel();
            }

            return(runSummary);
        }
        /// <summary>
        /// Runs this fixture.
        /// </summary>
        /// <param name="output">The test output helper.</param>
        /// <returns></returns>
        public async Task RunAsync(ITestOutputHelper output = null)
        {
            _run = true;

            try
            {
                if (RequestMessage == null)
                {
                    throw new InvalidOperationException($"Must call {nameof(When)} to configure an HTTP request");
                }

                if (!_assertions.Any())
                {
                    throw new InvalidOperationException("No assertions to run");
                }

                if (output != null)
                {
                    _loggerProvider.SetTestOutputHelper(output);
                }

                using var client = Factory.CreateClient();
                var provider = Factory.Server.Services;

                // Bootstrap.
                if (_bootstrapFunctions.Any())
                {
                    using var scope = provider.CreateScope();
                    foreach (var bootstrap in _bootstrapFunctions)
                    {
                        await bootstrap(scope.ServiceProvider);
                    }
                }

                var logger = provider.GetRequiredService <ILogger <MvcFunctionalTestFixture <TStartup> > >();

                var requestBody = await(RequestMessage.Content?.ReadAsStringAsync() ?? Task.FromResult <string>(null));
                logger.LogInformation($"Sending request {RequestMessage}\n{requestBody ?? "<no body>"}");

                var response = await client.SendAsync(RequestMessage);

                var responseBody = await(response.Content?.ReadAsStringAsync() ?? Task.FromResult <string>(null));
                logger.LogInformation($"Received {response}\n{responseBody ?? "<no body>"}");

                var aggregator = new ExceptionAggregator();

                foreach (var assertion in _assertions)
                {
                    switch (assertion)
                    {
                    case ResponseAssertion ra:
                        aggregator.Run(() => ra.Assertion(response));
                        break;

                    case ResponseBodyAssertion ra:
                        if (aggregator.TryRun(() => ra.Deserializer(responseBody), out var result))
                        {
                            foreach (var a in ra.Assertions)
                            {
                                await aggregator.RunAsync(() => a(provider, result));
                            }
                        }
                        break;

                    case ServiceAssertion sa:
                        using (var scope = provider.CreateScope())
                        {
                            await aggregator.RunAsync(() => sa.Assertion(scope.ServiceProvider));
                        }
                        break;

                    case RequestAssertion ra:
                        var context = await ra.ContextFactory(response);

                        var fixture = new MvcFunctionalTestFixture <TStartup>(_loggerProvider, this);
                        ra.Configurator(context, fixture);
                        await aggregator.RunAsync(() => fixture.RunAsync());

                        break;
                    }
                }

                aggregator.ThrowIfHasExceptions();
            }
            finally
            {
                Reset();
            }
        }