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

Commit 8a91874

Browse files
committed
test: stabilize async test suite
1 parent fd9858b commit 8a91874

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+520
-446
lines changed

google/cloud/spanner_v1/__init__.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,31 @@
2020

2121
__version__: str = package_version.__version__
2222

23+
from google.cloud.spanner_v1 import param_types
24+
from google.cloud.spanner_v1._async.client import Client as AsyncClient
25+
from google.cloud.spanner_v1._async.pool import BurstyPool as AsyncBurstyPool
26+
from google.cloud.spanner_v1._async.pool import PingingPool as AsyncPingingPool
27+
from google.cloud.spanner_v1._async.pool import (
28+
AbstractSessionPool as AsyncAbstractSessionPool,
29+
)
30+
from google.cloud.spanner_v1._async.pool import FixedSizePool as AsyncFixedSizePool
31+
from google.cloud.spanner_v1._async.pool import (
32+
TransactionPingingPool as AsyncTransactionPingingPool,
33+
)
34+
from google.cloud.spanner_v1.client import Client
35+
from google.cloud.spanner_v1.keyset import KeyRange, KeySet
36+
from google.cloud.spanner_v1.pool import (
37+
AbstractSessionPool,
38+
BurstyPool,
39+
FixedSizePool,
40+
PingingPool,
41+
TransactionPingingPool,
42+
)
43+
44+
from .data_types import Interval, JsonObject
45+
from .exceptions import wrap_with_request_id
46+
from .services.spanner import SpannerAsyncClient, SpannerClient
47+
from .transaction import BatchTransactionId, DefaultTransactionOptions
2348
from .types import RequestOptions
2449
from .types.commit_response import CommitResponse
2550
from .types.keys import KeyRange as KeyRangePB
@@ -61,32 +86,6 @@
6186
from .types.transaction import Transaction, TransactionOptions, TransactionSelector
6287
from .types.type import StructType, Type, TypeAnnotationCode, TypeCode
6388

64-
from .data_types import Interval, JsonObject
65-
from .exceptions import wrap_with_request_id
66-
from .services.spanner import SpannerAsyncClient, SpannerClient
67-
from .transaction import BatchTransactionId, DefaultTransactionOptions
68-
69-
from google.cloud.spanner_v1 import param_types
70-
from google.cloud.spanner_v1.client import Client
71-
from google.cloud.spanner_v1.keyset import KeyRange, KeySet
72-
from google.cloud.spanner_v1.pool import (
73-
AbstractSessionPool,
74-
BurstyPool,
75-
FixedSizePool,
76-
PingingPool,
77-
TransactionPingingPool,
78-
)
79-
from google.cloud.spanner_v1._async.client import Client as AsyncClient
80-
from google.cloud.spanner_v1._async.pool import BurstyPool as AsyncBurstyPool
81-
from google.cloud.spanner_v1._async.pool import PingingPool as AsyncPingingPool
82-
from google.cloud.spanner_v1._async.pool import (
83-
AbstractSessionPool as AsyncAbstractSessionPool,
84-
)
85-
from google.cloud.spanner_v1._async.pool import FixedSizePool as AsyncFixedSizePool
86-
from google.cloud.spanner_v1._async.pool import (
87-
TransactionPingingPool as AsyncTransactionPingingPool,
88-
)
89-
9089
COMMIT_TIMESTAMP = "spanner.commit_timestamp()"
9190
"""Placeholder be used to store commit timestamp of a transaction in a column.
9291
This value can only be used for timestamp columns that have set the option

google/cloud/spanner_v1/_async/_helpers.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import inspect
23
import time
34

45
from google.api_core.exceptions import Aborted
@@ -7,9 +8,15 @@
78
async def _delay_until_retry(exc, deadline, attempts, default_retry_delay=None):
89
from google.cloud.spanner_v1._helpers import _get_retry_delay
910

10-
delay = _get_retry_delay(exc, attempts, default_retry_delay)
11-
if time.time() + delay > deadline:
11+
cause = exc.errors[0] if hasattr(exc, "errors") and exc.errors else exc
12+
now = time.time()
13+
if now >= deadline:
1214
raise exc
15+
16+
delay = _get_retry_delay(cause, attempts, default_retry_delay)
17+
if now + delay > deadline:
18+
raise exc
19+
1320
await asyncio.sleep(delay)
1421

1522

@@ -39,9 +46,14 @@ async def _retry(
3946
retries = 0
4047
while True:
4148
try:
42-
return await func()
49+
res = func()
50+
if asyncio.iscoroutine(res) or inspect.isawaitable(res):
51+
return await res
52+
return res
4353
except Exception as e:
44-
if allowed_exceptions and type(e) in allowed_exceptions:
54+
if allowed_exceptions is not None:
55+
if type(e) not in allowed_exceptions:
56+
raise e
4557
_check_err = allowed_exceptions.get(type(e))
4658
if callable(_check_err) and not _check_err(e):
4759
raise e
@@ -80,8 +92,8 @@ def _create_experimental_host_transport(
8092
Raises:
8193
ValueError: If TLS/mTLS configuration is invalid.
8294
"""
83-
import grpc.aio
8495
from google.auth.credentials import AnonymousCredentials
96+
import grpc.aio
8597

