summaryrefslogtreecommitdiff
path: root/oslo_db/tests/sqlalchemy/test_ndb.py
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_db/tests/sqlalchemy/test_ndb.py')
-rw-r--r--oslo_db/tests/sqlalchemy/test_ndb.py176
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))