diff options
Diffstat (limited to 'oslo_db/tests/sqlalchemy/test_ndb.py')
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_ndb.py | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/oslo_db/tests/sqlalchemy/test_ndb.py b/oslo_db/tests/sqlalchemy/test_ndb.py new file mode 100644 index 0000000..a5a811b --- /dev/null +++ b/oslo_db/tests/sqlalchemy/test_ndb.py @@ -0,0 +1,176 @@ +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +"""Tests for MySQL Cluster (NDB) Support.""" + +import logging + +import mock + +from oslo_db import exception +from oslo_db.sqlalchemy import enginefacade +from oslo_db.sqlalchemy import engines +from oslo_db.sqlalchemy import ndb +from oslo_db.sqlalchemy import test_fixtures +from oslo_db.sqlalchemy import utils + +from oslotest import base as test_base + +from sqlalchemy import Column +from sqlalchemy import Integer +from sqlalchemy import MetaData +from sqlalchemy import String +from sqlalchemy import Table +from sqlalchemy import Text + +from sqlalchemy import create_engine +from sqlalchemy import schema + +from sqlalchemy.dialects.mysql.types import TINYTEXT + +LOG = logging.getLogger(__name__) + +_MOCK_CONNECTION = 'mysql+pymysql://' +_TEST_TABLE = Table("test_ndb", MetaData(), + Column('id', Integer, primary_key=True), + Column('test1', ndb.AutoStringTinyText(255)), + Column('test2', ndb.AutoStringText(4096)), + Column('test3', ndb.AutoStringSize(255, 64)), + mysql_engine='InnoDB') + + +class NDBMockTestBase(test_base.BaseTestCase): + def setUp(self): + super(NDBMockTestBase, self).setUp() + mock_dbapi = mock.Mock() + self.test_engine = test_engine = create_engine( + _MOCK_CONNECTION, module=mock_dbapi) + test_engine.dialect._oslodb_enable_ndb_support = True + ndb.init_ndb_events(test_engine) + + +class NDBEventTestCase(NDBMockTestBase): + + def test_ndb_createtable_override(self): + test_engine = self.test_engine + self.assertRegex( + str(schema.CreateTable(_TEST_TABLE).compile( + dialect=test_engine.dialect)), + "ENGINE=NDBCLUSTER") + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_engine_override(self): + test_engine = self.test_engine + statement = "ENGINE=InnoDB" + for fn in test_engine.dispatch.before_cursor_execute: + statement, dialect = fn( + mock.Mock(), mock.Mock(), statement, {}, mock.Mock(), False) + self.assertEqual(statement, "ENGINE=NDBCLUSTER") + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_savepoint_override(self): + test_engine = self.test_engine + statement = "SAVEPOINT xyx" + for fn in test_engine.dispatch.before_cursor_execute: + statement, dialect = fn( + mock.Mock(), mock.Mock(), statement, {}, mock.Mock(), False) + self.assertEqual(statement, + "SET @oslo_db_ndb_savepoint_rollback_disabled = 0;") + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_rollback_override(self): + test_engine = self.test_engine + statement = "ROLLBACK TO SAVEPOINT xyz" + for fn in test_engine.dispatch.before_cursor_execute: + statement, dialect = fn( + mock.Mock(), mock.Mock(), statement, {}, mock.Mock(), False) + self.assertEqual(statement, + "SET @oslo_db_ndb_savepoint_rollback_disabled = 0;") + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_rollback_release_override(self): + test_engine = self.test_engine + statement = "RELEASE SAVEPOINT xyz" + for fn in test_engine.dispatch.before_cursor_execute: + statement, dialect = fn( + mock.Mock(), mock.Mock(), statement, {}, mock.Mock(), False) + self.assertEqual(statement, + "SET @oslo_db_ndb_savepoint_rollback_disabled = 0;") + test_engine.dialect._oslodb_enable_ndb_support = False + + +class NDBDatatypesTestCase(NDBMockTestBase): + def test_ndb_autostringtinytext(self): + test_engine = self.test_engine + self.assertEqual("TINYTEXT", + str(ndb.AutoStringTinyText(255).compile( + dialect=test_engine.dialect))) + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_autostringtext(self): + test_engine = self.test_engine + self.assertEqual("TEXT", + str(ndb.AutoStringText(4096).compile( + dialect=test_engine.dialect))) + test_engine.dialect._oslodb_enable_ndb_support = False + + def test_ndb_autostringsize(self): + test_engine = self.test_engine + self.assertEqual('VARCHAR(64)', + str(ndb.AutoStringSize(255, 64).compile( + dialect=test_engine.dialect))) + test_engine.dialect._oslodb_enable_ndb_support = False + + +class NDBOpportunisticTestCase( + test_fixtures.OpportunisticDBTestMixin, test_base.BaseTestCase): + + FIXTURE = test_fixtures.MySQLOpportunisticFixture + + def init_db(self, use_ndb): + # get the MySQL engine created by the opportunistic + # provisioning system + self.engine = enginefacade.writer.get_engine() + if use_ndb: + # if we want NDB, make a new local engine that uses the + # URL / database / schema etc. of the provisioned engine, + # since NDB-ness is a per-table thing + self.engine = engines.create_engine( + self.engine.url, mysql_enable_ndb=True + ) + self.addCleanup(self.engine.dispose) + self.test_table = _TEST_TABLE + try: + self.test_table.create(self.engine) + except exception.DBNotSupportedError: + self.skip("MySQL NDB Cluster not available") + + def test_ndb_enabled(self): + self.init_db(True) + self.assertTrue(ndb.ndb_status(self.engine)) + self.assertIsInstance(self.test_table.c.test1.type, TINYTEXT) + self.assertIsInstance(self.test_table.c.test2.type, Text) + self.assertIsInstance(self.test_table.c.test3.type, String) + self.assertEqual(64, self.test_table.c.test3.type.length) + self.assertEqual([], utils.get_non_ndbcluster_tables(self.engine)) + + def test_ndb_disabled(self): + self.init_db(False) + self.assertFalse(ndb.ndb_status(self.engine)) + self.assertIsInstance(self.test_table.c.test1.type, String) + self.assertEqual(255, self.test_table.c.test1.type.length) + self.assertIsInstance(self.test_table.c.test2.type, String) + self.assertEqual(4096, self.test_table.c.test2.type.length) + self.assertIsInstance(self.test_table.c.test3.type, String) + self.assertEqual(255, self.test_table.c.test3.type.length) + self.assertEqual([], utils.get_non_innodb_tables(self.engine)) |