| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2014-09-01 03:54:45 +08:00
										 |  |  |     tests.regression | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Tests regressions. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-03 02:21:07 +08:00
										 |  |  |     :copyright: (c) 2014 by Armin Ronacher. | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  |     :license: BSD, see LICENSE for more details. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | import pytest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-14 18:51:38 +08:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | import gc | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import flask | 
					
						
							|  |  |  | import threading | 
					
						
							| 
									
										
										
										
											2012-10-08 04:58:41 +08:00
										 |  |  | from werkzeug.exceptions import NotFound | 
					
						
							| 
									
										
										
										
											2014-09-04 03:02:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | _gc_lock = threading.Lock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  | class assert_no_leak(object): | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         gc.disable() | 
					
						
							|  |  |  |         _gc_lock.acquire() | 
					
						
							|  |  |  |         loc = flask._request_ctx_stack._local | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Force Python to track this dictionary at all times. | 
					
						
							|  |  |  |         # This is necessary since Python only starts tracking | 
					
						
							|  |  |  |         # dicts if they contain mutable objects.  It's a horrible, | 
					
						
							|  |  |  |         # horrible hack but makes this kinda testable. | 
					
						
							|  |  |  |         loc.__storage__['FOOO'] = [1, 2, 3] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         gc.collect() | 
					
						
							|  |  |  |         self.old_objects = len(gc.get_objects()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exc_type, exc_value, tb): | 
					
						
							|  |  |  |         if not hasattr(sys, 'getrefcount'): | 
					
						
							|  |  |  |             gc.collect() | 
					
						
							|  |  |  |         new_objects = len(gc.get_objects()) | 
					
						
							|  |  |  |         if new_objects > self.old_objects: | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |             pytest.fail('Example code leaked') | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  |         _gc_lock.release() | 
					
						
							|  |  |  |         gc.enable() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 20:35:01 +08:00
										 |  |  | # XXX: untitaker: These tests need to be revised. They broke around the time we | 
					
						
							|  |  |  | # ported Flask to Python 3. | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | @pytest.mark.skipif(os.environ.get('RUN_FLASK_MEMORY_TESTS') != '1', | 
					
						
							|  |  |  |                     reason='Turned off due to envvar.') | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  | def test_memory_consumption(): | 
					
						
							|  |  |  |     app = flask.Flask(__name__) | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     @app.route('/') | 
					
						
							|  |  |  |     def index(): | 
					
						
							|  |  |  |         return flask.render_template('simple_template.html', whiskey=42) | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     def fire(): | 
					
						
							|  |  |  |         with app.test_client() as c: | 
					
						
							|  |  |  |             rv = c.get('/') | 
					
						
							|  |  |  |             assert rv.status_code == 200 | 
					
						
							|  |  |  |             assert rv.data == b'<h1>42</h1>' | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     # Trigger caches | 
					
						
							|  |  |  |     fire() | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     # This test only works on CPython 2.7. | 
					
						
							|  |  |  |     if sys.version_info >= (2, 7) and \ | 
					
						
							|  |  |  |             not hasattr(sys, 'pypy_translation_info'): | 
					
						
							|  |  |  |         with assert_no_leak(): | 
					
						
							|  |  |  |             for x in range(10): | 
					
						
							|  |  |  |                 fire() | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-08 04:58:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  | def test_safe_join_toplevel_pardir(): | 
					
						
							|  |  |  |     from flask.helpers import safe_join | 
					
						
							|  |  |  |     with pytest.raises(NotFound): | 
					
						
							|  |  |  |         safe_join('/foo', '..') | 
					
						
							| 
									
										
										
										
											2011-11-06 00:43:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-22 01:55:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  | def test_aborting(): | 
					
						
							|  |  |  |     class Foo(Exception): | 
					
						
							|  |  |  |         whatever = 42 | 
					
						
							|  |  |  |     app = flask.Flask(__name__) | 
					
						
							|  |  |  |     app.testing = True | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     @app.errorhandler(Foo) | 
					
						
							|  |  |  |     def handle_foo(e): | 
					
						
							|  |  |  |         return str(e.whatever) | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     @app.route('/') | 
					
						
							|  |  |  |     def index(): | 
					
						
							|  |  |  |         raise flask.abort(flask.redirect(flask.url_for('test'))) | 
					
						
							| 
									
										
										
										
											2014-09-01 03:56:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     @app.route('/test') | 
					
						
							|  |  |  |     def test(): | 
					
						
							|  |  |  |         raise Foo() | 
					
						
							| 
									
										
										
										
											2013-01-22 01:55:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 21:32:50 +08:00
										 |  |  |     with app.test_client() as c: | 
					
						
							|  |  |  |         rv = c.get('/') | 
					
						
							|  |  |  |         assert rv.headers['Location'] == 'http://localhost/test' | 
					
						
							|  |  |  |         rv = c.get('/test') | 
					
						
							|  |  |  |         assert rv.data == b'42' |