Esempio n. 1
0
        private bool TryCreateInjectionControllerCore(ExceptionAggregator aggregator, out IXunitInjectionController controller)
        {
            var asm = Assembly.Load(_assemblyName);

            if (asm == null)
            {
                aggregator.Add(new InvalidOperationException($"Cannot load assembly: {_assemblyName}"));
                controller = null;
                return(false);
            }

            var typ = asm.GetType(_typeName);

            if (typ == null)
            {
                aggregator.Add(new InvalidOperationException($"Cannot find type: {_typeName}"));
                controller = null;
                return(false);
            }

            var method = typ.GetMethod(_methodName, BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder, Type.EmptyTypes, new ParameterModifier[0]);

            if (method == null)
            {
                aggregator.Add(new InvalidOperationException($"Cannot find public static parameter-less method: {_methodName}"));
                controller = null;
                return(false);
            }

            if (method.ReturnType != typeof(IServiceProvider))
            {
                aggregator.Add(new InvalidOperationException($"{_methodName} does not return an {nameof(IServiceProvider)}"));
                controller = null;
                return(false);
            }

            // Invoke the method
            var result = method.Invoke(null, new object[0]);

            if (result == null)
            {
                aggregator.Add(new InvalidOperationException($"{_methodName} returned null"));
                controller = null;
                return(false);
            }

            controller = new ServiceProviderXunitInjectionController((IServiceProvider)result);
            return(true);
        }
        public bool TryCreateInjectionControllerForAssembly(ExceptionAggregator aggregator, IReflectionAssemblyInfo assembly, out IXunitInjectionController controller)
        {
            if (TryFindStartupType(assembly, out var type))
            {
                // TODO: Use generic host?

                // Check for a ConfigureServices method
                var configureServicesMethod = type.GetMethod("ConfigureServices", BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new[] { typeof(IServiceCollection) }, new ParameterModifier[0]);
                if (configureServicesMethod == null)
                {
                    aggregator.Add(new InvalidOperationException($"Could not find appropriate ConfigureServices method on TestStartup type {type.FullName}"));
                    controller = null;
                    return(false);
                }

                // Create the service collection
                var services = new ServiceCollection();

                try
                {
                    // Activate the type
                    var startup = Activator.CreateInstance(type);

                    // Configure the services
                    configureServicesMethod.Invoke(startup, new object[] { services });
                }
                catch (TargetInvocationException tex)
                {
                    aggregator.Add(tex.InnerException);
                    controller = null;
                    return(false);
                }
                catch (Exception ex)
                {
                    aggregator.Add(ex);
                    controller = null;
                    return(false);
                }

                // Create a ServiceProvider-based controller from the service provider
                controller = new ServiceProviderXunitInjectionController(services.BuildServiceProvider());
                return(true);
            }

            aggregator.Add(new InvalidOperationException("Could not find TestStartup class in target assembly"));
            controller = null;
            return(false);
        }
Esempio n. 3
0
        public static TestableTestMethodRunner Create(
            IMessageBus messageBus            = null,
            ITestCase[] testCases             = null,
            RunSummary result                 = null,
            Exception aggregatorSeedException = null,
            bool cancelInRunTestCaseAsync     = false)
        {
            if (testCases == null)
            {
                testCases = new[] { Mocks.TestCase <ClassUnderTest>("Passing") }
            }
            ;

            var firstTestCase = testCases.First();

            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestMethodRunner(
                       firstTestCase.TestMethod,
                       (IReflectionTypeInfo)firstTestCase.TestMethod.TestClass.Class,
                       (IReflectionMethodInfo)firstTestCase.TestMethod.Method,
                       testCases,
                       messageBus ?? new SpyMessageBus(),
                       aggregator,
                       new CancellationTokenSource(),
                       result ?? new RunSummary(),
                       cancelInRunTestCaseAsync
                       ));
        }
Esempio n. 4
0
        public static TestableTestCollectionRunner Create(
            IMessageBus?messageBus            = null,
            _ITestCase[]?testCases            = null,
            RunSummary?result                 = null,
            Exception?aggregatorSeedException = null,
            bool cancelInRunTestClassAsync    = false)
        {
            if (testCases == null)
            {
                testCases = new[] { Mocks.TestCase <ClassUnderTest>("Passing") }
            }
            ;

            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestCollectionRunner(
                       testCases.First().TestCollection,
                       testCases,
                       messageBus ?? new SpyMessageBus(),
                       new MockTestCaseOrderer(),
                       aggregator,
                       new CancellationTokenSource(),
                       result ?? new RunSummary(),
                       cancelInRunTestClassAsync
                       ));
        }
