예제 #1
0
        /// <summary>
        /// For given file checks if it is a binary, then finds and deploys PDB for line number info in call stack.
        /// </summary>
        /// <returns>
        /// Returns deployed destination pdb file path if everything is Ok, otherwise null.
        /// </returns>
        /// <param name="destinationFile">The file we need to find PDBs for (we care only about binaries).</param>
        /// <param name="relativeDestination">Destination relative to the root of deployment dir.</param>
        /// <param name="sourceFile">Original file of destinationFile, i.e. the file copied to deployment dir.</param>
        /// <param name="destToSource">destToSource map.</param>
        internal string FindAndDeployPdb(string destinationFile, string relativeDestination, string sourceFile, Dictionary <string, string> destToSource)
        {
            Debug.Assert(!string.IsNullOrEmpty(destinationFile), "destination should not be null or empty.");
            Debug.Assert(!string.IsNullOrEmpty(relativeDestination), "relative destination path should not be null or empty.");
            Debug.Assert(!string.IsNullOrEmpty(sourceFile), "sourceFile should not be null or empty.");
            Debug.Assert(destToSource != null, "destToSource should not be null.");

            if (!this.assemblyUtility.IsAssemblyExtension(Path.GetExtension(destinationFile)))
            {
                return(null);
            }

            string pdbSource = this.GetSymbolsFileName(sourceFile);

            if (string.IsNullOrEmpty(pdbSource))
            {
                return(null);
            }

            string pdbDestination         = null;
            string relativePdbDestination = null;

            try
            {
                pdbDestination         = Path.Combine(Path.GetDirectoryName(destinationFile), Path.GetFileName(pdbSource));
                relativePdbDestination = Path.Combine(
                    Path.GetDirectoryName(relativeDestination), Path.GetFileName(pdbDestination));
            }
            catch (ArgumentException ex)
            {
                EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "Error while trying to locate pdb for deployed assembly '{0}': {1}", destinationFile, ex);
                return(null);
            }

            // If already processed, do nothing.
            if (!destToSource.ContainsKey(relativePdbDestination))
            {
                if (this.DoesFileExist(pdbSource))
                {
                    string warning;
                    pdbDestination = this.CopyFileOverwrite(pdbSource, pdbDestination, out warning);
                    if (!string.IsNullOrEmpty(pdbDestination))
                    {
                        destToSource.Add(relativePdbDestination, pdbSource);
                        return(pdbDestination);
                    }
                }
            }
            else if (!string.Equals(pdbSource, destToSource[relativePdbDestination], StringComparison.OrdinalIgnoreCase))
            {
                EqtTrace.WarningIf(
                    EqtTrace.IsWarningEnabled,
                    "Conflict during copiyng PDBs for line number info: '{0}' and '{1}' are from different origins although they might be the same.",
                    pdbSource,
                    destToSource[relativePdbDestination]);
            }

            return(null);
        }
