@@ -157,8 +157,41 @@ def test_interceptor_non_recording_span(mock_tracer, monkeypatch):
157157 mock_span_obj .set_attribute .assert_not_called ()
158158
159159
160- def test_interceptor_extracts_destination_id (mock_tracer , monkeypatch ):
161- """F1.7 (Partial): Verifies that the interceptor extracts gcp.resource.destination.id from metadata."""
160+ @pytest .mark .parametrize (
161+ "metadata,expected_destination_id" ,
162+ [
163+ # Case A: Success with 'name'
164+ (
165+ [
166+ (
167+ "x-goog-request-params" ,
168+ "name=projects/my-project/secrets/my-secret/versions/1&other=val" ,
169+ )
170+ ],
171+ "projects/my-project/secrets/my-secret/versions/1" ,
172+ ),
173+ # Case B: Success with 'parent'
174+ (
175+ [
176+ (
177+ "x-goog-request-params" ,
178+ "parent=projects/my-project/locations/us-central1&other=val" ,
179+ )
180+ ],
181+ "projects/my-project/locations/us-central1" ,
182+ ),
183+ # Case C: Other metadata keys (Loop continues, no destination id)
184+ ([("some-other-header" , "value" )], None ),
185+ # Case D: x-goog-request-params exists but no name/parent
186+ ([("x-goog-request-params" , "other=val" )], None ),
187+ # Case E: Malformed x-goog-request-params (Exception caught, fails open)
188+ ([("x-goog-request-params" , "name=foo=bar" )], None ),
189+ ],
190+ )
191+ def test_interceptor_metadata_parsing (
192+ mock_tracer , monkeypatch , metadata , expected_destination_id
193+ ):
194+ """F1.7 (Partial): Verifies metadata parsing scenarios, including success, missing keys, and malformed data."""
162195 from google .api_core .observability .tracing import OtelUnaryClientInterceptor
163196
164197 monkeypatch .setenv ("GOOGLE_CLOUD_PYTHON_TRACING_ENABLED" , "true" )
@@ -170,19 +203,18 @@ def test_interceptor_extracts_destination_id(mock_tracer, monkeypatch):
170203
171204 continuation = Mock (return_value = "response" )
172205 details = MockClientCallDetails ()
173- # Simulate standard routing metadata
174- details .metadata = [
175- (
176- "x-goog-request-params" ,
177- "name=projects/my-project/secrets/my-secret/versions/1&other=val" ,
178- )
179- ]
206+ details .metadata = metadata
180207 request = "request_payload"
181208
182209 interceptor .intercept_unary_unary (continuation , details , request )
183210
184- # Verify attribute was extracted and set
185- mock_span_obj .set_attribute .assert_any_call (
186- "gcp.resource.destination.id" ,
187- "projects/my-project/secrets/my-secret/versions/1" ,
188- )
211+ if expected_destination_id :
212+ mock_span_obj .set_attribute .assert_any_call (
213+ "gcp.resource.destination.id" , expected_destination_id
214+ )
215+ else :
216+ # Verify gcp.resource.destination.id was NOT called
217+ called_keys = [
218+ call [0 ][0 ] for call in mock_span_obj .set_attribute .call_args_list
219+ ]
220+ assert "gcp.resource.destination.id" not in called_keys
0 commit comments