Esempio n. 5
0
        public static TestableTestMethodRunner Create(
            IMessageBus?messageBus            = null,
            _ITestCase[]?testCases            = null,
            RunSummary?result                 = null,
            Exception?aggregatorSeedException = null,
            bool cancelInRunTestCaseAsync     = false)
        {
            if (testCases == null)
            {
                testCases = new[] { Mocks.TestCase <ClassUnderTest>("Passing") }
            }
            ;

            var firstTestCase = testCases.First();

            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestMethodRunner(
                       firstTestCase.TestClass ?? throw new InvalidOperationException("testCase.TestClass must not be null"),
                       firstTestCase.TestMethod ?? throw new InvalidOperationException("testCase.TestMethod must not be null"),
                       firstTestCase.TestClass.Class as _IReflectionTypeInfo ?? throw new InvalidOperationException("testCase.TestClass.Class must be based on reflection"),
                       firstTestCase.TestMethod.Method as _IReflectionMethodInfo ?? throw new InvalidOperationException("testCase.TestMethod.Method must be based on reflection"),
                       testCases,
                       messageBus ?? new SpyMessageBus(),
                       aggregator,
                       new CancellationTokenSource(),
                       result ?? new RunSummary(),
                       cancelInRunTestCaseAsync
                       ));
        }
Esempio n. 6
0
        public static TestableTestRunner Create(IMessageBus messageBus,
                                                ITestCase testCase = null,
                                                string displayName = null,
                                                string skipReason  = null,
                                                decimal runTime    = 0m,
                                                string output      = "",
                                                Exception aggregatorSeedException = null,
                                                Action lambda = null)
        {
            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }
            if (testCase == null)
            {
                testCase = Mocks.TestCase <object>("ToString");
            }
            var test = Mocks.Test(testCase, displayName);

            return(new TestableTestRunner(
                       test,
                       messageBus,
                       typeof(object),
                       new object[0],
                       typeof(object).GetMethod("ToString"),
                       new object[0],
                       skipReason,
                       aggregator,
                       new CancellationTokenSource(),
                       runTime,
                       output,
                       lambda));
        }
Esempio n. 7
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);
            }
        }
Esempio n. 8
0
        private async Task <RunSummary> RunAsyncCore(VsixTestCase testCase, IMessageBus messageBus, ExceptionAggregator aggregator)
        {
            if (!EnsureConnected(testCase, messageBus))
            {
                return(new RunSummary
                {
                    Failed = 1,
                });
            }

            var xunitTest = new XunitTest(testCase, testCase.DisplayName);

            try
            {
                var remoteBus = _remoteBuses.GetOrAdd(messageBus, bus =>
                {
                    var instance = new RemoteMessageBus(bus);
                    _remoteObjects.Add(instance);
                    return(instance);
                });
                var outputBus = new TraceOutputMessageBus(remoteBus);
                var summary   = await Task.Run(
                    () => _runner.Run(testCase, outputBus))
                                .TimeoutAfter(testCase.TimeoutSeconds * 1000);

                if (summary.Exception != null)
                {
                    aggregator.Add(summary.Exception);
                }

                return(summary.ToRunSummary());
            }
            catch (Exception ex)
            {
                if (ex is RemotingException || ex is TimeoutException)
                {
                    Stop();
                }

                aggregator.Add(ex);
                messageBus.QueueMessage(new TestFailed(xunitTest, 0, ex.Message, ex));
                return(new RunSummary
                {
                    Failed = 1
                });
            }
        }
Esempio n. 9
0
        // This method is called by the xUnit test framework class es to run the test case. We will do the
        // loop here, forwarding on to the implementation in XunitTestCase to do the heavy lifting. We will
        // continue to re-run the test until the aggregator has an error (meaning that some internal error
        // condition happened), or the test runs without failure, or we've hit the maximum number of tries.
        /// <inheritdoc />
        public override async Task <RunSummary> RunAsync(
            IMessageSink diagnosticMessageSink,
            IMessageBus messageBus,
            object[] constructorArguments,
            ExceptionAggregator aggregator,
            CancellationTokenSource cancellationTokenSource)
        {
            int runCount = 0;

            while (true)
            {
                // This is really the only tricky bit: we need to capture and delay messages (since those will
                // contain run status) until we know we've decided to accept the final result;
                var delayedMessageBus = new DelayedMessageBus(messageBus);

                try
                {
                    var summary = await base.RunAsync(
                        diagnosticMessageSink,
                        delayedMessageBus,
                        constructorArguments,
                        aggregator,
                        cancellationTokenSource).WithTimeout(30_000);

                    if (aggregator.HasExceptions || summary.Failed == 0 || ++runCount >= _maxRetries)
                    {
                        delayedMessageBus.Dispose(); // Sends all the delayed messages
                        return(summary);
                    }
                }
                catch (TimeoutException ex)
                {
                    if (++runCount >= _maxRetries)
                    {
                        var runSummary = new RunSummary {
                            Total = 1, Failed = 1
                        };
                        aggregator.Add(ex);

                        if (!delayedMessageBus.QueueMessage(new TestCleanupFailure(
                                                                new XunitTest(this, DisplayName),
                                                                aggregator.ToException() !)))
                        {
                            cancellationTokenSource.Cancel();
                        }
                        delayedMessageBus.Dispose(); // Sends all the delayed messages

                        return(runSummary);
                    }
                }

                diagnosticMessageSink.OnMessage(
                    new DiagnosticMessage("Execution of '{0}' failed (attempt #{1}), retrying...", DisplayName,
                                          runCount));
                GC.Collect();
                await Task.Delay(100);
            }
        }
        public static ExceptionAggregator CreateExceptionAggregator(Exception exception)
        {
            var aggregator = new ExceptionAggregator();

            if (exception != null)
            {
                if (exception is AggregateException aggregateException)
                {
                    foreach (var innerException in aggregateException.InnerExceptions)
                    {
                        aggregator.Add(innerException);
                    }
                }
                else
                {
                    aggregator.Add(exception);
                }
            }
            return(aggregator);
        }
