/// <summary> /// Performs an action for all the databases configured from all sources. /// </summary> /// <param name="targetType">The type of the class currently running a test.</param> /// <param name="dbAttributes"> /// All the <see cref="UsesDatabasesAttribute"/> attributes on the target class.</param> /// <param name="provider">The current provider for which connections are being provided through.</param> /// <param name="action">The action to execute for each database.</param> private static void ExecuteActionForAllDatabases( Type targetType, IEnumerable <UsesDatabasesAttribute> dbAttributes, IDatabaseProvider <IDbConnection> provider, Action <string> action) { List <Action> dbSetupActions = new List <Action>(); List <string> alreadyActionedDatabases = new List <string>(); if (dbAttributes.Any()) { // Perform the action for all the databases defined in the UsesDatabaseAttribute. foreach (var databaseName in dbAttributes.First().Databases) { dbSetupActions.Add(() => action(databaseName)); alreadyActionedDatabases.Add(databaseName); } } // Perform the action for all the databases defined in the application configuration file. ProviderConfigurationBase providerConfig = (ProviderConfigurationBase)ConfigurationManager.GetSection("dbTestMonkey/" + provider.ConfigurationSectionName); foreach (var databaseName in providerConfig.Databases .Cast <DatabaseConfiguration>() .Select(dc => dc.DatabaseName) .Where(dn => !alreadyActionedDatabases.Any(asd => asd == dn))) { dbSetupActions.Add(() => action(databaseName)); alreadyActionedDatabases.Add(databaseName); } // Finally perform the action for all databases defined on connection properties in the class. foreach (var connectionAttribute in targetType .GetProperties() .Where(pi => pi.CustomAttributes.Any(a => a.AttributeType.Name == "ConnectionAttribute")) .Select(pi => pi.GetCustomAttribute(typeof(ConnectionAttribute), true))) { var connAttribute = connectionAttribute as ConnectionAttribute; if (connAttribute.TargetDatabaseName != null && !alreadyActionedDatabases.Contains(connAttribute.TargetDatabaseName)) { dbSetupActions.Add(() => action(connAttribute.TargetDatabaseName)); alreadyActionedDatabases.Add(connAttribute.TargetDatabaseName); } } GlobalConfiguration globalConfig = (GlobalConfiguration)ConfigurationManager.GetSection("dbTestMonkey/global"); if (globalConfig.UseParallelInitialisation) { Parallel.Invoke(dbSetupActions.ToArray()); } else { dbSetupActions.ForEach(act => act.Invoke()); } }
/// <summary> /// Examines an object to determine the correct property to populate with a database connection. /// </summary> /// <param name="targetObject">The object to examine for best match properties.</param> /// <param name="databaseName">The name of the database the connection will be to.</param> /// <param name="providerConfig"> /// An object representing the app.config configuration for the current provider.</param> /// <returns>A property information object containing the best match.</returns> private static PropertyInfo FindBestMatchConnectionProperty( object targetObject, string databaseName, ProviderConfigurationBase providerConfig) { var properties = targetObject.GetType().GetProperties( BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); string preConfiguredConnectionPropertyName = null; if (providerConfig.Databases.Cast <DatabaseConfiguration>() .Any(d => d.DatabaseName == databaseName && !string.IsNullOrWhiteSpace(d.ConnectionPropertyName))) { preConfiguredConnectionPropertyName = providerConfig.Databases.Cast <DatabaseConfiguration>().First().ConnectionPropertyName; } return(properties.FirstOrDefault(prop => { if (string.IsNullOrWhiteSpace(preConfiguredConnectionPropertyName)) { return prop.GetCustomAttributes().Cast <Attribute>().RequiresConnectionToDatabase(databaseName) || prop.Name == UppercaseFirstChar(databaseName) + "Connection"; } else { return prop.Name == preConfiguredConnectionPropertyName; } })); }
public void LoadSettings(ProviderConfigurationBase uc, string providerName) { _uc = uc; this.Title = Properties.Resources.ProviderSettingsTitle + providerName; //spContent.Children.Add(uc); }
/// <summary> /// Method called before a test is executed. /// </summary> /// <param name="sender">The object which called this method.</param> /// <param name="methodBase">Contextual information about the method which called this method.</param> public static void BeforeTest(object sender, MethodBase methodBase, Action <string> logAction) { logAction("Preparing to execute before test DbTestMonkey actions."); var dbAttributes = methodBase .DeclaringType .GetCustomAttributes(typeof(UsesDatabasesAttribute), true) .Cast <UsesDatabasesAttribute>(); List <PropertyInfo> activeConnectionProperties = new List <PropertyInfo>(); Type providerType = null; GlobalConfiguration globalConfig = (GlobalConfiguration)ConfigurationManager.GetSection("dbTestMonkey/global"); if (dbAttributes.Count() > 1) { throw new NotImplementedException( "Multiple UsesDatabaseAttributes have been defined on the test class. " + "Only one attribute is currently supported at this time."); } else if (globalConfig != null && globalConfig.DeployDatabasesEachClass && dbAttributes.Any()) { providerType = dbAttributes.First().ProviderType; logAction("Using the provider type " + providerType.Name + " as configured in the UsesDatabasesAttribute."); } else { if (globalConfig == null || string.IsNullOrWhiteSpace(globalConfig.DefaultDbProvider)) { throw new InvalidOperationException( "DefaultDbProvider global configuration setting has not been configured but it is required for the current configuration."); } providerType = globalConfig.DefaultDbProviderType; logAction("Using the provider type " + providerType.Name + " as configured in app.config."); } var provider = Activator.CreateInstance(providerType) as IDatabaseProvider <IDbConnection>; if (provider == null) { throw new InvalidOperationException( "Provider type " + providerType.FullName + " does not implement the DbTestMonkey.Contracts.IDatabaseProvider<IDbConnection> interface."); } provider.LogAction = logAction; logAction( "Provider has been successfully created. Preparing to clear database and run pre-deployment scripts if required."); // Clear all the existing data out of the configured databases and re-seed base data. ExecuteActionForAllDatabases(sender.GetType(), dbAttributes, provider, dbName => provider.ExecutePreTestTasks(dbName)); logAction("Databases have successfully been cleared and potentially re-seeded. Connections will now be set up."); ProviderConfigurationBase providerConfig = (ProviderConfigurationBase)ConfigurationManager.GetSection("dbTestMonkey/" + provider.ConfigurationSectionName); if (dbAttributes.Any()) { // Set up connections for database defined in the UsesDatabasesAttribute. foreach (var database in dbAttributes.First().Databases) { var connectionProperty = FindBestMatchConnectionProperty(sender, database, providerConfig); if (connectionProperty != null) { logAction("Populating connection property " + connectionProperty.Name + " as configured in the UsesDatabaseAttribute."); SetConnectionProperty(sender, activeConnectionProperties, provider, database, connectionProperty); } } } // Set up any remaining connections that have target database names defined in a ConnectionAttribute. foreach (var connectionProperty in methodBase.DeclaringType .GetProperties() .Where(pi => !activeConnectionProperties.Contains(pi) && pi.CustomAttributes.Any(a => a.AttributeType.Name == "ConnectionAttribute"))) { var connAttribute = connectionProperty.GetCustomAttribute(typeof(ConnectionAttribute), true) as ConnectionAttribute; if (connAttribute != null && connAttribute.TargetDatabaseName != null) { logAction("Populating connection property " + connectionProperty.Name + " as configured in the ConnectionAttribute."); SetConnectionProperty( sender, activeConnectionProperties, provider, connAttribute.TargetDatabaseName, connectionProperty); } } // Get all the properties that haven't yet been populated and populate them. foreach (var prop in methodBase.DeclaringType.GetProperties().Where(p => !activeConnectionProperties.Any(c => c.Name == p.Name))) { var databases = providerConfig.Databases.Cast <DatabaseConfiguration>(); if (databases.Any(d => d.ConnectionPropertyName == prop.Name)) { string databaseName = databases.FirstOrDefault(d => d.ConnectionPropertyName == prop.Name).DatabaseName; if (databaseName != null) { logAction("Populating connection property " + prop.Name + " as configured in app.config."); SetConnectionProperty(sender, activeConnectionProperties, provider, databaseName, prop); } } } }