/// <summary>
 /// Construct an ExtensionNode supplying the assembly path and type name.
 /// </summary>
 /// <param name="assemblyPath">The path to the assembly where this extension is found.</param>
 /// <param name="typeName">The full name of the Type of the extension object.</param>
 /// <param name="targetFramework">The target framework of the extension assembly.</param>
 public ExtensionNode(string assemblyPath, string typeName, IRuntimeFramework targetFramework)
 {
     AssemblyPath    = assemblyPath;
     TypeName        = typeName;
     TargetFramework = targetFramework;
     Enabled         = true; // By default
 }
Example #2
0
        /// <summary>
        /// Scan a single assembly for extensions marked by ExtensionAttribute.
        /// For each extension, create an ExtensionNode and link it to the
        /// correct ExtensionPoint. Public for testing.
        /// </summary>
        internal void FindExtensionsInAssembly(ExtensionAssembly assembly)
        {
            log.Info("Scanning {0} assembly for Extensions", assembly.FilePath);

            if (CanLoadTargetFramework(Assembly.GetEntryAssembly(), assembly))
            {
                IRuntimeFramework assemblyTargetFramework = null;
#if !NETSTANDARD2_0
                var currentFramework = RuntimeFramework.CurrentFramework;
                assemblyTargetFramework = assembly.TargetFramework;
                if (!currentFramework.CanLoad(assemblyTargetFramework))
                {
                    if (!assembly.FromWildCard)
                    {
                        throw new NUnitEngineException($"Extension {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available.");
                    }
                    else
                    {
                        log.Info($"Assembly {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available. Assembly found via wildcard.");
                        return;
                    }
                }
#endif

                foreach (var type in assembly.MainModule.GetTypes())
                {
                    CustomAttribute extensionAttr = type.GetAttribute("NUnit.Engine.Extensibility.ExtensionAttribute");

                    if (extensionAttr == null)
                    {
                        continue;
                    }

                    object versionArg = extensionAttr.GetNamedArgument("EngineVersion");
                    if (versionArg != null && new Version((string)versionArg) > ENGINE_VERSION)
                    {
                        continue;
                    }

                    var node = new ExtensionNode(assembly.FilePath, type.FullName, assemblyTargetFramework);
                    node.Path        = extensionAttr.GetNamedArgument("Path") as string;
                    node.Description = extensionAttr.GetNamedArgument("Description") as string;

                    object enabledArg = extensionAttr.GetNamedArgument("Enabled");
                    node.Enabled = enabledArg != null
                        ? (bool)enabledArg : true;

                    log.Info("  Found ExtensionAttribute on Type " + type.Name);

                    foreach (var attr in type.GetAttributes("NUnit.Engine.Extensibility.ExtensionPropertyAttribute"))
                    {
                        string name  = attr.ConstructorArguments[0].Value as string;
                        string value = attr.ConstructorArguments[1].Value as string;

                        if (name != null && value != null)
                        {
                            node.AddProperty(name, value);
                            log.Info("        ExtensionProperty {0} = {1}", name, value);
                        }
                    }

                    _extensions.Add(node);

                    ExtensionPoint ep;
                    if (node.Path == null)
                    {
                        ep = DeduceExtensionPointFromType(type);
                        if (ep == null)
                        {
                            string msg = string.Format(
                                "Unable to deduce ExtensionPoint for Type {0}. Specify Path on ExtensionAttribute to resolve.",
                                type.FullName);
                            throw new NUnitEngineException(msg);
                        }

                        node.Path = ep.Path;
                    }
                    else
                    {
                        ep = GetExtensionPoint(node.Path);
                        if (ep == null)
                        {
                            string msg = string.Format(
                                "Unable to locate ExtensionPoint for Type {0}. The Path {1} cannot be found.",
                                type.FullName,
                                node.Path);
                            throw new NUnitEngineException(msg);
                        }
                    }

                    ep.Install(node);
                }
            }
        }
