Skip to content

Commit 39df92d

Browse files
author
Alex Boten
committed
Using InMemorySpanExporter for wsgi/flask tests
Signed-off-by: Alex Boten <[email protected]>
1 parent eee7d84 commit 39df92d

File tree

4 files changed

+59
-97
lines changed

4 files changed

+59
-97
lines changed

ext/opentelemetry-ext-flask/tests/test_flask_integration.py

+41-78
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414

1515
import unittest
16-
from unittest import mock
1716

1817
from flask import Flask
1918
from werkzeug.test import Client
@@ -28,14 +27,6 @@ class TestFlaskIntegration(WsgiTestBase):
2827
def setUp(self):
2928
super().setUp()
3029

31-
self.span_attrs = {}
32-
33-
def setspanattr(key, value):
34-
self.assertIsInstance(key, str)
35-
self.span_attrs[key] = value
36-
37-
self.span.set_attribute = setspanattr
38-
3930
self.app = Flask(__name__)
4031

4132
def hello_endpoint(helloid):
@@ -49,88 +40,60 @@ def hello_endpoint(helloid):
4940
self.client = Client(self.app, BaseResponse)
5041

5142
def test_simple(self):
43+
expected_attrs = {
44+
"component": "http",
45+
"http.method": "GET",
46+
"http.host": "localhost",
47+
"http.url": "http://localhost/hello/123",
48+
"http.route": "/hello/<int:helloid>",
49+
"http.status_code": 200,
50+
"http.status_text": "OK",
51+
}
5252
resp = self.client.get("/hello/123")
5353
self.assertEqual(200, resp.status_code)
5454
self.assertEqual([b"Hello: 123"], list(resp.response))
55-
56-
self.start_span.assert_called_with(
57-
"hello_endpoint",
58-
trace_api.INVALID_SPAN_CONTEXT,
59-
kind=trace_api.SpanKind.SERVER,
60-
start_time=mock.ANY,
61-
)
62-
63-
# TODO: Change this test to use the SDK, as mocking becomes painful
64-
65-
self.assertEqual(
66-
self.span_attrs,
67-
{
68-
"component": "http",
69-
"http.method": "GET",
70-
"http.host": "localhost",
71-
"http.url": "http://localhost/hello/123",
72-
"http.route": "/hello/<int:helloid>",
73-
"http.status_code": 200,
74-
"http.status_text": "OK",
75-
},
76-
)
55+
span_list = self.memory_exporter.get_finished_spans()
56+
self.assertEqual(len(span_list), 1)
57+
self.assertEqual(span_list[0].name, "hello_endpoint")
58+
self.assertEqual(span_list[0].kind, trace_api.SpanKind.SERVER)
59+
self.assertEqual(span_list[0].attributes, expected_attrs)
7760

7861
def test_404(self):
62+
expected_attrs = {
63+
"component": "http",
64+
"http.method": "POST",
65+
"http.host": "localhost",
66+
"http.url": "http://localhost/bye",
67+
"http.status_code": 404,
68+
"http.status_text": "NOT FOUND",
69+
}
7970
resp = self.client.post("/bye")
8071
self.assertEqual(404, resp.status_code)
8172
resp.close()
82-
83-
self.start_span.assert_called_with(
84-
"/bye",
85-
trace_api.INVALID_SPAN_CONTEXT,
86-
kind=trace_api.SpanKind.SERVER,
87-
start_time=mock.ANY,
88-
)
89-
90-
# Nope, this uses Tracer.use_span(end_on_exit)
91-
# self.assertEqual(1, self.span.end.call_count)
92-
# TODO: Change this test to use the SDK, as mocking becomes painful
93-
94-
self.assertEqual(
95-
self.span_attrs,
96-
{
97-
"component": "http",
98-
"http.method": "POST",
99-
"http.host": "localhost",
100-
"http.url": "http://localhost/bye",
101-
"http.status_code": 404,
102-
"http.status_text": "NOT FOUND",
103-
},
104-
)
73+
span_list = self.memory_exporter.get_finished_spans()
74+
self.assertEqual(len(span_list), 1)
75+
self.assertEqual(span_list[0].name, "/bye")
76+
self.assertEqual(span_list[0].kind, trace_api.SpanKind.SERVER)
77+
self.assertEqual(span_list[0].attributes, expected_attrs)
10578

