diff options
Diffstat (limited to 'oslo_db')
-rw-r--r-- | oslo_db/locale/en_GB/LC_MESSAGES/oslo_db.po | 8 | ||||
-rw-r--r-- | oslo_db/options.py | 5 | ||||
-rw-r--r-- | oslo_db/sqlalchemy/enginefacade.py | 12 | ||||
-rw-r--r-- | oslo_db/sqlalchemy/engines.py | 20 | ||||
-rw-r--r-- | oslo_db/sqlalchemy/test_base.py | 8 | ||||
-rw-r--r-- | oslo_db/sqlalchemy/test_migrations.py | 8 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/base.py | 35 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_async_eventlet.py | 4 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_enginefacade.py | 28 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_exc_filters.py | 30 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_migration_common.py | 2 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_migrations.py | 12 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_models.py | 4 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_provision.py | 6 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_sqlalchemy.py | 88 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_types.py | 2 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_update_match.py | 6 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_utils.py | 14 |
18 files changed, 218 insertions, 74 deletions
diff --git a/oslo_db/locale/en_GB/LC_MESSAGES/oslo_db.po b/oslo_db/locale/en_GB/LC_MESSAGES/oslo_db.po index bc5d79a..c99e59e 100644 --- a/oslo_db/locale/en_GB/LC_MESSAGES/oslo_db.po +++ b/oslo_db/locale/en_GB/LC_MESSAGES/oslo_db.po @@ -7,18 +7,18 @@ # Andreas Jaeger <jaegerandi@gmail.com>, 2016. #zanata msgid "" msgstr "" -"Project-Id-Version: oslo.db 4.6.1.dev46\n" +"Project-Id-Version: oslo.db VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-06-15 11:18+0000\n" +"POT-Creation-Date: 2018-02-20 22:06+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-06-20 06:31+0000\n" "Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n" -"Language: en-GB\n" +"Language: en_GB\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" +"X-Generator: Zanata 4.3.3\n" "Language-Team: English (United Kingdom)\n" msgid "Invalid Parameter: Encoding directive wasn't provided." diff --git a/oslo_db/options.py b/oslo_db/options.py index 8bd70a2..9a08552 100644 --- a/oslo_db/options.py +++ b/oslo_db/options.py @@ -146,6 +146,11 @@ database_opts = [ 'error before error is ' 'raised. Set to -1 to specify an infinite retry ' 'count.'), + cfg.StrOpt('connection_parameters', + default='', + help='Optional URL parameters to append onto the connection ' + 'URL at connect time; specify as ' + 'param1=value1¶m2=value2&...'), ] diff --git a/oslo_db/sqlalchemy/enginefacade.py b/oslo_db/sqlalchemy/enginefacade.py index cca694b..2b9f81e 100644 --- a/oslo_db/sqlalchemy/enginefacade.py +++ b/oslo_db/sqlalchemy/enginefacade.py @@ -149,7 +149,8 @@ class _TransactionFactory(object): 'thread_checkin': _Default(True), 'json_serializer': _Default(None), 'json_deserializer': _Default(None), - 'logging_name': _Default(None) + 'logging_name': _Default(None), + 'connection_parameters': _Default(None) } self._maker_cfg = { 'expire_on_commit': _Default(False), @@ -219,6 +220,9 @@ class _TransactionFactory(object): :param connection_debug: engine logging level, defaults to 0. set to 50 for INFO, 100 for DEBUG. + :param connection_parameters: additional parameters to append onto the + database URL query string, pass as "param1=value1¶m2=value2&..." + :param max_pool_size: max size of connection pool, uses CONF for default @@ -393,7 +397,8 @@ class _TransactionFactory(object): self._start() if mode is _WRITER: return self._writer_engine.connect() - elif self.synchronous_reader or mode is _ASYNC_READER: + elif mode is _ASYNC_READER or \ + (mode is _READER and not self.synchronous_reader): return self._reader_engine.connect() else: return self._writer_engine.connect() @@ -408,7 +413,8 @@ class _TransactionFactory(object): kw['bind'] = bind if mode is _WRITER: return self._writer_maker(**kw) - elif self.synchronous_reader or mode is _ASYNC_READER: + elif mode is _ASYNC_READER or \ + (mode is _READER and not self.synchronous_reader): return self._reader_maker(**kw) else: return self._writer_maker(**kw) diff --git a/oslo_db/sqlalchemy/engines.py b/oslo_db/sqlalchemy/engines.py index 2808ef4..05045ca 100644 --- a/oslo_db/sqlalchemy/engines.py +++ b/oslo_db/sqlalchemy/engines.py @@ -104,6 +104,21 @@ def _setup_logging(connection_debug=0): logger.setLevel(logging.WARNING) +def _extend_url_parameters(url, connection_parameters): + for key, value in six.moves.urllib.parse.parse_qs( + connection_parameters).items(): + if key in url.query: + existing = url.query[key] + if not isinstance(existing, list): + url.query[key] = existing = utils.to_list(existing) + existing.extend(value) + value = existing + else: + url.query[key] = value + if len(value) == 1: + url.query[key] = value[0] + + def _vet_url(url): if "+" not in url.drivername and not url.drivername.startswith("sqlite"): if url.drivername.startswith("mysql"): @@ -132,11 +147,14 @@ def create_engine(sql_connection, sqlite_fk=False, mysql_sql_mode=None, connection_trace=False, max_retries=10, retry_interval=10, thread_checkin=True, logging_name=None, json_serializer=None, - json_deserializer=None): + json_deserializer=None, connection_parameters=None): """Return a new SQLAlchemy engine.""" url = sqlalchemy.engine.url.make_url(sql_connection) + if connection_parameters: + _extend_url_parameters(url, connection_parameters) + _vet_url(url) engine_args = { diff --git a/oslo_db/sqlalchemy/test_base.py b/oslo_db/sqlalchemy/test_base.py index f4659e8..8c6fdbd 100644 --- a/oslo_db/sqlalchemy/test_base.py +++ b/oslo_db/sqlalchemy/test_base.py @@ -34,7 +34,9 @@ from oslo_db.sqlalchemy import provision from oslo_db.sqlalchemy import session -@debtcollector.removals.removed_class("DbFixture") +@debtcollector.removals.removed_class( + "DbFixture", + message="Please use oslo_db.sqlalchemy.test_fixtures directly") class DbFixture(fixtures.Fixture): """Basic database fixture. @@ -89,7 +91,9 @@ class DbFixture(fixtures.Fixture): self.addCleanup(self.test.enginefacade.dispose_global) -@debtcollector.removals.removed_class("DbTestCase") +@debtcollector.removals.removed_class( + "DbTestCase", + message="Please use oslo_db.sqlalchemy.test_fixtures directly") class DbTestCase(test_base.BaseTestCase): """Base class for testing of DB code. diff --git a/oslo_db/sqlalchemy/test_migrations.py b/oslo_db/sqlalchemy/test_migrations.py index d650025..4b8cb12 100644 --- a/oslo_db/sqlalchemy/test_migrations.py +++ b/oslo_db/sqlalchemy/test_migrations.py @@ -476,9 +476,10 @@ class ModelsMigrationsSync(object): if isinstance(meta_col.type, sqlalchemy.Boolean): if meta_def is None or insp_def is None: return meta_def != insp_def + insp_def = insp_def.strip("'") return not ( - isinstance(meta_def.arg, expr.True_) and insp_def == "'1'" or - isinstance(meta_def.arg, expr.False_) and insp_def == "'0'" + isinstance(meta_def.arg, expr.True_) and insp_def == "1" or + isinstance(meta_def.arg, expr.False_) and insp_def == "0" ) impl_type = meta_col.type @@ -487,7 +488,8 @@ class ModelsMigrationsSync(object): if isinstance(impl_type, (sqlalchemy.Integer, sqlalchemy.BigInteger)): if meta_def is None or insp_def is None: return meta_def != insp_def - return meta_def.arg != insp_def.split("'")[1] + insp_def = insp_def.strip("'") + return meta_def.arg != insp_def @_compare_server_default.dispatch_for('postgresql') def _compare_server_default(bind, meta_col, insp_def, meta_def): diff --git a/oslo_db/tests/sqlalchemy/base.py b/oslo_db/tests/sqlalchemy/base.py index a23f249..e07b45c 100644 --- a/oslo_db/tests/sqlalchemy/base.py +++ b/oslo_db/tests/sqlalchemy/base.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import debtcollector + from oslo_db.sqlalchemy import enginefacade from oslo_db.sqlalchemy.test_base import backend_specific # noqa from oslo_db.sqlalchemy import test_fixtures as db_fixtures @@ -26,6 +28,10 @@ class Context(object): context = Context() +@debtcollector.removals.removed_class( + "DbTestCase", + message="Do not import from oslo_db.tests! " + "Please use oslo_db.sqlalchemy.test_fixtures directly") class DbTestCase(db_fixtures.OpportunisticDBTestMixin, test_base.BaseTestCase): def setUp(self): @@ -35,9 +41,38 @@ class DbTestCase(db_fixtures.OpportunisticDBTestMixin, test_base.BaseTestCase): self.sessionmaker = enginefacade.writer.get_sessionmaker() +@debtcollector.removals.removed_class( + "MySQLOpportunisticTestCase", + message="Do not import from oslo_db.tests! " + "Please use oslo_db.sqlalchemy.test_fixtures directly") class MySQLOpportunisticTestCase(DbTestCase): FIXTURE = db_fixtures.MySQLOpportunisticFixture +@debtcollector.removals.removed_class( + "PostgreSQLOpportunisticTestCase", + message="Do not import from oslo_db.tests! " + "Please use oslo_db.sqlalchemy.test_fixtures directly") class PostgreSQLOpportunisticTestCase(DbTestCase): FIXTURE = db_fixtures.PostgresqlOpportunisticFixture + + +# NOTE (zzzeek) These test classes are **private to oslo.db**. Please +# make use of oslo_db.sqlalchemy.test_fixtures directly. + +class _DbTestCase( + db_fixtures.OpportunisticDBTestMixin, test_base.BaseTestCase): + + def setUp(self): + super(_DbTestCase, self).setUp() + + self.engine = enginefacade.writer.get_engine() + self.sessionmaker = enginefacade.writer.get_sessionmaker() + + +class _MySQLOpportunisticTestCase(_DbTestCase): + FIXTURE = db_fixtures.MySQLOpportunisticFixture + + +class _PostgreSQLOpportunisticTestCase(_DbTestCase): + FIXTURE = db_fixtures.PostgresqlOpportunisticFixture diff --git a/oslo_db/tests/sqlalchemy/test_async_eventlet.py b/oslo_db/tests/sqlalchemy/test_async_eventlet.py index 7eebed4..747601b 100644 --- a/oslo_db/tests/sqlalchemy/test_async_eventlet.py +++ b/oslo_db/tests/sqlalchemy/test_async_eventlet.py @@ -118,10 +118,10 @@ class EventletTestMixin(object): # ie: This file performs no tests by default. class MySQLEventletTestCase(EventletTestMixin, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): pass class PostgreSQLEventletTestCase(EventletTestMixin, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): pass diff --git a/oslo_db/tests/sqlalchemy/test_enginefacade.py b/oslo_db/tests/sqlalchemy/test_enginefacade.py index 91e40a1..ced9483 100644 --- a/oslo_db/tests/sqlalchemy/test_enginefacade.py +++ b/oslo_db/tests/sqlalchemy/test_enginefacade.py @@ -135,15 +135,15 @@ class MockFacadeTest(oslo_test_base.BaseTestCase): async_reader_maker = writer_maker if self.synchronous_reader: - reader_conn = async_reader_conn - reader_engine = async_reader_engine - reader_session = async_reader_session - reader_maker = async_reader_maker - else: reader_conn = writer_conn reader_engine = writer_engine reader_session = writer_session reader_maker = writer_maker + else: + reader_conn = async_reader_conn + reader_engine = async_reader_engine + reader_session = async_reader_session + reader_maker = async_reader_maker self.connections = AssertDataSource( writer_conn, reader_conn, async_reader_conn @@ -236,9 +236,9 @@ class MockFacadeTest(oslo_test_base.BaseTestCase): async_reader_engine = writer_engine if self.synchronous_reader: - reader_engine = async_reader_engine - else: reader_engine = writer_engine + else: + reader_engine = async_reader_engine engines = AssertDataSource( writer_engine, reader_engine, async_reader_engine) @@ -333,9 +333,9 @@ class MockFacadeTest(oslo_test_base.BaseTestCase): async_reader_maker = writer_maker if self.synchronous_reader: - reader_maker = async_reader_maker - else: reader_maker = writer_maker + else: + reader_maker = async_reader_maker makers = AssertDataSource( writer_maker, @@ -1335,7 +1335,7 @@ class AsyncReaderWSlaveMockFacadeTest(MockFacadeTest): slave_uri = 'some_slave_connection' -class LegacyIntegrationtest(test_base.DbTestCase): +class LegacyIntegrationtest(test_base._DbTestCase): def test_legacy_integration(self): legacy_facade = enginefacade.get_legacy_facade() @@ -1393,7 +1393,7 @@ class LegacyIntegrationtest(test_base.DbTestCase): ) -class ThreadingTest(test_base.DbTestCase): +class ThreadingTest(test_base._DbTestCase): """Test copy/pickle on new threads using real connections and sessions.""" def _assert_ctx_connection(self, context, connection): @@ -1586,7 +1586,7 @@ class ThreadingTest(test_base.DbTestCase): assert session is not session2 -class LiveFacadeTest(test_base.DbTestCase): +class LiveFacadeTest(test_base._DbTestCase): """test using live SQL with test-provisioned databases. Several of these tests require that multiple transactions run @@ -2127,12 +2127,12 @@ class LiveFacadeTest(test_base.DbTestCase): class MySQLLiveFacadeTest( - test_base.MySQLOpportunisticTestCase, LiveFacadeTest): + test_base._MySQLOpportunisticTestCase, LiveFacadeTest): pass class PGLiveFacadeTest( - test_base.PostgreSQLOpportunisticTestCase, LiveFacadeTest): + test_base._PostgreSQLOpportunisticTestCase, LiveFacadeTest): pass diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py index 9c2b417..208a40a 100644 --- a/oslo_db/tests/sqlalchemy/test_exc_filters.py +++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py @@ -251,7 +251,7 @@ class TestFallthroughsAndNonDBAPI(TestsExceptionFilter): class TestNonExistentConstraint( _SQLAExceptionMatcher, - test_base.DbTestCase): + test_base._DbTestCase): def setUp(self): super(TestNonExistentConstraint, self).setUp() @@ -269,7 +269,7 @@ class TestNonExistentConstraint( class TestNonExistentConstraintPostgreSQL( TestNonExistentConstraint, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -293,7 +293,7 @@ class TestNonExistentConstraintPostgreSQL( class TestNonExistentConstraintMySQL( TestNonExistentConstraint, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -317,7 +317,7 @@ class TestNonExistentConstraintMySQL( class TestNonExistentTable( _SQLAExceptionMatcher, - test_base.DbTestCase): + test_base._DbTestCase): def setUp(self): super(TestNonExistentTable, self).setUp() @@ -348,7 +348,7 @@ class TestNonExistentTable( class TestNonExistentTablePostgreSQL( TestNonExistentTable, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -367,7 +367,7 @@ class TestNonExistentTablePostgreSQL( class TestNonExistentTableMySQL( TestNonExistentTable, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -385,7 +385,7 @@ class TestNonExistentTableMySQL( class TestNonExistentDatabase( _SQLAExceptionMatcher, - test_base.DbTestCase): + test_base._DbTestCase): def setUp(self): super(TestNonExistentDatabase, self).setUp() @@ -411,7 +411,7 @@ class TestNonExistentDatabase( class TestNonExistentDatabaseMySQL( TestNonExistentDatabase, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -430,7 +430,7 @@ class TestNonExistentDatabaseMySQL( class TestNonExistentDatabasePostgreSQL( TestNonExistentDatabase, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( @@ -446,7 +446,7 @@ class TestNonExistentDatabasePostgreSQL( ) -class TestReferenceErrorSQLite(_SQLAExceptionMatcher, test_base.DbTestCase): +class TestReferenceErrorSQLite(_SQLAExceptionMatcher, test_base._DbTestCase): def setUp(self): super(TestReferenceErrorSQLite, self).setUp() @@ -520,7 +520,7 @@ class TestReferenceErrorSQLite(_SQLAExceptionMatcher, test_base.DbTestCase): class TestReferenceErrorPostgreSQL(TestReferenceErrorSQLite, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): def test_raise(self): params = {'id': 1, 'foo_id': 2} matched = self.assertRaises( @@ -571,7 +571,7 @@ class TestReferenceErrorPostgreSQL(TestReferenceErrorSQLite, class TestReferenceErrorMySQL(TestReferenceErrorSQLite, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): def test_raise(self): matched = self.assertRaises( exception.DBReferenceError, @@ -632,7 +632,7 @@ class TestReferenceErrorMySQL(TestReferenceErrorSQLite, self.assertEqual("resource_foo", matched.key_table) -class TestExceptionCauseMySQLSavepoint(test_base.MySQLOpportunisticTestCase): +class TestExceptionCauseMySQLSavepoint(test_base._MySQLOpportunisticTestCase): def setUp(self): super(TestExceptionCauseMySQLSavepoint, self).setUp() @@ -762,7 +762,7 @@ class TestExceptionCauseMySQLSavepoint(test_base.MySQLOpportunisticTestCase): assert False, "no exception raised" -class TestDBDataErrorSQLite(_SQLAExceptionMatcher, test_base.DbTestCase): +class TestDBDataErrorSQLite(_SQLAExceptionMatcher, test_base._DbTestCase): def setUp(self): super(TestDBDataErrorSQLite, self).setUp() @@ -1084,7 +1084,7 @@ class TestDataError(TestsExceptionFilter): self.DataError) -class IntegrationTest(test_base.DbTestCase): +class IntegrationTest(test_base._DbTestCase): """Test an actual error-raising round trips against the database.""" def setUp(self): diff --git a/oslo_db/tests/sqlalchemy/test_migration_common.py b/oslo_db/tests/sqlalchemy/test_migration_common.py index 3f5f8ff..377c6a9 100644 --- a/oslo_db/tests/sqlalchemy/test_migration_common.py +++ b/oslo_db/tests/sqlalchemy/test_migration_common.py @@ -28,7 +28,7 @@ from oslo_db.tests.sqlalchemy import base as test_base from oslo_db.tests import utils as test_utils -class TestMigrationCommon(test_base.DbTestCase): +class TestMigrationCommon(test_base._DbTestCase): def setUp(self): super(TestMigrationCommon, self).setUp() diff --git a/oslo_db/tests/sqlalchemy/test_migrations.py b/oslo_db/tests/sqlalchemy/test_migrations.py index d42812d..62cbdfb 100644 --- a/oslo_db/tests/sqlalchemy/test_migrations.py +++ b/oslo_db/tests/sqlalchemy/test_migrations.py @@ -180,7 +180,7 @@ class TestWalkVersions(test.BaseTestCase, migrate.WalkVersionsMixin): self.assertEqual(upgraded, self.migrate_up.call_args_list) -class ModelsMigrationSyncMixin(test_base.DbTestCase): +class ModelsMigrationSyncMixin(test_base._DbTestCase): def setUp(self): super(ModelsMigrationSyncMixin, self).setUp() @@ -359,7 +359,7 @@ class ModelsMigrationSyncMixin(test_base.DbTestCase): class ModelsMigrationsSyncMysql(ModelsMigrationSyncMixin, migrate.ModelsMigrationsSync, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): def test_models_not_sync(self): self._test_models_not_sync() @@ -370,7 +370,7 @@ class ModelsMigrationsSyncMysql(ModelsMigrationSyncMixin, class ModelsMigrationsSyncPsql(ModelsMigrationSyncMixin, migrate.ModelsMigrationsSync, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): def test_models_not_sync(self): self._test_models_not_sync() @@ -379,7 +379,7 @@ class ModelsMigrationsSyncPsql(ModelsMigrationSyncMixin, self._test_models_not_sync_filtered() -class TestOldCheckForeignKeys(test_base.DbTestCase): +class TestOldCheckForeignKeys(test_base._DbTestCase): def setUp(self): super(TestOldCheckForeignKeys, self).setUp() @@ -557,10 +557,10 @@ class TestOldCheckForeignKeys(test_base.DbTestCase): class PGTestOldCheckForeignKeys( - TestOldCheckForeignKeys, test_base.PostgreSQLOpportunisticTestCase): + TestOldCheckForeignKeys, test_base._PostgreSQLOpportunisticTestCase): pass class MySQLTestOldCheckForeignKeys( - TestOldCheckForeignKeys, test_base.MySQLOpportunisticTestCase): + TestOldCheckForeignKeys, test_base._MySQLOpportunisticTestCase): pass diff --git a/oslo_db/tests/sqlalchemy/test_models.py b/oslo_db/tests/sqlalchemy/test_models.py index 0b0f6d8..540f4f8 100644 --- a/oslo_db/tests/sqlalchemy/test_models.py +++ b/oslo_db/tests/sqlalchemy/test_models.py @@ -30,7 +30,7 @@ from oslo_db.tests.sqlalchemy import base as test_base BASE = declarative_base() -class ModelBaseTest(test_base.DbTestCase): +class ModelBaseTest(test_base._DbTestCase): def setUp(self): super(ModelBaseTest, self).setUp() self.mb = models.ModelBase() @@ -191,7 +191,7 @@ class SoftDeletedModel(BASE, models.ModelBase, models.SoftDeleteMixin): smth = Column('smth', String(255)) -class SoftDeleteMixinTest(test_base.DbTestCase): +class SoftDeleteMixinTest(test_base._DbTestCase): def setUp(self): super(SoftDeleteMixinTest, self).setUp() diff --git a/oslo_db/tests/sqlalchemy/test_provision.py b/oslo_db/tests/sqlalchemy/test_provision.py index 8f0928f..d985595 100644 --- a/oslo_db/tests/sqlalchemy/test_provision.py +++ b/oslo_db/tests/sqlalchemy/test_provision.py @@ -27,7 +27,7 @@ from oslo_db.sqlalchemy import utils from oslo_db.tests.sqlalchemy import base as test_base -class DropAllObjectsTest(test_base.DbTestCase): +class DropAllObjectsTest(test_base._DbTestCase): def setUp(self): super(DropAllObjectsTest, self).setUp() @@ -138,12 +138,12 @@ class BackendNotAvailableTest(oslo_test_base.BaseTestCase): class MySQLDropAllObjectsTest( - DropAllObjectsTest, test_base.MySQLOpportunisticTestCase): + DropAllObjectsTest, test_base._MySQLOpportunisticTestCase): pass class PostgreSQLDropAllObjectsTest( - DropAllObjectsTest, test_base.PostgreSQLOpportunisticTestCase): + DropAllObjectsTest, test_base._PostgreSQLOpportunisticTestCase): pass diff --git a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py index 4ae2506..9ebf58c 100644 --- a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py +++ b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py @@ -52,7 +52,7 @@ class RegexpTable(BASE, models.ModelBase): bar = Column(String(255)) -class RegexpFilterTestCase(test_base.DbTestCase): +class RegexpFilterTestCase(test_base._DbTestCase): def setUp(self): super(RegexpFilterTestCase, self).setUp() @@ -90,7 +90,7 @@ class RegexpFilterTestCase(test_base.DbTestCase): self._test_regexp_filter(u'♦', []) -class SQLiteSavepointTest(test_base.DbTestCase): +class SQLiteSavepointTest(test_base._DbTestCase): def setUp(self): super(SQLiteSavepointTest, self).setUp() meta = MetaData() @@ -213,7 +213,80 @@ class FakeDB2Engine(object): pass -class MySQLDefaultModeTestCase(test_base.MySQLOpportunisticTestCase): +class QueryParamTest(test_base.DbTestCase): + def _fixture(self): + from sqlalchemy import create_engine + + def _mock_create_engine(*arg, **kw): + return create_engine("sqlite://") + + return mock.patch( + "oslo_db.sqlalchemy.engines.sqlalchemy.create_engine", + side_effect=_mock_create_engine) + + def test_add_assorted_params(self): + with self._fixture() as ce: + engines.create_engine( + "mysql+pymysql://foo:bar@bat", + connection_parameters="foo=bar&bat=hoho&bat=param2") + + self.assertEqual( + ce.mock_calls[0][1][0].query, + {'bat': ['hoho', 'param2'], 'foo': 'bar'} + ) + + def test_add_no_params(self): + with self._fixture() as ce: + engines.create_engine( + "mysql+pymysql://foo:bar@bat") + + self.assertEqual( + ce.mock_calls[0][1][0].query, + {} + ) + + def test_combine_params(self): + with self._fixture() as ce: + engines.create_engine( + "mysql+pymysql://foo:bar@bat/" + "?charset=utf8¶m_file=tripleo.cnf", + connection_parameters="plugin=sqlalchemy_collectd&" + "collectd_host=127.0.0.1&" + "bind_host=192.168.1.5") + + self.assertEqual( + ce.mock_calls[0][1][0].query, + { + 'bind_host': '192.168.1.5', + 'charset': 'utf8', + 'collectd_host': '127.0.0.1', + 'param_file': 'tripleo.cnf', + 'plugin': 'sqlalchemy_collectd' + } + ) + + def test_combine_multi_params(self): + with self._fixture() as ce: + engines.create_engine( + "mysql+pymysql://foo:bar@bat/" + "?charset=utf8¶m_file=tripleo.cnf&plugin=connmon", + connection_parameters="plugin=sqlalchemy_collectd&" + "collectd_host=127.0.0.1&" + "bind_host=192.168.1.5") + + self.assertEqual( + ce.mock_calls[0][1][0].query, + { + 'bind_host': '192.168.1.5', + 'charset': 'utf8', + 'collectd_host': '127.0.0.1', + 'param_file': 'tripleo.cnf', + 'plugin': ['connmon', 'sqlalchemy_collectd'] + } + ) + + +class MySQLDefaultModeTestCase(test_base._MySQLOpportunisticTestCase): def test_default_is_traditional(self): with self.engine.connect() as conn: sql_mode = conn.execute( @@ -223,7 +296,7 @@ class MySQLDefaultModeTestCase(test_base.MySQLOpportunisticTestCase): self.assertIn("TRADITIONAL", sql_mode) -class MySQLModeTestCase(test_base.MySQLOpportunisticTestCase): +class MySQLModeTestCase(test_base._MySQLOpportunisticTestCase): def __init__(self, *args, **kwargs): super(MySQLModeTestCase, self).__init__(*args, **kwargs) @@ -357,6 +430,7 @@ class EngineFacadeTestCase(oslo_test.BaseTestCase): thread_checkin=mock.ANY, json_serializer=None, json_deserializer=None, + connection_parameters='', logging_name=mock.ANY, ) get_maker.assert_called_once_with(engine=create_engine(), @@ -438,7 +512,7 @@ class SQLiteConnectTest(oslo_test.BaseTestCase): ) -class MysqlConnectTest(test_base.MySQLOpportunisticTestCase): +class MysqlConnectTest(test_base._MySQLOpportunisticTestCase): def _fixture(self, sql_mode): return session.create_engine(self.engine.url, mysql_sql_mode=sql_mode) @@ -716,7 +790,7 @@ class CreateEngineTest(oslo_test.BaseTestCase): ) -class ProcessGuardTest(test_base.DbTestCase): +class ProcessGuardTest(test_base._DbTestCase): def test_process_guard(self): self.engine.dispose() @@ -744,7 +818,7 @@ class ProcessGuardTest(test_base.DbTestCase): self.assertEqual(new_dbapi_id, newer_dbapi_id) -class PatchStacktraceTest(test_base.DbTestCase): +class PatchStacktraceTest(test_base._DbTestCase): def test_trace(self): engine = self.engine diff --git a/oslo_db/tests/sqlalchemy/test_types.py b/oslo_db/tests/sqlalchemy/test_types.py index 6103ce3..8eeb401 100644 --- a/oslo_db/tests/sqlalchemy/test_types.py +++ b/oslo_db/tests/sqlalchemy/test_types.py @@ -33,7 +33,7 @@ class JsonTable(BASE, models.ModelBase): json = Column(types.JsonEncodedType) -class JsonTypesTestCase(test_base.DbTestCase): +class JsonTypesTestCase(test_base._DbTestCase): def setUp(self): super(JsonTypesTestCase, self).setUp() JsonTable.__table__.create(self.engine) diff --git a/oslo_db/tests/sqlalchemy/test_update_match.py b/oslo_db/tests/sqlalchemy/test_update_match.py index c876bf3..36ebf73 100644 --- a/oslo_db/tests/sqlalchemy/test_update_match.py +++ b/oslo_db/tests/sqlalchemy/test_update_match.py @@ -85,7 +85,7 @@ class ManufactureCriteriaTest(oslo_test_base.BaseTestCase): ) -class UpdateMatchTest(test_base.DbTestCase): +class UpdateMatchTest(test_base._DbTestCase): def setUp(self): super(UpdateMatchTest, self).setUp() Base.metadata.create_all(self.engine) @@ -435,11 +435,11 @@ class UpdateMatchTest(test_base.DbTestCase): class PGUpdateMatchTest( UpdateMatchTest, - test_base.PostgreSQLOpportunisticTestCase): + test_base._PostgreSQLOpportunisticTestCase): pass class MySQLUpdateMatchTest( UpdateMatchTest, - test_base.MySQLOpportunisticTestCase): + test_base._MySQLOpportunisticTestCase): pass diff --git a/oslo_db/tests/sqlalchemy/test_utils.py b/oslo_db/tests/sqlalchemy/test_utils.py index d6fb3a3..7f44ef5 100644 --- a/oslo_db/tests/sqlalchemy/test_utils.py +++ b/oslo_db/tests/sqlalchemy/test_utils.py @@ -547,7 +547,7 @@ class TestPaginateQueryActualSQL(test_base.BaseTestCase): ) -class TestMigrationUtils(db_test_base.DbTestCase): +class TestMigrationUtils(db_test_base._DbTestCase): """Class for testing utils that are used in db migrations.""" @@ -957,14 +957,14 @@ class TestMigrationUtils(db_test_base.DbTestCase): class PostgresqlTestMigrations(TestMigrationUtils, - db_test_base.PostgreSQLOpportunisticTestCase): + db_test_base._PostgreSQLOpportunisticTestCase): """Test migrations on PostgreSQL.""" pass class MySQLTestMigrations(TestMigrationUtils, - db_test_base.MySQLOpportunisticTestCase): + db_test_base._MySQLOpportunisticTestCase): """Test migrations on MySQL.""" pass @@ -1146,7 +1146,7 @@ class TestModelQuery(test_base.BaseTestCase): self.session.query.assert_called_with(MyModel.id) -class TestUtils(db_test_base.DbTestCase): +class TestUtils(db_test_base._DbTestCase): def setUp(self): super(TestUtils, self).setUp() meta = MetaData(bind=self.engine) @@ -1222,12 +1222,12 @@ class TestUtils(db_test_base.DbTestCase): class TestUtilsMysqlOpportunistically( - TestUtils, db_test_base.MySQLOpportunisticTestCase): + TestUtils, db_test_base._MySQLOpportunisticTestCase): pass class TestUtilsPostgresqlOpportunistically( - TestUtils, db_test_base.PostgreSQLOpportunisticTestCase): + TestUtils, db_test_base._PostgreSQLOpportunisticTestCase): pass @@ -1536,7 +1536,7 @@ class TestDialectFunctionDispatcher(test_base.BaseTestCase): ) -class TestGetInnoDBTables(db_test_base.MySQLOpportunisticTestCase): +class TestGetInnoDBTables(db_test_base._MySQLOpportunisticTestCase): def test_all_tables_use_innodb(self): self.engine.execute("CREATE TABLE customers " |