예제 #1
0
        // It's internal because `Umbraco.Core.Persistence.LocalDb` is internal
        internal LocalDbTestDatabase(TestDatabaseSettings settings, ILoggerFactory loggerFactory, LocalDb localDb, string filesPath, IUmbracoDatabaseFactory dbFactory)
        {
            _loggerFactory   = loggerFactory;
            _databaseFactory = dbFactory;

            _settings   = settings;
            _localDb    = localDb;
            s_filesPath = filesPath;

            Instance = this; // For GlobalSetupTeardown.cs

            var counter = 0;

            var schema = Enumerable.Range(0, _settings.SchemaDatabaseCount)
                         .Select(x => TestDbMeta.CreateWithoutConnectionString($"{DatabaseName}-{++counter}", false));

            var empty = Enumerable.Range(0, _settings.EmptyDatabasesCount)
                        .Select(x => TestDbMeta.CreateWithoutConnectionString($"{DatabaseName}-{++counter}", true));

            _testDatabases = schema.Concat(empty).ToList();

            s_localDbInstance = _localDb.GetInstance(InstanceName);
            if (s_localDbInstance != null)
            {
                return;
            }

            if (_localDb.CreateInstance(InstanceName) == false)
            {
                throw new Exception("Failed to create a LocalDb instance.");
            }

            s_localDbInstance = _localDb.GetInstance(InstanceName);
        }
예제 #2
0
        protected override void Initialize()
        {
            string tempName = Guid.NewGuid().ToString("N");

            s_localDbInstance.CreateDatabase(tempName, s_filesPath);
            s_localDbInstance.DetachDatabase(tempName);

            _prepareQueue     = new BlockingCollection <TestDbMeta>();
            _readySchemaQueue = new BlockingCollection <TestDbMeta>();
            _readyEmptyQueue  = new BlockingCollection <TestDbMeta>();

            for (int i = 0; i < _testDatabases.Count; i++)
            {
                TestDbMeta meta   = _testDatabases[i];
                bool       isLast = i == _testDatabases.Count - 1;

                _localDb.CopyDatabaseFiles(tempName, s_filesPath, targetDatabaseName: meta.Name, overwrite: true, delete: isLast);
                meta.ConnectionString = s_localDbInstance.GetAttachedConnectionString(meta.Name, s_filesPath);
                _prepareQueue.Add(meta);
            }

            for (int i = 0; i < _settings.PrepareThreadCount; i++)
            {
                var thread = new Thread(PrepareDatabase);
                thread.Start();
            }
        }
        private void Drop(TestDbMeta meta)
        {
            using (var connection = new SqlConnection(_settings.SQLServerMasterConnectionString))
            {
                connection.Open();
                using (SqlCommand command = connection.CreateCommand())
                {
                    SetCommand(command, "select count(1) from sys.databases where name = @0", meta.Name);
                    var records = (int)command.ExecuteScalar();
                    if (records == 0)
                    {
                        return;
                    }

                    string sql = $@"
                        ALTER DATABASE {LocalDb.QuotedName(meta.Name)}
                        SET SINGLE_USER 
                        WITH ROLLBACK IMMEDIATE";
                    SetCommand(command, sql);
                    command.ExecuteNonQuery();

                    SetCommand(command, $@"DROP DATABASE {LocalDb.QuotedName(meta.Name)}");
                    command.ExecuteNonQuery();
                }
            }
        }
예제 #4
0
 private void CreateDatabase(TestDbMeta meta)
 {
     using (var connection = new SqlConnection(_masterConnectionString))
     {
         connection.Open();
         using (SqlCommand command = connection.CreateCommand())
         {
             SetCommand(command, $@"CREATE DATABASE {LocalDb.QuotedName(meta.Name)}");
             command.ExecuteNonQuery();
         }
     }
 }
        private void ConfigureTestDatabaseFactory(TestDbMeta meta, IUmbracoDatabaseFactory factory, IRuntimeState state)
        {
            ILogger <UmbracoIntegrationTest> log = Services.GetRequiredService <ILogger <UmbracoIntegrationTest> >();

            log.LogInformation($"ConfigureTestDatabaseFactory - Using test database: [{meta.Name}] - IsEmpty: [{meta.IsEmpty}]");

            // It's just been pulled from container and wasn't used to create test database
            Assert.IsFalse(factory.Configured);

            factory.Configure(meta.ConnectionString, Constants.DatabaseProviders.SqlServer);
            state.DetermineRuntimeLevel();
            log.LogInformation($"ConfigureTestDatabaseFactory - Determined RuntimeLevel: [{state.Level}]");
        }
예제 #6
0
        private void RebuildSchemaFirstTime(TestDbMeta meta)
        {
            _databaseFactory.Configure(meta.ConnectionString, Constants.DatabaseProviders.SqlServer);

            using (var database = (UmbracoDatabase)_databaseFactory.CreateDatabase())
            {
                database.LogCommands = true;

                using (NPoco.ITransaction transaction = database.GetTransaction())
                {
                    var schemaCreator = new DatabaseSchemaCreator(database, _loggerFactory.CreateLogger <DatabaseSchemaCreator>(), _loggerFactory, new UmbracoVersion(), Mock.Of <IEventAggregator>());
                    schemaCreator.InitializeDatabaseSchema();

                    transaction.Complete();

                    _cachedDatabaseInitCommands = database.Commands.ToArray();
                }
            }
        }