Esempio n. 11
0
        private bool TryCreateInjectionControllerCore(ExceptionAggregator aggregator, out IXunitInjectionController controller)
        {
            var asm = Assembly.Load(_assemblyName);

            if (asm == null)
            {
                aggregator.Add(new InvalidOperationException($"Cannot load assembly: {_assemblyName}"));
                controller = null;
                return(false);
            }

            var typ = asm.GetType(_typeName);

            if (typ == null)
            {
                aggregator.Add(new InvalidOperationException($"Cannot find type: {_typeName}"));
                controller = null;
                return(false);
            }

            controller = (IXunitInjectionController)Activator.CreateInstance(typ);
            return(true);
        }
Esempio n. 12
0
        public static TestableTestCaseRunner Create(IMessageBus messageBus, ITestCase testCase = null, RunSummary result = null, Exception aggregatorSeedException = null)
        {
            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestCaseRunner(
                       testCase ?? Mocks.TestCase <Object>("ToString"),
                       messageBus,
                       aggregator,
                       new CancellationTokenSource(),
                       result ?? new RunSummary()
                       ));
        }
Esempio n. 13
0
        public static TestableTestClassRunner Create(
            IMessageBus messageBus            = null,
            ITestCase[] testCases             = null,
            ITestCaseOrderer orderer          = null,
            ConstructorInfo constructor       = null,
            object[] availableArguments       = null,
            RunSummary result                 = null,
            Exception aggregatorSeedException = null,
            bool cancelInRunTestMethodAsync   = false)
        {
            if (testCases == null)
            {
                testCases = new[] { Mocks.TestCase <ClassUnderTest>("Passing") }
            }
            ;
            if (availableArguments == null)
            {
                availableArguments = new object[0];
            }

            var firstTest = testCases.First();

            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestClassRunner(
                       firstTest.TestMethod.TestClass,
                       (IReflectionTypeInfo)firstTest.TestMethod.TestClass.Class,
                       testCases,
                       new List <IMessageSinkMessage>(),
                       messageBus ?? new SpyMessageBus(),
                       orderer ?? new MockTestCaseOrderer(),
                       aggregator,
                       new CancellationTokenSource(),
                       constructor,
                       availableArguments,
                       result ?? new RunSummary(),
                       cancelInRunTestMethodAsync
                       ));
        }
        protected override async Task AfterTestCaseStartingAsync()
        {
            await base.AfterTestCaseStartingAsync();

            try
            {
                var scenarioAttributes = TestCase.TestMethod.GetScenarioAttributes(DiagnosticMessageSink);

                if (!scenarioAttributes.Any())
                {
                    throw new InvalidOperationException(
                              $"No scenario specified for {TestCase.TestMethod.TestClass.Class.Name}.{TestCase.TestMethod.Method.Name}. Make sure to add at least one ScenarioAttribute to the test method or class.");
                }

                foreach (var scenarioAttribute in scenarioAttributes)
                {
                    IScenarioIdentifier scenarioIdentifier = null;
                    var testRunnerAggregator = new ExceptionAggregator(Aggregator);
                    var skipReason           = scenarioAttribute.GetNamedArgument <string>("Skip");

                    try
                    {
                        var scenarioDiscoverer = ScenarioDiscovererFactory.GetDiscoverer(DiagnosticMessageSink, scenarioAttribute);
                        scenarioIdentifier = scenarioDiscoverer.GetScenarioIdentifier(scenarioAttribute);
                    }
                    catch (Exception exception)
                    {
                        scenarioIdentifier = new DummyScenarioDiscoverer().GetScenarioIdentifier(scenarioAttribute);
                        testRunnerAggregator.Add(exception);
                    }

                    var test       = CreateTest(TestCase, scenarioIdentifier);
                    var testRunner = new ScenarioTestRunner(test, DiagnosticMessageSink, MessageBus, TestClass, ConstructorArguments, TestMethod,
                                                            TestMethodArguments, skipReason, BeforeAfterAttributes, testRunnerAggregator,
                                                            CancellationTokenSource);

                    _testRunners.Add(testRunner);
                }
            }
            catch (Exception ex)
            {
                ScenarioDiscoveryException = ex;
            }
        }