예제 #2
0
        public override List <string> GetDataTablesAndViews()
        {
            WriteDiagnostics("GetDataTablesAndViews");
            List <string> tableNames = new List <string>();

            try
            {
                string defaultSchema = this.GetDefaultSchema();
                WriteDiagnostics("Default schema is {0}", defaultSchema);

                SchemaMetaData[] metadatas = this.GetSchemaMetaData();

                // TODO: may be find better way to enumerate tables/views.
                foreach (SchemaMetaData metadata in metadatas)
                {
                    DataTable dataTable = null;
                    try
                    {
                        WriteDiagnostics("Getting schema table {0}", metadata.SchemaTable);
                        dataTable = this.Connection.GetSchema(metadata.SchemaTable);
                    }
                    catch (Exception ex)
                    {
                        WriteDiagnostics("Failed to get schema table");

                        // This can be normal case as some providers do not support views.
                        EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DataUtil.GetDataTablesAndViews: exception (can be normal case as some providers do not support views): " + ex);
                        continue;
                    }

                    Debug.Assert(dataTable != null, "Failed to get data table that contains metadata about tables!");

                    foreach (DataRow row in dataTable.Rows)
                    {
                        WriteDiagnostics("Row: {0}", row);
                        string tableSchema     = null;
                        bool   isDefaultSchema = false;

                        // Check the table type for validity
                        if (metadata.TableTypeColumn != null)
                        {
                            if (row[metadata.TableTypeColumn] != DBNull.Value)
                            {
                                string tableType = row[metadata.TableTypeColumn] as string;
                                if (!IsInArray(tableType, metadata.ValidTableTypes))
                                {
                                    WriteDiagnostics("Table type {0} is not acceptable", tableType);

                                    // Not a valid table type, get the next row
                                    continue;
                                }
                            }
                        }

                        // Get the schema name, and filter bad schemas
                        if (row[metadata.SchemaColumn] != DBNull.Value)
                        {
                            tableSchema = row[metadata.SchemaColumn] as string;

                            if (IsInArray(tableSchema, metadata.InvalidSchemas))
                            {
                                WriteDiagnostics("Schema {0} is not acceptable", tableSchema);

                                // A table in a schema we do not want to see, get the next row
                                continue;
                            }

                            isDefaultSchema = string.Equals(tableSchema, defaultSchema, StringComparison.OrdinalIgnoreCase);
                        }

                        string tableName = row[metadata.NameColumn] as string;
                        WriteDiagnostics("Table {0}{1} found", tableSchema != null ? tableSchema + "." : string.Empty, tableName);

                        // If schema is defined and is not equal to default, prepend table schema in front of the table.
                        string qualifiedTableName = tableName;
                        if (isDefaultSchema)
                        {
                            qualifiedTableName = this.FormatTableNameForDisplay(null, tableName);
                        }
                        else
                        {
                            qualifiedTableName = this.FormatTableNameForDisplay(tableSchema, tableName);
                        }

                        WriteDiagnostics("Adding Table {0}", qualifiedTableName);
                        tableNames.Add(qualifiedTableName);
                    }

                    tableNames.Sort(StringComparer.OrdinalIgnoreCase);
                }
            }
            catch (Exception e)
            {
                WriteDiagnostics("Failed to fetch tables for {0}, exception: {1}", this.Connection.ConnectionString, e);

                // OK to fall through and return whatever we do have...
            }

            return(tableNames);
        }
