# based on the database connection url.
# The cell0 database will use the same database scheme and
# netloc as the main database, with a related path.
+ # NOTE(sbauza): The URL has to be RFC1738 compliant in order to
+ # be usable by sqlalchemy.
connection = CONF.database.connection
# sqlalchemy has a nice utility for parsing database connection
# URLs so we use that here to get the db name so we don't have to
# worry about parsing and splitting a URL which could have special
# characters in the password, which makes parsing a nightmare.
url = sqla_url.make_url(connection)
- cell0_db_name = url.database + '_cell0'
- # We need to handle multiple occurrences of the substring, e.g. if
- # the username and db name are both 'nova' we need to only replace
- # the last one, which is the database name in the URL, not the
- # username.
- connection = connection.rstrip(url.database)
- return connection + cell0_db_name
+ url.database = url.database + '_cell0'
+ return urlparse.unquote(str(url))
dbc = database_connection or cell0_default_connection()
ctxt = context.RequestContext()
self.assertEqual('fake://netloc/nova_cell0',
cell_mapping.database_connection)
- @ddt.data('mysql+pymysql://nova:abcd0123:AB@controller/nova',
- 'mysql+pymysql://nova:abcd0123?AB@controller/nova',
- 'mysql+pymysql://nova:abcd0123@AB@controller/nova',
- 'mysql+pymysql://nova:abcd0123/AB@controller/nova',
- 'mysql+pymysql://test:abcd0123%AB@controller/nova')
+ @ddt.data('mysql+pymysql://nova:abcd0123:AB@controller/%s',
+ 'mysql+pymysql://nova:abcd0123?AB@controller/%s',
+ 'mysql+pymysql://nova:abcd0123@AB@controller/%s',
+ 'mysql+pymysql://nova:abcd0123/AB@controller/%s',
+ 'mysql+pymysql://test:abcd0123/AB@controller/%s?charset=utf8')
def test_map_cell0_default_database_special_characters(self,
- decoded_connection):
+ connection):
"""Tests that a URL with special characters, like in the credentials,
is handled properly.
"""
+ decoded_connection = connection % 'nova'
self.flags(connection=decoded_connection, group='database')
ctxt = context.RequestContext()
self.commands.map_cell0()
self.assertEqual('cell0', cell_mapping.name)
self.assertEqual('none:///', cell_mapping.transport_url)
self.assertEqual(
- decoded_connection + '_cell0',
+ connection % 'nova_cell0',
cell_mapping.database_connection)
# Delete the cell mapping for the next iteration.
cell_mapping.destroy()