Esempio n. 15
0
        public static TestableTestClassRunner Create(
            IMessageBus?messageBus            = null,
            _ITestCase[]?testCases            = null,
            ITestCaseOrderer?orderer          = null,
            ConstructorInfo?constructor       = null,
            object[]?availableArguments       = null,
            RunSummary?result                 = null,
            Exception?aggregatorSeedException = null,
            bool cancelInRunTestMethodAsync   = false)
        {
            if (testCases == null)
            {
                testCases = new[] { Mocks.TestCase <ClassUnderTest>("Passing") }
            }
            ;
            if (availableArguments == null)
            {
                availableArguments = new object[0];
            }

            var firstTest = testCases.First();

            var aggregator = new ExceptionAggregator();

            if (aggregatorSeedException != null)
            {
                aggregator.Add(aggregatorSeedException);
            }

            return(new TestableTestClassRunner(
                       firstTest.TestClass ?? throw new InvalidOperationException("testCase.TestClass must not be null"),
                       firstTest.TestClass.Class as _IReflectionTypeInfo ?? throw new InvalidOperationException("testCase.TestClass.Class must be based on reflection"),
                       testCases,
                       messageBus ?? new SpyMessageBus(),
                       orderer ?? new MockTestCaseOrderer(),
                       aggregator,
                       new CancellationTokenSource(),
                       constructor,
                       availableArguments,
                       result ?? new RunSummary(),
                       cancelInRunTestMethodAsync
                       ));
        }
Esempio n. 16
0
        public bool TryGetConstructorArgument(ExceptionAggregator exceptionAggregator, ConstructorInfo constructor, int index, ParameterInfo parameter, out object argumentValue)
        {
            try
            {
                // Try to resolve it out of the service provider
                var service = _serviceProvider.GetService(parameter.ParameterType);
                if (service != null)
                {
                    argumentValue = service;
                    return(true);
                }
            }
            catch (Exception ex)
            {
                exceptionAggregator.Add(ex);
            }

            argumentValue = null;
            return(false);
        }
        public bool TryGetConstructorArgument(IServiceProvider provider, ExceptionAggregator aggregator,
                                              out object?argumentValue)
        {
            argumentValue = null;

            try
            {
                argumentValue = provider.GetService(Parameter.ParameterType);
            }
            catch (Exception ex)
            {
                aggregator.Add(ex);

                return(true);
            }

            if (argumentValue != null)
            {
                return(true);
            }

            if (Parameter.HasDefaultValue)
            {
                argumentValue = Parameter.DefaultValue;
            }
            else if (Parameter.IsOptional)
            {
                argumentValue = GetDefaultValue(Parameter.ParameterType);
            }
            else if (Parameter.GetCustomAttribute <ParamArrayAttribute>() != null)
            {
                argumentValue = Array.CreateInstance(Parameter.ParameterType, new int[1]);
            }
            else
            {
                return(false);
            }

            return(true);
        }
    protected internal static object?[] CreateTestClassConstructorArguments(IServiceProvider provider,
                                                                            object?[] constructorArguments, ExceptionAggregator aggregator)
    {
        var unusedArguments = new List <Tuple <int, ParameterInfo> >();
        Func <IReadOnlyList <Tuple <int, ParameterInfo> >, string>?formatConstructorArgsMissingMessage = null;

        var args = new object?[constructorArguments.Length];

        for (var index = 0; index < constructorArguments.Length; index++)
        {
            if (constructorArguments[index] is DependencyInjectionTestClassRunner.DelayArgument delay)
            {
                formatConstructorArgsMissingMessage = delay.FormatConstructorArgsMissingMessage;

                if (delay.TryGetConstructorArgument(provider, aggregator, out var arg))
                {
                    args[index] = arg;
                }
                else
                {
                    unusedArguments.Add(Tuple.Create(index, delay.Parameter));
                }
            }
            else
            {
                args[index] = constructorArguments[index];
            }
        }

        if (unusedArguments.Count > 0 && formatConstructorArgsMissingMessage != null)
        {
            aggregator.Add(new TestClassException(formatConstructorArgsMissingMessage(unusedArguments)));
        }

        return(args);
    }