--- /dev/null
+[run]
+include=lib/sqlalchemy/*
+
+[report]
+omit=lib/sqlalchemy/testing/*
\ No newline at end of file
/doc/build/output/
/dogpile_data/
*.orig
+*,cover
/.tox
.venv
*.egg-info
.coverage
+coverage.xml
.*,cover
*.class
*.so
--- /dev/null
+"""
+Bootstrapper for nose/pytest plugins.
+
+The entire rationale for this system is to get the modules in plugin/
+imported without importing all of the supporting library, so that we can
+set up things for testing before coverage starts.
+
+The rationale for all of plugin/ being *in* the supporting library in the
+first place is so that the testing and plugin suite is available to other
+libraries, mainly external SQLAlchemy and Alembic dialects, to make use
+of the same test environment and standard suites available to
+SQLAlchemy/Alembic themselves without the need to ship/install a separate
+package outside of SQLAlchemy.
+
+NOTE: copied/adapted from SQLAlchemy master for backwards compatibility;
+this should be removable when Alembic targets SQLAlchemy 1.0.0.
+
+"""
+
+import os
+import sys
+
+bootstrap_file = locals()['bootstrap_file']
+to_bootstrap = locals()['to_bootstrap']
+
+
+def load_file_as_module(name):
+ path = os.path.join(os.path.dirname(bootstrap_file), "%s.py" % name)
+ if sys.version_info >= (3, 3):
+ from importlib import machinery
+ mod = machinery.SourceFileLoader(name, path).load_module()
+ else:
+ import imp
+ mod = imp.load_source(name, path)
+ return mod
+
+if to_bootstrap == "pytest":
+ sys.modules["sqla_plugin_base"] = load_file_as_module("plugin_base")
+ sys.modules["sqla_pytestplugin"] = load_file_as_module("pytestplugin")
+elif to_bootstrap == "nose":
+ sys.modules["sqla_plugin_base"] = load_file_as_module("plugin_base")
+ sys.modules["sqla_noseplugin"] = load_file_as_module("noseplugin")
+else:
+ raise Exception("unknown bootstrap: %s" % to_bootstrap) # noqa
"""
+try:
+ # installed by bootstrap.py
+ import sqla_plugin_base as plugin_base
+except ImportError:
+ # assume we're a package, use traditional import
+ from . import plugin_base
+
+
import os
import sys
fixtures = None
py3k = sys.version_info >= (3, 0)
-# no package imports yet! this prevents us from tripping coverage
-# too soon.
-path = os.path.join(os.path.dirname(__file__), "plugin_base.py")
-if sys.version_info >= (3, 3):
- from importlib import machinery
- plugin_base = machinery.SourceFileLoader(
- "plugin_base", path).load_module()
-else:
- import imp
- plugin_base = imp.load_source("plugin_base", path)
class NoseSQLAlchemy(Plugin):
plugin_base.set_coverage_flag(options.enable_plugin_coverage)
+ def begin(self):
global fixtures
- from sqlalchemy.testing import fixtures
+ from sqlalchemy.testing import fixtures # noqa
- def begin(self):
plugin_base.post_begin()
def describeTest(self, test):
def wantMethod(self, fn):
if py3k:
+ if not hasattr(fn.__self__, 'cls'):
+ return False
cls = fn.__self__.cls
else:
cls = fn.im_class
- print "METH:", fn, "CLS:", cls
return plugin_base.want_method(cls, fn)
def wantClass(self, cls):
return plugin_base.want_class(cls)
def beforeTest(self, test):
- plugin_base.before_test(test,
- test.test.cls.__module__,
- test.test.cls, test.test.method.__name__)
+ plugin_base.before_test(
+ test,
+ test.test.cls.__module__,
+ test.test.cls, test.test.method.__name__)
def afterTest(self, test):
plugin_base.after_test(test)
else:
import ConfigParser as configparser
-FOLLOWER_IDENT = None
-
# late imports
fixtures = None
engines = None
help="Drop all tables in the target database first")
make_option("--backend-only", action="store_true", dest="backend_only",
help="Run only tests marked with __backend__")
- make_option("--mockpool", action="store_true", dest="mockpool",
- help="Use mock pool (asserts only one connection used)")
make_option("--low-connections", action="store_true",
dest="low_connections",
help="Use a low number of distinct connections - "
make_option("--exclude-tag", action="callback", callback=_exclude_tag,
type="string",
help="Exclude tests with tag <tag>")
- make_option("--serverside", action="store_true",
- help="Turn on server side cursors for PG")
- make_option("--mysql-engine", action="store",
- dest="mysql_engine", default=None,
- help="Use the specified MySQL storage engine for all tables, "
- "default is a db-default/InnoDB combo.")
- make_option("--tableopts", action="append", dest="tableopts", default=[],
- help="Add a dialect-specific table option, key=value")
make_option("--write-profiles", action="store_true",
dest="write_profiles", default=False,
help="Write/update profiling data.")
database creation.
"""
- global FOLLOWER_IDENT
- FOLLOWER_IDENT = follower_ident
+ from sqlalchemy.testing import provision
+ provision.FOLLOWER_IDENT = follower_ident
def memoize_important_follower_config(dict_):
global util, fixtures, engines, exclusions, \
assertions, warnings, profiling,\
config, testing
- from sqlalchemy import testing
- from sqlalchemy.testing import fixtures, engines, exclusions, \
- assertions, warnings, profiling, config
- from sqlalchemy import util
+ from sqlalchemy import testing # noqa
+ from sqlalchemy.testing import fixtures, engines, exclusions # noqa
+ from sqlalchemy.testing import assertions, warnings, profiling # noqa
+ from sqlalchemy.testing import config # noqa
+ from sqlalchemy import util # noqa
warnings.setup_filters()
+
def _log(opt_str, value, parser):
global logging
if not logging:
options = opt
-@pre
-def _server_side_cursors(options, file_config):
- if options.serverside:
- db_opts['server_side_cursors'] = True
-
-
@pre
def _monkeypatch_cdecimal(options, file_config):
if options.cdecimal:
def _engine_uri(options, file_config):
from sqlalchemy.testing import config
from sqlalchemy import testing
- from sqlalchemy.testing.plugin import provision
+ from sqlalchemy.testing import provision
if options.dburi:
db_urls = list(options.dburi)
for db_url in db_urls:
cfg = provision.setup_config(
- db_url, db_opts, options, file_config, FOLLOWER_IDENT)
+ db_url, db_opts, options, file_config, provision.FOLLOWER_IDENT)
if not config._current:
cfg.set_as_current(cfg, testing)
-@post
-def _engine_pool(options, file_config):
- if options.mockpool:
- from sqlalchemy import pool
- db_opts['poolclass'] = pool.AssertionPool
-
-
@post
def _requirements(options, file_config):
schema=enum['schema'])))
-@post
-def _set_table_options(options, file_config):
- from sqlalchemy.testing import schema
-
- table_options = schema.table_options
- for spec in options.tableopts:
- key, value = spec.split('=')
- table_options[key] = value
-
- if options.mysql_engine:
- table_options['mysql_engine'] = options.mysql_engine
-
-
@post
def _reverse_topological(options, file_config):
if options.reversetop:
+try:
+ # installed by bootstrap.py
+ import sqla_plugin_base as plugin_base
+except ImportError:
+ # assume we're a package, use traditional import
+ from . import plugin_base
+
import pytest
import argparse
import inspect
-from . import plugin_base
import collections
import itertools
plugin_base.set_coverage_flag(bool(getattr(config.option,
"cov_source", False)))
+
+def pytest_sessionstart(session):
plugin_base.post_begin()
if has_xdist:
plugin_base.memoize_important_follower_config(node.slaveinput)
node.slaveinput["follower_ident"] = "test_%s" % next(_follower_count)
- from . import provision
+ from sqlalchemy.testing import provision
provision.create_follower_db(node.slaveinput["follower_ident"])
def pytest_testnodedown(node, error):
- from . import provision
+ from sqlalchemy.testing import provision
provision.drop_follower_db(node.slaveinput["follower_ident"])
from sqlalchemy.engine import url as sa_url
from sqlalchemy import text
from sqlalchemy.util import compat
-from .. import config, engines
-import os
+from . import config, engines
+
+
+FOLLOWER_IDENT = None
class register(object):
"""
-from sqlalchemy.testing.plugin.noseplugin import NoseSQLAlchemy
+from .plugin.noseplugin import NoseSQLAlchemy
import nose
"""
import sys
import nose
-import warnings
+import os
-from os import path
for pth in ['./lib']:
- sys.path.insert(0, path.join(path.dirname(path.abspath(__file__)), pth))
+ sys.path.insert(
+ 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), pth))
-# installing without importing SQLAlchemy, so that coverage includes
-# SQLAlchemy itself.
-path = "lib/sqlalchemy/testing/plugin/noseplugin.py"
-if sys.version_info >= (3, 3):
- from importlib import machinery
- noseplugin = machinery.SourceFileLoader("noseplugin", path).load_module()
-else:
- import imp
- noseplugin = imp.load_source("noseplugin", path)
+# use bootstrapping so that test plugins are loaded
+# without touching the main library before coverage starts
+bootstrap_file = os.path.join(
+ os.path.dirname(__file__), "lib", "sqlalchemy",
+ "testing", "plugin", "bootstrap.py"
+)
+with open(bootstrap_file) as f:
+ code = compile(f.read(), "bootstrap.py", 'exec')
+ to_bootstrap = "nose"
+ exec(code, globals(), locals())
-nose.main(addplugins=[noseplugin.NoseSQLAlchemy()])
+
+from noseplugin import NoseSQLAlchemy
+nose.main(addplugins=[NoseSQLAlchemy()])
"""
import sys
+import os
-from os import path
for pth in ['../lib']:
- sys.path.insert(0, path.join(path.dirname(path.abspath(__file__)), pth))
+ sys.path.insert(
+ 0,
+ os.path.join(os.path.dirname(os.path.abspath(__file__)), pth))
-from sqlalchemy.testing.plugin.pytestplugin import *
+
+# use bootstrapping so that test plugins are loaded
+# without touching the main library before coverage starts
+bootstrap_file = os.path.join(
+ os.path.dirname(__file__), "..", "lib", "sqlalchemy",
+ "testing", "plugin", "bootstrap.py"
+)
+
+with open(bootstrap_file) as f:
+ code = compile(f.read(), "bootstrap.py", 'exec')
+ to_bootstrap = "pytest"
+ exec(code, globals(), locals())
+ from pytestplugin import * # noqa
[tox]
-envlist = full
+envlist = full,py26,py27,py33,py34
[testenv]
deps=pytest
- flake8
- coverage
mock
sitepackages=True
usedevelop=True
commands=
- python -m pytest {posargs}
-envdir=pytest
+ python -m pytest -n4 {posargs}
[testenv:full]
setenv=
DISABLE_SQLALCHEMY_CEXT=1
+# see also .coveragerc
+deps=coverage
commands=
- python -m pytest \
- --cov=lib/sqlalchemy \
- --exclude-tag memory-intensive \
- --exclude-tag timing-intensive \
- -k "not aaa_profiling" \
- {posargs}
- python -m coverage xml --include=lib/sqlalchemy/*
+ python -m pytest --cov=sqlalchemy --cov-report term --cov-report xml \
+ --exclude-tag memory-intensive \
+ --exclude-tag timing-intensive \
+ -k "not aaa_profiling" \
+ {posargs}
+
[testenv:pep8]
commands = python -m flake8 {posargs}
[flake8]
-
+deps=flake8
show-source = True
ignore = E711,E712,E721,F841,F811
exclude=.venv,.git,.tox,dist,doc,*egg,build