Skip to content

Commit 6e72cdf

Browse files
Update flask tests and enable flaskmaster (#1163)
* Update flask tests and enable flaskmaster * Remove use of egg for flaskmaster * import separately instead of using extra --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 16838fb commit 6e72cdf

File tree

6 files changed

+181
-127
lines changed

6 files changed

+181
-127
lines changed

tests/framework_flask/_test_blueprints.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,70 +13,82 @@
1313
# limitations under the License.
1414

1515
import webtest
16-
17-
from flask import Flask
18-
from flask import Blueprint
19-
from werkzeug.routing import Rule
20-
2116
from conftest import is_flask_v2 as nested_blueprint_support
17+
from conftest import is_not_flask_v2_3 as before_app_first_request_support
18+
from flask import Blueprint, Flask
19+
from werkzeug.routing import Rule
2220

2321
# Blueprints are only available in 0.7.0 onwards.
2422

25-
blueprint = Blueprint('blueprint', __name__)
23+
blueprint = Blueprint("blueprint", __name__)
2624

2725
application = Flask(__name__)
2826

29-
@blueprint.route('/index')
27+
28+
@blueprint.route("/index")
3029
def index_page():
31-
return 'BLUEPRINT INDEX RESPONSE'
30+
return "BLUEPRINT INDEX RESPONSE"
3231

33-
@blueprint.endpoint('endpoint')
32+
33+
@blueprint.endpoint("endpoint")
3434
def endpoint_page():
35-
return 'BLUEPRINT ENDPOINT RESPONSE'
35+
return "BLUEPRINT ENDPOINT RESPONSE"
36+
37+
38+
# < Flask v2.3.0
39+
if before_app_first_request_support:
40+
41+
@blueprint.before_app_first_request
42+
def before_app_first_request():
43+
pass
3644

37-
@blueprint.before_app_first_request
38-
def before_app_first_request():
39-
pass
4045

4146
@blueprint.before_request
4247
def before_request():
4348
pass
4449

50+
4551
@blueprint.before_app_request
4652
def before_app_request():
4753
pass
4854

55+
4956
@blueprint.after_request
5057
def after_request(response):
5158
return response
5259

60+
5361
@blueprint.after_app_request
5462
def after_app_request(response):
5563
return response
5664

65+
5766
@blueprint.teardown_request
5867
def teardown_request(exc):
5968
pass
6069

70+
6171
@blueprint.teardown_app_request
6272
def teardown_app_request(exc):
6373
pass
6474

75+
6576
# Support for nested blueprints was added in Flask 2.0
6677
if nested_blueprint_support:
67-
parent = Blueprint('parent', __name__, url_prefix='/parent')
68-
child = Blueprint('child', __name__, url_prefix='/child')
78+
parent = Blueprint("parent", __name__, url_prefix="/parent")
79+
child = Blueprint("child", __name__, url_prefix="/child")
6980

7081
parent.register_blueprint(child)
7182

72-
@child.route('/nested')
83+
@child.route("/nested")
7384
def nested_page():
74-
return 'PARENT NESTED RESPONSE'
85+
return "PARENT NESTED RESPONSE"
86+
7587
application.register_blueprint(parent)
7688

7789
application.register_blueprint(blueprint)
7890

7991

80-
application.url_map.add(Rule('/endpoint', endpoint='endpoint'))
92+
application.url_map.add(Rule("/endpoint", endpoint="endpoint"))
8193

8294
_test_application = webtest.TestApp(application)

tests/framework_flask/_test_middleware.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,48 @@
1313
# limitations under the License.
1414

1515
import webtest
16-
16+
from conftest import is_not_flask_v2_3 as before_first_request_support
1717
from flask import Flask
1818

1919
application = Flask(__name__)
2020

21-
@application.before_first_request
22-
def before_first_request():
23-
pass
21+
# < Flask v2.3.0
22+
if before_first_request_support:
23+
24+
@application.before_first_request
25+
def before_first_request():
26+
pass
27+
28+
29+
# >= Flask v2.3.0
30+
def application_app_context():
31+
with application.app_context():
32+
pass
33+
2434

2535
@application.before_request
2636
def before_request():
2737
pass
2838

39+
2940
@application.after_request
3041
def after_request(response):
3142
return response
3243

44+
3345
@application.teardown_request
3446
def teardown_request(exc):
3547
pass
3648

49+
3750
@application.teardown_appcontext
3851
def teardown_appcontext(exc):
3952
pass
4053

41-
@application.route('/middleware')
54+
55+
@application.route("/middleware")
4256
def index_page():
43-
return 'INDEX RESPONSE'
57+
return "INDEX RESPONSE"
58+
4459

4560
_test_application = webtest.TestApp(application)

tests/framework_flask/conftest.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@
1515
import platform
1616

1717
import pytest
18-
from flask import __version__ as flask_version
18+
from flask import (
19+
__version__ as flask_version, # required for python 3.7 in lieu of get_package_version_tuple
20+
)
21+
22+
from newrelic.common.package_version_utils import get_package_version_tuple
23+
24+
try:
25+
FLASK_VERSION = tuple(int(v) for v in flask_version.split("."))
26+
except:
27+
# This does not work for Python 3.7 for v2.2.5
28+
# This only works for flaskmaster
29+
FLASK_VERSION = get_package_version_tuple("flask")
30+
1931
from testing_support.fixtures import ( # noqa: F401; pylint: disable=W0611
2032
collector_agent_registration_fixture,
2133
collector_available_fixture,
@@ -36,10 +48,11 @@
3648
)
3749

3850

39-
is_flask_v2 = int(flask_version.split(".")[0]) >= 2
51+
is_flask_v2 = FLASK_VERSION[0] >= 2
52+
is_not_flask_v2_3 = FLASK_VERSION < (2, 3, 0)
4053
is_pypy = platform.python_implementation() == "PyPy"
4154
async_handler_support = is_flask_v2 and not is_pypy
4255
skip_if_not_async_handler_support = pytest.mark.skipif(
4356
not async_handler_support,
44-
reason="Requires async handler support. (Flask >=v2.0.0)",
57+
reason="Requires async handler support. (Flask >=v2.0.0, CPython)",
4558
)

tests/framework_flask/test_blueprints.py

Lines changed: 73 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@
1313
# limitations under the License.
1414

1515
import pytest
16-
17-
from testing_support.fixtures import override_application_settings
18-
from testing_support.validators.validate_code_level_metrics import validate_code_level_metrics
19-
from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics
20-
from testing_support.validators.validate_transaction_errors import validate_transaction_errors
21-
22-
from newrelic.packages import six
23-
2416
from conftest import is_flask_v2 as nested_blueprint_support
17+
from testing_support.validators.validate_code_level_metrics import (
18+
validate_code_level_metrics,
19+
)
20+
from testing_support.validators.validate_transaction_errors import (
21+
validate_transaction_errors,
22+
)
23+
from testing_support.validators.validate_transaction_metrics import (
24+
validate_transaction_metrics,
25+
)
2526

26-
skip_if_not_nested_blueprint_support = pytest.mark.skipif(not nested_blueprint_support,
27-
reason="Requires nested blueprint support. (Flask >=v2.0.0)")
27+
skip_if_not_nested_blueprint_support = pytest.mark.skipif(
28+
not nested_blueprint_support, reason="Requires nested blueprint support. (Flask >=v2.0.0)"
29+
)
2830

2931

3032
def target_application():
@@ -38,29 +40,32 @@ def target_application():
3840
# showing <local> scope in path.
3941

4042
from _test_blueprints import _test_application
43+
4144
return _test_application
4245

46+
4347
_test_blueprints_index_scoped_metrics = [
44-
('Function/flask.app:Flask.wsgi_app', 1),
45-
('Python/WSGI/Application', 1),
46-
('Python/WSGI/Response', 1),
47-
('Python/WSGI/Finalize', 1),
48-
('Function/_test_blueprints:index_page', 1),
49-
('Function/flask.app:Flask.preprocess_request', 1),
50-
('Function/_test_blueprints:before_app_request', 1),
51-
('Function/_test_blueprints:before_request', 1),
52-
('Function/flask.app:Flask.process_response', 1),
53-
('Function/_test_blueprints:after_request', 1),
54-
('Function/_test_blueprints:after_app_request', 1),
55-
('Function/flask.app:Flask.do_teardown_request', 1),
56-
('Function/_test_blueprints:teardown_app_request', 1),
57-
('Function/_test_blueprints:teardown_request', 1),
58-
('Function/flask.app:Flask.do_teardown_appcontext', 1),
59-
('Function/werkzeug.wsgi:ClosingIterator.close', 1)]
48+
("Function/flask.app:Flask.wsgi_app", 1),
49+
("Python/WSGI/Application", 1),
50+
("Python/WSGI/Response", 1),
51+
("Python/WSGI/Finalize", 1),
52+
("Function/_test_blueprints:index_page", 1),
53+
("Function/flask.app:Flask.preprocess_request", 1),
54+
("Function/_test_blueprints:before_app_request", 1),
55+
("Function/_test_blueprints:before_request", 1),
56+
("Function/flask.app:Flask.process_response", 1),
57+
("Function/_test_blueprints:after_request", 1),
58+
("Function/_test_blueprints:after_app_request", 1),
59+
("Function/flask.app:Flask.do_teardown_request", 1),
60+
("Function/_test_blueprints:teardown_app_request", 1),
61+
("Function/_test_blueprints:teardown_request", 1),
62+
("Function/flask.app:Flask.do_teardown_appcontext", 1),
63+
("Function/werkzeug.wsgi:ClosingIterator.close", 1),
64+
]
65+
6066

