diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-14 12:07:14 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-14 17:19:40 -0400 |
commit | 3231e281efb2f36dd0dbd628efcd684175064386 (patch) | |
tree | e4a961d163c6d594e29fc09d1bd7240123d13548 /lib/sqlalchemy/testing/provision.py | |
parent | 743d22f3607d24243f55521a5de286f4651faca7 (diff) | |
download | sqlalchemy-3231e281efb2f36dd0dbd628efcd684175064386.tar.gz |
Provision on different drivers dynamically
We want TOX_POSTGRESQL and similar to be the fixed variable
that is configured from CI environment. These variables should refer
to database servers but individual drivers like asyncpg mysqlconnector
etc. should come from local tox.ini. add a new system to generate
per-driver URLs from a simple list of hostname-based URLs delivered
from CI environment.
Change-Id: I4267b4a70742765388c7e7c4432c1da9d9adece2
Diffstat (limited to 'lib/sqlalchemy/testing/provision.py')
-rw-r--r-- | lib/sqlalchemy/testing/provision.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/lib/sqlalchemy/testing/provision.py b/lib/sqlalchemy/testing/provision.py index 660a3bd24..13a5ea078 100644 --- a/lib/sqlalchemy/testing/provision.py +++ b/lib/sqlalchemy/testing/provision.py @@ -1,8 +1,10 @@ import collections +import copy import logging from . import config from . import engines +from .. import exc from ..engine import url as sa_url from ..util import compat @@ -73,6 +75,91 @@ def drop_follower_db(follower_ident): drop_db(cfg, cfg.db, follower_ident) +def generate_db_urls(db_urls, extra_drivers): + """Generate a set of URLs to test given configured URLs plus additional + driver names. + + Given:: + + --dburi postgresql://db1 \ + --dburi postgresql://db2 \ + --dburi postgresql://db2 \ + --dbdriver=psycopg2 --dbdriver=asyncpg + + Noting that the default postgresql driver is psycopg2. the output + would be:: + + postgresql+psycopg2://db1 + postgresql+asyncpg://db1?async_fallback=true + postgresql+psycopg2://db2 + postgresql+psycopg2://db3 + + That is, for the driver in a --dburi, we want to keep that and use that + driver for each URL it's part of . For a driver that is only + in --dbdrivers, we want to use it just once for one of the URLs. + for a driver that is both coming from --dburi as well as --dbdrivers, + we want to keep it in that dburi. + + + """ + urls = set() + + backend_to_driver_we_already_have = collections.defaultdict(set) + + urls_plus_dialects = [ + (url_obj, url_obj.get_dialect()) + for url_obj in [sa_url.make_url(db_url) for db_url in db_urls] + ] + + for url_obj, dialect in urls_plus_dialects: + backend_to_driver_we_already_have[dialect.name].add(dialect.driver) + + backend_to_driver_we_need = {} + + for url_obj, dialect in urls_plus_dialects: + backend = dialect.name + dialect.load_provisioning() + + if backend not in backend_to_driver_we_need: + backend_to_driver_we_need[backend] = extra_per_backend = set( + extra_drivers + ).difference(backend_to_driver_we_already_have[backend]) + else: + extra_per_backend = backend_to_driver_we_need[backend] + + for driver_url in _generate_driver_urls(url_obj, extra_per_backend): + if driver_url in urls: + continue + urls.add(driver_url) + yield driver_url + + +def _generate_driver_urls(url, extra_drivers): + main_driver = url.get_driver_name() + extra_drivers.discard(main_driver) + + yield str(url) + + for drv in list(extra_drivers): + new_url = generate_driver_url(url, drv) + if new_url: + extra_drivers.remove(drv) + yield str(new_url) + + +@register.init +def generate_driver_url(url, driver): + backend = url.get_backend_name() + new_url = copy.copy(url) + new_url.drivername = "%s+%s" % (backend, driver) + try: + new_url.get_dialect() + except exc.NoSuchModuleError: + return None + else: + return new_url + + def _configs_for_db_operation(): hosts = set() |