|
24 | 24 | from opentelemetry.sdk.environment_variables import ( |
25 | 25 | OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, |
26 | 26 | ) |
| 27 | +from opentelemetry.util._importlib_metadata import ( |
| 28 | + entry_points as real_entry_points, |
| 29 | +) |
27 | 30 | from opentelemetry.sdk.resources import ( |
28 | 31 | _DEFAULT_RESOURCE, |
29 | 32 | _EMPTY_RESOURCE, |
@@ -475,6 +478,16 @@ def test_service_name_env(self): |
475 | 478 |
|
476 | 479 |
|
477 | 480 | # pylint: disable=too-many-public-methods |
| 481 | +def _make_detector_ep(resource): |
| 482 | + return Mock( |
| 483 | + **{ |
| 484 | + "load.return_value": Mock( |
| 485 | + return_value=Mock(**{"detect.return_value": resource}) |
| 486 | + ) |
| 487 | + } |
| 488 | + ) |
| 489 | + |
| 490 | + |
478 | 491 | class TestOTELResourceDetector(unittest.TestCase): |
479 | 492 | def setUp(self) -> None: |
480 | 493 | environ[OTEL_RESOURCE_ATTRIBUTES] = "" |
@@ -774,6 +787,48 @@ def test_resource_detector_entry_points_otel(self): |
774 | 787 | self.assertIn(PROCESS_RUNTIME_VERSION, resource.attributes.keys()) |
775 | 788 | self.assertEqual(resource.schema_url, "") |
776 | 789 |
|
| 790 | + @patch.dict( |
| 791 | + environ, |
| 792 | + {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock_a,mock_b"}, |
| 793 | + clear=True, |
| 794 | + ) |
| 795 | + def test_resource_detector_ordering_last_wins(self): |
| 796 | + """Last detector in OTEL_EXPERIMENTAL_RESOURCE_DETECTORS wins on conflict.""" |
| 797 | + ep_a = _make_detector_ep(Resource({"conflict_key": "from_a"})) |
| 798 | + ep_b = _make_detector_ep(Resource({"conflict_key": "from_b"})) |
| 799 | + |
| 800 | + def side_effect(*args, **kwargs): |
| 801 | + return {"mock_a": [ep_a], "mock_b": [ep_b]}.get( |
| 802 | + kwargs.get("name", ""), [] |
| 803 | + ) |
| 804 | + |
| 805 | + with patch("opentelemetry.sdk.resources.entry_points", side_effect=side_effect): |
| 806 | + resource = Resource({}).create() |
| 807 | + |
| 808 | + self.assertEqual(resource.attributes["conflict_key"], "from_b") |
| 809 | + |
| 810 | + @patch.dict( |
| 811 | + environ, |
| 812 | + { |
| 813 | + OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock", |
| 814 | + OTEL_RESOURCE_ATTRIBUTES: "conflict_key=otel_value", |
| 815 | + }, |
| 816 | + clear=True, |
| 817 | + ) |
| 818 | + def test_otel_detector_appended_last(self): |
| 819 | + """'otel' detector is always appended last, so its attributes win over earlier detectors.""" |
| 820 | + ep_mock = _make_detector_ep(Resource({"conflict_key": "mock_value"})) |
| 821 | + |
| 822 | + def side_effect(*args, **kwargs): |
| 823 | + if kwargs.get("name") == "mock": |
| 824 | + return [ep_mock] |
| 825 | + return real_entry_points(*args, **kwargs) |
| 826 | + |
| 827 | + with patch("opentelemetry.sdk.resources.entry_points", side_effect=side_effect): |
| 828 | + resource = Resource({}).create() |
| 829 | + |
| 830 | + self.assertEqual(resource.attributes["conflict_key"], "otel_value") |
| 831 | + |
777 | 832 | @patch("platform.system", lambda: "Linux") |
778 | 833 | @patch("platform.release", lambda: "666.5.0-35-generic") |
779 | 834 | def test_os_detector_linux(self): |
|
0 commit comments