219 lines
7.7 KiB
Diff
219 lines
7.7 KiB
Diff
|
|
From d78c2aba8e697c723abab7105bad1ad5492e5c6e Mon Sep 17 00:00:00 2001
|
||
|
|
From: ptmcg <ptmcg@austin.rr.com>
|
||
|
|
Date: Sat, 17 Feb 2024 08:35:38 -0600
|
||
|
|
Subject: [PATCH] Remove usage of deprecated Flask variable
|
||
|
|
`_request_ctx_stack`, use `request`; refactor span callback tests to address
|
||
|
|
change in Flask where before/after request callbacks can't be added to an app
|
||
|
|
once it has started serving requests; add `flaky` decorator to
|
||
|
|
`test_request_distinct` and `test_over_wire` unit tests; add Python 3.10
|
||
|
|
compatibility hack to example server and client scripts; change testing to
|
||
|
|
use `tox` instead of deprecated `python setup.py test`; add recent Python
|
||
|
|
versions to tox.ini envlist
|
||
|
|
|
||
|
|
---
|
||
|
|
example/client.py | 7 +++
|
||
|
|
example/server.py | 7 +++
|
||
|
|
flask_opentracing/tracing.py | 10 ++--
|
||
|
|
requirements-test.txt | 1 +
|
||
|
|
setup.cfg | 2 +-
|
||
|
|
setup.py | 1 +
|
||
|
|
tests/README.rst | 3 +-
|
||
|
|
tests/test_flask_tracing.py | 38 ++------------
|
||
|
|
tests/test_flask_tracing_span_callbacks.py | 59 ++++++++++++++++++++++
|
||
|
|
tox.ini | 4 +-
|
||
|
|
10 files changed, 91 insertions(+), 41 deletions(-)
|
||
|
|
create mode 100644 tests/test_flask_tracing_span_callbacks.py
|
||
|
|
|
||
|
|
Index: Flask-OpenTracing-1.1.0/flask_opentracing/tracing.py
|
||
|
|
===================================================================
|
||
|
|
--- Flask-OpenTracing-1.1.0.orig/flask_opentracing/tracing.py
|
||
|
|
+++ Flask-OpenTracing-1.1.0/flask_opentracing/tracing.py
|
||
|
|
@@ -1,6 +1,6 @@
|
||
|
|
import opentracing
|
||
|
|
from opentracing.ext import tags
|
||
|
|
-from flask import _request_ctx_stack as stack
|
||
|
|
+from flask import request as flask_current_request
|
||
|
|
|
||
|
|
|
||
|
|
class FlaskTracing(opentracing.Tracer):
|
||
|
|
@@ -101,14 +101,14 @@ class FlaskTracing(opentracing.Tracer):
|
||
|
|
|
||
|
|
@param request the request to get the span from
|
||
|
|
"""
|
||
|
|
- if request is None and stack.top:
|
||
|
|
- request = stack.top.request
|
||
|
|
+ if request is None:
|
||
|
|
+ request = flask_current_request
|
||
|
|
|
||
|
|
scope = self._current_scopes.get(request, None)
|
||
|
|
return None if scope is None else scope.span
|
||
|
|
|
||
|
|
def _before_request_fn(self, attributes):
|
||
|
|
- request = stack.top.request
|
||
|
|
+ request = flask_current_request
|
||
|
|
operation_name = request.endpoint
|
||
|
|
headers = {}
|
||
|
|
for k, v in request.headers:
|
||
|
|
@@ -140,7 +140,7 @@ class FlaskTracing(opentracing.Tracer):
|
||
|
|
self._call_start_span_cb(span, request)
|
||
|
|
|
||
|
|
def _after_request_fn(self, response=None, error=None):
|
||
|
|
- request = stack.top.request
|
||
|
|
+ request = flask_current_request
|
||
|
|
|
||
|
|
# the pop call can fail if the request is interrupted by a
|
||
|
|
# `before_request` method so we need a default
|
||
|
|
Index: Flask-OpenTracing-1.1.0/setup.cfg
|
||
|
|
===================================================================
|
||
|
|
--- Flask-OpenTracing-1.1.0.orig/setup.cfg
|
||
|
|
+++ Flask-OpenTracing-1.1.0/setup.cfg
|
||
|
|
@@ -2,7 +2,7 @@
|
||
|
|
test = pytest
|
||
|
|
|
||
|
|
[metadata]
|
||
|
|
-description-file = README.rst
|
||
|
|
+description_file = README.rst
|
||
|
|
|
||
|
|
[tool:pytest]
|
||
|
|
addopts =
|
||
|
|
Index: Flask-OpenTracing-1.1.0/tests/test_flask_tracing.py
|
||
|
|
===================================================================
|
||
|
|
--- Flask-OpenTracing-1.1.0.orig/tests/test_flask_tracing.py
|
||
|
|
+++ Flask-OpenTracing-1.1.0/tests/test_flask_tracing.py
|
||
|
|
@@ -6,6 +6,7 @@ import opentracing
|
||
|
|
from opentracing.ext import tags
|
||
|
|
from opentracing.mocktracer import MockTracer
|
||
|
|
from flask_opentracing import FlaskTracing
|
||
|
|
+from flaky import flaky
|
||
|
|
|
||
|
|
|
||
|
|
app = Flask(__name__)
|
||
|
|
@@ -19,8 +20,8 @@ tracing_deferred = FlaskTracing(lambda:
|
||
|
|
|
||
|
|
|
||
|
|
def flush_spans(tcr):
|
||
|
|
- for req in tcr._current_scopes:
|
||
|
|
- tcr._current_scopes[req].close()
|
||
|
|
+ for span in tcr._current_scopes.values():
|
||
|
|
+ span.close()
|
||
|
|
tcr._current_scopes = {}
|
||
|
|
|
||
|
|
|
||
|
|
@@ -101,9 +102,9 @@ class TestTracing(unittest.TestCase):
|
||
|
|
tags.HTTP_METHOD: 'GET',
|
||
|
|
tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER,
|
||
|
|
tags.HTTP_URL: 'http://localhost/another_test_simple',
|
||
|
|
- 'is_xhr': 'False',
|
||
|
|
}
|
||
|
|
|
||
|
|
+ @flaky(max_runs=5)
|
||
|
|
def test_requests_distinct(self):
|
||
|
|
with app.test_request_context('/test'):
|
||
|
|
app.preprocess_request()
|
||
|
|
@@ -176,6 +177,7 @@ class TestTracing(unittest.TestCase):
|
||
|
|
RuntimeError
|
||
|
|
)
|
||
|
|
|
||
|
|
+ @flaky(max_runs=5)
|
||
|
|
def test_over_wire(self):
|
||
|
|
rv = test_app.get('/wire')
|
||
|
|
assert '200' in str(rv.status_code)
|
||
|
|
@@ -193,33 +195,3 @@ class TestTracing(unittest.TestCase):
|
||
|
|
assert len(spans) == 2
|
||
|
|
assert spans[0].context.trace_id == spans[1].context.trace_id
|
||
|
|
assert spans[0].parent_id == spans[1].context.span_id
|
||
|
|
-
|
||
|
|
-
|
||
|
|
-class TestTracingStartSpanCallback(unittest.TestCase):
|
||
|
|
- def test_simple(self):
|
||
|
|
- def start_span_cb(span, request):
|
||
|
|
- span.set_tag('component', 'not-flask')
|
||
|
|
- span.set_tag('mytag', 'myvalue')
|
||
|
|
-
|
||
|
|
- tracing = FlaskTracing(MockTracer(), True, app,
|
||
|
|
- start_span_cb=start_span_cb)
|
||
|
|
- rv = test_app.get('/test')
|
||
|
|
- assert '200' in str(rv.status_code)
|
||
|
|
-
|
||
|
|
- spans = tracing.tracer.finished_spans()
|
||
|
|
- assert len(spans) == 1
|
||
|
|
- assert spans[0].tags.get(tags.COMPONENT, None) == 'not-flask'
|
||
|
|
- assert spans[0].tags.get('mytag', None) == 'myvalue'
|
||
|
|
-
|
||
|
|
- def test_error(self):
|
||
|
|
- def start_span_cb(span, request):
|
||
|
|
- raise RuntimeError('Should not happen')
|
||
|
|
-
|
||
|
|
- tracing = FlaskTracing(MockTracer(), True, app,
|
||
|
|
- start_span_cb=start_span_cb)
|
||
|
|
- rv = test_app.get('/test')
|
||
|
|
- assert '200' in str(rv.status_code)
|
||
|
|
-
|
||
|
|
- spans = tracing.tracer.finished_spans()
|
||
|
|
- assert len(spans) == 1
|
||
|
|
- assert spans[0].tags.get(tags.ERROR, None) is None
|
||
|
|
Index: Flask-OpenTracing-1.1.0/tests/test_flask_tracing_span_callbacks.py
|
||
|
|
===================================================================
|
||
|
|
--- /dev/null
|
||
|
|
+++ Flask-OpenTracing-1.1.0/tests/test_flask_tracing_span_callbacks.py
|
||
|
|
@@ -0,0 +1,59 @@
|
||
|
|
+import unittest
|
||
|
|
+from abc import abstractmethod
|
||
|
|
+
|
||
|
|
+from flask import Flask
|
||
|
|
+from opentracing.ext import tags
|
||
|
|
+from opentracing.mocktracer import MockTracer
|
||
|
|
+from flask_opentracing import FlaskTracing
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+class _StartSpanCallbackTestCase(unittest.TestCase):
|
||
|
|
+ @staticmethod
|
||
|
|
+ @abstractmethod
|
||
|
|
+ def start_span_cb(span, request):
|
||
|
|
+ pass
|
||
|
|
+
|
||
|
|
+ def setUp(self):
|
||
|
|
+ self.app = Flask(__name__)
|
||
|
|
+ self.tracing = FlaskTracing(
|
||
|
|
+ MockTracer(), True, self.app, start_span_cb=self.start_span_cb
|
||
|
|
+ )
|
||
|
|
+ self.test_app = self.app.test_client()
|
||
|
|
+
|
||
|
|
+ @self.app.route('/test')
|
||
|
|
+ def check_test_works():
|
||
|
|
+ return 'Success'
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+class TestFlaskTracingStartSpanCallbackSetTags(_StartSpanCallbackTestCase):
|
||
|
|
+ @staticmethod
|
||
|
|
+ def start_span_cb(span, request):
|
||
|
|
+ print('setting tags')
|
||
|
|
+ span.set_tag('component', 'not-flask')
|
||
|
|
+ span.set_tag('mytag', 'myvalue')
|
||
|
|
+
|
||
|
|
+ def test_simple(self):
|
||
|
|
+ rv = self.test_app.get('/test')
|
||
|
|
+ assert '200' in str(rv.status_code)
|
||
|
|
+
|
||
|
|
+ spans = self.tracing.tracer.finished_spans()
|
||
|
|
+ assert len(spans) == 1
|
||
|
|
+ assert spans[0].tags.get(tags.COMPONENT, None) == 'not-flask'
|
||
|
|
+ assert spans[0].tags.get('mytag', None) == 'myvalue'
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+class TestFlaskTracingStartSpanCallbackRaisesError(
|
||
|
|
+ _StartSpanCallbackTestCase
|
||
|
|
+):
|
||
|
|
+ @staticmethod
|
||
|
|
+ def start_span_cb(span, request):
|
||
|
|
+ print('raising exception')
|
||
|
|
+ raise RuntimeError('Should not happen')
|
||
|
|
+
|
||
|
|
+ def test_error(self):
|
||
|
|
+ rv = self.test_app.get('/test')
|
||
|
|
+ assert '200' in str(rv.status_code)
|
||
|
|
+
|
||
|
|
+ spans = self.tracing.tracer.finished_spans()
|
||
|
|
+ assert len(spans) == 1
|
||
|
|
+ assert spans[0].tags.get(tags.ERROR, None) is None
|