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

Commit 27e8fc7

Browse files
committed
Plumb test_context_manager
1 parent 760d6cd commit 27e8fc7

File tree

7 files changed

+84
-17
lines changed

7 files changed

+84
-17
lines changed

google/cloud/spanner_v1/_helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ def __radd__(self, n):
566566
"""
567567
return self.__add__(n)
568568

569+
def reset(self):
570+
with self.__lock:
571+
self.__value = 0
572+
569573

570574
def _metadata_with_request_id(*args, **kwargs):
571575
return with_request_id(*args, **kwargs)

google/cloud/spanner_v1/batch.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from google.cloud.spanner_v1._helpers import (
2626
_metadata_with_prefix,
2727
_metadata_with_leader_aware_routing,
28+
AtomicCounter,
2829
)
2930
from google.cloud.spanner_v1._opentelemetry_tracing import trace_call
3031
from google.cloud.spanner_v1 import RequestOptions
@@ -222,13 +223,24 @@ def commit(
222223
trace_attributes,
223224
observability_options=observability_options,
224225
):
225-
method = functools.partial(
226-
api.commit,
227-
request=request,
228-
metadata=metadata,
229-
)
226+
attempt = AtomicCounter(0)
227+
next_nth_request = database._next_nth_request
228+
229+
def wrapped_method(*args, **kwargs):
230+
all_metadata = database.metadata_with_request_id(
231+
next_nth_request,
232+
attempt.increment(),
233+
metadata,
234+
)
235+
method = functools.partial(
236+
api.commit,
237+
request=request,
238+
metadata=all_metadata,
239+
)
240+
return method(*args, **kwargs)
241+
230242
response = _retry(
231-
method,
243+
wrapped_method,
232244
allowed_exceptions={InternalServerError: _check_rst_stream_error},
233245
)
234246
self.committed = response.commit_timestamp
@@ -341,13 +353,24 @@ def batch_write(self, request_options=None, exclude_txn_from_change_streams=Fals
341353
trace_attributes,
342354
observability_options=observability_options,
343355
):
344-
method = functools.partial(
345-
api.batch_write,
346-
request=request,
347-
metadata=metadata,
348-
)
356+
attempt = AtomicCounter(0)
357+
next_nth_request = database._next_nth_request
358+
359+
def wrapped_method(*args, **kwargs):
360+
all_metadata = database.metadata_with_request_id(
361+
next_nth_request,
362+
attempt.increment(),
363+
metadata,
364+
)
365+
method = functools.partial(
366+
api.batch_write,
367+
request=request,
368+
metadata=all_metadata,
369+
)
370+
return method(*args, **kwargs)
371+
349372
response = _retry(
350-
method,
373+
wrapped_method,
351374
allowed_exceptions={InternalServerError: _check_rst_stream_error},
352375
)
353376
self.committed = True

google/cloud/spanner_v1/client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
"""
2626
import grpc
2727
import os
28-
import sys
2928
import warnings
3029

3130
from google.api_core.gapic_v1 import client_info
@@ -208,7 +207,6 @@ def __init__(
208207

209208
@property
210209
def _next_nth_request(self):
211-
print("next_nth_request called by", sys._getframe().f_back.f_code.co_name)
212210
return self._nth_request.increment()
213211

214212
@property

google/cloud/spanner_v1/database.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,9 @@ def wrapped_method(*args, **kwargs):
804804

805805
@property
806806
def _next_nth_request(self):
807-
return self._instance._client._next_nth_request
807+
if self._instance and self._instance._client:
808+
return self._instance._client._next_nth_request
809+
return 1
808810

809811
@property
810812
def _nth_client_id(self):

tests/mockserver_tests/mock_server_test_base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
start_mock_server,
2121
SpannerServicer,
2222
)
23+
from google.cloud.spanner_v1.client import Client
2324
import google.cloud.spanner_v1.types.type as spanner_type
2425
import google.cloud.spanner_v1.types.result_set as result_set
2526
from google.api_core.client_options import ClientOptions
@@ -133,6 +134,7 @@ def teardown_class(cls):
133134
if MockServerTestBase.server is not None:
134135
MockServerTestBase.server.stop(grace=None)
135136
MockServerTestBase.server = None
137+
Client.NTH_CLIENT.reset()
136138

137139
def setup_method(self, *args, **kwargs):
138140
self._client = None

tests/unit/test_batch.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
enrich_with_otel_scope,
2121
)
2222
from google.cloud.spanner_v1 import RequestOptions
23+
from google.cloud.spanner_v1._helpers import (
24+
_metadata_with_request_id,
25+
)
26+
from google.cloud.spanner_v1.request_id_header import REQ_RAND_PROCESS_ID
2327

2428
TABLE_NAME = "citizens"
2529
COLUMNS = ["email", "first_name", "last_name", "age"]
@@ -435,6 +439,10 @@ def test_context_mgr_success(self):
435439
[
436440
("google-cloud-resource-prefix", database.name),
437441
("x-goog-spanner-route-to-leader", "true"),
442+
(
443+
"x-goog-spanner-request-id",
444+
f"1.{REQ_RAND_PROCESS_ID}.{_Database.NTH_CLIENT}.1.1.1",
445+
),
438446
],
439447
)
440448
self.assertEqual(request_options, RequestOptions())
@@ -622,6 +630,32 @@ def session_id(self):
622630
class _Database(object):
623631
name = "testing"
624632
_route_to_leader_enabled = True
633+
NTH_CLIENT = 1
634+
635+
def __init__(self):
636+
self._nth_request = 0
637+
638+
@property
639+
def _next_nth_request(self):
640+
self._nth_request += 1
641+
return self._nth_request
642+
643+
@property
644+
def _nth_client_id(self):
645+
return 1
646+
647+
def metadata_with_request_id(self, nth_request, nth_attempt, prior_metadata=[]):
648+
return _metadata_with_request_id(
649+
self._nth_client_id,
650+
self._channel_id,
651+
nth_request,
652+
nth_attempt,
653+
prior_metadata,
654+
)
655+
656+
@property
657+
def _channel_id(self):
658+
return 1
625659

626660

627661
class _FauxSpannerAPI:

tests/unit/test_database.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,11 +3251,15 @@ def __init__(self, name, instance=None):
32513251

32523252
@property
32533253
def _next_nth_request(self):
3254-
return self._instance._client._next_nth_request
3254+
if self._instance and self._instance._client:
3255+
return self._instance._client._next_nth_request
3256+
return 1
32553257

32563258
@property
32573259
def _nth_client_id(self):
3258-
return self._instance._client._nth_client_id
3260+
if self._instance and self._instance._client:
3261+
return self._instance._client._nth_client_id
3262+
return 1
32593263

32603264
def metadata_with_request_id(self, nth_request, nth_attempt, prior_metadata=[]):
32613265
return _metadata_with_request_id(

0 commit comments

Comments
 (0)