def test_models_sync(self): # recent versions of sqlalchemy and alembic are needed for running of # this test, but we already have them in requirements try: pkg.require('sqlalchemy>=0.8.4', 'alembic>=0.6.2') except (pkg.VersionConflict, pkg.DistributionNotFound) as e: self.skipTest('sqlalchemy>=0.8.4 and alembic>=0.6.3 are required' ' for running of this test: %s' % e) # drop all objects after a test run engine = self.get_engine() backend = provision.Backend(engine.name, engine.url) self.addCleanup(functools.partial(backend.drop_all_objects, engine)) # run migration scripts self.db_sync(self.get_engine()) with self.get_engine().connect() as conn: opts = { 'include_object': self.include_object, 'compare_type': self.compare_type, 'compare_server_default': self.compare_server_default, } mc = alembic.migration.MigrationContext.configure(conn, opts=opts) # compare schemas and fail with diff, if it's not empty diff = self.filter_metadata_diff( alembic.autogenerate.compare_metadata(mc, self.get_metadata())) if diff: msg = pprint.pformat(diff, indent=2, width=20) self.fail("Models and migration scripts aren't in sync:\n%s" % msg)
def test_skip_no_dbapi_legacy(self): class FakeDatabaseOpportunisticFixture( legacy_test_base.DbFixture, ): DRIVER = 'postgresql' class SomeTest(legacy_test_base.DbTestCase): FIXTURE = FakeDatabaseOpportunisticFixture def runTest(self): pass st = SomeTest() # patch in replacement lookup dictionaries to avoid # leaking from/to other tests with mock.patch( "oslo_db.sqlalchemy.provision." "Backend.backends_by_database_type", {"postgresql": provision.Backend("postgresql", "postgresql://")}): st._database_resources = {} st._db_not_available = {} st._schema_resources = {} with mock.patch("sqlalchemy.create_engine", mock.Mock(side_effect=ImportError())): self.assertEqual([], st.resources) ex = self.assertRaises(self.skipException, st.setUp) self.assertEqual( "Backend 'postgresql' is unavailable: No DBAPI installed", str(ex))
def test_cant_connect(self): backend = provision.Backend( "postgresql", "postgresql+nosuchdbapi://hostname/dsn") with mock.patch( "sqlalchemy.create_engine", mock.Mock(return_value=mock.Mock(connect=mock.Mock( side_effect=sa_exc.OperationalError( "can't connect", None, None)) )) ): # NOTE(zzzeek): Call and test the _verify function twice, as it # exercises a different code path on subsequent runs vs. # the first run ex = self.assertRaises( exception.BackendNotAvailable, backend._verify) self.assertEqual( "Backend 'postgresql+nosuchdbapi' is unavailable: " "Could not connect", str(ex)) ex = self.assertRaises( exception.BackendNotAvailable, backend._verify) self.assertEqual( "Backend 'postgresql+nosuchdbapi' is unavailable: " "Could not connect", str(ex))
def test_no_dbapi(self): backend = provision.Backend("postgresql", "postgresql+nosuchdbapi://hostname/dsn") with mock.patch("sqlalchemy.create_engine", mock.Mock(side_effect=ImportError("nosuchdbapi"))): # NOTE(zzzeek): Call and test the _verify function twice, as it # exercises a different code path on subsequent runs vs. # the first run ex = self.assertRaises(exception.BackendNotAvailable, backend._verify) self.assertEqual( "Backend 'postgresql+nosuchdbapi' is unavailable: " "No DBAPI installed", str(ex)) ex = self.assertRaises(exception.BackendNotAvailable, backend._verify) self.assertEqual( "Backend 'postgresql+nosuchdbapi' is unavailable: " "No DBAPI installed", str(ex))
def test_models_sync(self): # drop all objects after a test run engine = self.get_engine() backend = provision.Backend(engine.name, engine.url) self.addCleanup(functools.partial(backend.drop_all_objects, engine)) # run migration scripts self.db_sync(self.get_engine()) with self.get_engine().connect() as conn: opts = { 'include_object': self.include_object, 'compare_type': self.compare_type, 'compare_server_default': self.compare_server_default, } mc = alembic.migration.MigrationContext.configure(conn, opts=opts) # compare schemas and fail with diff, if it's not empty diff = self.filter_metadata_diff( alembic.autogenerate.compare_metadata(mc, self.get_metadata())) if diff: msg = pprint.pformat(diff, indent=2, width=20) self.fail("Models and migration scripts aren't in sync:\n%s" % msg)