/// <summary> /// Setup the isolation host. /// </summary> public void SetupHost() { List <string> resolutionPaths = this.GetResolutionPaths(this.sourceFileName, VSInstallationUtilities.IsCurrentProcessRunningInPortableMode()); if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("DesktopTestSourceHost.SetupHost(): Creating assembly resolver with resolution paths {0}.", string.Join(",", resolutionPaths.ToArray())); } // Case when DisableAppDomain setting is present in runsettings and no child-appdomain needs to be created if (this.isAppDomainCreationDisabled) { this.parentDomainAssemblyResolver = new AssemblyResolver(resolutionPaths); this.AddSearchDirectoriesSpecifiedInRunSettingsToAssemblyResolver(this.parentDomainAssemblyResolver, Path.GetDirectoryName(this.sourceFileName)); } // Create child-appdomain and set assembly resolver on it else { // Setup app-domain var appDomainSetup = new AppDomainSetup(); this.targetFrameworkVersion = this.GetTargetFrameworkVersionString(this.sourceFileName); AppDomainUtilities.SetAppDomainFrameworkVersionBasedOnTestSource(appDomainSetup, this.targetFrameworkVersion); // Temporarily set appbase to the location from where adapter should be picked up from. We will later reset this to test source location // once adapter gets loaded in the child app domain. appDomainSetup.ApplicationBase = Path.GetDirectoryName(typeof(TestSourceHost).Assembly.Location); var configFile = this.GetConfigFileForTestSource(this.sourceFileName); AppDomainUtilities.SetConfigurationFile(appDomainSetup, configFile); EqtTrace.Info("DesktopTestSourceHost.SetupHost(): Creating app-domain for source {0} with application base path {1}.", this.sourceFileName, appDomainSetup.ApplicationBase); string domainName = string.Format("TestSourceHost: Enumering source ({0})", this.sourceFileName); this.domain = this.appDomain.CreateDomain(domainName, null, appDomainSetup); // Load objectModel before creating assembly resolver otherwise in 3.5 process, we run into a recurive assembly resolution // which is trigged by AppContainerUtilities.AttachEventToResolveWinmd method. EqtTrace.SetupRemoteEqtTraceListeners(this.domain); // Add an assembly resolver in the child app-domain... Type assemblyResolverType = typeof(AssemblyResolver); EqtTrace.Info("DesktopTestSourceHost.SetupHost(): assemblyenumerator location: {0} , fullname: {1} ", assemblyResolverType.Assembly.Location, assemblyResolverType.FullName); var resolver = AppDomainUtilities.CreateInstance( this.domain, assemblyResolverType, new object[] { resolutionPaths }); EqtTrace.Info( "DesktopTestSourceHost.SetupHost(): resolver type: {0} , resolve type assembly: {1} ", resolver.GetType().FullName, resolver.GetType().Assembly.Location); this.childDomainAssemblyResolver = (AssemblyResolver)resolver; this.AddSearchDirectoriesSpecifiedInRunSettingsToAssemblyResolver(this.childDomainAssemblyResolver, Path.GetDirectoryName(this.sourceFileName)); } }
public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRunsettings() { string runSettingxml = @"<RunSettings> <RunConfiguration> <DisableAppDomain>False</DisableAppDomain> </RunConfiguration> <MSTestV2> <AssemblyResolution> <Directory path = "" % Temp %\directory"" includeSubDirectories = ""true"" /> <Directory path = ""C:\windows"" includeSubDirectories = ""false"" /> <Directory path = "".\ComponentTests"" /> </AssemblyResolution> </MSTestV2> </RunSettings>"; var testSource = GetTestAssemblyPath("DesktopTestProjectx86Debug.dll"); this.testSourceHost = new TestSourceHost(testSource, this.GetMockedIRunSettings(runSettingxml).Object, null); this.testSourceHost.SetupHost(); var assemblyResolution = "ComponentTests\\TestProjectForAssemblyResolution.dll"; var asm = Assembly.LoadFrom(assemblyResolution); var type = asm.GetType("PlatformServices.Desktop.ComponentTests.TestProjectForAssemblyResolution"); // Creating instance of TestProjectForAssemblyResolution should not throw. // It is present in <Directory path = ".\ComponentTests" /> specified in runsettings AppDomainUtilities.CreateInstance(this.testSourceHost.AppDomain, type, null); }
public void GetTargetFrameworkVersionFromVersionStringShouldReturnCurrectVersion() { var expected = new Version("4.5"); var version = AppDomainUtilities.GetTargetFrameworkVersionFromVersionString(".NETFramework,Version=v4.5"); Assert.AreEqual(expected.Major, version.Major); Assert.AreEqual(expected.Minor, version.Minor); }
public void GetTargetFrameworkVersionFromVersionStringShouldReturnDefaultVersionIfversionIsPortable() { var expected = new Version(); var version = AppDomainUtilities.GetTargetFrameworkVersionFromVersionString(".NETPortable,Version=v4.5,Profile=Profile259"); Assert.AreEqual(expected.Major, version.Major); Assert.AreEqual(expected.Minor, version.Minor); }
/// <summary> /// Creates an instance of a given type in the test source host. /// </summary> /// <param name="type"> The type that needs to be created in the host. </param> /// <param name="args">The arguments to pass to the constructor. /// This array of arguments must match in number, order, and type the parameters of the constructor to invoke. /// Pass in null for a constructor with no arguments. /// </param> /// <returns> An instance of the type created in the host. </returns> /// <remarks> If a type is to be created in isolation then it needs to be a MarshalByRefObject. </remarks> public object CreateInstanceForType(Type type, object[] args) { // Honor DisableAppDomain setting if it is present in runsettings if (this.isAppDomainCreationDisabled) { return(Activator.CreateInstance(type, args)); } return(AppDomainUtilities.CreateInstance(this.domain, type, args)); }
public void SetConfigurationFileShouldSetToCurrentDomainsConfigFileIfSourceDoesNotHaveAConfig() { AppDomainSetup setup = new AppDomainSetup(); AppDomainUtilities.SetConfigurationFile(setup, null); // Assert Config file being set. Assert.AreEqual(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, setup.ConfigurationFile); Assert.IsNull(setup.GetConfigurationBytes()); }
/// <summary> /// Creates an instance of a given type in the test source host. /// </summary> /// <param name="type"> The type that needs to be created in the host. </param> /// <param name="args">The arguments to pass to the constructor. /// This array of arguments must match in number, order, and type the parameters of the constructor to invoke. /// Pass in null for a constructor with no arguments. /// </param> /// <returns> An instance of the type created in the host. </returns> /// <remarks> If a type is to be created in isolation then it needs to be a MarshalByRefObject. </remarks> public object CreateInstanceForType(Type type, object[] args) { // Honour DisableAppDomain setting if it is present in runsettings if (this.runSettings != null && MSTestAdapterSettings.IsAppDomainCreationDisabled(this.runSettings.SettingsXml)) { return(Activator.CreateInstance(type, args)); } return(AppDomainUtilities.CreateInstance( this.domain, type, args)); }
public void SetConfigurationFileShouldSetOMRedirectionIfConfigFileIsPresent() { AppDomainSetup setup = new AppDomainSetup(); var configFile = @"C:\temp\foo.dll.config"; // Setup mocks. this.testableXmlUtilities.ConfigXml = @"<?xml version=""1.0"" encoding=""utf-8"" ?> <configuration> </configuration>"; AppDomainUtilities.SetConfigurationFile(setup, configFile); // Assert Config file being set. Assert.AreEqual(configFile, setup.ConfigurationFile); // Assert Config Bytes. var expectedRedir = "<dependentAssembly><assemblyIdentity name=\"Microsoft.VisualStudio.TestPlatform.ObjectModel\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" /><bindingRedirect oldVersion=\"11.0.0.0\" newVersion=\"15.0.0.0\" />"; var observedConfigBytes = setup.GetConfigurationBytes(); var observedXml = System.Text.Encoding.UTF8.GetString(observedConfigBytes); Assert.IsTrue(observedXml.Replace("\r\n", string.Empty).Replace(" ", string.Empty).Contains(expectedRedir.Replace(" ", string.Empty)), "Config must have OM redirection"); }
public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRunsettings() { string runSettingxml = @"<RunSettings> <RunConfiguration> <DisableAppDomain>False</DisableAppDomain> </RunConfiguration> <MSTestV2> <AssemblyResolution> <Directory path = "" % Temp %\directory"" includeSubDirectories = ""true"" /> <Directory path = ""C:\windows"" includeSubDirectories = ""false"" /> <Directory path = "".\ComponentTests"" /> </AssemblyResolution> </MSTestV2> </RunSettings>"; this.testSourceHost = new TestSourceHost(this.testSource, this.GetMockedIRunSettings(runSettingxml).Object, null); this.testSourceHost.SetupHost(); // Creating instance of TestProjectForAssemblyResolution should not throw. // It is present in <Directory path = ".\ComponentTests" /> specified in runsettings AppDomainUtilities.CreateInstance(this.testSourceHost.AppDomain, typeof(TestProjectForAssemblyResolution), null); }
internal virtual string GetTargetFrameworkVersionString(string sourceFileName) { return(AppDomainUtilities.GetTargetFrameworkVersionString(sourceFileName)); }
/// <summary> /// Setup the isolation host. /// </summary> public void SetupHost() { List <string> resolutionPaths = this.GetResolutionPaths(this.sourceFileName, VSInstallationUtilities.IsCurrentProcessRunningInPortableMode()); // Check if user specified any runsettings MSTestAdapterSettings adapterSettings = MSTestSettingsProvider.Settings; if (resolutionPaths != null && resolutionPaths.Count > 0) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("TestSourceHost: Creating assembly resolver with resolution paths {0}.", string.Join(",", resolutionPaths.ToArray())); } // Adding adapter folder to resolution paths if (!resolutionPaths.Contains(Path.GetDirectoryName(typeof(TestSourceHost).Assembly.Location))) { resolutionPaths.Add(Path.GetDirectoryName(typeof(TestSourceHost).Assembly.Location)); } // Adding extensions folder to resolution paths if (!resolutionPaths.Contains(Path.GetDirectoryName(typeof(AssemblyHelper).Assembly.Location))) { resolutionPaths.Add(Path.GetDirectoryName(typeof(AssemblyHelper).Assembly.Location)); } } // Honour DisableAppDomain setting if it is present in runsettings if (this.runSettings != null && MSTestAdapterSettings.IsAppDomainCreationDisabled(this.runSettings.SettingsXml)) { if (adapterSettings != null) { try { this.assemblyResolver = new AssemblyResolver(resolutionPaths); this.assemblyResolver.AddSearchDirectoriesFromRunSetting(adapterSettings.GetDirectoryListWithRecursiveProperty(null)); } catch (Exception exception) { if (EqtTrace.IsErrorEnabled) { EqtTrace.Error(exception); } } } } var appDomainSetup = new AppDomainSetup(); // The below logic of preferential setting the appdomains appbase is needed because: // 1. We set this to the location of the test source if it is built for Full CLR -> Ideally this needs to be done in all situations. // 2. We set this to the location where the current adapter is being picked up from for UWP and .Net Core scenarios -> This needs to be // different especially for UWP because we use the desktop adapter(from %temp%\VisualStudioTestExplorerExtensions) itself for test discovery // in IDE scenarios. If the app base is set to the test source location, discovery will not work because we drop the // UWP platform service assembly at the test source location and since CLR starts looking for assemblies from the app base location, // there would be a mismatch of platform service assemblies during discovery. var frameworkVersionString = this.GetTargetFrameworkVersionString(this.sourceFileName); if (frameworkVersionString.Contains(PlatformServices.Constants.DotNetFrameWorkStringPrefix)) { appDomainSetup.ApplicationBase = Path.GetDirectoryName(this.sourceFileName) ?? Path.GetDirectoryName(typeof(TestSourceHost).Assembly.Location); } else { appDomainSetup.ApplicationBase = Path.GetDirectoryName(typeof(TestSourceHost).Assembly.Location); } if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("TestSourceHost: Creating app-domain for source {0} with application base path {1}.", this.sourceFileName, appDomainSetup.ApplicationBase); } AppDomainUtilities.SetAppDomainFrameworkVersionBasedOnTestSource(appDomainSetup, frameworkVersionString); var configFile = this.GetConfigFileForTestSource(this.sourceFileName); AppDomainUtilities.SetConfigurationFile(appDomainSetup, configFile); this.domain = this.appDomain.CreateDomain("TestSourceHost: Enumering assembly", null, appDomainSetup); // Load objectModel before creating assembly resolver otherwise in 3.5 process, we run into a recurive assembly resolution // which is trigged by AppContainerUtilities.AttachEventToResolveWinmd method. EqtTrace.SetupRemoteEqtTraceListeners(this.domain); // Add an assembly resolver... Type assemblyResolverType = typeof(AssemblyResolver); if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("TestSourceHost: assemblyenumerator location: {0} , fullname: {1} ", assemblyResolverType.Assembly.Location, assemblyResolverType.FullName); } var resolver = AppDomainUtilities.CreateInstance( this.domain, assemblyResolverType, new object[] { resolutionPaths }); if (EqtTrace.IsInfoEnabled) { EqtTrace.Info( "TestSourceHost: resolver type: {0} , resolve type assembly: {1} ", resolver.GetType().FullName, resolver.GetType().Assembly.Location); } this.assemblyResolver = (AssemblyResolver)resolver; if (adapterSettings != null) { try { var additionalSearchDirectories = adapterSettings.GetDirectoryListWithRecursiveProperty(appDomainSetup.ApplicationBase); if (additionalSearchDirectories?.Count > 0) { this.assemblyResolver.AddSearchDirectoriesFromRunSetting( adapterSettings.GetDirectoryListWithRecursiveProperty(appDomainSetup.ApplicationBase)); } } catch (Exception exception) { if (EqtTrace.IsErrorEnabled) { EqtTrace.Error(exception); } } } }