|
16 | 16 | from unittest.mock import Mock, patch
|
17 | 17 |
|
18 | 18 | from http_server_mock import HttpServerMock
|
| 19 | +from tornado.httpclient import HTTPClientError |
19 | 20 | from tornado.testing import AsyncHTTPTestCase
|
20 | 21 |
|
21 | 22 | from opentelemetry import trace
|
|
32 | 33 | from opentelemetry.semconv.trace import SpanAttributes
|
33 | 34 | from opentelemetry.test.test_base import TestBase
|
34 | 35 | from opentelemetry.test.wsgitestutil import WsgiTestBase
|
35 |
| -from opentelemetry.trace import SpanKind |
| 36 | +from opentelemetry.trace import SpanKind, StatusCode |
36 | 37 | from opentelemetry.util.http import (
|
37 | 38 | OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
|
38 | 39 | OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE,
|
@@ -493,7 +494,6 @@ def test_response_headers(self):
|
493 | 494 | self.assertEqual(len(spans), 3)
|
494 | 495 | self.assertTraceResponseHeaderMatchesSpan(response.headers, spans[1])
|
495 | 496 |
|
496 |
| - self.memory_exporter.clear() |
497 | 497 | set_global_response_propagator(orig)
|
498 | 498 |
|
499 | 499 | def test_credential_removal(self):
|
@@ -602,6 +602,49 @@ def client_response_hook(span, response):
|
602 | 602 | self.memory_exporter.clear()
|
603 | 603 |
|
604 | 604 |
|
| 605 | +class TestTornadoHTTPClientInstrumentation(TornadoTest, WsgiTestBase): |
| 606 | + def test_http_client_success_response(self): |
| 607 | + response = self.fetch("/") |
| 608 | + self.assertEqual(response.code, 201) |
| 609 | + |
| 610 | + spans = self.memory_exporter.get_finished_spans() |
| 611 | + self.assertEqual(len(spans), 3) |
| 612 | + manual, server, client = self.sorted_spans(spans) |
| 613 | + self.assertEqual(manual.name, "manual") |
| 614 | + self.assertEqual(server.name, "GET /") |
| 615 | + self.assertEqual(client.name, "GET") |
| 616 | + self.assertEqual(client.status.status_code, StatusCode.UNSET) |
| 617 | + self.memory_exporter.clear() |
| 618 | + |
| 619 | + def test_http_client_failed_response(self): |
| 620 | + # when an exception isn't thrown |
| 621 | + response = self.fetch("/some-404") |
| 622 | + self.assertEqual(response.code, 404) |
| 623 | + |
| 624 | + spans = self.memory_exporter.get_finished_spans() |
| 625 | + self.assertEqual(len(spans), 2) |
| 626 | + server, client = self.sorted_spans(spans) |
| 627 | + self.assertEqual(server.name, "GET /some-404") |
| 628 | + self.assertEqual(client.name, "GET") |
| 629 | + self.assertEqual(client.status.status_code, StatusCode.ERROR) |
| 630 | + self.memory_exporter.clear() |
| 631 | + |
| 632 | + # when an exception is thrown |
| 633 | + try: |
| 634 | + response = self.fetch("/some-404", raise_error=True) |
| 635 | + self.assertEqual(response.code, 404) |
| 636 | + except HTTPClientError: |
| 637 | + pass # expected exception - continue |
| 638 | + |
| 639 | + spans = self.memory_exporter.get_finished_spans() |
| 640 | + self.assertEqual(len(spans), 2) |
| 641 | + server, client = self.sorted_spans(spans) |
| 642 | + self.assertEqual(server.name, "GET /some-404") |
| 643 | + self.assertEqual(client.name, "GET") |
| 644 | + self.assertEqual(client.status.status_code, StatusCode.ERROR) |
| 645 | + self.memory_exporter.clear() |
| 646 | + |
| 647 | + |
605 | 648 | class TestTornadoUninstrument(TornadoTest):
|
606 | 649 | def test_uninstrument(self):
|
607 | 650 | response = self.fetch("/")
|
|
0 commit comments