From eb28ebb0f8a48ba57f68f21d64479b56bf689d24 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 2 Jun 2016 17:42:51 -0400 Subject: [PATCH] - limit oracle DB reaps to identifiers generated from this run to prevent race conditions against concurrent runs Change-Id: I065d1cec346ea7af03792c3cc2f30766f73c2bd3 --- lib/sqlalchemy/testing/plugin/plugin_base.py | 3 +++ lib/sqlalchemy/testing/plugin/pytestplugin.py | 11 ++++++++++- lib/sqlalchemy/testing/provision.py | 10 +++++++--- reap_oracle_dbs.py | 5 +++-- tox.ini | 4 ++-- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/sqlalchemy/testing/plugin/plugin_base.py b/lib/sqlalchemy/testing/plugin/plugin_base.py index fd33c56a0c..fc9d71165b 100644 --- a/lib/sqlalchemy/testing/plugin/plugin_base.py +++ b/lib/sqlalchemy/testing/plugin/plugin_base.py @@ -67,6 +67,9 @@ def setup_options(make_option): dest="low_connections", help="Use a low number of distinct connections - " "i.e. for Oracle TNS") + make_option("--write-idents", type="string", dest="write_idents", + help="write out generated follower idents to , " + "when -n is used") make_option("--reversetop", action="store_true", dest="reversetop", default=False, help="Use a random-ordering set implementation in the ORM " diff --git a/lib/sqlalchemy/testing/plugin/pytestplugin.py b/lib/sqlalchemy/testing/plugin/pytestplugin.py index 0bd79eea04..d7da73828a 100644 --- a/lib/sqlalchemy/testing/plugin/pytestplugin.py +++ b/lib/sqlalchemy/testing/plugin/pytestplugin.py @@ -9,7 +9,7 @@ import pytest import argparse import inspect import collections -import itertools +import os try: import xdist # noqa @@ -43,6 +43,14 @@ def pytest_configure(config): config.slaveinput["follower_ident"] ) + if config.option.write_idents: + with open(config.option.write_idents, "a") as file_: + file_.write(config.slaveinput["follower_ident"] + "\n") + else: + if config.option.write_idents and \ + os.path.exists(config.option.write_idents): + os.remove(config.option.write_idents) + plugin_base.pre_begin(config.option) plugin_base.set_coverage_flag(bool(getattr(config.option, @@ -58,6 +66,7 @@ def pytest_sessionstart(session): def pytest_sessionfinish(session): plugin_base.final_process_cleanup() + if has_xdist: import uuid diff --git a/lib/sqlalchemy/testing/provision.py b/lib/sqlalchemy/testing/provision.py index 65a3c10a6e..23d504b848 100644 --- a/lib/sqlalchemy/testing/provision.py +++ b/lib/sqlalchemy/testing/provision.py @@ -40,7 +40,6 @@ class register(object): def create_follower_db(follower_ident): - for cfg in _configs_for_db_operation(): _create_db(cfg, cfg.db, follower_ident) @@ -271,9 +270,14 @@ def _oracle_drop_db(cfg, eng, ident): _ora_drop_ignore(conn, "%s_ts2" % ident) -def reap_oracle_dbs(eng): +def reap_oracle_dbs(eng, idents_file): log.info("Reaping Oracle dbs...") with eng.connect() as conn: + with open(idents_file) as file_: + idents = set(line.strip() for line in file_) + + log.info("identifiers in file: %s", ", ".join(idents)) + to_reap = conn.execute( "select u.username from all_users u where username " "like 'TEST_%' and not exists (select username " @@ -283,7 +287,7 @@ def reap_oracle_dbs(eng): for name in all_names: if name.endswith("_ts1") or name.endswith("_ts2"): continue - else: + elif name in idents: to_drop.add(name) if "%s_ts1" % name in all_names: to_drop.add("%s_ts1" % name) diff --git a/reap_oracle_dbs.py b/reap_oracle_dbs.py index ff638a01ed..4762faac55 100644 --- a/reap_oracle_dbs.py +++ b/reap_oracle_dbs.py @@ -1,4 +1,4 @@ -"""Drop Oracle databases that are left over from a +"""Drop Oracle databases that are left over from a multiprocessing test run. Currently the cx_Oracle driver seems to sometimes not release a @@ -10,6 +10,7 @@ from sqlalchemy.testing.plugin import plugin_base from sqlalchemy.testing import engines from sqlalchemy.testing import provision import logging +import sys logging.basicConfig() logging.getLogger(provision.__name__).setLevel(logging.INFO) @@ -19,6 +20,6 @@ oracle = plugin_base.file_config.get('db', 'oracle') from sqlalchemy.testing import provision engine = engines.testing_engine(oracle, {}) -provision.reap_oracle_dbs(engine) +provision.reap_oracle_dbs(engine, sys.argv[1]) diff --git a/tox.ini b/tox.ini index d5c3b670b1..3c577eb0de 100644 --- a/tox.ini +++ b/tox.ini @@ -52,7 +52,7 @@ setenv= sqlite: SQLITE=--db sqlite postgresql: POSTGRESQL=--db postgresql mysql: MYSQL=--db mysql --db pymysql - oracle: ORACLE=--db oracle --low-connections + oracle: ORACLE=--db oracle --low-connections --write-idents oracle_idents.txt mssql: MSSQL=--db pyodbc --db pymssql backendonly: BACKENDONLY=--backend-only @@ -65,7 +65,7 @@ passenv=ORACLE_HOME NLS_LANG commands= {nocext}: sh -c "rm -f lib/sqlalchemy/*.so" {env:BASECOMMAND} {env:WORKERS} {env:SQLITE:} {env:POSTGRESQL:} {env:MYSQL:} {env:ORACLE:} {env:MSSQL:} {env:BACKENDONLY:} {env:COVERAGE:} {posargs} - {oracle}: python reap_oracle_dbs.py + {oracle}: python reap_oracle_dbs.py oracle_idents.txt [testenv:pep8] -- 2.47.2