6167
@validate_transaction_errors(errors=[])
62-
@validate_transaction_metrics('_test_blueprints:index_page',
63-
scoped_metrics=_test_blueprints_index_scoped_metrics)
68+
@validate_transaction_metrics("_test_blueprints:index_page", scoped_metrics=_test_blueprints_index_scoped_metrics)
6469
@validate_code_level_metrics("_test_blueprints", "index_page")
6570
@validate_code_level_metrics("_test_blueprints", "before_app_request")
6671
@validate_code_level_metrics("_test_blueprints", "before_request")
@@ -70,60 +75,61 @@ def target_application():
7075
@validate_code_level_metrics("_test_blueprints", "teardown_request")
7176
def test_blueprints_index():
7277
application = target_application()
73-
response = application.get('/index')
74-
response.mustcontain('BLUEPRINT INDEX RESPONSE')
78+
response = application.get("/index")
79+
response.mustcontain("BLUEPRINT INDEX RESPONSE")
80+
7581

7682
_test_blueprints_endpoint_scoped_metrics = [
77-
('Function/flask.app:Flask.wsgi_app', 1),
78-
('Python/WSGI/Application', 1),
79-
('Python/WSGI/Response', 1),
80-
('Python/WSGI/Finalize', 1),
81-
('Function/_test_blueprints:endpoint_page', 1),
82-
('Function/flask.app:Flask.preprocess_request', 1),
83-
('Function/_test_blueprints:before_app_request', 1),
84-
('Function/flask.app:Flask.process_response', 1),
85-
('Function/_test_blueprints:after_app_request', 1),
86-
('Function/flask.app:Flask.do_teardown_request', 1),
87-
('Function/_test_blueprints:teardown_app_request', 1),
88-
('Function/flask.app:Flask.do_teardown_appcontext', 1),
89-
('Function/werkzeug.wsgi:ClosingIterator.close', 1)]
83+
("Function/flask.app:Flask.wsgi_app", 1),
84+
("Python/WSGI/Application", 1),
85+
("Python/WSGI/Response", 1),
86+
("Python/WSGI/Finalize", 1),
87+
("Function/_test_blueprints:endpoint_page", 1),
88+
("Function/flask.app:Flask.preprocess_request", 1),
89+
("Function/_test_blueprints:before_app_request", 1),
90+
("Function/flask.app:Flask.process_response", 1),
91+
("Function/_test_blueprints:after_app_request", 1),
92+
("Function/flask.app:Flask.do_teardown_request", 1),
93+
("Function/_test_blueprints:teardown_app_request", 1),
94+
("Function/flask.app:Flask.do_teardown_appcontext", 1),
95+
("Function/werkzeug.wsgi:ClosingIterator.close", 1),
96+
]
97+
9098

