示例#1
0
        protected virtual List <IRunnerReporter> GetAvailableRunnerReporters()
        {
            var result     = new List <IRunnerReporter>();
            var runnerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetLocalCodeBase());

            foreach (var dllFile in Directory.GetFiles(runnerPath, "*.dll").Select(f => Path.Combine(runnerPath, f)))
            {
                Type[] types;

                try
                {
                    var assembly = CrossPlatform.LoadAssembly(dllFile);
                    types = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException ex)
                {
                    types = ex.Types;
                }
                catch
                {
                    continue;
                }

                foreach (var type in types)
                {
#pragma warning disable CS0618
                    if (type == null || type.GetTypeInfo().IsAbstract || type == typeof(DefaultRunnerReporter) || type == typeof(DefaultRunnerReporterWithTypes) || !type.GetInterfaces().Any(t => t == typeof(IRunnerReporter)))
                    {
                        continue;
                    }
#pragma warning restore CS0618

                    var ctor = type.GetConstructor(new Type[0]);
                    if (ctor == null)
                    {
                        Log.LogWarning("Type {0} in assembly {1} appears to be a runner reporter, but does not have an empty constructor.", type.FullName, dllFile);
                        continue;
                    }

                    result.Add((IRunnerReporter)ctor.Invoke(new object[0]));
                }
            }

            return(result);
        }
示例#2
0
        public override bool Execute()
        {
            RemotingUtility.CleanUpRegisteredChannels();

            XElement assembliesElement = null;
            var      environment       = $"{IntPtr.Size * 8}-bit {CrossPlatform.Version}";

            if (NeedsXml)
            {
                assembliesElement = new XElement("assemblies");
            }

            var appDomains = default(AppDomainSupport?);

            switch (AppDomains?.ToLowerInvariant())    // Using ToLowerInvariant() here for back compat for when this was a boolean
            {
            case null:
                break;

            case "ifavailable":
                appDomains = AppDomainSupport.IfAvailable;
                break;

            case "true":
            case "required":
                appDomains = AppDomainSupport.Required;
                break;

            case "false":
            case "denied":
                appDomains = AppDomainSupport.Denied;
                break;

            default:
                Log.LogError("AppDomains value '{0}' is invalid: must be 'ifavailable', 'required', or 'denied'", AppDomains);
                return(false);
            }

            switch (MaxParallelThreads)
            {
            case null:
            case "default":
                break;

            case "unlimited":
                maxThreadCount = -1;
                break;

            default:
                int threadValue;
                if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1)
                {
                    Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads);
                    return(false);
                }

                maxThreadCount = threadValue;
                break;
            }

            var originalWorkingFolder          = Directory.GetCurrentDirectory();
            var internalDiagnosticsMessageSink = DiagnosticMessageSink.ForInternalDiagnostics(Log, InternalDiagnosticMessages);

            using (AssemblyHelper.SubscribeResolveForAssembly(typeof(xunit), internalDiagnosticsMessageSink))
            {
                var reporter = GetReporter();
                if (reporter == null)
                {
                    return(false);
                }

                logger = new MSBuildLogger(Log);
                reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger));

                if (!NoLogo)
                {
                    var versionAttribute = typeof(xunit).GetTypeInfo().Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>();
                    Log.LogMessage(MessageImportance.High, $"xUnit.net MSBuild Runner v{versionAttribute.InformationalVersion} ({environment})");
                }

                var project = new XunitProject();
                foreach (var assembly in Assemblies)
                {
                    var assemblyFileName = assembly.GetMetadata("FullPath");
                    var configFileName   = assembly.GetMetadata("ConfigFile");
                    if (configFileName != null && configFileName.Length == 0)
                    {
                        configFileName = null;
                    }

                    var projectAssembly = new XunitProjectAssembly {
                        AssemblyFilename = assemblyFileName, ConfigFilename = configFileName
                    };
                    if (shadowCopy.HasValue)
                    {
                        projectAssembly.Configuration.ShadowCopy = shadowCopy;
                    }

                    project.Add(projectAssembly);
                }

                if (WorkingFolder != null)
                {
                    Directory.SetCurrentDirectory(WorkingFolder);
                }

                var clockTime = Stopwatch.StartNew();

                if (!parallelizeAssemblies.HasValue)
                {
                    parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault);
                }

                if (parallelizeAssemblies.GetValueOrDefault())
                {
                    var tasks   = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly, appDomains)));
                    var results = Task.WhenAll(tasks).GetAwaiter().GetResult();
                    foreach (var assemblyElement in results.Where(result => result != null))
                    {
                        assembliesElement.Add(assemblyElement);
                    }
                }
                else
                {
                    foreach (var assembly in project.Assemblies)
                    {
                        var assemblyElement = ExecuteAssembly(assembly, appDomains);
                        if (assemblyElement != null)
                        {
                            assembliesElement.Add(assemblyElement);
                        }
                    }
                }

                clockTime.Stop();

                if (assembliesElement != null)
                {
                    assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture)));
                }

                if (completionMessages.Count > 0)
                {
                    reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList()));
                }
            }

            Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder);

            if (NeedsXml)
            {
                if (Xml != null)
                {
                    using (var xmlStream = new FileStream(Xml.GetMetadata("FullPath"), FileMode.OpenOrCreate, FileAccess.Write))
                        assembliesElement.Save(xmlStream);
                }

                if (XmlV1 != null)
                {
                    CrossPlatform.Transform(logger, "XmlV1", "xUnit1.xslt", assembliesElement, XmlV1);
                }

                if (Html != null)
                {
                    CrossPlatform.Transform(logger, "Html", "HTML.xslt", assembliesElement, Html);
                }

                if (NUnit != null)
                {
                    CrossPlatform.Transform(logger, "NUnit", "NUnitXml.xslt", assembliesElement, NUnit);
                }

                if (JUnit != null)
                {
                    CrossPlatform.Transform(logger, "JUnit", "JUnitXml.xslt", assembliesElement, JUnit);
                }
            }

            // ExitCode is set to 1 for test failures and -1 for Exceptions.
            return(ExitCode == 0 || (ExitCode == 1 && IgnoreFailures));
        }