summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Podoliaka <rpodolyaka@mirantis.com>2014-02-21 14:55:32 +0200
committerRoman Podoliaka <rpodolyaka@mirantis.com>2014-02-21 14:55:32 +0200
commitd57afc788ae6869e8ae2c96534397bb2c54cab21 (patch)
tree0517ce8c140a4280d459ece843361195e149b266
parent73664755f97fe484a7969cf7d153ce3b3555ec91 (diff)
downloadoslo-db-d57afc788ae6869e8ae2c96534397bb2c54cab21.tar.gz
Adapt DB provisioning code for CI requirements
With recent changes made to our CI MySQL openstack_citest user now has enough priviliges to create and drop databases. But the code, that we use for provisioning of databases must be updated, so that it's not mandatory for openstack_citest user to be also able to do GRANT/ALTER ROLE queries. Actually this simplifies provisioning code a bit and allows to reuse the same queries for PostgreSQL and MySQL. This will be used for opportunistic db test cases as well as for running of DbTestCase tests on different backends. Change-Id: Ia917f647182d908dbb2a86659ad8b4e49c492881
-rw-r--r--openstack/common/db/sqlalchemy/provision.py88
1 files changed, 29 insertions, 59 deletions
diff --git a/openstack/common/db/sqlalchemy/provision.py b/openstack/common/db/sqlalchemy/provision.py
index 28db8e7..33882a8 100644
--- a/openstack/common/db/sqlalchemy/provision.py
+++ b/openstack/common/db/sqlalchemy/provision.py
@@ -16,6 +16,7 @@
"""Provision test environment for specific DB backends"""
import argparse
+import logging
import os
import random
import string
@@ -26,23 +27,12 @@ import sqlalchemy
from openstack.common.db import exception as exc
-SQL_CONNECTION = os.getenv('OS_TEST_DBAPI_ADMIN_CONNECTION', 'sqlite://')
+LOG = logging.getLogger(__name__)
-def _gen_credentials(*names):
- """Generate credentials."""
- auth_dict = {}
- for name in names:
- val = ''.join(random.choice(string.ascii_lowercase)
- for i in moves.range(10))
- auth_dict[name] = val
- return auth_dict
-
-
-def _get_engine(uri=SQL_CONNECTION):
+def get_engine(uri):
"""Engine creation
- By default the uri is SQL_CONNECTION which is admin credentials.
Call the function without arguments to get admin connection. Admin
connection required to create temporary user and database for each
particular test. Otherwise use existing connection to recreate connection
@@ -62,50 +52,43 @@ def _execute_sql(engine, sql, driver):
except sqlalchemy.exc.OperationalError:
msg = ('%s does not match database admin '
'credentials or database does not exist.')
- raise exc.DBConnectionError(msg % SQL_CONNECTION)
+ LOG.exception(msg % engine.url)
+ raise exc.DBConnectionError(msg % engine.url)
def create_database(engine):
"""Provide temporary user and database for each particular test."""
driver = engine.name
- auth = _gen_credentials('database', 'user', 'passwd')
-
- sqls = {
- 'mysql': [
- "drop database if exists %(database)s;",
- "grant all on %(database)s.* to '%(user)s'@'localhost'"
- " identified by '%(passwd)s';",
- "create database %(database)s;",
- ],
- 'postgresql': [
- "drop database if exists %(database)s;",
- "drop user if exists %(user)s;",
- "create user %(user)s with password '%(passwd)s';",
- "create database %(database)s owner %(user)s;",
- ]
+ auth = {
+ 'database': ''.join(random.choice(string.ascii_lowercase)
+ for i in moves.range(10)),
+ 'user': engine.url.username,
+ 'passwd': engine.url.password,
}
+ sqls = [
+ "drop database if exists %(database)s;",
+ "create database %(database)s;"
+ ]
+
if driver == 'sqlite':
return 'sqlite:////tmp/%s' % auth['database']
-
- try:
- sql_rows = sqls[driver]
- except KeyError:
+ elif driver in ['mysql', 'postgresql']:
+ sql_query = map(lambda x: x % auth, sqls)
+ _execute_sql(engine, sql_query, driver)
+ else:
raise ValueError('Unsupported RDBMS %s' % driver)
- sql_query = map(lambda x: x % auth, sql_rows)
-
- _execute_sql(engine, sql_query, driver)
params = auth.copy()
params['backend'] = driver
return "%(backend)s://%(user)s:%(passwd)s@localhost/%(database)s" % params
-def drop_database(engine, current_uri):
+def drop_database(admin_engine, current_uri):
"""Drop temporary database and user after each particular test."""
- engine = _get_engine(current_uri)
- admin_engine = _get_engine()
+
+ engine = get_engine(current_uri)
driver = engine.name
auth = {'database': engine.url.database, 'user': engine.url.username}
@@ -114,26 +97,11 @@ def drop_database(engine, current_uri):
os.remove(auth['database'])
except OSError:
pass
- return
-
- sqls = {
- 'mysql': [
- "drop database if exists %(database)s;",
- "drop user '%(user)s'@'localhost';",
- ],
- 'postgresql': [
- "drop database if exists %(database)s;",
- "drop user if exists %(user)s;",
- ]
- }
-
- try:
- sql_rows = sqls[driver]
- except KeyError:
+ elif driver in ['mysql', 'postgresql']:
+ sql = "drop database if exists %(database)s;"
+ _execute_sql(admin_engine, [sql % auth], driver)
+ else:
raise ValueError('Unsupported RDBMS %s' % driver)
- sql_query = map(lambda x: x % auth, sql_rows)
-
- _execute_sql(admin_engine, sql_query, driver)
def main():
@@ -172,7 +140,9 @@ def main():
args = parser.parse_args()
- engine = _get_engine()
+ connection_string = os.getenv('OS_TEST_DBAPI_ADMIN_CONNECTION',
+ 'sqlite://')
+ engine = get_engine(connection_string)
which = args.which
if which == "create":