|
57 | 57 | _HostResourceDetector, |
58 | 58 | get_aggregated_resources, |
59 | 59 | ) |
| 60 | +from opentelemetry.util._importlib_metadata import ( |
| 61 | + entry_points as real_entry_points, |
| 62 | +) |
60 | 63 |
|
61 | 64 | try: |
62 | 65 | import psutil |
@@ -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,52 @@ 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( |
| 806 | + "opentelemetry.sdk.resources.entry_points", side_effect=side_effect |
| 807 | + ): |
| 808 | + resource = Resource({}).create() |
| 809 | + |
| 810 | + self.assertEqual(resource.attributes["conflict_key"], "from_b") |
| 811 | + |
| 812 | + @patch.dict( |
| 813 | + environ, |
| 814 | + { |
| 815 | + OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock", |
| 816 | + OTEL_RESOURCE_ATTRIBUTES: "conflict_key=otel_value", |
| 817 | + }, |
| 818 | + clear=True, |
| 819 | + ) |
| 820 | + def test_otel_detector_appended_last(self): |
| 821 | + """'otel' detector is always appended last, so its attributes win over earlier detectors.""" |
| 822 | + ep_mock = _make_detector_ep(Resource({"conflict_key": "mock_value"})) |
| 823 | + |
| 824 | + def side_effect(*args, **kwargs): |
| 825 | + if kwargs.get("name") == "mock": |
| 826 | + return [ep_mock] |
| 827 | + return real_entry_points(*args, **kwargs) |
| 828 | + |
| 829 | + with patch( |
| 830 | + "opentelemetry.sdk.resources.entry_points", side_effect=side_effect |
| 831 | + ): |
| 832 | + resource = Resource({}).create() |
| 833 | + |
| 834 | + self.assertEqual(resource.attributes["conflict_key"], "otel_value") |
| 835 | + |
777 | 836 | @patch("platform.system", lambda: "Linux") |
778 | 837 | @patch("platform.release", lambda: "666.5.0-35-generic") |
779 | 838 | def test_os_detector_linux(self): |
|
0 commit comments