config.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. # -*- coding: utf-8 -*-
  2. """
  3. flask.testsuite.config
  4. ~~~~~~~~~~~~~~~~~~~~~~
  5. Configuration and instances.
  6. :copyright: (c) 2011 by Armin Ronacher.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. import os
  10. import sys
  11. import flask
  12. import pkgutil
  13. import unittest
  14. from contextlib import contextmanager
  15. from flask.testsuite import FlaskTestCase
  16. # config keys used for the ConfigTestCase
  17. TEST_KEY = 'foo'
  18. SECRET_KEY = 'devkey'
  19. class ConfigTestCase(FlaskTestCase):
  20. def common_object_test(self, app):
  21. self.assert_equal(app.secret_key, 'devkey')
  22. self.assert_equal(app.config['TEST_KEY'], 'foo')
  23. self.assert_not_in('ConfigTestCase', app.config)
  24. def test_config_from_file(self):
  25. app = flask.Flask(__name__)
  26. app.config.from_pyfile(__file__.rsplit('.', 1)[0] + '.py')
  27. self.common_object_test(app)
  28. def test_config_from_object(self):
  29. app = flask.Flask(__name__)
  30. app.config.from_object(__name__)
  31. self.common_object_test(app)
  32. def test_config_from_class(self):
  33. class Base(object):
  34. TEST_KEY = 'foo'
  35. class Test(Base):
  36. SECRET_KEY = 'devkey'
  37. app = flask.Flask(__name__)
  38. app.config.from_object(Test)
  39. self.common_object_test(app)
  40. def test_config_from_envvar(self):
  41. env = os.environ
  42. try:
  43. os.environ = {}
  44. app = flask.Flask(__name__)
  45. try:
  46. app.config.from_envvar('FOO_SETTINGS')
  47. except RuntimeError as e:
  48. self.assert_true("'FOO_SETTINGS' is not set" in str(e))
  49. else:
  50. self.assert_true(0, 'expected exception')
  51. self.assert_false(app.config.from_envvar('FOO_SETTINGS', silent=True))
  52. os.environ = {'FOO_SETTINGS': __file__.rsplit('.', 1)[0] + '.py'}
  53. self.assert_true(app.config.from_envvar('FOO_SETTINGS'))
  54. self.common_object_test(app)
  55. finally:
  56. os.environ = env
  57. def test_config_from_envvar_missing(self):
  58. env = os.environ
  59. try:
  60. os.environ = {'FOO_SETTINGS': 'missing.cfg'}
  61. try:
  62. app = flask.Flask(__name__)
  63. app.config.from_envvar('FOO_SETTINGS')
  64. except IOError as e:
  65. msg = str(e)
  66. self.assert_true(msg.startswith('[Errno 2] Unable to load configuration '
  67. 'file (No such file or directory):'))
  68. self.assert_true(msg.endswith("missing.cfg'"))
  69. else:
  70. self.fail('expected IOError')
  71. self.assertFalse(app.config.from_envvar('FOO_SETTINGS', silent=True))
  72. finally:
  73. os.environ = env
  74. def test_config_missing(self):
  75. app = flask.Flask(__name__)
  76. try:
  77. app.config.from_pyfile('missing.cfg')
  78. except IOError as e:
  79. msg = str(e)
  80. self.assert_true(msg.startswith('[Errno 2] Unable to load configuration '
  81. 'file (No such file or directory):'))
  82. self.assert_true(msg.endswith("missing.cfg'"))
  83. else:
  84. self.assert_true(0, 'expected config')
  85. self.assert_false(app.config.from_pyfile('missing.cfg', silent=True))
  86. def test_session_lifetime(self):
  87. app = flask.Flask(__name__)
  88. app.config['PERMANENT_SESSION_LIFETIME'] = 42
  89. self.assert_equal(app.permanent_session_lifetime.seconds, 42)
  90. class LimitedLoaderMockWrapper(object):
  91. def __init__(self, loader):
  92. self.loader = loader
  93. def __getattr__(self, name):
  94. if name in ('archive', 'get_filename'):
  95. msg = 'Mocking a loader which does not have `%s.`' % name
  96. raise AttributeError(msg)
  97. return getattr(self.loader, name)
  98. @contextmanager
  99. def patch_pkgutil_get_loader(wrapper_class=LimitedLoaderMockWrapper):
  100. """Patch pkgutil.get_loader to give loader without get_filename or archive.
  101. This provides for tests where a system has custom loaders, e.g. Google App
  102. Engine's HardenedModulesHook, which have neither the `get_filename` method
  103. nor the `archive` attribute.
  104. """
  105. old_get_loader = pkgutil.get_loader
  106. def get_loader(*args, **kwargs):
  107. return wrapper_class(old_get_loader(*args, **kwargs))
  108. try:
  109. pkgutil.get_loader = get_loader
  110. yield
  111. finally:
  112. pkgutil.get_loader = old_get_loader
  113. class InstanceTestCase(FlaskTestCase):
  114. def test_explicit_instance_paths(self):
  115. here = os.path.abspath(os.path.dirname(__file__))
  116. try:
  117. flask.Flask(__name__, instance_path='instance')
  118. except ValueError as e:
  119. self.assert_in('must be absolute', str(e))
  120. else:
  121. self.fail('Expected value error')
  122. app = flask.Flask(__name__, instance_path=here)
  123. self.assert_equal(app.instance_path, here)
  124. def test_main_module_paths(self):
  125. # Test an app with '__main__' as the import name, uses cwd.
  126. from main_app import app
  127. here = os.path.abspath(os.getcwd())
  128. self.assert_equal(app.instance_path, os.path.join(here, 'instance'))
  129. if 'main_app' in sys.modules:
  130. del sys.modules['main_app']
  131. def test_uninstalled_module_paths(self):
  132. from config_module_app import app
  133. here = os.path.abspath(os.path.dirname(__file__))
  134. self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance'))
  135. def test_uninstalled_package_paths(self):
  136. from config_package_app import app
  137. here = os.path.abspath(os.path.dirname(__file__))
  138. self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance'))
  139. def test_installed_module_paths(self):
  140. here = os.path.abspath(os.path.dirname(__file__))
  141. expected_prefix = os.path.join(here, 'test_apps')
  142. real_prefix, sys.prefix = sys.prefix, expected_prefix
  143. site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
  144. sys.path.append(site_packages)
  145. try:
  146. import site_app
  147. self.assert_equal(site_app.app.instance_path,
  148. os.path.join(expected_prefix, 'var',
  149. 'site_app-instance'))
  150. finally:
  151. sys.prefix = real_prefix
  152. sys.path.remove(site_packages)
  153. if 'site_app' in sys.modules:
  154. del sys.modules['site_app']
  155. def test_installed_module_paths_with_limited_loader(self):
  156. here = os.path.abspath(os.path.dirname(__file__))
  157. expected_prefix = os.path.join(here, 'test_apps')
  158. real_prefix, sys.prefix = sys.prefix, expected_prefix
  159. site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
  160. sys.path.append(site_packages)
  161. with patch_pkgutil_get_loader():
  162. try:
  163. import site_app
  164. self.assert_equal(site_app.app.instance_path,
  165. os.path.join(expected_prefix, 'var',
  166. 'site_app-instance'))
  167. finally:
  168. sys.prefix = real_prefix
  169. sys.path.remove(site_packages)
  170. if 'site_app' in sys.modules:
  171. del sys.modules['site_app']
  172. def test_installed_package_paths(self):
  173. here = os.path.abspath(os.path.dirname(__file__))
  174. expected_prefix = os.path.join(here, 'test_apps')
  175. real_prefix, sys.prefix = sys.prefix, expected_prefix
  176. installed_path = os.path.join(expected_prefix, 'path')
  177. sys.path.append(installed_path)
  178. try:
  179. import installed_package
  180. self.assert_equal(installed_package.app.instance_path,
  181. os.path.join(expected_prefix, 'var',
  182. 'installed_package-instance'))
  183. finally:
  184. sys.prefix = real_prefix
  185. sys.path.remove(installed_path)
  186. if 'installed_package' in sys.modules:
  187. del sys.modules['installed_package']
  188. def test_installed_package_paths_with_limited_loader(self):
  189. here = os.path.abspath(os.path.dirname(__file__))
  190. expected_prefix = os.path.join(here, 'test_apps')
  191. real_prefix, sys.prefix = sys.prefix, expected_prefix
  192. installed_path = os.path.join(expected_prefix, 'path')
  193. sys.path.append(installed_path)
  194. with patch_pkgutil_get_loader():
  195. try:
  196. import installed_package
  197. self.assert_equal(installed_package.app.instance_path,
  198. os.path.join(expected_prefix, 'var',
  199. 'installed_package-instance'))
  200. finally:
  201. sys.prefix = real_prefix
  202. sys.path.remove(installed_path)
  203. if 'installed_package' in sys.modules:
  204. del sys.modules['installed_package']
  205. def test_prefix_package_paths(self):
  206. here = os.path.abspath(os.path.dirname(__file__))
  207. expected_prefix = os.path.join(here, 'test_apps')
  208. real_prefix, sys.prefix = sys.prefix, expected_prefix
  209. site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
  210. sys.path.append(site_packages)
  211. try:
  212. import site_package
  213. self.assert_equal(site_package.app.instance_path,
  214. os.path.join(expected_prefix, 'var',
  215. 'site_package-instance'))
  216. finally:
  217. sys.prefix = real_prefix
  218. sys.path.remove(site_packages)
  219. if 'site_package' in sys.modules:
  220. del sys.modules['site_package']
  221. def test_prefix_package_paths_with_limited_loader(self):
  222. here = os.path.abspath(os.path.dirname(__file__))
  223. expected_prefix = os.path.join(here, 'test_apps')
  224. real_prefix, sys.prefix = sys.prefix, expected_prefix
  225. site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
  226. sys.path.append(site_packages)
  227. with patch_pkgutil_get_loader():
  228. try:
  229. import site_package
  230. self.assert_equal(site_package.app.instance_path,
  231. os.path.join(expected_prefix, 'var',
  232. 'site_package-instance'))
  233. finally:
  234. sys.prefix = real_prefix
  235. sys.path.remove(site_packages)
  236. if 'site_package' in sys.modules:
  237. del sys.modules['site_package']
  238. def test_egg_installed_paths(self):
  239. here = os.path.abspath(os.path.dirname(__file__))
  240. expected_prefix = os.path.join(here, 'test_apps')
  241. real_prefix, sys.prefix = sys.prefix, expected_prefix
  242. site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages')
  243. egg_path = os.path.join(site_packages, 'SiteEgg.egg')
  244. sys.path.append(site_packages)
  245. sys.path.append(egg_path)
  246. try:
  247. import site_egg # in SiteEgg.egg
  248. self.assert_equal(site_egg.app.instance_path,
  249. os.path.join(expected_prefix, 'var',
  250. 'site_egg-instance'))
  251. finally:
  252. sys.prefix = real_prefix
  253. sys.path.remove(site_packages)
  254. sys.path.remove(egg_path)
  255. if 'site_egg' in sys.modules:
  256. del sys.modules['site_egg']
  257. def suite():
  258. suite = unittest.TestSuite()
  259. suite.addTest(unittest.makeSuite(ConfigTestCase))
  260. suite.addTest(unittest.makeSuite(InstanceTestCase))
  261. return suite