8698
channel = None
8799
if use_plain_text:

google/cloud/spanner_v1/_async/batch.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@
2929
RequestOptions,
3030
TransactionOptions,
3131
)
32-
from google.cloud.spanner_v1._async._helpers import _retry_on_aborted_exception
32+
from google.cloud.spanner_v1._async._helpers import _retry, _retry_on_aborted_exception
3333
from google.cloud.spanner_v1._helpers import (
3434
AtomicCounter,
3535
_merge_client_context,
3636
_merge_request_options,
3737
_validate_client_context,
3838
_check_rst_stream_error,
3939
_make_list_value_pbs,
40+
4041
_merge_Transaction_Options,
4142
_metadata_with_leader_aware_routing,
4243
_metadata_with_prefix,

google/cloud/spanner_v1/_async/client.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,9 @@
6666
ListInstanceConfigsRequest,
6767
ListInstancesRequest,
6868
)
69-
from google.cloud.spanner_v1 import (
70-
DefaultTransactionOptions,
71-
ExecuteSqlRequest,
72-
__version__,
73-
)
69+
from google.cloud.spanner_v1.gapic_version import __version__
70+
from google.cloud.spanner_v1.transaction import DefaultTransactionOptions
71+
from google.cloud.spanner_v1.types.spanner import ExecuteSqlRequest
7472
from google.cloud.spanner_v1._helpers import (
7573
_create_experimental_host_transport,
7674
_validate_client_context,
@@ -402,12 +400,12 @@ def instance_admin_api(self):
402400
transport=transport,
403401
)
404402
elif self._experimental_host:
405-
from google.cloud.spanner_v1._helpers import (
406-
_create_experimental_host_transport as _create_experimental_host_transport_sync,
407-
)
408403
from google.cloud.spanner_v1._async._helpers import (
409404
_create_experimental_host_transport as _create_experimental_host_transport_async,
410405
)
406+
from google.cloud.spanner_v1._helpers import (
407+
_create_experimental_host_transport as _create_experimental_host_transport_sync,
408+
)
411409

412410
if CrossSync.is_async:
413411
transport = _create_experimental_host_transport_async(
@@ -456,12 +454,12 @@ def database_admin_api(self):
456454
transport=transport,
457455
)
458456
elif self._experimental_host:
459-
from google.cloud.spanner_v1._helpers import (
460-
_create_experimental_host_transport as _create_experimental_host_transport_sync,
461-
)
462457
from google.cloud.spanner_v1._async._helpers import (
463458
_create_experimental_host_transport as _create_experimental_host_transport_async,
464459
)
460+
from google.cloud.spanner_v1._helpers import (
461+
_create_experimental_host_transport as _create_experimental_host_transport_sync,
462+
)
465463