예제 #3
0
        /// <summary>
        /// Does the deployment of parameter deployment items & the testSource to the parameter directory.
        /// </summary>
        /// <param name="deploymentItems">The deployment item.</param>
        /// <param name="testSource">The test source.</param>
        /// <param name="deploymentDirectory">The deployment directory.</param>
        /// <param name="resultsDirectory">Root results directory</param>
        /// <returns>Returns a list of deployment warnings</returns>
        protected IEnumerable <string> Deploy(IList <DeploymentItem> deploymentItems, string testSource, string deploymentDirectory, string resultsDirectory)
        {
            Validate.IsFalse(string.IsNullOrWhiteSpace(deploymentDirectory), "Deployment directory is null or empty");
            Validate.IsTrue(this.FileUtility.DoesDirectoryExist(deploymentDirectory), $"Deployment directory {deploymentDirectory} does not exist");
            Validate.IsFalse(string.IsNullOrWhiteSpace(testSource), "TestSource directory is null/empty");
            Validate.IsTrue(this.FileUtility.DoesFileExist(testSource), $"TestSource {testSource} does not exist.");

            testSource = Path.GetFullPath(testSource);
            var warnings = new List <string>();

            this.AddDeploymentItemsBasedOnMsTestSetting(testSource, deploymentItems, warnings);

            // Maps relative to Out dir destination -> source and used to determine if there are conflicted items.
            var destToSource = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            // Copy the deployment items. (As deployment item can correspond to directories as well, so each deployment item may map to n files)
            foreach (var deploymentItem in deploymentItems)
            {
                ValidateArg.NotNull(deploymentItem, "deploymentItem should not be null.");

                // Validate the output directory.
                if (!this.IsOutputDirectoryValid(deploymentItem, deploymentDirectory, warnings))
                {
                    continue;
                }

                // Get the files corresponding to this deployment item
                var deploymentItemFiles = this.GetFullPathToFilesCorrespondingToDeploymentItem(deploymentItem, testSource, resultsDirectory, warnings, out bool itemIsDirectory);
                if (deploymentItemFiles == null)
                {
                    continue;
                }

                var fullPathToDeploymentItemSource = this.GetFullPathToDeploymentItemSource(deploymentItem.SourcePath, testSource);

                // Note: source is already rooted.
                foreach (var deploymentItemFile in deploymentItemFiles)
                {
                    Debug.Assert(Path.IsPathRooted(deploymentItemFile), "File " + deploymentItemFile + " is not rooted");

                    // List of files to deploy, by default, just itemFile.
                    var filesToDeploy = new List <string>(1);
                    filesToDeploy.Add(deploymentItemFile);

                    // Find dependencies of test deployment items and deploy them at the same time as master file.
                    if (deploymentItem.OriginType == DeploymentItemOriginType.PerTestDeployment &&
                        this.AssemblyUtility.IsAssemblyExtension(Path.GetExtension(deploymentItemFile)))
                    {
                        this.AddDependenciesOfDeploymentItem(deploymentItemFile, filesToDeploy, warnings);
                    }

                    foreach (var fileToDeploy in filesToDeploy)
                    {
                        Debug.Assert(Path.IsPathRooted(fileToDeploy), "File " + fileToDeploy + " is not rooted");

                        // Ignore the test platform files.
                        var tempFile     = Path.GetFileName(fileToDeploy);
                        var assemblyName = Path.GetFileName(this.GetType().GetTypeInfo().Assembly.Location);
                        if (tempFile.Equals(assemblyName, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        string relativeDestination;
                        if (itemIsDirectory)
                        {
                            // Deploy into subdirectory of deployment (Out) dir.
                            Debug.Assert(fileToDeploy.StartsWith(fullPathToDeploymentItemSource, StringComparison.Ordinal), "Somehow source is outside original dir.");
                            relativeDestination = this.FileUtility.TryConvertPathToRelative(fileToDeploy, fullPathToDeploymentItemSource);
                        }
                        else
                        {
                            // Deploy just to the deployment (Out) dir.
                            relativeDestination = Path.GetFileName(fileToDeploy);
                        }

                        relativeDestination = Path.Combine(deploymentItem.RelativeOutputDirectory, relativeDestination);  // Ignores empty arg1.
                        var destination = Path.Combine(deploymentDirectory, relativeDestination);
                        try
                        {
                            destination = Path.GetFullPath(destination);
                        }
                        catch (Exception e)
                        {
                            var warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorFailedToAccessFile, destination, e.GetType(), e.Message);
                            warnings.Add(warning);

                            continue;
                        }

                        if (!destToSource.ContainsKey(relativeDestination))
                        {
                            destToSource.Add(relativeDestination, fileToDeploy);

                            // Now, finally we can copy the file...
                            destination = this.FileUtility.CopyFileOverwrite(fileToDeploy, destination, out string warning);
                            if (!string.IsNullOrEmpty(warning))
                            {
                                warnings.Add(warning);
                            }

                            if (string.IsNullOrEmpty(destination))
                            {
                                continue;
                            }

                            // We clear the attributes so that e.g. you can write to the copies of files originally under SCC.
                            this.FileUtility.SetAttributes(destination, FileAttributes.Normal);

                            // Deploy PDB for line number info in stack trace.
                            this.FileUtility.FindAndDeployPdb(destination, relativeDestination, fileToDeploy, destToSource);
                        }
                        else if (
                            !string.Equals(
                                fileToDeploy,
                                destToSource[relativeDestination],
                                StringComparison.OrdinalIgnoreCase))
                        {
                            EqtTrace.WarningIf(
                                EqtTrace.IsWarningEnabled,
                                "Conflict during copiyng file: '{0}' and '{1}' are from different origins although they might be the same.",
                                fileToDeploy,
                                destToSource[relativeDestination]);
                        }
                    } // foreach fileToDeploy.
                }     // foreach itemFile.
            }

            return(warnings);
        }
예제 #4
0
        private IEnumerable <DeploymentItem> GetSatellites(IEnumerable <DeploymentItem> deploymentItems, string testSource, IList <string> warnings)
        {
            List <DeploymentItem> satellites = new List <DeploymentItem>();

            foreach (DeploymentItem item in deploymentItems)
            {
                // We do not care about deployment items which are directories because in that case we deploy all files underneath anyway.
                string path = null;
                try
                {
                    path = this.GetFullPathToDeploymentItemSource(item.SourcePath, testSource);
                    path = Path.GetFullPath(path);

                    if (string.IsNullOrEmpty(path) || !this.assemblyUtility.IsAssemblyExtension(Path.GetExtension(path)) ||
                        !this.fileUtility.DoesFileExist(path) || !this.assemblyUtility.IsAssembly(path))
                    {
                        continue;
                    }
                }
                catch (ArgumentException ex)
                {
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                }
                catch (SecurityException ex)
                {
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                }
                catch (IOException ex)
                {
                    // This covers PathTooLongException.
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                }
                catch (NotSupportedException ex)
                {
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                }

                // Note: now Path operations with itemPath should not result in any exceptions.
                // path is already canonicalized.

                // If we cannot access satellite due to security, etc, we report warning.
                try
                {
                    string itemDir = Path.GetDirectoryName(path).TrimEnd(
                        new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                    List <string> itemSatellites = this.assemblyUtility.GetSatelliteAssemblies(path);
                    foreach (string satellite in itemSatellites)
                    {
                        Debug.Assert(!string.IsNullOrEmpty(satellite), "DeploymentManager.DoDeployment: got empty satellite!");
                        Debug.Assert(
                            satellite.IndexOf(itemDir, StringComparison.OrdinalIgnoreCase) == 0,
                            "DeploymentManager.DoDeployment: Got satellite that does not start with original item path");

                        string satelliteDir = Path.GetDirectoryName(satellite).TrimEnd(
                            new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });

                        Debug.Assert(!string.IsNullOrEmpty(satelliteDir), "DeploymentManager.DoDeployment: got empty satellite dir!");
                        Debug.Assert(satelliteDir.Length > itemDir.Length + 1, "DeploymentManager.DoDeployment: wrong satellite dir lenght!");

                        string localeDir = satelliteDir.Substring(itemDir.Length + 1);
                        Debug.Assert(!string.IsNullOrEmpty(localeDir), "DeploymentManager.DoDeployment: got empty dir name for satellite dir!");

                        string relativeOutputDir = Path.Combine(item.RelativeOutputDirectory, localeDir);

                        // Now finally add the item!
                        DeploymentItem satelliteItem = new DeploymentItem(satellite, relativeOutputDir, DeploymentItemOriginType.Satellite);
                        this.deploymentItemUtility.AddDeploymentItem(satellites, satelliteItem);
                    }
                }
                catch (ArgumentException ex)
                {
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                    string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage());
                    warnings.Add(warning);
                }
                catch (SecurityException ex)
                {
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                    string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage());
                    warnings.Add(warning);
                }
                catch (IOException ex)
                {
                    // This covers PathTooLongException.
                    EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, "DeploymentManager.GetSatellites: {0}", ex);
                    string warning = string.Format(CultureInfo.CurrentCulture, Resource.DeploymentErrorGettingSatellite, item, ex.GetType(), ex.GetExceptionMessage());
                    warnings.Add(warning);
                }
            }

            return(satellites);
        }
