/// <summary> /// Selects a target runtime framework for a TestPackage based on /// the settings in the package and the assemblies themselves. /// The package RuntimeFramework setting may be updated as a /// result and the selected runtime is returned. /// </summary> /// <param name="package">A TestPackage</param> /// <returns>The selected RuntimeFramework</returns> public RuntimeFramework SelectRuntimeFramework(TestPackage package) { RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; string frameworkSetting = package.GetSetting(RunnerSettings.RuntimeFramework, ""); RuntimeFramework requestedFramework = frameworkSetting.Length > 0 ? RuntimeFramework.Parse(frameworkSetting) : new RuntimeFramework(RuntimeType.Any, RuntimeFramework.DefaultVersion); log.Debug("Current framework is {0}", currentFramework); if (requestedFramework == null) log.Debug("No specific framework requested"); else log.Debug("Requested framework is {0}", requestedFramework); RuntimeType targetRuntime = requestedFramework.Runtime; Version targetVersion = requestedFramework.FrameworkVersion; if (targetRuntime == RuntimeType.Any) targetRuntime = currentFramework.Runtime; if (targetVersion == RuntimeFramework.DefaultVersion) { if (ServiceContext.UserSettings.GetSetting("Options.TestLoader.RuntimeSelectionEnabled", true)) foreach (string assembly in package.TestFiles) { using (AssemblyReader reader = new AssemblyReader(assembly)) { Version v = new Version(reader.ImageRuntimeVersion.Substring(1)); log.Debug("Assembly {0} uses version {1}", assembly, v); if (v > targetVersion) targetVersion = v; } } else targetVersion = RuntimeFramework.CurrentFramework.ClrVersion; RuntimeFramework checkFramework = new RuntimeFramework(targetRuntime, targetVersion); if (!checkFramework.IsAvailable || !ServiceContext.TestAgency.IsRuntimeVersionSupported(targetVersion)) { log.Debug("Preferred version {0} is not installed or this NUnit installation does not support it", targetVersion); if (targetVersion < currentFramework.FrameworkVersion) targetVersion = currentFramework.FrameworkVersion; } } RuntimeFramework targetFramework = new RuntimeFramework(targetRuntime, targetVersion); package.Settings[RunnerSettings.RuntimeFramework] = targetFramework.ToString(); log.Debug("Test will use {0} framework", targetFramework); return targetFramework; }
/// <summary> /// Selects a target runtime framework for a TestPackage based on /// the settings in the package and the assemblies themselves. /// The package RuntimeFramework setting may be updated as a result /// and a string representing the selected runtime is returned. /// </summary> /// <param name="package">A TestPackage</param> /// <returns>A string representing the selected RuntimeFramework</returns> public string SelectRuntimeFramework(TestPackage package) { RuntimeFramework currentFramework = RuntimeFramework.CurrentFramework; string frameworkSetting = package.GetSetting(PackageSettings.RuntimeFramework, ""); RuntimeFramework requestedFramework = frameworkSetting.Length > 0 ? RuntimeFramework.Parse(frameworkSetting) : new RuntimeFramework(RuntimeType.Any, RuntimeFramework.DefaultVersion); log.Debug("Current framework is {0}", currentFramework); if (requestedFramework == null) log.Debug("No specific framework requested"); else log.Debug("Requested framework is {0}", requestedFramework); RuntimeType targetRuntime = requestedFramework.Runtime; Version targetVersion = requestedFramework.FrameworkVersion; if (targetRuntime == RuntimeType.Any) targetRuntime = currentFramework.Runtime; if (targetVersion == RuntimeFramework.DefaultVersion) { var packages = package.SubPackages; if (packages.Count == 0) packages.Add(package); foreach (var subPackage in packages) { var assembly = subPackage.FullName; // If the file is not an assembly or doesn't exist, then it can't // contribute any information to the decision, so we skip it. if (PathUtils.IsAssemblyFileType(assembly) && File.Exists(assembly)) { using (var reader = new AssemblyReader(assembly)) { if (!reader.IsValidPeFile) log.Debug("{0} is not a valid PE file", assembly); else if (!reader.IsDotNetFile) log.Debug("{0} is not a managed assembly", assembly); else { if (reader.ShouldRun32Bit) { package.Settings[PackageSettings.RunAsX86] = true; log.Debug("Assembly {0} will be run x86", assembly); } var imageRuntimeVersion = reader.ImageRuntimeVersion; if (imageRuntimeVersion != null) { var v = new Version(imageRuntimeVersion.Substring(1)); log.Debug("Assembly {0} uses version {1}", assembly, v); // TODO: We are doing two jobs here: (1) getting the // target version and (2) applying a policy that says // we run under the highest version of all assemblies. // We should implement the policy at a higher level. if (v > targetVersion) targetVersion = v; } } } } } RuntimeFramework checkFramework = new RuntimeFramework(targetRuntime, targetVersion); if (!checkFramework.IsAvailable) { log.Debug("Preferred version {0} is not installed or this NUnit installation does not support it", targetVersion); if (targetVersion < currentFramework.FrameworkVersion) targetVersion = currentFramework.FrameworkVersion; } } RuntimeFramework targetFramework = new RuntimeFramework(targetRuntime, targetVersion); package.Settings[PackageSettings.RuntimeFramework] = targetFramework.ToString(); log.Debug("Test will use {0} framework", targetFramework); return targetFramework.ToString(); }