1616
1717import  unittest 
1818from  timeit  import  default_timer 
19- from  unittest .mock  import  Mock , patch 
19+ from  unittest .mock  import  Mock , call ,  patch 
2020
2121import  fastapi 
2222from  fastapi .middleware .httpsredirect  import  HTTPSRedirectMiddleware 
3737from  opentelemetry .instrumentation .auto_instrumentation ._load  import  (
3838    _load_instrumentors ,
3939)
40+ from  opentelemetry .instrumentation .dependencies  import  (
41+     DependencyConflict ,
42+     DependencyConflictError ,
43+ )
4044from  opentelemetry .sdk .metrics .export  import  (
4145    HistogramDataPoint ,
4246    NumberDataPoint ,
5458from  opentelemetry .semconv .trace  import  SpanAttributes 
5559from  opentelemetry .test .globals_test  import  reset_trace_globals 
5660from  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 
6162from  opentelemetry .util .http  import  (
6263    OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS ,
6364    OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST ,
@@ -1031,26 +1032,6 @@ def client_response_hook(send_span, scope, message):
10311032            )
10321033
10331034
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- 
10541035class  TestAutoInstrumentation (TestBaseAutoFastAPI ):
10551036    """Test the auto-instrumented variant 
10561037
@@ -1062,31 +1043,65 @@ def test_entry_point_exists(self):
10621043        (ep ,) =  entry_points (group = "opentelemetry_instrumentor" )
10631044        self .assertEqual (ep .name , "fastapi" )
10641045
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 ):
10681058        mock_distro  =  Mock ()
1059+         mock_distro .load_instrumentor .return_value  =  None 
10691060        _load_instrumentors (mock_distro )
1070-         mock_version .assert_called_once_with ("fastapi" )
10711061        self .assertEqual (len (mock_distro .load_instrumentor .call_args_list ), 1 )
10721062        (ep ,) =  mock_distro .load_instrumentor .call_args .args 
10731063        self .assertEqual (ep .name , "fastapi" )
1064+         mock_logger .debug .assert_has_calls (
1065+             [self ._instrumentation_loaded_successfully_call ()]
1066+         )
10741067
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" ) 
10781071        mock_distro  =  Mock ()
1072+         mock_distro .load_instrumentor .side_effect  =  DependencyConflictError (
1073+             dependency_conflict 
1074+         )
10791075        _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+         )
10821086
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 ) 
10861090        mock_distro  =  Mock ()
1091+         mock_distro .load_instrumentor .side_effect  =  DependencyConflictError (
1092+             dependency_conflict 
1093+         )
10871094        _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+         )
10901105
10911106    def  _create_app (self ):
10921107        # instrumentation is handled by the instrument call 
0 commit comments