/// <summary>
 /// Initializes a new instance of the <see cref="TestDeployment"/> class. Used for unit tests.
 /// </summary>
 /// <param name="deploymentItemUtility"> The deployment item utility. </param>
 /// <param name="deploymentUtility"> The deployment utility. </param>
 /// <param name="fileUtility"> The file utility. </param>
 internal TestDeployment(DeploymentItemUtility deploymentItemUtility, DeploymentUtility deploymentUtility, FileUtility fileUtility)
 {
     this.deploymentItemUtility = deploymentItemUtility;
     this.deploymentUtility     = deploymentUtility;
     this.fileUtility           = fileUtility;
     this.adapterSettings       = null;
     RunDirectories             = null;
 }
Esempio n. 2
0
        private void AppDomainCreationDisabledInRunSettings()
        {
            if (this.runSettings != null && MSTestAdapterSettings.IsAppDomainCreationDisabled(this.runSettings.SettingsXml))
            {
                this.isAppDomainCreationDisabled = true;
            }

            this.isAppDomainCreationDisabled = false;
        }
Esempio n. 3
0
        internal TestSourceHost(string sourceFileName, IRunSettings runSettings, IFrameworkHandle frameworkHandle, IAppDomain appDomain)
        {
            this.sourceFileName  = sourceFileName;
            this.runSettings     = runSettings;
            this.frameworkHandle = frameworkHandle;
            this.appDomain       = appDomain;

            // Set the environment context.
            this.SetContext(sourceFileName);

            // Set isAppDomainCreationDisabled flag
            this.isAppDomainCreationDisabled = (this.runSettings != null) && MSTestAdapterSettings.IsAppDomainCreationDisabled(this.runSettings.SettingsXml);
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
        /// <summary>
        /// Deploy files related to the list of tests specified.
        /// </summary>
        /// <param name="tests"> The tests. </param>
        /// <param name="runContext"> The run context. </param>
        /// <param name="frameworkHandle"> The framework handle. </param>
        /// <returns> Return true if deployment is done. </returns>
        public bool Deploy(IEnumerable <TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle)
        {
            Debug.Assert(tests != null, "tests");

            // Reset runDirectories before doing deployment, so that older values of runDirectories is not picked
            // even if test host is kept alive.
            RunDirectories = null;

            this.adapterSettings = MSTestSettingsProvider.Settings;
            bool canDeploy          = this.CanDeploy();
            var  hasDeploymentItems = tests.Any(test => this.deploymentItemUtility.HasDeploymentItems(test));

            // deployment directories should not be created in this case,simply return
            if (!canDeploy && hasDeploymentItems)
            {
                return(false);
            }

            RunDirectories = this.deploymentUtility.CreateDeploymentDirectories(runContext);

            // Deployment directories are created but deployment will not happen.
            // This is added just to keep consistency with MSTestv1 behavior.
            if (!hasDeploymentItems)
            {
                return(false);
            }

            // Object model currently does not have support for SuspendCodeCoverage. We can remove this once support is added
#if !NETSTANDARD1_5 && !NET5_0
            using (new SuspendCodeCoverage())
#endif
            {
                // Group the tests by source
                var testsBySource = from test in tests
                                    group test by test.Source into testGroup
                                    select new { Source = testGroup.Key, Tests = testGroup };

                var runDirectories = RunDirectories;
                foreach (var group in testsBySource)
                {
                    // do the deployment
                    this.deploymentUtility.Deploy(@group.Tests, @group.Source, runContext, frameworkHandle, RunDirectories);
                }

                // Update the runDirectories
                RunDirectories = runDirectories;
            }

            return(true);
        }
Esempio n. 6
0
        private void AddSearchDirectoriesSpecifiedInRunSettingsToAssemblyResolver(AssemblyResolver assemblyResolver, string baseDirectory)
        {
            // Check if user specified any adapter settings
            MSTestAdapterSettings adapterSettings = MSTestSettingsProvider.Settings;

            if (adapterSettings != null)
            {
                try
                {
                    var additionalSearchDirectories = adapterSettings.GetDirectoryListWithRecursiveProperty(baseDirectory);
                    if (additionalSearchDirectories?.Count > 0)
                    {
                        assemblyResolver.AddSearchDirectoriesFromRunSetting(additionalSearchDirectories);
                    }
                }
                catch (Exception exception)
                {
                    EqtTrace.Error(
                        "DesktopTestSourceHost.AddSearchDirectoriesSpecifiedInRunSettingsToAssemblyResolver(): Exception hit while trying to set assembly resolver for domain. Exception : {0} \n Message : {1}",
                        exception,
                        exception.Message);
                }
            }
        }
Esempio n. 7
0
 /// <summary>
 /// Reset the settings to its default.
 /// Used for testing purposes.
 /// </summary>
 internal static void Reset()
 {
     settings = null;
 }
Esempio n. 8
0
        /// <summary>
        /// Load the settings from the reader.
        /// </summary>
        /// <param name="reader">Reader to load the settings from.</param>
        public void Load(XmlReader reader)
        {
            ValidateArg.NotNull <XmlReader>(reader, "reader");

            settings = MSTestAdapterSettings.ToSettings(reader);
        }
Esempio n. 9
0
        public static MSTestAdapterSettings ToSettings(XmlReader reader)
        {
            ValidateArg.NotNull <XmlReader>(reader, "reader");

            // Expected format of the xml is: -
            //
            // <MSTestV2>
            //     <DeploymentEnabled>true</DeploymentEnabled>
            //     <DeleteDeploymentDirectoryAfterTestRunIsComplete>true</DeleteDeploymentDirectoryAfterTestRunIsComplete>
            //     <AssemblyResolution>
            //          <Directory path= "% HOMEDRIVE %\direvtory "includeSubDirectories = "true" />
            //          <Directory path= "C:\windows" includeSubDirectories = "false" />
            //          <Directory path= ".\DirectoryName" />  ...// by default includeSubDirectories is false
            //     </AssemblyResolution>
            // </MSTestV2>
            MSTestAdapterSettings settings = MSTestSettingsProvider.Settings;

            if (!reader.IsEmptyElement)
            {
                reader.Read();

                while (reader.NodeType == XmlNodeType.Element)
                {
                    bool   result;
                    string elementName = reader.Name.ToUpperInvariant();
                    switch (elementName)
                    {
                    case "ASSEMBLYRESOLUTION":
                    {
                        settings.ReadAssemblyResolutionPath(reader);
                        break;
                    }

                    case "DEPLOYMENTENABLED":
                    {
                        if (bool.TryParse(reader.ReadInnerXml(), out result))
                        {
                            settings.DeploymentEnabled = result;
                        }

                        break;
                    }

                    case "DELETEDEPLOYMENTDIRECTORYAFTERTESTRUNISCOMPLETE":
                    {
                        if (bool.TryParse(reader.ReadInnerXml(), out result))
                        {
                            settings.DeleteDeploymentDirectoryAfterTestRunIsComplete = result;
                        }

                        break;
                    }

                    default:
                    {
                        reader.Skip();
                        break;
                    }
                    }
                }
            }

            return(settings);
        }
Esempio n. 10
0
 /// <summary>
 /// Reset the settings to its default.
 /// </summary>
 public static void Reset()
 {
     settings = null;
 }
Esempio n. 11
0
        /// <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);
                    }
                }
            }
        }