Rework test_config

This commit is contained in:
Markus Unterwaditzer 2014-09-01 18:03:16 +02:00
parent a497b10d4f
commit ba82bac3d8

View file

@ -9,11 +9,14 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import pytest
import os import os
import sys import sys
import flask import flask
import pkgutil import pkgutil
import unittest import unittest
import textwrap
from contextlib import contextmanager from contextlib import contextmanager
from tests import TestFlask from tests import TestFlask
from flask._compat import PY2 from flask._compat import PY2
@ -178,7 +181,21 @@ class TestConfig(TestFlask):
self.assert_equal('bar stuff 2', bar_options['STUFF_2']) self.assert_equal('bar stuff 2', bar_options['STUFF_2'])
class LimitedLoaderMockWrapper(object): @pytest.fixture(params=(True, False))
def limit_loader(request, monkeypatch):
"""Patch pkgutil.get_loader to give loader without get_filename or archive.
This provides for tests where a system has custom loaders, e.g. Google App
Engine's HardenedModulesHook, which have neither the `get_filename` method
nor the `archive` attribute.
This fixture will run the testcase twice, once with and once without the
limitation/mock.
"""
if not request.param:
return
class LimitedLoader(object):
def __init__(self, loader): def __init__(self, loader):
self.loader = loader self.loader = loader
@ -188,178 +205,161 @@ class LimitedLoaderMockWrapper(object):
raise AttributeError(msg) raise AttributeError(msg)
return getattr(self.loader, name) return getattr(self.loader, name)
@contextmanager
def patch_pkgutil_get_loader(wrapper_class=LimitedLoaderMockWrapper):
"""Patch pkgutil.get_loader to give loader without get_filename or archive.
This provides for tests where a system has custom loaders, e.g. Google App
Engine's HardenedModulesHook, which have neither the `get_filename` method
nor the `archive` attribute.
"""
old_get_loader = pkgutil.get_loader old_get_loader = pkgutil.get_loader
def get_loader(*args, **kwargs): def get_loader(*args, **kwargs):
return wrapper_class(old_get_loader(*args, **kwargs)) return LimitedLoader(old_get_loader(*args, **kwargs))
try: monkeypatch.setattr(pkgutil, 'get_loader', get_loader)
pkgutil.get_loader = get_loader
yield
finally:
pkgutil.get_loader = old_get_loader
class TestInstance(TestFlask): class TestInstance(TestFlask):
@pytest.fixture
def apps_tmpdir(self, tmpdir, monkeypatch):
'''Test folder for all instance tests.'''
rv = tmpdir.mkdir('test_apps')
monkeypatch.syspath_prepend(str(rv))
return rv
def test_explicit_instance_paths(self): @pytest.fixture
here = os.path.abspath(os.path.dirname(__file__)) def apps_tmpdir_prefix(self, apps_tmpdir, monkeypatch):
try: monkeypatch.setattr(sys, 'prefix', str(apps_tmpdir))
return apps_tmpdir
@pytest.fixture
def site_packages(self, apps_tmpdir, monkeypatch):
'''Create a fake site-packages'''
rv = apps_tmpdir \
.mkdir('lib')\
.mkdir('python{x[0]}.{x[1]}'.format(x=sys.version_info))\
.mkdir('site-packages')
monkeypatch.syspath_prepend(str(rv))
return rv
@pytest.fixture
def install_egg(self, apps_tmpdir, monkeypatch):
'''Generate egg from package name inside base and put the egg into
sys.path'''
def inner(name, base=apps_tmpdir):
if not isinstance(name, str):
raise ValueError(name)
base.join(name).ensure_dir()
base.join(name).join('__init__.py').ensure()
egg_setup = base.join('setup.py')
egg_setup.write(textwrap.dedent("""
from setuptools import setup
setup(name='{0}',
version='1.0',
packages=['site_egg'],
zip_safe=True)
""".format(name)))
import subprocess
subprocess.check_call(
[sys.executable, 'setup.py', 'bdist_egg'],
cwd=str(apps_tmpdir)
)
egg_path, = apps_tmpdir.join('dist/').listdir()
monkeypatch.syspath_prepend(str(egg_path))
return egg_path
return inner
@pytest.fixture
def purge_module(self, request):
def inner(name):
request.addfinalizer(lambda: sys.modules.pop(name, None))
return inner
def test_explicit_instance_paths(self, apps_tmpdir):
with pytest.raises(ValueError) as excinfo:
flask.Flask(__name__, instance_path='instance') flask.Flask(__name__, instance_path='instance')
except ValueError as e: assert 'must be absolute' in str(excinfo.value)
self.assert_in('must be absolute', str(e))
else:
self.fail('Expected value error')
app = flask.Flask(__name__, instance_path=here) app = flask.Flask(__name__, instance_path=str(apps_tmpdir))
self.assert_equal(app.instance_path, here) self.assert_equal(app.instance_path, str(apps_tmpdir))
def test_main_module_paths(self, apps_tmpdir, purge_module):
app = apps_tmpdir.join('main_app.py')
app.write('import flask\n\napp = flask.Flask("__main__")')
purge_module('main_app')
def test_main_module_paths(self):
# Test an app with '__main__' as the import name, uses cwd.
from main_app import app from main_app import app
here = os.path.abspath(os.getcwd()) here = os.path.abspath(os.getcwd())
self.assert_equal(app.instance_path, os.path.join(here, 'instance')) assert app.instance_path == os.path.join(here, 'instance')
if 'main_app' in sys.modules:
del sys.modules['main_app'] def test_uninstalled_module_paths(self, apps_tmpdir, purge_module):
app = apps_tmpdir.join('config_module_app.py').write(
'import os\n'
'import flask\n'
'here = os.path.abspath(os.path.dirname(__file__))\n'
'app = flask.Flask(__name__)\n'
)
purge_module('config_module_app')
def test_uninstalled_module_paths(self):
from config_module_app import app from config_module_app import app
here = os.path.abspath(os.path.dirname(__file__)) assert app.instance_path == str(apps_tmpdir.join('instance'))
self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance'))
def test_uninstalled_package_paths(self, apps_tmpdir, purge_module):
app = apps_tmpdir.mkdir('config_package_app')
init = app.join('__init__.py')
init.write(
'import os\n'
'import flask\n'
'here = os.path.abspath(os.path.dirname(__file__))\n'
'app = flask.Flask(__name__)\n'
)
purge_module('config_package_app')
def test_uninstalled_package_paths(self):
from config_package_app import app from config_package_app import app
here = os.path.abspath(os.path.dirname(__file__)) assert app.instance_path == str(apps_tmpdir.join('instance'))
self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance'))
def test_installed_module_paths(self): def test_installed_module_paths(self, apps_tmpdir, apps_tmpdir_prefix,
here = os.path.abspath(os.path.dirname(__file__)) purge_module, site_packages, limit_loader):
expected_prefix = os.path.join(here, 'test_apps') site_packages.join('site_app.py').write(
real_prefix, sys.prefix = sys.prefix, expected_prefix 'import flask\n'
site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') 'app = flask.Flask(__name__)\n'
sys.path.append(site_packages) )
try: purge_module('site_app')
import site_app
self.assert_equal(site_app.app.instance_path,
os.path.join(expected_prefix, 'var',
'site_app-instance'))
finally:
sys.prefix = real_prefix
sys.path.remove(site_packages)
if 'site_app' in sys.modules:
del sys.modules['site_app']
def test_installed_module_paths_with_limited_loader(self): from site_app import app
here = os.path.abspath(os.path.dirname(__file__)) assert app.instance_path == \
expected_prefix = os.path.join(here, 'test_apps') apps_tmpdir.join('var').join('site_app-instance')
real_prefix, sys.prefix = sys.prefix, expected_prefix
site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
sys.path.append(site_packages)
with patch_pkgutil_get_loader():
try:
import site_app
self.assert_equal(site_app.app.instance_path,
os.path.join(expected_prefix, 'var',
'site_app-instance'))
finally:
sys.prefix = real_prefix
sys.path.remove(site_packages)
if 'site_app' in sys.modules:
del sys.modules['site_app']
def test_installed_package_paths(self): def test_installed_package_paths(self, limit_loader, apps_tmpdir,
here = os.path.abspath(os.path.dirname(__file__)) apps_tmpdir_prefix, purge_module,
expected_prefix = os.path.join(here, 'test_apps') monkeypatch):
real_prefix, sys.prefix = sys.prefix, expected_prefix installed_path = apps_tmpdir.mkdir('path')
installed_path = os.path.join(expected_prefix, 'path') monkeypatch.syspath_prepend(installed_path)
sys.path.append(installed_path)
try:
import installed_package
self.assert_equal(installed_package.app.instance_path,
os.path.join(expected_prefix, 'var',
'installed_package-instance'))
finally:
sys.prefix = real_prefix
sys.path.remove(installed_path)
if 'installed_package' in sys.modules:
del sys.modules['installed_package']
def test_installed_package_paths_with_limited_loader(self): app = installed_path.mkdir('installed_package')
here = os.path.abspath(os.path.dirname(__file__)) init = app.join('__init__.py')
expected_prefix = os.path.join(here, 'test_apps') init.write('import flask\napp = flask.Flask(__name__)')
real_prefix, sys.prefix = sys.prefix, expected_prefix purge_module('installed_package')
installed_path = os.path.join(expected_prefix, 'path')
sys.path.append(installed_path) from installed_package import app
with patch_pkgutil_get_loader(): assert app.instance_path == \
try: apps_tmpdir.join('var').join('installed_package-instance')
import installed_package
self.assert_equal(installed_package.app.instance_path, def test_prefix_package_paths(self, limit_loader, apps_tmpdir,
os.path.join(expected_prefix, 'var', apps_tmpdir_prefix, purge_module,
'installed_package-instance')) site_packages):
finally: app = site_packages.mkdir('site_package')
sys.prefix = real_prefix init = app.join('__init__.py')
sys.path.remove(installed_path) init.write('import flask\napp = flask.Flask(__name__)')
if 'installed_package' in sys.modules: purge_module('site_package')
del sys.modules['installed_package']
def test_prefix_package_paths(self):
here = os.path.abspath(os.path.dirname(__file__))
expected_prefix = os.path.join(here, 'test_apps')
real_prefix, sys.prefix = sys.prefix, expected_prefix
site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
sys.path.append(site_packages)
try:
import site_package import site_package
self.assert_equal(site_package.app.instance_path, assert site_package.app.instance_path == \
os.path.join(expected_prefix, 'var', apps_tmpdir.join('var').join('site_package-instance')
'site_package-instance'))
finally:
sys.prefix = real_prefix
sys.path.remove(site_packages)
if 'site_package' in sys.modules:
del sys.modules['site_package']
def test_prefix_package_paths_with_limited_loader(self): def test_egg_installed_paths(self, install_egg, apps_tmpdir,
here = os.path.abspath(os.path.dirname(__file__)) apps_tmpdir_prefix):
expected_prefix = os.path.join(here, 'test_apps') apps_tmpdir.mkdir('site_egg').join('__init__.py').write(
real_prefix, sys.prefix = sys.prefix, expected_prefix 'import flask\n\napp = flask.Flask(__name__)'
site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') )
sys.path.append(site_packages) install_egg('site_egg')
with patch_pkgutil_get_loader():
try: try:
import site_package import site_egg
self.assert_equal(site_package.app.instance_path, assert site_egg.app.instance_path == \
os.path.join(expected_prefix, 'var', str(apps_tmpdir.join('var/').join('site_egg-instance'))
'site_package-instance'))
finally:
sys.prefix = real_prefix
sys.path.remove(site_packages)
if 'site_package' in sys.modules:
del sys.modules['site_package']
def test_egg_installed_paths(self, monkeypatch):
here = os.path.abspath(os.path.dirname(__file__))
expected_prefix = os.path.join(here, 'test_apps')
monkeypatch.setattr(sys, 'prefix', expected_prefix)
site_packages = os.path.join(expected_prefix, 'lib', 'python2.5',
'site-packages')
egg_path = os.path.join(site_packages, 'SiteEgg.egg')
monkeypatch.syspath_prepend(egg_path)
monkeypatch.syspath_prepend(site_packages)
try:
import site_egg # in SiteEgg.egg
self.assert_equal(site_egg.app.instance_path,
os.path.join(expected_prefix, 'var',
'site_egg-instance'))
finally: finally:
if 'site_egg' in sys.modules: if 'site_egg' in sys.modules:
del sys.modules['site_egg'] del sys.modules['site_egg']
@ -375,10 +375,3 @@ class TestInstance(TestFlask):
flask.Flask(__name__) flask.Flask(__name__)
finally: finally:
sys.meta_path.pop() sys.meta_path.pop()
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestConfig))
suite.addTest(unittest.makeSuite(TestInstance))
return suite