|
16 | 16 | )
|
17 | 17 | from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
|
18 | 18 | from opentelemetry.instrumentation.botocore.extensions import _KNOWN_EXTENSIONS
|
| 19 | +from opentelemetry.propagate import get_global_textmap |
19 | 20 | from opentelemetry.semconv.trace import SpanAttributes
|
20 | 21 | from opentelemetry.trace.span import Span
|
21 | 22 |
|
@@ -80,14 +81,18 @@ def _run_patch_behaviour_tests(self):
|
80 | 81 |
|
81 | 82 | # Validate unpatched upstream behaviour - important to detect upstream changes that may break instrumentation
|
82 | 83 | self._test_unpatched_botocore_instrumentation()
|
| 84 | + self._test_unpatched_botocore_propagator() |
83 | 85 | self._test_unpatched_gevent_instrumentation()
|
| 86 | + self._test_unpatched_starlette_instrumentation() |
84 | 87 |
|
85 | 88 | # Apply patches
|
86 | 89 | apply_instrumentation_patches()
|
87 | 90 |
|
88 | 91 | # Validate patched upstream behaviour - important to detect downstream changes that may break instrumentation
|
89 | 92 | self._test_patched_botocore_instrumentation()
|
| 93 | + self._test_patched_botocore_propagator() |
90 | 94 | self._test_unpatched_gevent_instrumentation()
|
| 95 | + self._test_patched_starlette_instrumentation() |
91 | 96 |
|
92 | 97 | # Test setup to check whether only these two modules get patched by gevent monkey
|
93 | 98 | os.environ[AWS_GEVENT_PATCH_MODULES] = "os, ssl"
|
@@ -123,6 +128,8 @@ def _run_patch_mechanism_tests(self):
|
123 | 128 | self._reset_mocks()
|
124 | 129 | self._test_resource_detector_patches()
|
125 | 130 | self._reset_mocks()
|
| 131 | + self._test_starlette_installed_flag() |
| 132 | + self._reset_mocks() |
126 | 133 |
|
127 | 134 | def _test_unpatched_botocore_instrumentation(self):
|
128 | 135 | # Kinesis
|
@@ -567,6 +574,80 @@ def _test_resource_detector_patches(self):
|
567 | 574 | # Verify SSL context was created with correct CA file
|
568 | 575 | mock_ssl.assert_called_once_with(cafile="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
|
569 | 576 |
|
| 577 | + def _test_unpatched_botocore_propagator(self): |
| 578 | + """Test that BotocoreInstrumentor uses its own propagator by default.""" |
| 579 | + # Create a fresh instrumentor to test its initial state |
| 580 | + test_instrumentor = BotocoreInstrumentor() |
| 581 | + # Check that it has its own propagator (not the global one) |
| 582 | + self.assertIsNotNone(test_instrumentor.propagator) |
| 583 | + # The default propagator should not be the global propagator initially |
| 584 | + # This test ensures upstream hasn't changed their default behavior |
| 585 | + |
| 586 | + def _test_patched_botocore_propagator(self): |
| 587 | + """Test that BotocoreInstrumentor uses global propagator after patching.""" |
| 588 | + # Create a new instrumentor after patches have been applied |
| 589 | + test_instrumentor = BotocoreInstrumentor() |
| 590 | + # After patching, the propagator should be the global one |
| 591 | + self.assertEqual(test_instrumentor.propagator, get_global_textmap()) |
| 592 | + |
| 593 | + def _test_unpatched_starlette_instrumentation(self): |
| 594 | + """Test unpatched starlette instrumentation dependencies.""" |
| 595 | + try: |
| 596 | + # pylint: disable=import-outside-toplevel |
| 597 | + from opentelemetry.instrumentation.starlette import StarletteInstrumentor |
| 598 | + |
| 599 | + # Store original method to verify it hasn't been patched yet |
| 600 | + original_deps = StarletteInstrumentor.instrumentation_dependencies |
| 601 | + # Create an instance to test the method |
| 602 | + instrumentor = StarletteInstrumentor() |
| 603 | + deps = original_deps(instrumentor) |
| 604 | + # Default should have version constraint |
| 605 | + self.assertEqual(deps, ("starlette >= 0.13, <0.15",)) |
| 606 | + except ImportError: |
| 607 | + # If starlette instrumentation is not installed, skip this test |
| 608 | + pass |
| 609 | + |
| 610 | + def _test_patched_starlette_instrumentation(self): |
| 611 | + """Test patched starlette instrumentation dependencies.""" |
| 612 | + try: |
| 613 | + # pylint: disable=import-outside-toplevel |
| 614 | + from opentelemetry.instrumentation.starlette import StarletteInstrumentor |
| 615 | + |
| 616 | + # After patching, the version constraint should be relaxed |
| 617 | + instrumentor = StarletteInstrumentor() |
| 618 | + deps = instrumentor.instrumentation_dependencies() |
| 619 | + self.assertEqual(deps, ("starlette >= 0.13",)) |
| 620 | + except ImportError: |
| 621 | + # If starlette instrumentation is not installed, skip this test |
| 622 | + pass |
| 623 | + |
| 624 | + def _test_starlette_installed_flag(self): # pylint: disable=no-self-use |
| 625 | + """Test that starlette patches are only applied when starlette is installed.""" |
| 626 | + with patch( |
| 627 | + "amazon.opentelemetry.distro.patches._starlette_patches._apply_starlette_instrumentation_patches" |
| 628 | + ) as mock_apply_patches: |
| 629 | + # Test when starlette is not installed |
| 630 | + with patch( |
| 631 | + "amazon.opentelemetry.distro.patches._instrumentation_patch.is_installed", return_value=False |
| 632 | + ) as mock_is_installed: |
| 633 | + apply_instrumentation_patches() |
| 634 | + # Check that is_installed was called for starlette |
| 635 | + mock_is_installed.assert_any_call("starlette") |
| 636 | + # Patches should not be applied when starlette is not installed |
| 637 | + mock_apply_patches.assert_not_called() |
| 638 | + |
| 639 | + mock_apply_patches.reset_mock() |
| 640 | + |
| 641 | + # Test when starlette is installed |
| 642 | + with patch( |
| 643 | + "amazon.opentelemetry.distro.patches._instrumentation_patch.is_installed", return_value=True |
| 644 | + ) as mock_is_installed: |
| 645 | + apply_instrumentation_patches() |
| 646 | + # Check that is_installed was called for starlette |
| 647 | + mock_is_installed.assert_any_call("starlette") |
| 648 | + # Patches should be applied when starlette is installed |
| 649 | + mock_apply_patches.assert_called() |
| 650 | + |
570 | 651 | def _reset_mocks(self):
|
571 | 652 | for method_patch in self.method_patches.values():
|
572 | 653 | method_patch.reset_mock()
|
|
0 commit comments