9199
@validate_transaction_errors(errors=[])
92-
@validate_transaction_metrics('_test_blueprints:endpoint_page',
93-
scoped_metrics=_test_blueprints_endpoint_scoped_metrics)
100+
@validate_transaction_metrics("_test_blueprints:endpoint_page", scoped_metrics=_test_blueprints_endpoint_scoped_metrics)
94101
@validate_code_level_metrics("_test_blueprints", "endpoint_page")
95102
@validate_code_level_metrics("_test_blueprints", "before_app_request")
96103
@validate_code_level_metrics("_test_blueprints", "after_app_request")
97104
@validate_code_level_metrics("_test_blueprints", "teardown_app_request")
98105
def test_blueprints_endpoint():
99106
application = target_application()
100-
response = application.get('/endpoint')
101-
response.mustcontain('BLUEPRINT ENDPOINT RESPONSE')
107+
response = application.get("/endpoint")
108+
response.mustcontain("BLUEPRINT ENDPOINT RESPONSE")
102109

103110

104111
_test_blueprints_nested_scoped_metrics = [
105-
('Function/flask.app:Flask.wsgi_app', 1),
106-
('Python/WSGI/Application', 1),
107-
('Python/WSGI/Response', 1),
108-
('Python/WSGI/Finalize', 1),
109-
('Function/_test_blueprints:nested_page', 1),
110-
('Function/flask.app:Flask.preprocess_request', 1),
111-
('Function/_test_blueprints:before_app_request', 1),
112-
('Function/_test_blueprints:before_request', 1),
113-
('Function/flask.app:Flask.process_response', 1),
114-
('Function/_test_blueprints:after_request', 1),
115-
('Function/_test_blueprints:after_app_request', 1),
116-
('Function/flask.app:Flask.do_teardown_request', 1),
117-
('Function/_test_blueprints:teardown_app_request', 1),
118-
('Function/_test_blueprints:teardown_request', 1),
119-
('Function/flask.app:Flask.do_teardown_appcontext', 1),
120-
('Function/werkzeug.wsgi:ClosingIterator.close', 1)]
112+
("Function/flask.app:Flask.wsgi_app", 1),
113+
("Python/WSGI/Application", 1),
114+
("Python/WSGI/Response", 1),
115+
("Python/WSGI/Finalize", 1),
116+
("Function/_test_blueprints:nested_page", 1),
117+
("Function/flask.app:Flask.preprocess_request", 1),
118+
("Function/_test_blueprints:before_app_request", 1),
119+
("Function/flask.app:Flask.process_response", 1),
120+
("Function/_test_blueprints:after_app_request", 1),
121+
("Function/flask.app:Flask.do_teardown_request", 1),
122+
("Function/_test_blueprints:teardown_app_request", 1),
123+
("Function/flask.app:Flask.do_teardown_appcontext", 1),
124+
("Function/werkzeug.wsgi:ClosingIterator.close", 1),
125+
]
126+
121127

122128
@skip_if_not_nested_blueprint_support
123129
@validate_transaction_errors(errors=[])
124-
@validate_transaction_metrics('_test_blueprints:nested_page')
130+
@validate_transaction_metrics("_test_blueprints:nested_page", scoped_metrics=_test_blueprints_nested_scoped_metrics)
125131
@validate_code_level_metrics("_test_blueprints", "nested_page")
126132
def test_blueprints_nested():
127-
application = target_application()
128-
response = application.get('/parent/child/nested')
129-
response.mustcontain('PARENT NESTED RESPONSE')
133+
application = target_application()
134+
response = application.get("/parent/child/nested")
135+
response.mustcontain("PARENT NESTED RESPONSE")

0 commit comments

Comments
 (0)