16
16
17
17
import unittest
18
18
from timeit import default_timer
19
- from unittest .mock import Mock , patch
19
+ from unittest .mock import Mock , call , patch
20
20
21
21
import fastapi
22
22
from fastapi .middleware .httpsredirect import HTTPSRedirectMiddleware
37
37
from opentelemetry .instrumentation .auto_instrumentation ._load import (
38
38
_load_instrumentors ,
39
39
)
40
+ from opentelemetry .instrumentation .dependencies import (
41
+ DependencyConflict ,
42
+ DependencyConflictError ,
43
+ )
40
44
from opentelemetry .sdk .metrics .export import (
41
45
HistogramDataPoint ,
42
46
NumberDataPoint ,
54
58
from opentelemetry .semconv .trace import SpanAttributes
55
59
from opentelemetry .test .globals_test import reset_trace_globals
56
60
from opentelemetry .test .test_base import TestBase
57
- from opentelemetry .util ._importlib_metadata import (
58
- PackageNotFoundError ,
59
- entry_points ,
60
- )
61
+ from opentelemetry .util ._importlib_metadata import entry_points
61
62
from opentelemetry .util .http import (
62
63
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS ,
63
64
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST ,
@@ -1031,26 +1032,6 @@ def client_response_hook(send_span, scope, message):
1031
1032
)
1032
1033
1033
1034
1034
- def mock_version_with_fastapi (* args , ** kwargs ):
1035
- req_name = args [0 ]
1036
- if req_name == "fastapi" :
1037
- # TODO: Value now matters
1038
- return "0.58"
1039
- raise PackageNotFoundError ()
1040
-
1041
-
1042
- def mock_version_with_old_fastapi (* args , ** kwargs ):
1043
- req_name = args [0 ]
1044
- if req_name == "fastapi" :
1045
- # TODO: Value now matters
1046
- return "0.57"
1047
- raise PackageNotFoundError ()
1048
-
1049
-
1050
- def mock_version_without_fastapi (* args , ** kwargs ):
1051
- raise PackageNotFoundError ()
1052
-
1053
-
1054
1035
class TestAutoInstrumentation (TestBaseAutoFastAPI ):
1055
1036
"""Test the auto-instrumented variant
1056
1037
@@ -1062,31 +1043,65 @@ def test_entry_point_exists(self):
1062
1043
(ep ,) = entry_points (group = "opentelemetry_instrumentor" )
1063
1044
self .assertEqual (ep .name , "fastapi" )
1064
1045
1065
- @patch ("opentelemetry.instrumentation.dependencies.version" )
1066
- def test_instruments_with_fastapi_installed (self , mock_version ):
1067
- mock_version .side_effect = mock_version_with_fastapi
1046
+ @staticmethod
1047
+ def _instrumentation_loaded_successfully_call ():
1048
+ return call ("Instrumented %s" , "fastapi" )
1049
+
1050
+ @staticmethod
1051
+ def _instrumentation_failed_to_load_call (dependency_conflict ):
1052
+ return call (
1053
+ "Skipping instrumentation %s: %s" , "fastapi" , dependency_conflict
1054
+ )
1055
+
1056
+ @patch ("opentelemetry.instrumentation.auto_instrumentation._load._logger" )
1057
+ def test_instruments_with_fastapi_installed (self , mock_logger ):
1068
1058
mock_distro = Mock ()
1059
+ mock_distro .load_instrumentor .return_value = None
1069
1060
_load_instrumentors (mock_distro )
1070
- mock_version .assert_called_once_with ("fastapi" )
1071
1061
self .assertEqual (len (mock_distro .load_instrumentor .call_args_list ), 1 )
1072
1062
(ep ,) = mock_distro .load_instrumentor .call_args .args
1073
1063
self .assertEqual (ep .name , "fastapi" )
1064
+ mock_logger .debug .assert_has_calls (
1065
+ [self ._instrumentation_loaded_successfully_call ()]
1066
+ )
1074
1067
1075
- @patch ("opentelemetry.instrumentation.dependencies.version " )
1076
- def test_instruments_with_old_fastapi_installed (self , mock_version ): # pylint: disable=no-self-use
1077
- mock_version . side_effect = mock_version_with_old_fastapi
1068
+ @patch ("opentelemetry.instrumentation.auto_instrumentation._load._logger " )
1069
+ def test_instruments_with_old_fastapi_installed (self , mock_logger ): # pylint: disable=no-self-use
1070
+ dependency_conflict = DependencyConflict ( "0.58" , "0.57" )
1078
1071
mock_distro = Mock ()
1072
+ mock_distro .load_instrumentor .side_effect = DependencyConflictError (
1073
+ dependency_conflict
1074
+ )
1079
1075
_load_instrumentors (mock_distro )
1080
- mock_version .assert_called_once_with ("fastapi" )
1081
- mock_distro .load_instrumentor .assert_not_called ()
1076
+ self .assertEqual (len (mock_distro .load_instrumentor .call_args_list ), 1 )
1077
+ (ep ,) = mock_distro .load_instrumentor .call_args .args
1078
+ self .assertEqual (ep .name , "fastapi" )
1079
+ assert (
1080
+ self ._instrumentation_loaded_successfully_call ()
1081
+ not in mock_logger .debug .call_args_list
1082
+ )
1083
+ mock_logger .debug .assert_has_calls (
1084
+ [self ._instrumentation_failed_to_load_call (dependency_conflict )]
1085
+ )
1082
1086
1083
- @patch ("opentelemetry.instrumentation.dependencies.version " )
1084
- def test_instruments_without_fastapi_installed (self , mock_version ): # pylint: disable=no-self-use
1085
- mock_version . side_effect = mock_version_without_fastapi
1087
+ @patch ("opentelemetry.instrumentation.auto_instrumentation._load._logger " )
1088
+ def test_instruments_without_fastapi_installed (self , mock_logger ): # pylint: disable=no-self-use
1089
+ dependency_conflict = DependencyConflict ( "0.58" , None )
1086
1090
mock_distro = Mock ()
1091
+ mock_distro .load_instrumentor .side_effect = DependencyConflictError (
1092
+ dependency_conflict
1093
+ )
1087
1094
_load_instrumentors (mock_distro )
1088
- mock_version .assert_called_once_with ("fastapi" )
1089
- mock_distro .load_instrumentor .assert_not_called ()
1095
+ self .assertEqual (len (mock_distro .load_instrumentor .call_args_list ), 1 )
1096
+ (ep ,) = mock_distro .load_instrumentor .call_args .args
1097
+ self .assertEqual (ep .name , "fastapi" )
1098
+ assert (
1099
+ self ._instrumentation_loaded_successfully_call ()
1100
+ not in mock_logger .debug .call_args_list
1101
+ )
1102
+ mock_logger .debug .assert_has_calls (
1103
+ [self ._instrumentation_failed_to_load_call (dependency_conflict )]
1104
+ )
1090
1105
1091
1106
def _create_app (self ):
1092
1107
# instrumentation is handled by the instrument call
0 commit comments