summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-03-01 17:36:39 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-03-01 17:36:39 -0500
commit908368b2bdc1397b0ab6cfad12d6532e9c4ebd4e (patch)
tree3be6547d76ad13562851bfdb9801e97f6ad09c7e
parentfa23570a338b53c813b6342fba0cacd4f5e61384 (diff)
downloadsqlalchemy-908368b2bdc1397b0ab6cfad12d6532e9c4ebd4e.tar.gz
- remove lots of old and unused nose options
- alter the plugin/requirements system to support multiple --db/--dburi options. The first option serves as the "default" database, and the subsequent ones serve as "available" databases. the requirement rules at the *class level only* now search among the "available" databases in order to run per-database test suites at once. rationale is to support using the test plugin system under Alembic as well, which already takes advantage of multiple database tests.
-rw-r--r--lib/sqlalchemy/testing/__init__.py8
-rw-r--r--lib/sqlalchemy/testing/config.py7
-rw-r--r--lib/sqlalchemy/testing/engines.py6
-rw-r--r--lib/sqlalchemy/testing/exclusions.py49
-rw-r--r--lib/sqlalchemy/testing/plugin/noseplugin.py293
-rw-r--r--lib/sqlalchemy/testing/requirements.py29
-rw-r--r--test/dialect/postgresql/test_compiler.py1
-rw-r--r--test/dialect/postgresql/test_types.py1
-rw-r--r--test/requirements.py24
9 files changed, 209 insertions, 209 deletions
diff --git a/lib/sqlalchemy/testing/__init__.py b/lib/sqlalchemy/testing/__init__.py
index 8ad856e2b..61e0f5429 100644
--- a/lib/sqlalchemy/testing/__init__.py
+++ b/lib/sqlalchemy/testing/__init__.py
@@ -10,8 +10,12 @@ from .warnings import testing_warn, assert_warnings, resetwarnings
from . import config
from .exclusions import db_spec, _is_excluded, fails_if, skip_if, future,\
- fails_on, fails_on_everything_except, skip, only_on, exclude, against,\
- _server_version, only_if
+ fails_on, fails_on_everything_except, skip, only_on, exclude, \
+ against as _against, _server_version, only_if
+
+
+def against(*queries):
+ return _against(config._current, *queries)
from .assertions import emits_warning, emits_warning_on, uses_deprecated, \
eq_, ne_, is_, is_not_, startswith_, assert_raises, \
diff --git a/lib/sqlalchemy/testing/config.py b/lib/sqlalchemy/testing/config.py
index 64f578dab..c25355396 100644
--- a/lib/sqlalchemy/testing/config.py
+++ b/lib/sqlalchemy/testing/config.py
@@ -6,3 +6,10 @@
requirements = None
db = None
+dbs = {}
+db_opts = None
+_current = None
+file_config = None
+
+def _unique_configs():
+ return set(dbs.values()) \ No newline at end of file
diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py
index d85771f8a..6da19d776 100644
--- a/lib/sqlalchemy/testing/engines.py
+++ b/lib/sqlalchemy/testing/engines.py
@@ -188,7 +188,7 @@ class ReconnectFixture(object):
def reconnecting_engine(url=None, options=None):
- url = url or config.db_url
+ url = url or config.db.url
dbapi = config.db.dialect.dbapi
if not options:
options = {}
@@ -216,7 +216,7 @@ def testing_engine(url=None, options=None):
else:
use_reaper = options.pop('use_reaper', True)
- url = url or config.db_url
+ url = url or config.db.url
if options is None:
options = config.db_opts
@@ -244,7 +244,7 @@ def utf8_engine(url=None, options=None):
config.db.driver in ['mysqldb', 'pymysql', 'cymysql']:
# note 1.2.1.gamma.6 or greater of MySQLdb
# needed here
- url = url or config.db_url
+ url = url or config.db.url
url = engine_url.make_url(url)
url.query['charset'] = 'utf8'
url.query['use_unicode'] = '0'
diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py
index f868f6396..0f976e4e0 100644
--- a/lib/sqlalchemy/testing/exclusions.py
+++ b/lib/sqlalchemy/testing/exclusions.py
@@ -11,7 +11,7 @@ from ..util import decorator
from . import config
from .. import util
import contextlib
-
+import inspect
class skip_if(object):
def __init__(self, predicate, reason=None):
@@ -20,10 +20,6 @@ class skip_if(object):
_fails_on = None
- @property
- def enabled(self):
- return not self.predicate()
-
def __add__(self, other):
def decorate(fn):
return other(self(fn))
@@ -34,13 +30,13 @@ class skip_if(object):
try:
yield
except Exception as ex:
- if self.predicate():
+ if self.predicate(config._current):
print(("%s failed as expected (%s): %s " % (
name, self.predicate, str(ex))))
else:
raise
else:
- if self.predicate():
+ if self.predicate(config._current):
raise AssertionError(
"Unexpected success for '%s' (%s)" %
(name, self.predicate))
@@ -48,7 +44,7 @@ class skip_if(object):
def __call__(self, fn):
@decorator
def decorate(fn, *args, **kw):
- if self.predicate():
+ if self.predicate(config._current):
if self.reason:
msg = "'%s' : %s" % (
fn.__name__,
@@ -122,7 +118,7 @@ class BooleanPredicate(Predicate):
self.value = value
self.description = description or "boolean %s" % value
- def __call__(self):
+ def __call__(self, config):
return self.value
def _as_string(self, negate=False):
@@ -153,9 +149,8 @@ class SpecPredicate(Predicate):
'between': lambda val, pair: val >= pair[0] and val <= pair[1],
}
- def __call__(self, engine=None):
- if engine is None:
- engine = config.db
+ def __call__(self, config):
+ engine = config.db
if "+" in self.db:
dialect, driver = self.db.split('+')
@@ -205,7 +200,11 @@ class SpecPredicate(Predicate):
class LambdaPredicate(Predicate):
def __init__(self, lambda_, description=None, args=None, kw=None):
- self.lambda_ = lambda_
+ spec = inspect.getargspec(lambda_)
+ if not spec[0]:
+ self.lambda_ = lambda db: lambda_
+ else:
+ self.lambda_ = lambda_
self.args = args or ()
self.kw = kw or {}
if description:
@@ -215,8 +214,8 @@ class LambdaPredicate(Predicate):
else:
self.description = "custom function"
- def __call__(self):
- return self.lambda_(*self.args, **self.kw)
+ def __call__(self, config):
+ return self.lambda_(config)
def _as_string(self, negate=False):
if negate:
@@ -232,8 +231,8 @@ class NotPredicate(Predicate):
def __init__(self, predicate):
self.predicate = predicate
- def __call__(self, *arg, **kw):
- return not self.predicate(*arg, **kw)
+ def __call__(self, config):
+ return not self.predicate(config)
def __str__(self):
return self.predicate._as_string(True)
@@ -244,9 +243,9 @@ class OrPredicate(Predicate):
self.predicates = predicates
self.description = description
- def __call__(self, *arg, **kw):
+ def __call__(self, config):
for pred in self.predicates:
- if pred(*arg, **kw):
+ if pred(config):
self._str = pred
return True
return False
@@ -286,7 +285,7 @@ _as_predicate = Predicate.as_predicate
def _is_excluded(db, op, spec):
- return SpecPredicate(db, op, spec)()
+ return SpecPredicate(db, op, spec)(config._current)
def _server_version(engine):
@@ -301,7 +300,7 @@ def _server_version(engine):
def db_spec(*dbs):
return OrPredicate(
- Predicate.as_predicate(db) for db in dbs
+ [Predicate.as_predicate(db) for db in dbs]
)
@@ -314,8 +313,8 @@ def closed():
@decorator
-def future(fn, *args, **kw):
- return fails_if(LambdaPredicate(fn, *args, **kw), "Future feature")
+def future(fn):
+ return fails_if(LambdaPredicate(fn), "Future feature")
def fails_on(db, reason=None):
@@ -344,8 +343,8 @@ def exclude(db, op, spec, reason=None):
return skip_if(SpecPredicate(db, op, spec), reason)
-def against(*queries):
+def against(config, *queries):
return OrPredicate([
Predicate.as_predicate(query)
for query in queries
- ])()
+ ])(config)
diff --git a/lib/sqlalchemy/testing/plugin/noseplugin.py b/lib/sqlalchemy/testing/plugin/noseplugin.py
index 27a028cd4..153d227a7 100644
--- a/lib/sqlalchemy/testing/plugin/noseplugin.py
+++ b/lib/sqlalchemy/testing/plugin/noseplugin.py
@@ -30,7 +30,6 @@ else:
from nose.plugins import Plugin
from nose import SkipTest
import sys
-import re
# late imports
fixtures = None
@@ -41,19 +40,24 @@ profiling = None
assertions = None
requirements = None
config = None
+testing = None
util = None
file_config = None
logging = None
-db = None
-db_label = None
-db_url = None
db_opts = {}
options = None
-_existing_engine = None
+_existing_config_obj = None
+class Config(object):
+ def __init__(self, db, db_opts, options, file_config):
+ self.db = db
+ self.db_opts = db_opts
+ self.options = options
+ self.file_config = file_config
+
def _log(option, opt_str, value, parser):
global logging
if not logging:
@@ -77,10 +81,6 @@ def _server_side_cursors(options, opt_str, value, parser):
db_opts['server_side_cursors'] = True
-def _engine_strategy(options, opt_str, value, parser):
- if value:
- db_opts['strategy'] = value
-
pre_configure = []
post_configure = []
@@ -110,48 +110,38 @@ def _monkeypatch_cdecimal(options, file_config):
@post
def _engine_uri(options, file_config):
- global db_label, db_url
+ from sqlalchemy.testing import engines, config
+ from sqlalchemy import testing
if options.dburi:
- db_url = options.dburi
- db_label = db_url[:db_url.index(':')]
- elif options.db:
- db_label = options.db
- db_url = None
-
- if db_url is None:
- if db_label not in file_config.options('db'):
- raise RuntimeError(
- "Unknown URI specifier '%s'. Specify --dbs for known uris."
- % db_label)
- db_url = file_config.get('db', db_label)
-
-
-@post
-def _require(options, file_config):
- if not(options.require or
- (file_config.has_section('require') and
- file_config.items('require'))):
- return
+ db_urls = list(options.dburi)
+ else:
+ db_urls = []
+
+ if options.db:
+ for db in options.db:
+ if db not in file_config.options('db'):
+ raise RuntimeError(
+ "Unknown URI specifier '%s'. Specify --dbs for known uris."
+ % db)
+ else:
+ db_urls.append(file_config.get('db', db))
+
+ if not db_urls:
+ db_urls.append(file_config.get('db', 'default'))
+
+ for db_url in db_urls:
+ eng = engines.testing_engine(db_url, db_opts)
+ eng.connect().close()
+ config_obj = Config(eng, db_opts, options, file_config)
+ if not config.db:
+ config.db = testing.db = eng
+ config._current = config_obj
+ config.dbs[eng.name] = config_obj
+ config.dbs[(eng.name, eng.dialect)] = config_obj
+ config.dbs[eng] = config_obj
- try:
- import pkg_resources
- except ImportError:
- raise RuntimeError("setuptools is required for version requirements")
-
- cmdline = []
- for requirement in options.require:
- pkg_resources.require(requirement)
- cmdline.append(re.split('\s*(<!>=)', requirement, 1)[0])
-
- if file_config.has_section('require'):
- for label, requirement in file_config.items('require'):
- if not label == db_label or label.startswith('%s.' % db_label):
- continue
- seen = [c for c in cmdline if requirement.startswith(c)]
- if seen:
- continue
- pkg_resources.require(requirement)
+ config.db_opts = db_opts
@post
@@ -160,55 +150,40 @@ def _engine_pool(options, file_config):
from sqlalchemy import pool
db_opts['poolclass'] = pool.AssertionPool
-
-@post
-def _create_testing_engine(options, file_config):
- from sqlalchemy.testing import engines, config
- from sqlalchemy import testing
- global db
- config.db = testing.db = db = engines.testing_engine(db_url, db_opts)
- config.db.connect().close()
- config.db_opts = db_opts
- config.db_url = db_url
-
-
@post
def _prep_testing_database(options, file_config):
- from sqlalchemy.testing import engines
+ from sqlalchemy.testing import config
from sqlalchemy import schema, inspect
- # also create alt schemas etc. here?
if options.dropfirst:
- e = engines.utf8_engine()
- inspector = inspect(e)
-
- try:
- view_names = inspector.get_view_names()
- except NotImplementedError:
- pass
- else:
- for vname in view_names:
- e.execute(schema._DropView(schema.Table(vname, schema.MetaData())))
-
- try:
- view_names = inspector.get_view_names(schema="test_schema")
- except NotImplementedError:
- pass
- else:
- for vname in view_names:
- e.execute(schema._DropView(
- schema.Table(vname,
- schema.MetaData(), schema="test_schema")))
-
- for tname in reversed(inspector.get_table_names(order_by="foreign_key")):
- e.execute(schema.DropTable(schema.Table(tname, schema.MetaData())))
-
- for tname in reversed(inspector.get_table_names(
- order_by="foreign_key", schema="test_schema")):
- e.execute(schema.DropTable(
- schema.Table(tname, schema.MetaData(), schema="test_schema")))
-
- e.dispose()
+ for e in set(config.dbs.values()):
+ inspector = inspect(e)
+
+ try:
+ view_names = inspector.get_view_names()
+ except NotImplementedError:
+ pass
+ else:
+ for vname in view_names:
+ e.execute(schema._DropView(schema.Table(vname, schema.MetaData())))
+
+ try:
+ view_names = inspector.get_view_names(schema="test_schema")
+ except NotImplementedError:
+ pass
+ else:
+ for vname in view_names:
+ e.execute(schema._DropView(
+ schema.Table(vname,
+ schema.MetaData(), schema="test_schema")))
+
+ for tname in reversed(inspector.get_table_names(order_by="foreign_key")):
+ e.execute(schema.DropTable(schema.Table(tname, schema.MetaData())))
+
+ for tname in reversed(inspector.get_table_names(
+ order_by="foreign_key", schema="test_schema")):
+ e.execute(schema.DropTable(
+ schema.Table(tname, schema.MetaData(), schema="test_schema")))
@post
@@ -255,8 +230,8 @@ def _setup_requirements(argument):
for component in modname.split(".")[1:]:
mod = getattr(mod, component)
req_cls = getattr(mod, clsname)
- config.requirements = testing.requires = req_cls(config)
+ config.requirements = testing.requires = req_cls()
@post
def _post_setup_options(opt, file_config):
@@ -288,14 +263,13 @@ class NoseSQLAlchemy(Plugin):
help="turn on info logging for <LOG> (multiple OK)")
opt("--log-debug", action="callback", type="string", callback=_log,
help="turn on debug logging for <LOG> (multiple OK)")
- opt("--require", action="append", dest="require", default=[],
- help="require a particular driver or module version (multiple OK)")
- opt("--db", action="store", dest="db", default="default",
- help="Use prefab database uri")
+ opt("--db", action="append", type="string", dest="db",
+ help="Use prefab database uri. Multiple OK, "
+ "first one is run by default.")
opt('--dbs', action='callback', callback=_list_dbs,
help="List available prefab dbs")
- opt("--dburi", action="store", dest="dburi",
- help="Database uri (overrides --db)")
+ opt("--dburi", action="append", type="string", dest="dburi",
+ help="Database uri. Multiple OK, first one is run by default.")
opt("--dropfirst", action="store_true", dest="dropfirst",
help="Drop all tables in the target database first")
opt("--mockpool", action="store_true", dest="mockpool",
@@ -303,9 +277,6 @@ class NoseSQLAlchemy(Plugin):
opt("--low-connections", action="store_true", dest="low_connections",
help="Use a low number of distinct connections - i.e. for Oracle TNS"
)
- opt("--enginestrategy", action="callback", type="string",
- callback=_engine_strategy,
- help="Engine strategy (plain or threadlocal, defaults to plain)")
opt("--reversetop", action="store_true", dest="reversetop", default=False,
help="Use a random-ordering set implementation in the ORM (helps "
"reveal dependency issues)")
@@ -314,12 +285,6 @@ class NoseSQLAlchemy(Plugin):
help="requirements class for testing, overrides setup.cfg")
opt("--with-cdecimal", action="store_true", dest="cdecimal", default=False,
help="Monkeypatch the cdecimal library into Python 'decimal' for all tests")
- opt("--unhashable", action="store_true", dest="unhashable", default=False,
- help="Disallow SQLAlchemy from performing a hash() on mapped test objects.")
- opt("--noncomparable", action="store_true", dest="noncomparable", default=False,
- help="Disallow SQLAlchemy from performing == on mapped test objects.")
- opt("--truthless", action="store_true", dest="truthless", default=False,
- help="Disallow SQLAlchemy from truth-evaluating mapped test objects.")
opt("--serverside", action="callback", callback=_server_side_cursors,
help="Turn on server side cursors for PG")
opt("--mysql-engine", action="store", dest="mysql_engine", default=None,
@@ -348,7 +313,8 @@ class NoseSQLAlchemy(Plugin):
# as nose plugins like coverage
global util, fixtures, engines, exclusions, \
assertions, warnings, profiling,\
- config
+ config, testing
+ from sqlalchemy import testing
from sqlalchemy.testing import fixtures, engines, exclusions, \
assertions, warnings, profiling, config
from sqlalchemy import util
@@ -381,42 +347,34 @@ class NoseSQLAlchemy(Plugin):
def _do_skips(self, cls):
from sqlalchemy.testing import config
+
+ all_configs = set(config._unique_configs())
+ reasons = []
+
if hasattr(cls, '__requires__'):
- def test_suite():
- return 'ok'
- test_suite.__name__ = cls.__name__
- for requirement in cls.__requires__:
- check = getattr(config.requirements, requirement)
-
- if not check.enabled:
- raise SkipTest(
- check.reason if check.reason
- else
- (
- "'%s' unsupported on DB implementation '%s' == %s" % (
- cls.__name__, config.db.name,
- config.db.dialect.server_version_info
- )
- )
- )
+ requirements = config.requirements
+ for config_obj in list(all_configs):
+ for requirement in cls.__requires__:
+ check = getattr(requirements, requirement)
+
+ if check.predicate(config_obj):
+ all_configs.remove(config_obj)
+ if check.reason:
+ reasons.append(check.reason)
+ break
if cls.__unsupported_on__:
spec = exclusions.db_spec(*cls.__unsupported_on__)
- if spec(config.db):
- raise SkipTest(
- "'%s' unsupported on DB implementation '%s' == %s" % (
- cls.__name__, config.db.name,
- config.db.dialect.server_version_info)
- )
+ for config_obj in list(all_configs):
+ if spec(config_obj):
+ all_configs.remove(config_obj)
if getattr(cls, '__only_on__', None):
spec = exclusions.db_spec(*util.to_list(cls.__only_on__))
- if not spec(config.db):
- raise SkipTest(
- "'%s' unsupported on DB implementation '%s' == %s" % (
- cls.__name__, config.db.name,
- config.db.dialect.server_version_info)
- )
+ for config_obj in list(all_configs):
+ if not spec(config_obj):
+ all_configs.remove(config_obj)
+
if getattr(cls, '__skip_if__', False):
for c in getattr(cls, '__skip_if__'):
@@ -425,11 +383,33 @@ class NoseSQLAlchemy(Plugin):
cls.__name__, c.__name__)
)
- for db, op, spec in getattr(cls, '__excluded_on__', ()):
- exclusions.exclude(db, op, spec,
- "'%s' unsupported on DB %s version %s" % (
- cls.__name__, config.db.name,
- exclusions._server_version(config.db)))
+ for db_spec, op, spec in getattr(cls, '__excluded_on__', ()):
+ for config_obj in list(all_configs):
+ if exclusions.skip_if(exclusions.SpecPredicate(db_spec, op, spec)).predicate(config_obj):
+ all_configs.remove(config_obj)
+
+
+ if not all_configs:
+ raise SkipTest(
+ "'%s' unsupported on DB implementation %s%s" % (
+ cls.__name__,
+ ", ".join("'%s' = %s" % (config_obj.db.name, config_obj.db.dialect.server_version_info)
+ for config_obj in config._unique_configs()
+ ),
+ ", ".join(reasons)
+ )
+ )
+ elif hasattr(cls, '__prefer__'):
+ non_preferred = set()
+ spec = exclusions.db_spec(*util.to_list(cls.__prefer__))
+ for config_obj in all_configs:
+ if not spec(config_obj):
+ non_preferred.add(config_obj)
+ if all_configs.difference(non_preferred):
+ all_configs.difference_update(non_preferred)
+
+ if config._current not in all_configs:
+ self._setup_config(all_configs.pop(), cls)
def beforeTest(self, test):
warnings.resetwarnings()
@@ -439,17 +419,30 @@ class NoseSQLAlchemy(Plugin):
engines.testing_reaper._after_test_ctx()
warnings.resetwarnings()
+ def _setup_config(self, config_obj, ctx):
+ ctx.__use_config__ = config_obj
+
def _setup_engine(self, ctx):
if getattr(ctx, '__engine_options__', None):
- global _existing_engine
- _existing_engine = config.db
- config.db = engines.testing_engine(options=ctx.__engine_options__)
+ eng = engines.testing_engine(options=ctx.__engine_options__)
+ config_obj = Config(eng, db_opts, options, file_config)
+ elif getattr(ctx, '__use_config__', None):
+ config_obj = ctx.__use_config__
+ else:
+ config_obj = None
+
+ if config_obj:
+ global _existing_config_obj
+ _existing_config_obj = config._current
+ config._current = config_obj
+ config.db = testing.db = config_obj.db
def _restore_engine(self, ctx):
- global _existing_engine
- if _existing_engine is not None:
- config.db = _existing_engine
- _existing_engine = None
+ global _existing_config_obj
+ if _existing_config_obj is not None:
+ config.db = testing.db = _existing_config_obj.db
+ config._current = _existing_config_obj
+ _existing_config_obj = None
def startContext(self, ctx):
if not isinstance(ctx, type) \
diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py
index 77a17c1bd..5dd2435d7 100644
--- a/lib/sqlalchemy/testing/requirements.py
+++ b/lib/sqlalchemy/testing/requirements.py
@@ -14,16 +14,11 @@ to provide specific inclusion/exlusions.
"""
-from . import exclusions, config
+from . import exclusions
class Requirements(object):
- def __init__(self, config):
- self.config = config
-
- @property
- def db(self):
- return config.db
+ pass
class SuiteRequirements(Requirements):
@@ -158,8 +153,8 @@ class SuiteRequirements(Requirements):
INSERT DEFAULT VALUES or equivalent."""
return exclusions.only_if(
- lambda: self.config.db.dialect.supports_empty_insert or \
- self.config.db.dialect.supports_default_values,
+ lambda config: config.db.dialect.supports_empty_insert or \
+ config.db.dialect.supports_default_values,
"empty inserts not supported"
)
@@ -174,7 +169,7 @@ class SuiteRequirements(Requirements):
"""target platform supports RETURNING."""
return exclusions.only_if(
- lambda: self.config.db.dialect.implicit_returning,
+ lambda config: config.db.dialect.implicit_returning,
"'returning' not supported by database"
)
@@ -184,7 +179,7 @@ class SuiteRequirements(Requirements):
UPPERCASE as case insensitive names."""
return exclusions.skip_if(
- lambda: not self.db.dialect.requires_name_normalize,
+ lambda config: not config.db.dialect.requires_name_normalize,
"Backend does not require denormalized names."
)
@@ -194,7 +189,7 @@ class SuiteRequirements(Requirements):
INSERT statement."""
return exclusions.skip_if(
- lambda: not self.db.dialect.supports_multivalues_insert,
+ lambda config: not config.db.dialect.supports_multivalues_insert,
"Backend does not support multirow inserts."
)
@@ -245,7 +240,7 @@ class SuiteRequirements(Requirements):
"""Target database must support SEQUENCEs."""
return exclusions.only_if([
- lambda: self.config.db.dialect.supports_sequences
+ lambda config: config.db.dialect.supports_sequences
], "no sequence support")
@property
@@ -254,8 +249,8 @@ class SuiteRequirements(Requirements):
as a means of generating new PK values."""
return exclusions.only_if([
- lambda: self.config.db.dialect.supports_sequences and \
- self.config.db.dialect.sequences_optional
+ lambda config: config.db.dialect.supports_sequences and \
+ config.db.dialect.sequences_optional
], "no sequence support, or sequences not optional")
@@ -528,8 +523,8 @@ class SuiteRequirements(Requirements):
"""Catchall for a large variety of MySQL on Windows failures"""
return exclusions.open()
- def _has_mysql_on_windows(self):
+ def _has_mysql_on_windows(self, config):
return False
- def _has_mysql_fully_case_sensitive(self):
+ def _has_mysql_fully_case_sensitive(self, config):
return False
diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py
index e64afb186..db6efa34a 100644
--- a/test/dialect/postgresql/test_compiler.py
+++ b/test/dialect/postgresql/test_compiler.py
@@ -19,6 +19,7 @@ from sqlalchemy.sql import table, column, operators
from sqlalchemy.util import u
class SequenceTest(fixtures.TestBase, AssertsCompiledSQL):
+ __prefer__ = 'postgresql'
def test_format(self):
seq = Sequence('my_seq_no_schema')
diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py
index 4540b7537..7450a5d2c 100644
--- a/test/dialect/postgresql/test_types.py
+++ b/test/dialect/postgresql/test_types.py
@@ -448,6 +448,7 @@ class TimezoneTest(fixtures.TestBase):
class TimePrecisionTest(fixtures.TestBase, AssertsCompiledSQL):
__dialect__ = postgresql.dialect()
+ __prefer__ = 'postgresql'
def test_compile(self):
for type_, expected in [
diff --git a/test/requirements.py b/test/requirements.py
index c75a110c6..6f6945818 100644
--- a/test/requirements.py
+++ b/test/requirements.py
@@ -651,11 +651,11 @@ class DefaultRequirements(SuiteRequirements):
@property
def hstore(self):
- def check_hstore():
- if not against("postgresql"):
+ def check_hstore(config):
+ if not against(config, "postgresql"):
return False
try:
- self.db.execute("SELECT 'a=>1,a=>2'::hstore;")
+ config.db.execute("SELECT 'a=>1,a=>2'::hstore;")
return True
except:
return False
@@ -664,11 +664,11 @@ class DefaultRequirements(SuiteRequirements):
@property
def range_types(self):
- def check_range_types():
- if not against("postgresql+psycopg2"):
+ def check_range_types(config):
+ if not against(config, "postgresql+psycopg2"):
return False
try:
- self.db.execute("select '[1,2)'::int4range;")
+ config.db.execute("select '[1,2)'::int4range;")
# only supported in psycopg 2.5+
from psycopg2.extras import NumericRange
return True
@@ -684,7 +684,7 @@ class DefaultRequirements(SuiteRequirements):
@property
def oracle_test_dblink(self):
return skip_if(
- lambda: not self.config.file_config.has_option(
+ lambda config: not config.file_config.has_option(
'sqla_testing', 'oracle_db_link'),
"oracle_db_link option not specified in config"
)
@@ -740,11 +740,11 @@ class DefaultRequirements(SuiteRequirements):
except ImportError:
return False
- def _has_mysql_on_windows(self):
- return against('mysql') and \
+ def _has_mysql_on_windows(self, config):
+ return against(config.db, 'mysql') and \
self.db.dialect._detect_casing(self.db) == 1
- def _has_mysql_fully_case_sensitive(self):
- return against('mysql') and \
- self.db.dialect._detect_casing(self.db) == 0
+ def _has_mysql_fully_case_sensitive(self, config):
+ return against(config.db, 'mysql') and \
+ config.db.dialect._detect_casing(config.db) == 0