namespace Blah.Model.Tests { using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Threading; using Microsoft.SqlServer.Management.Smo; using Microsoft.VisualStudio.TestTools.UnitTesting; using NHibernate; using NHibernate.ByteCode.LinFu; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Tool.hbm2ddl; using Configuration = NHibernate.Cfg.Configuration; using Environment = NHibernate.Cfg.Environment; [TestClass] public abstract class IntegrationTestBase { private static Configuration configuration; private static readonly string databaseName = "EquineTest"; private static readonly object lockObject = new object(); private static readonly string serverInstance = @"(local)\SQLEXPRESS"; private static readonly IEnumerable schemas = new List() { "Core" }; private static ISessionFactory sessionFactory; private string dataFilePath; private string logFilePath; protected ISession session; [TestInitialize] public void TestInitialize() { Monitor.Enter(lockObject); try { this.InitializePaths(); this.DeleteDatabaseIfExists(); this.CreateDatabase(); if (configuration == null) { // Disabling connection pooling is important var connectionString = string.Format( CultureInfo.InvariantCulture, @"Data Source={0}; Integrated Security=true; Initial Catalog={1}; Connection Timeout=120; Pooling=false;", serverInstance, databaseName); configuration = new Configuration() .SetProperty(Environment.ReleaseConnections, "on_close") .SetProperty(Environment.Dialect, typeof(MsSql2008Dialect).AssemblyQualifiedName) .SetProperty(Environment.ConnectionDriver, typeof(SqlClientDriver).AssemblyQualifiedName) .SetProperty(Environment.ConnectionString, connectionString) .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName) .AddAssembly("EquineBusinessBureau.Model"); sessionFactory = configuration.BuildSessionFactory(); } this.session = sessionFactory.OpenSession(); // SchemaExport won't create the database schemas for us foreach (string schema in schemas) { var sql = string.Format(CultureInfo.InvariantCulture, "CREATE SCHEMA {0}", schema); this.session.CreateSQLQuery(sql).ExecuteUpdate(); } new SchemaExport(configuration).Execute( true, true, false, session.Connection, Console.Out); } catch { Monitor.Exit(lockObject); throw; } } [TestCleanup] public void TestCleanup() { this.session.Dispose(); this.DeleteDatabaseIfExists(); Monitor.Exit(lockObject); } private void CreateDatabase() { var server = new Server(serverInstance); var database = new Database(server, databaseName); var fileGroup = new FileGroup(database, "PRIMARY"); database.FileGroups.Add(fileGroup); var dataFile = new DataFile(fileGroup, databaseName, this.dataFilePath); dataFile.Growth = 10; dataFile.GrowthType = FileGrowthType.Percent; fileGroup.Files.Add(dataFile); var logFile = new LogFile(database, databaseName + "_log", this.logFilePath); logFile.Growth = 10; logFile.GrowthType = FileGrowthType.Percent; database.LogFiles.Add(logFile); database.Create(); } private void DeleteDatabaseIfExists() { var server = new Server(serverInstance); if (server.Databases.Contains(databaseName)) { var sql = string.Format( CultureInfo.InvariantCulture, "ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE", databaseName); server.Databases[databaseName].ExecuteNonQuery(sql); server.DetachDatabase(databaseName, true); File.Delete(this.dataFilePath); File.Delete(this.logFilePath); } } private string GetExecutingDirectory() { var path = Assembly.GetExecutingAssembly().GetName().CodeBase; return Path.GetDirectoryName(new Uri(path).LocalPath); } private void InitializePaths() { var directoryPath = this.GetExecutingDirectory(); this.dataFilePath = Path.Combine(directoryPath, databaseName + ".mdf"); this.logFilePath = Path.Combine(directoryPath, databaseName + "_log.ldf"); } } }