Example #3
0
 // Some early versions of the engine return .NET 4.5 Client profile, which doesn't really exist
 private static bool IsErroneousNet45ClientProfile(IRuntimeFramework runtime)
 {
     return(runtime.FrameworkVersion.Major == 4 && runtime.FrameworkVersion.Minor > 0 && runtime.Profile == "Client");
 }
        /// <summary>
        /// Scan a single assembly for extensions marked by ExtensionAttribute.
        /// For each extension, create an ExtensionNode and link it to the
        /// correct ExtensionPoint. Public for testing.
        /// </summary>
        internal void FindExtensionsInAssembly(ExtensionAssembly assembly)
        {
            log.Info($"Scanning {assembly.FilePath} for Extensions");

            if (!CanLoadTargetFramework(Assembly.GetEntryAssembly(), assembly))
            {
                log.Info($"{assembly.FilePath} cannot be loaded on this runtime");
                return;
            }

            IRuntimeFramework assemblyTargetFramework = null;

#if NETFRAMEWORK
            var currentFramework = RuntimeFramework.CurrentFramework;
            assemblyTargetFramework = assembly.TargetFramework;
            if (!currentFramework.CanLoad(assemblyTargetFramework))
            {
                //Temp fix: Prevent crash in agent if an extension is used by the main engine, which targets a framework that can not be loaded on a particular agent
                // https://github.com/nunit/nunit-console/issues/757
                //Long-term fix is to not search for extensions within the agent, see https://github.com/nunit/nunit-console/issues/760
                if (_isRunningOnAgent)
                {
                    return;
                }

                if (!assembly.FromWildCard)
                {
                    throw new NUnitEngineException($"Extension {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available.");
                }
                else
                {
                    log.Info($"Assembly {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available. Assembly found via wildcard.");
                    return;
                }
            }
#endif

            foreach (var type in assembly.MainModule.GetTypes())
            {
                CustomAttribute extensionAttr = type.GetAttribute("NUnit.Engine.Extensibility.ExtensionAttribute");

                if (extensionAttr == null)
                {
                    continue;
                }

                object versionArg = extensionAttr.GetNamedArgument("EngineVersion");
                if (versionArg != null && new Version((string)versionArg) > ENGINE_VERSION)
                {
                    continue;
                }

                var node = new ExtensionNode(assembly.FilePath, assembly.AssemblyVersion, type.FullName, assemblyTargetFramework);
                node.Path        = extensionAttr.GetNamedArgument("Path") as string;
                node.Description = extensionAttr.GetNamedArgument("Description") as string;

                object enabledArg = extensionAttr.GetNamedArgument("Enabled");
                node.Enabled = enabledArg != null
                    ? (bool)enabledArg : true;

                log.Info("  Found ExtensionAttribute on Type " + type.Name);

                foreach (var attr in type.GetAttributes("NUnit.Engine.Extensibility.ExtensionPropertyAttribute"))
                {
                    string name  = attr.ConstructorArguments[0].Value as string;
                    string value = attr.ConstructorArguments[1].Value as string;

                    if (name != null && value != null)
                    {
                        node.AddProperty(name, value);
                        log.Info("        ExtensionProperty {0} = {1}", name, value);
                    }
                }

                _extensions.Add(node);

                ExtensionPoint ep;
                if (node.Path == null)
                {
                    ep = DeduceExtensionPointFromType(type);
                    if (ep == null)
                    {
                        string msg = string.Format(
                            "Unable to deduce ExtensionPoint for Type {0}. Specify Path on ExtensionAttribute to resolve.",
                            type.FullName);
                        throw new NUnitEngineException(msg);
                    }

                    node.Path = ep.Path;
                }
                else
                {
                    ep = GetExtensionPoint(node.Path);
                    if (ep == null)
                    {
                        string msg = string.Format(
                            "Unable to locate ExtensionPoint for Type {0}. The Path {1} cannot be found.",
                            type.FullName,
                            node.Path);
                        throw new NUnitEngineException(msg);
                    }
                }

                ep.Install(node);
            }
        }
Example #5
0
 public bool CanLoad(IRuntimeFramework requested)
 {
     return(FrameworkVersion >= requested.FrameworkVersion);
 }