Beispiel #1
0
        public void SchemaCreationIsSerializedAndIdempotent()
        {
            using TestDatabase testDb = this.CreateTestDb();
            IOrchestrationService service = this.CreateServiceWithTestDb(testDb);

            // Simulate 4 workers starting up concurrently and trying to initialize
            // the same database schema. It should just work with predictable output.
            Parallel.For(0, 4, i =>
            {
                service.CreateIfNotExistsAsync().GetAwaiter().GetResult();
            });

            ValidateDatabaseSchema(testDb);

            // Operations are expected to be serialized, making the log output deterministic.
            LogAssert.Sequence(
                this.logProvider,
                // 1st
                LogAssert.AcquiredAppLock(statusCode: 0),
                LogAssert.SprocCompleted("dt._GetVersions"),
                LogAssert.ExecutedSqlScript("schema-0.2.0.sql"),
                LogAssert.ExecutedSqlScript("logic.sql"),
                LogAssert.ExecutedSqlScript("permissions.sql"),
                LogAssert.SprocCompleted("dt._UpdateVersion"),
                // 2nd
                LogAssert.AcquiredAppLock(statusCode: 1),
                LogAssert.SprocCompleted("dt._GetVersions"),
                // 3rd
                LogAssert.AcquiredAppLock(statusCode: 1),
                LogAssert.SprocCompleted("dt._GetVersions"),
                // 4th
                LogAssert.AcquiredAppLock(statusCode: 1),
                LogAssert.SprocCompleted("dt._GetVersions"));
        }
Beispiel #2
0
        public async Task CanCreateIfNotExists(bool isDatabaseMissing)
        {
            using TestDatabase testDb = this.CreateTestDb(!isDatabaseMissing);
            IOrchestrationService service = this.CreateServiceWithTestDb(testDb);

            await service.CreateIfNotExistsAsync();

            LogAssert.NoWarningsOrErrors(this.logProvider);
            LogAssert
            .For(this.logProvider)
            .Expect(
                LogAssert.CheckedDatabase())
            .ExpectIf(
                isDatabaseMissing,
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"),
                LogAssert.CreatedDatabase(testDb.Name))
            .Expect(
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"),
                LogAssert.ExecutedSqlScript("schema-0.2.0.sql"),
                LogAssert.ExecutedSqlScript("logic.sql"),
                LogAssert.ExecutedSqlScript("permissions.sql"),
                LogAssert.SprocCompleted("dt._UpdateVersion"))
            .EndOfLog();

            ValidateDatabaseSchema(testDb);
        }
Beispiel #3
0
        public async Task CanCreateAndDropSchema(bool isDatabaseMissing)
        {
            using TestDatabase testDb = this.CreateTestDb(!isDatabaseMissing);
            IOrchestrationService service = this.CreateServiceWithTestDb(testDb);

            // Create the DB schema for the first time
            await service.CreateAsync(recreateInstanceStore : true);

            LogAssert.NoWarningsOrErrors(this.logProvider);
            LogAssert
            .For(this.logProvider)
            .Expect(
                LogAssert.CheckedDatabase())
            .ExpectIf(
                isDatabaseMissing,
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"),
                LogAssert.CreatedDatabase(testDb.Name))
            .Expect(
                LogAssert.AcquiredAppLock(),
                LogAssert.ExecutedSqlScript("drop-schema.sql"),
                LogAssert.ExecutedSqlScript("schema-0.2.0.sql"),
                LogAssert.ExecutedSqlScript("logic.sql"),
                LogAssert.ExecutedSqlScript("permissions.sql"),
                LogAssert.SprocCompleted("dt._UpdateVersion"))
            .EndOfLog();

            ValidateDatabaseSchema(testDb);

            // Create the DB schema again - should be a no-op since it already exists
            this.logProvider.Clear();
            await service.CreateIfNotExistsAsync();

            ValidateDatabaseSchema(testDb);

            // The subsequent execution should run exactly one sproc and no scripts.
            // It's important to verify this to ensure the overhead of CreateIfNotExistsAsync is very small.
            LogAssert.NoWarningsOrErrors(this.logProvider);
            LogAssert.Sequence(
                this.logProvider,
                LogAssert.CheckedDatabase(),
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"));

            // Delete the database and validate
            this.logProvider.Clear();
            await service.DeleteAsync();

            LogAssert.NoWarningsOrErrors(this.logProvider);
            LogAssert.Sequence(
                this.logProvider,
                LogAssert.AcquiredAppLock(),
                LogAssert.ExecutedSqlScript("drop-schema.sql"));

            // The previous schema validation ensures all objects are in the "dt" schema.
            // We know that all objects were successfully removed if the "dt" no longer exists.
            Assert.DoesNotContain("dt", testDb.GetSchemas());
        }
Beispiel #4
0
        public void SchemaCreationIsSerializedAndIdempotent(bool isDatabaseMissing)
        {
            using TestDatabase testDb = this.CreateTestDb(!isDatabaseMissing);
            IOrchestrationService service = this.CreateServiceWithTestDb(testDb);

            // Simulate 4 workers starting up concurrently and trying to initialize
            // the same database schema. It should just work with predictable output.
            Parallel.For(0, 4, i =>
            {
                service.CreateIfNotExistsAsync().GetAwaiter().GetResult();
            });

            ValidateDatabaseSchema(testDb);

            // Operations are expected to be serialized, making the log output deterministic.
            LogAssert
            .For(this.logProvider)
            .Expect(
                // At least 1 worker will check the database first
                LogAssert.CheckedDatabase())
            .Contains(
                // The other 3 workers will check in some non-deterministic order
                LogAssert.CheckedDatabase(),
                LogAssert.CheckedDatabase(),
                LogAssert.CheckedDatabase())
            .ContainsIf(
                // One worker may obtain the lock after another worker created the database.
                isDatabaseMissing,
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"),
                LogAssert.CreatedDatabase(testDb.Name))
            .OptionallyContainsIf(
                // Anywhere from 0 to 3 of the workers may end up attempting to create the database.
                isDatabaseMissing,
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"),
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"),
                LogAssert.CommandCompleted($"CREATE DATABASE [{testDb.Name}]"))
            .Expect(
                // 1st
                LogAssert.AcquiredAppLock(statusCode: 0),
                LogAssert.SprocCompleted("dt._GetVersions"),
                LogAssert.ExecutedSqlScript("schema-0.2.0.sql"),
                LogAssert.ExecutedSqlScript("logic.sql"),
                LogAssert.ExecutedSqlScript("permissions.sql"),
                LogAssert.SprocCompleted("dt._UpdateVersion"),
                // 2nd
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"),
                // 3rd
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"),
                // 4th
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"))
            .EndOfLog();
        }
Beispiel #5
0
        public async Task CanCreateIfNotExists()
        {
            using TestDatabase testDb = this.CreateTestDb();
            IOrchestrationService service = this.CreateServiceWithTestDb(testDb);

            await service.CreateIfNotExistsAsync();

            LogAssert.NoWarningsOrErrors(this.logProvider);
            LogAssert.Sequence(
                this.logProvider,
                LogAssert.AcquiredAppLock(),
                LogAssert.SprocCompleted("dt._GetVersions"),
                LogAssert.ExecutedSqlScript("schema-0.2.0.sql"),
                LogAssert.ExecutedSqlScript("logic.sql"),
                LogAssert.ExecutedSqlScript("permissions.sql"),
                LogAssert.SprocCompleted("dt._UpdateVersion"));

            ValidateDatabaseSchema(testDb);
        }