/// <summary> /// IsBetterVersion determines whether another assembly is /// a better (higher) version than the current assembly. /// It is only intended to be called if IsDuplicateOf /// has already returned true. /// </summary> /// <param name="other"></param> /// <returns></returns> public bool IsBetterVersionOf(ExtensionAssembly other) { #if DEBUG if (!IsDuplicateOf(other)) throw new NUnitEngineException("IsBetterVersonOf should only be called on duplicate assemblies"); #endif var version = AssemblyName.Version; var otherVersion = other.AssemblyName.Version; if (version > otherVersion) return true; if (version < otherVersion) return false; // Versions are equal, override only if this one was specified exactly while the other wasn't return !FromWildCard && other.FromWildCard; }
/// <summary> /// IsDuplicateOf returns true if two assemblies have the same name. /// </summary> public bool IsDuplicateOf(ExtensionAssembly other) { return AssemblyName.Name == other.AssemblyName.Name; }
/// <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); ValidateTargetFramework(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); } }
/// <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> public void FindExtensionsInAssembly(ExtensionAssembly assembly) { log.Info("Scanning {0} assembly for Extensions", assembly.FilePath); 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); 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); } }
/// <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); } }
/// <summary> /// IsDuplicateOf returns true if two assemblies have the same name. /// </summary> public bool IsDuplicateOf(ExtensionAssembly other) { return(AssemblyName.Name == other.AssemblyName.Name); }