Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 1fbcadd

Browse files
committed
added sync tests
1 parent d4ae637 commit 1fbcadd

3 files changed

Lines changed: 485 additions & 16 deletions

File tree

google/cloud/bigtable/data/_sync_autogen/metrics_interceptor.py

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
# This file is automatically generated by CrossSync. Do not edit manually.
1616

1717
from __future__ import annotations
18+
import time
1819
from functools import wraps
20+
from grpc import RpcError
1921
from google.cloud.bigtable.data._metrics.data_model import (
2022
OPERATION_INTERCEPTOR_METADATA_KEY,
2123
)
@@ -42,7 +44,10 @@ def wrapper(self, continuation, client_call_details, request):
4244
)
4345
operation: "ActiveOperationMetric" = self.operation_map.get(key)
4446
if operation:
45-
if operation.state != OperationState.ACTIVE_ATTEMPT:
47+
if (
48+
operation.state == OperationState.CREATED
49+
or operation.state == OperationState.BETWEEN_ATTEMPTS
50+
):
4651
operation.start_attempt()
4752
return func(self, operation, continuation, client_call_details, request)
4853
else:
@@ -76,7 +81,8 @@ def register_operation(self, operation):
7681
operation.handlers.append(self)
7782

7883
def on_operation_complete(self, op):
79-
del self.operation_map[op.uuid]
84+
if op.uuid in self.operation_map:
85+
del self.operation_map[op.uuid]
8086

8187
def on_operation_cancelled(self, op):
8288
self.on_operation_complete(op)
@@ -86,36 +92,70 @@ def intercept_unary_unary(
8692
self, operation, continuation, client_call_details, request
8793
):
8894
encountered_exc: Exception | None = None
89-
call = None
95+
metadata = None
9096
try:
9197
call = continuation(client_call_details, request)
98+
metadata = (call.trailing_metadata() or []) + (
99+
call.initial_metadata() or []
100+
)
92101
return call
102+
except RpcError as rpc_error:
103+
try:
104+
metadata = (rpc_error.trailing_metadata() or []) + (
105+
rpc_error.initial_metadata() or []
106+
)
107+
except Exception:
108+
pass
109+
encountered_exc = rpc_error
110+
raise rpc_error
93111
except Exception as e:
94112
encountered_exc = e
95113
raise
96114
finally:
97-
if call is not None:
98-
metadata = call.trailing_metadata() + call.initial_metadata()
115+
if metadata is not None:
99116
operation.add_response_metadata(metadata)
100-
if encountered_exc is not None:
101-
operation.end_attempt_with_status(encountered_exc)
117+
if encountered_exc is not None:
118+
operation.end_attempt_with_status(encountered_exc)
102119

103120
@_with_operation_from_metadata
104121
def intercept_unary_stream(
105122
self, operation, continuation, client_call_details, request
106123
):
107124
def response_wrapper(call):
125+
has_first_response = operation.first_response_latency is not None
108126
encountered_exc = None
109127
try:
110128
for response in call:
129+
if not has_first_response:
130+
operation.first_response_latency_ns = (
131+
time.monotonic_ns() - operation.start_time_ns
132+
)
133+
has_first_response = True
111134
yield response
112135
except Exception as e:
113136
encountered_exc = e
114137
raise
115138
finally:
116-
metadata = call.trailing_metadata() + call.initial_metadata()
117-
operation.add_response_metadata(metadata)
118-
if encountered_exc is not None:
119-
operation.end_attempt_with_status(encountered_exc)
139+
if call is not None:
140+
metadata = (call.trailing_metadata() or []) + (
141+
call.initial_metadata() or []
142+
)
143+
operation.add_response_metadata(metadata)
144+
if encountered_exc is not None:
145+
operation.end_attempt_with_status(encountered_exc)
120146

121-
return response_wrapper(continuation(client_call_details, request))
147+
try:
148+
return response_wrapper(continuation(client_call_details, request))
149+
except RpcError as rpc_error:
150+
try:
151+
metadata = (rpc_error.trailing_metadata() or []) + (
152+
rpc_error.initial_metadata() or []
153+
)
154+
operation.add_response_metadata(metadata)
155+
except Exception:
156+
pass
157+
operation.end_attempt_with_status(rpc_error)
158+
raise rpc_error
159+
except Exception as e:
160+
operation.end_attempt_with_status(e)
161+
raise

tests/unit/data/_async/test_metrics_interceptor.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
except ImportError: # pragma: NO COVER
2626
import mock # type: ignore
2727

28+
if CrossSync.is_async:
29+
from google.cloud.bigtable.data._async.metrics_interceptor import AsyncBigtableMetricsInterceptor
30+
else:
31+
from google.cloud.bigtable.data._sync_autogen.metrics_interceptor import BigtableMetricsInterceptor
32+
2833

2934
__CROSS_SYNC_OUTPUT__ = "tests.unit.data._sync_autogen.test_metrics_interceptor"
3035

@@ -53,11 +58,9 @@ async def __anext__(self):
5358
@CrossSync.convert_class(sync_name="TestMetricsInterceptor")
5459
class TestMetricsInterceptorAsync:
5560
@staticmethod
56-
@CrossSync.convert
61+
@CrossSync.convert(replace_symbols={"AsyncBigtableMetricsInterceptor": "BigtableMetricsInterceptor"})
5762
def _get_target_class():
58-
from google.cloud.bigtable.data._async import metrics_interceptor
59-
60-
return metrics_interceptor.AsyncBigtableMetricsInterceptor
63+
return AsyncBigtableMetricsInterceptor
6164

6265
def _make_one(self, *args, **kwargs):
6366
return self._get_target_class()(*args, **kwargs)

0 commit comments

Comments
 (0)