/// <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); }
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); }
/// <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); }
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); }
/// <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); }