예제 #7
0
        private void Drop(TestDbMeta meta)
        {
            using (var connection = new SqlConnection(_masterConnectionString))
            {
                connection.Open();
                using (SqlCommand command = connection.CreateCommand())
                {
                    string sql = $@"
                        ALTER DATABASE{LocalDb.QuotedName(meta.Name)}
                        SET SINGLE_USER
                        WITH ROLLBACK IMMEDIATE";
                    SetCommand(command, sql);
                    command.ExecuteNonQuery();

                    SetCommand(command, $@"DROP DATABASE {LocalDb.QuotedName(meta.Name)}");
                    command.ExecuteNonQuery();
                }
            }
        }
        public SqlServerTestDatabase(TestDatabaseSettings settings, ILoggerFactory loggerFactory,
                                     IUmbracoDatabaseFactory databaseFactory)
        {
            _loggerFactory   = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
            _databaseFactory = databaseFactory ?? throw new ArgumentNullException(nameof(databaseFactory));

            _settings = settings;

            var counter = 0;

            var schema = Enumerable.Range(0, _settings.SchemaDatabaseCount)
                         .Select(x => TestDbMeta.CreateWithMasterConnectionString($"{DatabaseName}-{++counter}", false,
                                                                                  _settings.SQLServerMasterConnectionString));

            var empty = Enumerable.Range(0, _settings.EmptyDatabasesCount)
                        .Select(x => TestDbMeta.CreateWithMasterConnectionString($"{DatabaseName}-{++counter}", true,
                                                                                 _settings.SQLServerMasterConnectionString));

            _testDatabases = schema.Concat(empty).ToList();
        }
예제 #9
0
        public SqlDeveloperTestDatabase(TestDatabaseSettings settings, ILoggerFactory loggerFactory, IUmbracoDatabaseFactory databaseFactory, string masterConnectionString)
        {
            _loggerFactory   = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
            _databaseFactory = databaseFactory ?? throw new ArgumentNullException(nameof(databaseFactory));

            _settings = settings;
            _masterConnectionString = masterConnectionString;

            var counter = 0;

            var schema = Enumerable.Range(0, _settings.SchemaDatabaseCount)
                         .Select(x => TestDbMeta.CreateWithMasterConnectionString($"{DatabaseName}-{++counter}", false, masterConnectionString));

            var empty = Enumerable.Range(0, _settings.EmptyDatabasesCount)
                        .Select(x => TestDbMeta.CreateWithMasterConnectionString($"{DatabaseName}-{++counter}", true, masterConnectionString));

            _testDatabases = schema.Concat(empty).ToList();

            Instance = this; // For GlobalSetupTeardown.cs
        }
예제 #10
0
 public void Detach(TestDbMeta meta)
 {
     _prepareQueue.TryAdd(meta);
 }
        /// <summary>
        /// Creates a LocalDb instance to use for the test
        /// </summary>
        private void SetupTestDatabase(
            TestUmbracoDatabaseFactoryProvider testUmbracoDatabaseFactoryProvider,
            IUmbracoDatabaseFactory databaseFactory,
            ILoggerFactory loggerFactory,
            IRuntimeState runtimeState,
            string workingDirectory)
        {
            if (TestOptions.Database == UmbracoTestOptions.Database.None)
            {
                return;
            }

            // need to manually register this factory
            DbProviderFactories.RegisterFactory(Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance);

            string dbFilePath = Path.Combine(workingDirectory, "LocalDb");

            ITestDatabase db = GetOrCreateDatabase(dbFilePath, loggerFactory, testUmbracoDatabaseFactoryProvider);

            switch (TestOptions.Database)
            {
            case UmbracoTestOptions.Database.NewSchemaPerTest:

                // New DB + Schema
                TestDbMeta newSchemaDbMeta = db.AttachSchema();

                // Add teardown callback
                OnTestTearDown(() => db.Detach(newSchemaDbMeta));

                ConfigureTestDatabaseFactory(newSchemaDbMeta, databaseFactory, runtimeState);

                Assert.AreEqual(RuntimeLevel.Run, runtimeState.Level);

                break;

            case UmbracoTestOptions.Database.NewEmptyPerTest:
                TestDbMeta newEmptyDbMeta = db.AttachEmpty();

                // Add teardown callback
                OnTestTearDown(() => db.Detach(newEmptyDbMeta));

                ConfigureTestDatabaseFactory(newEmptyDbMeta, databaseFactory, runtimeState);

                Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);

                break;

            case UmbracoTestOptions.Database.NewSchemaPerFixture:
                // Only attach schema once per fixture
                // Doing it more than once will block the process since the old db hasn't been detached
                // and it would be the same as NewSchemaPerTest even if it didn't block
                if (_firstTestInFixture)
                {
                    // New DB + Schema
                    TestDbMeta newSchemaFixtureDbMeta = db.AttachSchema();
                    s_fixtureDbMeta = newSchemaFixtureDbMeta;

                    // Add teardown callback
                    OnFixtureTearDown(() => db.Detach(newSchemaFixtureDbMeta));
                }

                ConfigureTestDatabaseFactory(s_fixtureDbMeta, databaseFactory, runtimeState);

                break;

            case UmbracoTestOptions.Database.NewEmptyPerFixture:
                // Only attach schema once per fixture
                // Doing it more than once will block the process since the old db hasn't been detached
                // and it would be the same as NewSchemaPerTest even if it didn't block
                if (_firstTestInFixture)
                {
                    // New DB + Schema
                    TestDbMeta newEmptyFixtureDbMeta = db.AttachEmpty();
                    s_fixtureDbMeta = newEmptyFixtureDbMeta;

                    // Add teardown callback
                    OnFixtureTearDown(() => db.Detach(newEmptyFixtureDbMeta));
                }

                ConfigureTestDatabaseFactory(s_fixtureDbMeta, databaseFactory, runtimeState);

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(TestOptions), TestOptions, null);
            }
        }