예제 #5
0
        /// <summary>
        /// Gets the full path and expands any environment variables contained in the path.
        /// </summary>
        /// <param name="path">The path to be expanded.</param>
        /// <param name="baseDirectory">The base directory for the path which is not rooted path</param>
        /// <returns>The expanded path.</returns>
        internal string ResolveEnvironmentVariableAndReturnFullPathIfExist(string path, string baseDirectory)
        {
            // Trim begining and trailing white space from the path.
            path = path.Trim(' ', '\t');

            if (!string.IsNullOrEmpty(path))
            {
                string warningMessage = null;

                // Expand any environment variables in the path.
                path = this.ExpandEnvironmentVariables(path);

                // If the path is a relative path, expand it relative to the base directory
                if (!Path.IsPathRooted(path))
                {
                    if (!string.IsNullOrEmpty(baseDirectory))
                    {
                        path = Path.Combine(baseDirectory, path);
                    }
                    else
                    {
                        warningMessage = string.Format("The Directory: {0}, has following problem: {1}", path, "This is not an absolute path. A base directory should be provided for this to be used as a relative path.");

                        if (EqtTrace.IsWarningEnabled)
                        {
                            EqtTrace.Warning(warningMessage);
                        }

                        return(null);
                    }
                }

                try
                {
                    // Get the full path.
                    // This will cleanup the path converting any "..\" to the appropariate value
                    // and convert any alternative directory seperators to "\"
                    path = Path.GetFullPath(path);
                }
                catch (Exception e)
                {
                    warningMessage = e.Message;
                }

                if (!string.IsNullOrEmpty(warningMessage))
                {
                    warningMessage = string.Format("The Directory: {0}, has following problem: {1}", path, warningMessage);

                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning(warningMessage);
                    }

                    return(null);
                }

                if (this.DoesDirectoryExist(path))
                {
                    return(path);
                }

                // generate warning that path doesnot exist.
                EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, string.Format("The Directory: {0}, does not exist.", path));
            }

            return(null);
        }
 /// <summary>
 /// Log a warning in a given format.
 /// </summary>
 /// <param name="format"> The format. </param>
 /// <param name="args"> The args. </param>
 public void LogWarning(string format, params object[] args)
 {
     EqtTrace.WarningIf(EqtTrace.IsWarningEnabled, format, args);
 }