10679
def test_internal_error(self):
80+
expected_attrs = {
81+
"component": "http",
82+
"http.method": "GET",
83+
"http.host": "localhost",
84+
"http.url": "http://localhost/hello/500",
85+
"http.route": "/hello/<int:helloid>",
86+
"http.status_code": 500,
87+
"http.status_text": "INTERNAL SERVER ERROR",
88+
}
10789
resp = self.client.get("/hello/500")
10890
self.assertEqual(500, resp.status_code)
10991
resp.close()
110-
111-
self.start_span.assert_called_with(
112-
"hello_endpoint",
113-
trace_api.INVALID_SPAN_CONTEXT,
114-
kind=trace_api.SpanKind.SERVER,
115-
start_time=mock.ANY,
116-
)
117-
118-
# Nope, this uses Tracer.use_span(end_on_exit)
119-
# self.assertEqual(1, self.span.end.call_count)
120-
# TODO: Change this test to use the SDK, as mocking becomes painful
121-
122-
self.assertEqual(
123-
self.span_attrs,
124-
{
125-
"component": "http",
126-
"http.method": "GET",
127-
"http.host": "localhost",
128-
"http.url": "http://localhost/hello/500",
129-
"http.route": "/hello/<int:helloid>",
130-
"http.status_code": 500,
131-
"http.status_text": "INTERNAL SERVER ERROR",
132-
},
133-
)
92+
span_list = self.memory_exporter.get_finished_spans()
93+
self.assertEqual(len(span_list), 1)
94+
self.assertEqual(span_list[0].name, "hello_endpoint")
95+
self.assertEqual(span_list[0].kind, trace_api.SpanKind.SERVER)
96+
self.assertEqual(span_list[0].attributes, expected_attrs)
13497

13598

13699
if __name__ == "__main__":

ext/opentelemetry-ext-testutil/src/opentelemetry/ext/testutil/wsgitestutil.py

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
import io
22
import unittest
3-
import unittest.mock as mock
43
import wsgiref.util as wsgiref_util
54

65
from opentelemetry import trace as trace_api
6+
from opentelemetry.sdk.trace import Tracer, export
7+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
8+
InMemorySpanExporter,
9+
)
710

811

912
class WsgiTestBase(unittest.TestCase):
13+
@classmethod
14+
def setUpClass(cls):
15+
trace_api.set_preferred_tracer_implementation(lambda T: Tracer())
16+
1017
def setUp(self):
1118
tracer = trace_api.tracer()
12-
self.span = mock.create_autospec(trace_api.Span, spec_set=True)
13-
self.start_span_patcher = mock.patch.object(
14-
tracer,
15-
"start_span",
16-
autospec=True,
17-
spec_set=True,
18-
return_value=self.span,
19-
)
20-
self.start_span = self.start_span_patcher.start()
19+
20+
self.memory_exporter = InMemorySpanExporter()
21+
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
22+
tracer.add_span_processor(span_processor)
23+
2124
self.write_buffer = io.BytesIO()
2225
self.write = self.write_buffer.write
2326

@@ -28,9 +31,6 @@ def setUp(self):
2831
self.response_headers = None
2932
self.exc_info = None
3033

31-
def tearDown(self):
32-
self.start_span_patcher.stop()
33-
3434
def start_response(self, status, response_headers, exc_info=None):
3535
self.status = status
3636
self.response_headers = response_headers

ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,8 @@ def validate_response(self, response, error=None):
7878
while True:
7979
try:
8080
value = next(response)
81-
self.assertEqual(0, self.span.end.call_count)
8281
self.assertEqual(value, b"*")
8382
except StopIteration:
84-
self.span.end.assert_called_once_with()
8583
break
8684

8785
self.assertEqual(self.status, "200 OK")
@@ -95,10 +93,10 @@ def validate_response(self, response, error=None):
9593
else:
9694
self.assertIsNone(self.exc_info)
9795

98-
# Verify that start_span has been called
99-
self.start_span.assert_called_with(
100-
"/", trace_api.INVALID_SPAN_CONTEXT, kind=trace_api.SpanKind.SERVER
101-
)
96+
span_list = self.memory_exporter.get_finished_spans()
97+
self.assertEqual(len(span_list), 1)
98+
self.assertEqual(span_list[0].name, "/")
99+
self.assertEqual(span_list[0].kind, trace_api.SpanKind.SERVER)
102100

103101
def test_basic_wsgi_call(self):
104102
app = otel_wsgi.OpenTelemetryMiddleware(simple_wsgi)

tox.ini

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ commands_pre =
6666
ext: pip install {toxinidir}/opentelemetry-api
6767
wsgi,flask: pip install {toxinidir}/ext/opentelemetry-ext-testutil
6868
wsgi,flask: pip install {toxinidir}/ext/opentelemetry-ext-wsgi
69+
wsgi,flask: pip install {toxinidir}/opentelemetry-sdk
6970
flask: pip install {toxinidir}/ext/opentelemetry-ext-flask[test]
7071
pymongo: pip install {toxinidir}/ext/opentelemetry-ext-pymongo
7172
http-requests: pip install {toxinidir}/ext/opentelemetry-ext-http-requests

0 commit comments

Comments
 (0)