Skip to content

Commit b4c99cd

Browse files
committed
test(secretmanager): add OpenTelemetry observability unit tests with local in-memory gRPC server
1 parent 2bbbca4 commit b4c99cd

4 files changed

Lines changed: 346 additions & 20 deletions

File tree

packages/google-api-core/google/api_core/_observability.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
"""OpenTelemetry helpers for resolving and instantiating interceptors."""
1818

19-
import functools
2019
from typing import TYPE_CHECKING, Any, Callable
2120

2221
from google.api_core import _feature_gating_helpers
@@ -83,7 +82,7 @@ def _get_otel_interceptor(
8382
tracer_provider = getattr(client_options, _TRACER_PROVIDER, None)
8483

8584
if is_async:
86-
return otel_grpc.aio_client_interceptor(tracer_provider=tracer_provider)
85+
return otel_grpc.aio_client_interceptors(tracer_provider=tracer_provider)
8786
return otel_grpc.client_interceptor(tracer_provider=tracer_provider)
8887

8988

@@ -106,7 +105,11 @@ def get_otel_channel_wrapper(
106105
import opentelemetry.instrumentation.grpc as otel_grpc # type: ignore[import-not-found]
107106

108107
interceptor = _get_otel_interceptor(client_options, is_async=False)
109-
return functools.partial(otel_grpc.intercept_channel, interceptor=interceptor)
108+
109+
def channel_wrapper(channel: Any) -> Any:
110+
return otel_grpc.intercept_channel(channel, interceptor)
111+
112+
return channel_wrapper
110113

111114

112115
def get_otel_async_interceptor(

packages/google-api-core/tests/unit/test_observability.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ def test_get_otel_interceptor_async(monkeypatch):
160160

161161
mock_otel = mock.Mock()
162162
mock_otel_grpc = mock_otel.instrumentation.grpc
163-
mock_async_interceptor = mock.Mock()
164-
mock_otel_grpc.aio_client_interceptor.return_value = mock_async_interceptor
163+
mock_async_interceptors = [mock.Mock()]
164+
mock_otel_grpc.aio_client_interceptors.return_value = mock_async_interceptors
165165

166166
monkeypatch.setitem(sys.modules, "opentelemetry", mock_otel)
167167
monkeypatch.setitem(
@@ -172,8 +172,8 @@ def test_get_otel_interceptor_async(monkeypatch):
172172
)
173173

174174
result = _observability._get_otel_interceptor(client_options=options, is_async=True)
175-
assert result is mock_async_interceptor
176-
mock_otel_grpc.aio_client_interceptor.assert_called_once_with(
175+
assert result is mock_async_interceptors
176+
mock_otel_grpc.aio_client_interceptors.assert_called_once_with(
177177
tracer_provider=mock_tracer_provider
178178
)
179179

@@ -222,7 +222,7 @@ def test_get_otel_channel_wrapper_enabled(monkeypatch):
222222
result = wrapper(mock_raw_channel)
223223
assert result is mock_wrapped_channel
224224
mock_otel_grpc.intercept_channel.assert_called_once_with(
225-
mock_raw_channel, interceptor=mock_interceptor
225+
mock_raw_channel, mock_interceptor
226226
)
227227

228228

@@ -261,7 +261,7 @@ def test_get_otel_channel_wrapper_with_apply_channel_wrappers(monkeypatch):
261261
)
262262
assert result is mock_wrapped_channel
263263
mock_otel_grpc.intercept_channel.assert_called_once_with(
264-
mock_raw_channel, interceptor=mock_interceptor
264+
mock_raw_channel, mock_interceptor
265265
)
266266

267267

@@ -281,11 +281,11 @@ def test_get_otel_async_interceptor_enabled(monkeypatch):
281281
mock_tracer_provider = object()
282282
options = ClientOptions(tracer_provider=mock_tracer_provider)
283283

284-
mock_async_interceptor = mock.Mock(name="otel_async_interceptor")
284+
mock_async_interceptors = [mock.Mock(name="otel_async_interceptor")]
285285

286286
mock_otel = mock.Mock()
287287
mock_otel_grpc = mock_otel.instrumentation.grpc
288-
mock_otel_grpc.aio_client_interceptor.return_value = mock_async_interceptor
288+
mock_otel_grpc.aio_client_interceptors.return_value = mock_async_interceptors
289289

290290
monkeypatch.setitem(sys.modules, "opentelemetry", mock_otel)
291291
monkeypatch.setitem(
@@ -296,7 +296,7 @@ def test_get_otel_async_interceptor_enabled(monkeypatch):
296296
)
297297

298298
result = _observability.get_otel_async_interceptor(client_options=options)
299-
assert result is mock_async_interceptor
300-
mock_otel_grpc.aio_client_interceptor.assert_called_once_with(
299+
assert result is mock_async_interceptors
300+
mock_otel_grpc.aio_client_interceptors.assert_called_once_with(
301301
tracer_provider=mock_tracer_provider
302302
)

packages/google-cloud-secret-manager/noxfile.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
]
7373
UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = []
7474
UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [
75-
"../google-api-core[tracing,testing]",
75+
"../google-api-core",
7676
]
7777
UNIT_TEST_DEPENDENCIES: List[str] = []
7878
UNIT_TEST_EXTRAS: List[str] = []
@@ -266,19 +266,27 @@ def install_unittest_dependencies(session, *constraints):
266266

267267
@nox.session(python=ALL_PYTHON)
268268
@nox.parametrize(
269-
"protobuf_implementation",
270-
["python", "upb"],
269+
["protobuf_implementation", "install_otel"],
270+
[
271+
("python", True),
272+
("python", False),
273+
("upb", True),
274+
("upb", False),
275+
],
271276
)
272-
def unit(session, protobuf_implementation):
277+
def unit(session, protobuf_implementation, install_otel):
273278
# Install all test dependencies, then install this package in-place.
274279

275280
constraints_path = str(
276281
CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
277282
)
283+
if install_otel:
284+
session.install("../google-api-core[tracing,testing]")
285+
278286
install_unittest_dependencies(session, "-c", constraints_path)
279287

280288
# Run py.test against the unit tests.
281-
session.run(
289+
pytest_args = [
282290
"py.test",
283291
"--quiet",
284292
f"--junitxml=unit_{session.python}_sponge_log.xml",
@@ -288,8 +296,14 @@ def unit(session, protobuf_implementation):
288296
"--cov-config=.coveragerc",
289297
"--cov-report=",
290298
"--cov-fail-under=0",
291-
os.path.join("tests", "unit"),
292-
*session.posargs,
299+
]
300+
if not session.posargs:
301+
pytest_args.append(os.path.join("tests", "unit"))
302+
else:
303+
pytest_args.extend(session.posargs)
304+
305+
session.run(
306+
*pytest_args,
293307
env={
294308
"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation,
295309
},

0 commit comments

Comments
 (0)