|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | | -import builtins |
16 | | -import functools |
17 | | -import importlib.util |
18 | 15 | import logging |
19 | | -from pathlib import Path |
20 | 16 | from types import SimpleNamespace |
21 | 17 | from unittest import mock |
22 | 18 |
|
23 | 19 | import pytest |
24 | 20 |
|
| 21 | +from opentelemetry.instrumentation.openai_v2 import response_extractors |
25 | 22 | from opentelemetry.semconv._incubating.attributes import ( |
26 | 23 | openai_attributes as OpenAIAttributes, |
27 | 24 | ) |
28 | 25 | from opentelemetry.util.genai.types import LLMInvocation |
29 | 26 |
|
30 | | -_MODULE_PATH = ( |
31 | | - Path(__file__).resolve().parents[1] |
32 | | - / "src" |
33 | | - / "opentelemetry" |
34 | | - / "instrumentation" |
35 | | - / "openai_v2" |
36 | | - / "response_extractors.py" |
37 | | -) |
38 | | - |
39 | | - |
40 | | -def _load_module(block_genai_types_import=False): |
41 | | - spec = importlib.util.spec_from_file_location( |
42 | | - "test_response_extractors_module", _MODULE_PATH |
43 | | - ) |
44 | | - assert spec is not None and spec.loader is not None |
45 | | - module = importlib.util.module_from_spec(spec) |
46 | | - |
47 | | - if not block_genai_types_import: |
48 | | - spec.loader.exec_module(module) |
49 | | - return module |
50 | | - |
51 | | - original_import = builtins.__import__ |
52 | | - |
53 | | - def _patched_import( |
54 | | - name, globalns=None, localns=None, fromlist=(), level=0 |
55 | | - ): |
56 | | - if name == "opentelemetry.util.genai.types": |
57 | | - raise ImportError("simulated missing genai types") |
58 | | - return original_import(name, globalns, localns, fromlist, level) |
59 | | - |
60 | | - with mock.patch("builtins.__import__", side_effect=_patched_import): |
61 | | - spec.loader.exec_module(module) |
62 | | - return module |
63 | | - |
64 | | - |
65 | | -@functools.lru_cache(maxsize=None) |
66 | | -def _module(block_genai_types_import=False): |
67 | | - return _load_module(block_genai_types_import) |
68 | | - |
69 | | - |
70 | 27 | def _validate_compat_model(loaded_module, model_type, value): |
71 | 28 | return loaded_module._validate_model(model_type, value, "test") |
72 | 29 |
|
73 | 30 |
|
74 | 31 | @pytest.fixture(scope="module", name="loaded_module") |
75 | 32 | def _loaded_module_fixture(): |
76 | | - return _module() |
| 33 | + return response_extractors |
77 | 34 |
|
78 | 35 |
|
79 | 36 | @pytest.fixture( |
@@ -218,22 +175,22 @@ def test_extract_output_type_handles_text_format_mapping(loaded_module): |
218 | 175 | assert loaded_module._extract_output_type({"text": "plain"}) is None |
219 | 176 |
|
220 | 177 |
|
221 | | -def test_extractors_handle_missing_genai_types_import(): |
222 | | - module = _module(block_genai_types_import=True) |
223 | | - |
224 | | - assert module.Text is None |
225 | | - assert module.InputMessage is None |
226 | | - assert module.OutputMessage is None |
227 | | - assert module._extract_system_instruction({"instructions": "hi"}) == [] |
228 | | - assert module._extract_input_messages({"input": "hi"}) == [] |
229 | | - assert ( |
230 | | - module._extract_output_messages( |
231 | | - SimpleNamespace( |
232 | | - output=[SimpleNamespace(type="message", content=[])] |
| 178 | +def test_extractors_handle_missing_genai_types_import(loaded_module): |
| 179 | + with mock.patch.object(loaded_module, "Text", None), mock.patch.object( |
| 180 | + loaded_module, "InputMessage", None |
| 181 | + ), mock.patch.object(loaded_module, "OutputMessage", None): |
| 182 | + assert loaded_module._extract_system_instruction( |
| 183 | + {"instructions": "hi"} |
| 184 | + ) == [] |
| 185 | + assert loaded_module._extract_input_messages({"input": "hi"}) == [] |
| 186 | + assert ( |
| 187 | + loaded_module._extract_output_messages( |
| 188 | + SimpleNamespace( |
| 189 | + output=[SimpleNamespace(type="message", content=[])] |
| 190 | + ) |
233 | 191 | ) |
| 192 | + == [] |
234 | 193 | ) |
235 | | - == [] |
236 | | - ) |
237 | 194 |
|
238 | 195 |
|
239 | 196 | def test_set_invocation_response_attributes_populates_usage_and_metadata( |
|
0 commit comments