466464
if CrossSync.is_async:
467465
transport = _create_experimental_host_transport_async(

google/cloud/spanner_v1/_async/database.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,13 @@
4343
from google.cloud.spanner_admin_database_v1 import CreateDatabaseRequest
4444
from google.cloud.spanner_admin_database_v1 import Database as DatabasePB
4545
from google.cloud.spanner_admin_database_v1.types import DatabaseDialect
46-
from google.cloud.spanner_v1 import (
47-
DefaultTransactionOptions,
48-
ExecuteSqlRequest,
49-
RequestOptions,
50-
TransactionOptions,
51-
TransactionSelector,
52-
Type,
53-
TypeCode,
54-
)
46+
from google.cloud.spanner_v1.transaction import DefaultTransactionOptions
47+
from google.cloud.spanner_v1.types.spanner import ExecuteSqlRequest
48+
from google.cloud.spanner_v1.types.spanner import RequestOptions
49+
from google.cloud.spanner_v1.types.transaction import TransactionOptions
50+
from google.cloud.spanner_v1.types.transaction import TransactionSelector
51+
from google.cloud.spanner_v1.types.type import Type
52+
from google.cloud.spanner_v1.types.type import TypeCode
5553
from google.cloud.spanner_v1._async.batch import Batch, MutationGroups
5654
from google.cloud.spanner_v1._async.database_sessions_manager import (
5755
DatabaseSessionsManager,
@@ -482,12 +480,12 @@ def spanner_api(self):
482480
)
483481
return self._spanner_api
484482
if self._experimental_host is not None:
485-
from google.cloud.spanner_v1._helpers import (
486-
_create_experimental_host_transport as _create_experimental_host_transport_sync,
487-
)
488483
from google.cloud.spanner_v1._async._helpers import (
489484
_create_experimental_host_transport as _create_experimental_host_transport_async,
490485
)
486+
from google.cloud.spanner_v1._helpers import (
487+
_create_experimental_host_transport as _create_experimental_host_transport_sync,
488+
)
491489

492490
if CrossSync.is_async:
493491
transport = _create_experimental_host_transport_async(

google/cloud/spanner_v1/_async/pool.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121

2222
from google.cloud.aio._cross_sync import CrossSync
2323
from google.cloud.exceptions import NotFound
24-
from google.cloud.spanner_v1 import BatchCreateSessionsRequest
25-
from google.cloud.spanner_v1 import Session as SessionProto
24+
from google.cloud.spanner_v1.types.spanner import BatchCreateSessionsRequest
25+
from google.cloud.spanner_v1.types.spanner import Session as SessionProto
2626
from google.cloud.spanner_v1._async.session import Session
2727
from google.cloud.spanner_v1._helpers import (
2828
_metadata_with_leader_aware_routing,
@@ -35,7 +35,9 @@
3535
)
3636
from google.cloud.spanner_v1.metrics.metrics_capture import MetricsCapture
3737

38-
_NOW = datetime.datetime.utcnow # unit tests may replace
38+
39+
def _NOW():
40+
return datetime.datetime.now(datetime.timezone.utc)
3941

4042

4143
@CrossSync.convert_class

google/cloud/spanner_v1/_async/session.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
"""Wrapper for Cloud Spanner Session objects."""
1616
__CROSS_SYNC_OUTPUT__ = "google.cloud.spanner_v1.session"
17-
from datetime import datetime
17+
from datetime import datetime, timezone
1818
from functools import total_ordering
1919
import time
2020
from typing import MutableMapping, Optional
@@ -23,12 +23,13 @@
2323
from google.api_core.gapic_v1 import method
2424

2525
from google.cloud.aio._cross_sync import CrossSync
26-
from google.cloud.spanner_v1 import CreateSessionRequest, ExecuteSqlRequest
26+
from google.cloud.spanner_v1.types.spanner import CreateSessionRequest
27+
from google.cloud.spanner_v1.types.spanner import ExecuteSqlRequest
28+
from google.cloud.spanner_v1._async._helpers import _delay_until_retry
2729
from google.cloud.spanner_v1._async.batch import Batch
2830
from google.cloud.spanner_v1._async.snapshot import Snapshot
2931
from google.cloud.spanner_v1._async.transaction import Transaction
3032
from google.cloud.spanner_v1._helpers import (
31-
_delay_until_retry,
3233
_get_retry_delay,
3334
_metadata_with_leader_aware_routing,
3435
_metadata_with_prefix,
@@ -77,7 +78,7 @@ def __init__(self, database, labels=None, database_role=None, is_multiplexed=Fal
7778
self._labels: MutableMapping[str, str] = labels
7879
self._database_role: Optional[str] = database_role
7980
self._is_multiplexed: bool = is_multiplexed
80-
self._last_use_time: datetime = datetime.utcnow()
81+
self._last_use_time: datetime = datetime.now(timezone.utc)
8182

8283
@property
8384
def _resource_info(self):
@@ -393,7 +394,7 @@ async def read(self, table, columns, keyset, index="", limit=0, column_info=None
393394
:rtype: :class:`~google.cloud.spanner_v1.streamed.StreamedResultSet`
394395
:returns: a result set instance which can be used to consume rows.
395396
"""
396-
return self.snapshot().read(
397+
return await self.snapshot().read(
397398
table, columns, keyset, index, limit, column_info=column_info
398399
)
399400

@@ -460,7 +461,7 @@ async def execute_sql(
460461
:rtype: :class:`~google.cloud.spanner_v1.streamed.StreamedResultSet`
461462
:returns: a result set instance which can be used to consume rows.
462463
"""
463-
return self.snapshot().execute_sql(
464+
return await self.snapshot().execute_sql(
464465
sql,
465466
params,
466467
param_types,
@@ -599,7 +600,7 @@ async def run_in_transaction(self, func, *args, **kw):
599600
"Transaction was aborted in user operation, retrying",
600601
attributes,
601602
)
602-
_delay_until_retry(
603+
await _delay_until_retry(
603604
exc,
604605
deadline,
605606
attempts,
@@ -645,7 +646,7 @@ async def run_in_transaction(self, func, *args, **kw):
645646
"Transaction was aborted during commit, retrying",
646647
attributes,
647648
)
648-
_delay_until_retry(
649+
await _delay_until_retry(
649650
exc,
650651
deadline,
651652
attempts,

google/cloud/spanner_v1/_async/snapshot.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,19 @@
2727
from google.protobuf.struct_pb2 import Struct
2828

2929
from google.cloud.aio._cross_sync import CrossSync
30-
from google.cloud.spanner_v1 import (
31-
BeginTransactionRequest,
32-
ExecuteSqlRequest,
33-
Mutation,
34-
PartialResultSet,
35-
PartitionOptions,
36-
PartitionQueryRequest,
37-
PartitionReadRequest,
38-
ReadRequest,
39-
RequestOptions,
40-
ResultSet,
41-
Transaction,
42-
TransactionOptions,
43-
TransactionSelector,
44-
)
30+
from google.cloud.spanner_v1.types.mutation import Mutation
31+
from google.cloud.spanner_v1.types.result_set import PartialResultSet
32+
from google.cloud.spanner_v1.types.result_set import ResultSet
33+
from google.cloud.spanner_v1.types.spanner import BeginTransactionRequest
34+
from google.cloud.spanner_v1.types.spanner import ExecuteSqlRequest
35+
from google.cloud.spanner_v1.types.spanner import PartitionOptions
36+
from google.cloud.spanner_v1.types.spanner import PartitionQueryRequest
37+
from google.cloud.spanner_v1.types.spanner import PartitionReadRequest
38+
from google.cloud.spanner_v1.types.spanner import ReadRequest
39+
from google.cloud.spanner_v1.types.spanner import RequestOptions
40+
from google.cloud.spanner_v1.types.transaction import Transaction
41+
from google.cloud.spanner_v1.types.transaction import TransactionOptions
42+
from google.cloud.spanner_v1.types.transaction import TransactionSelector
4543
from google.cloud.spanner_v1._async._helpers import _retry
4644
from google.cloud.spanner_v1._async.streamed import StreamedResultSet
4745
from google.cloud.spanner_v1._helpers import (

google/cloud/spanner_v1/_async/streamed.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
from google.cloud import exceptions
2020
from google.cloud.aio._cross_sync import CrossSync
21-
from google.cloud.spanner_v1 import PartialResultSet, ResultSetMetadata, TypeCode
21+
from google.cloud.spanner_v1.types.result_set import PartialResultSet
22+
from google.cloud.spanner_v1.types.result_set import ResultSetMetadata
23+
from google.cloud.spanner_v1.types.type import TypeCode
2224
from google.cloud.spanner_v1._helpers import _get_type_decoder, _parse_nullable
2325

2426

0 commit comments

Comments
 (0)