From e49afa6931414609bd0e95210e24598f03465dfb Mon Sep 17 00:00:00 2001 From: Subham Sinha Date: Mon, 27 Oct 2025 10:48:44 +0530 Subject: [PATCH 1/6] feat: add cloud.region and transaction_tag in span attributes --- examples/trace.py | 30 ++-- google/cloud/spanner_v1/_helpers.py | 40 +++++- .../spanner_v1/_opentelemetry_tracing.py | 5 + google/cloud/spanner_v1/database.py | 6 + .../metrics/spanner_metrics_tracer_factory.py | 41 +----- google/cloud/spanner_v1/session.py | 5 + google/cloud/spanner_v1/transaction.py | 8 +- tests/unit/test__helpers.py | 43 ++++++ tests/unit/test__opentelemetry_tracing.py | 2 + tests/unit/test_batch.py | 1 + tests/unit/test_pool.py | 3 + tests/unit/test_session.py | 1 + tests/unit/test_snapshot.py | 136 +++++++++--------- .../test_spanner_metrics_tracer_factory.py | 47 ------ tests/unit/test_transaction.py | 20 +-- 15 files changed, 209 insertions(+), 179 deletions(-) diff --git a/examples/trace.py b/examples/trace.py index 5b826ca5ad..58db7a1fe7 100644 --- a/examples/trace.py +++ b/examples/trace.py @@ -27,7 +27,7 @@ from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator # Setup common variables that'll be used between Spanner and traces. -project_id = os.environ.get('SPANNER_PROJECT_ID', 'test-project') +project_id = os.environ.get('SPANNER_PROJECT_ID', 'span-cloud-testing') def spanner_with_cloud_trace(): # [START spanner_opentelemetry_traces_cloudtrace_usage] @@ -62,16 +62,13 @@ def spanner_with_otlp(): def main(): - # Setup OpenTelemetry, trace and Cloud Trace exporter. - tracer_provider = TracerProvider(sampler=ALWAYS_ON) - trace_exporter = CloudTraceSpanExporter(project_id=project_id) - tracer_provider.add_span_processor(BatchSpanProcessor(trace_exporter)) - # Setup the Cloud Spanner Client. # Change to "spanner_client = spanner_with_otlp" to use OTLP exporter spanner_client = spanner_with_cloud_trace() - instance = spanner_client.instance('test-instance') - database = instance.database('test-db') + instance = spanner_client.instance('suvham-testing') + instance.reload() + database = instance.database('gildb') + tracer_provider = spanner_client.observability_options["tracer_provider"] # Set W3C Trace Context as the global propagator for end to end tracing. set_global_textmap(TraceContextTextMapPropagator()) @@ -93,12 +90,27 @@ def main(): # Purposefully issue a bad SQL statement to examine exceptions # that get recorded and a ERROR span status. try: - data = snapshot.execute_sql('SELECT CURRENT_TIMESTAMPx()') + data = snapshot.execute_sql('SELECT CURRENT_TIMESTAMP()') for row in data: print(row) except Exception as e: print(e) + # Example of a read-write transaction with a transaction tag + with tracer.start_as_current_span('TaggedTransaction'): + def update_singer_name(transaction): + transaction.execute_update( + "UPDATE Singers SET FirstName = 'Timothy' WHERE SingerId = 1", + request_options={ + "request_tag": "app=concert,env=dev,action=update" + }, + ) + print("Updated singer's name.") + + database.run_in_transaction( + update_singer_name, transaction_tag="app=concert,env=dev" + ) + if __name__ == '__main__': main() diff --git a/google/cloud/spanner_v1/_helpers.py b/google/cloud/spanner_v1/_helpers.py index 00a69d462b..0d2f476a92 100644 --- a/google/cloud/spanner_v1/_helpers.py +++ b/google/cloud/spanner_v1/_helpers.py @@ -20,6 +20,7 @@ import time import base64 import threading +import logging from google.protobuf.struct_pb2 import ListValue from google.protobuf.struct_pb2 import Value @@ -29,11 +30,16 @@ from google.api_core import datetime_helpers from google.api_core.exceptions import Aborted from google.cloud._helpers import _date_from_iso8601_date -from google.cloud.spanner_v1 import TypeCode -from google.cloud.spanner_v1 import ExecuteSqlRequest -from google.cloud.spanner_v1 import JsonObject, Interval -from google.cloud.spanner_v1 import TransactionOptions +from google.cloud.spanner_v1.types import ExecuteSqlRequest +from google.cloud.spanner_v1.types import TransactionOptions +from google.cloud.spanner_v1.data_types import JsonObject, Interval from google.cloud.spanner_v1.request_id_header import with_request_id +from google.cloud.spanner_v1.types import TypeCode +from opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.resourcedetector.gcp_resource_detector import ( + GoogleCloudResourceDetector, +) + from google.rpc.error_details_pb2 import RetryInfo try: @@ -55,6 +61,10 @@ + "numeric has a whole component with precision {}" ) +GOOGLE_CLOUD_REGION_GLOBAL = "global" + +log = logging.getLogger(__name__) + if HAS_OPENTELEMETRY_INSTALLED: @@ -79,6 +89,28 @@ def set(self, carrier: List[Tuple[str, str]], key: str, value: str) -> None: carrier.append((key, value)) +def _get_cloud_region() -> str: + """Get the location of the resource. + + Returns: + str: The location of the resource. If OpenTelemetry is not installed, returns a global region. + """ + if not HAS_OPENTELEMETRY_INSTALLED: + return GOOGLE_CLOUD_REGION_GLOBAL + try: + detector = GoogleCloudResourceDetector() + resources = detector.detect() + + if ResourceAttributes.CLOUD_REGION in resources.attributes: + return resources.attributes[ResourceAttributes.CLOUD_REGION] + except Exception as e: + log.warning( + "Failed to detect GCP resource location for Spanner metrics, defaulting to 'global'. Error: %s", + e, + ) + return GOOGLE_CLOUD_REGION_GLOBAL + + def _try_to_coerce_bytes(bytestring): """Try to coerce a byte string into the right thing based on Python version and whether or not it is base64 encoded. diff --git a/google/cloud/spanner_v1/_opentelemetry_tracing.py b/google/cloud/spanner_v1/_opentelemetry_tracing.py index eafc983850..7cefa7e736 100644 --- a/google/cloud/spanner_v1/_opentelemetry_tracing.py +++ b/google/cloud/spanner_v1/_opentelemetry_tracing.py @@ -21,6 +21,7 @@ from google.cloud.spanner_v1 import SpannerClient from google.cloud.spanner_v1 import gapic_version from google.cloud.spanner_v1._helpers import ( + _get_cloud_region, _metadata_with_span_context, ) @@ -85,6 +86,7 @@ def trace_call( enable_end_to_end_tracing = False db_name = "" + cloud_region = None if session and getattr(session, "_database", None): db_name = session._database.name @@ -97,7 +99,9 @@ def trace_call( "enable_end_to_end_tracing", enable_end_to_end_tracing ) db_name = observability_options.get("db_name", db_name) + cloud_region = observability_options.get("cloud_region", cloud_region) + cloud_region = _get_cloud_region() tracer = get_tracer(tracer_provider) # Set base attributes that we know for every trace created @@ -107,6 +111,7 @@ def trace_call( "db.instance": db_name, "net.host.name": SpannerClient.DEFAULT_ENDPOINT, OTEL_SCOPE_NAME: TRACER_NAME, + "cloud.region": cloud_region, OTEL_SCOPE_VERSION: TRACER_VERSION, # Standard GCP attributes for OTel, attributes are used for internal purpose and are subjected to change "gcp.client.service": "spanner", diff --git a/google/cloud/spanner_v1/database.py b/google/cloud/spanner_v1/database.py index c5fc56bcc9..394636f20b 100644 --- a/google/cloud/spanner_v1/database.py +++ b/google/cloud/spanner_v1/database.py @@ -1012,8 +1012,14 @@ def run_in_transaction(self, func, *args, **kw): reraises any non-ABORT exceptions raised by ``func``. """ observability_options = getattr(self, "observability_options", None) + transaction_tag = kw.get("transaction_tag") + extra_attributes = {} + if transaction_tag: + extra_attributes["transaction.tag"] = transaction_tag + with trace_call( "CloudSpanner.Database.run_in_transaction", + extra_attributes=extra_attributes, observability_options=observability_options, ), MetricsCapture(): # Sanity check: Is there a transaction already running? diff --git a/google/cloud/spanner_v1/metrics/spanner_metrics_tracer_factory.py b/google/cloud/spanner_v1/metrics/spanner_metrics_tracer_factory.py index 881a5bfca9..9566e61a28 100644 --- a/google/cloud/spanner_v1/metrics/spanner_metrics_tracer_factory.py +++ b/google/cloud/spanner_v1/metrics/spanner_metrics_tracer_factory.py @@ -18,20 +18,9 @@ from .metrics_tracer_factory import MetricsTracerFactory import os import logging -from .constants import ( - SPANNER_SERVICE_NAME, - GOOGLE_CLOUD_REGION_KEY, - GOOGLE_CLOUD_REGION_GLOBAL, -) +from .constants import SPANNER_SERVICE_NAME try: - from opentelemetry.resourcedetector import gcp_resource_detector - - # Overwrite the requests timeout for the detector. - # This is necessary as the client will wait the full timeout if the - # code is not run in a GCP environment, with the location endpoints available. - gcp_resource_detector._TIMEOUT_SEC = 0.2 - import mmh3 logging.getLogger("opentelemetry.resourcedetector.gcp_resource_detector").setLevel( @@ -44,6 +33,7 @@ from .metrics_tracer import MetricsTracer from google.cloud.spanner_v1 import __version__ +from google.cloud.spanner_v1._helpers import _get_cloud_region from uuid import uuid4 log = logging.getLogger(__name__) @@ -86,7 +76,7 @@ def __new__( cls._metrics_tracer_factory.set_client_hash( cls._generate_client_hash(client_uid) ) - cls._metrics_tracer_factory.set_location(cls._get_location()) + cls._metrics_tracer_factory.set_location(_get_cloud_region()) cls._metrics_tracer_factory.gfe_enabled = gfe_enabled if cls._metrics_tracer_factory.enabled != enabled: @@ -153,28 +143,3 @@ def _generate_client_hash(client_uid: str) -> str: # Return as 6 digit zero padded hex string return f"{sig_figs:06x}" - - @staticmethod - def _get_location() -> str: - """Get the location of the resource. - - In case of any error during detection, this method will log a warning - and default to the "global" location. - - Returns: - str: The location of the resource. If OpenTelemetry is not installed, returns a global region. - """ - if not HAS_OPENTELEMETRY_INSTALLED: - return GOOGLE_CLOUD_REGION_GLOBAL - try: - detector = gcp_resource_detector.GoogleCloudResourceDetector() - resources = detector.detect() - - if GOOGLE_CLOUD_REGION_KEY in resources.attributes: - return resources.attributes[GOOGLE_CLOUD_REGION_KEY] - except Exception as e: - log.warning( - "Failed to detect GCP resource location for Spanner metrics, defaulting to 'global'. Error: %s", - e, - ) - return GOOGLE_CLOUD_REGION_GLOBAL diff --git a/google/cloud/spanner_v1/session.py b/google/cloud/spanner_v1/session.py index 7b6634c728..2d22fca10c 100644 --- a/google/cloud/spanner_v1/session.py +++ b/google/cloud/spanner_v1/session.py @@ -531,9 +531,14 @@ def run_in_transaction(self, func, *args, **kw): database = self._database log_commit_stats = database.log_commit_stats + extra_attributes = {} + if transaction_tag: + extra_attributes["transaction.tag"] = transaction_tag + with trace_call( "CloudSpanner.Session.run_in_transaction", self, + extra_attributes=extra_attributes, observability_options=getattr(database, "observability_options", None), ) as span, MetricsCapture(): attempts: int = 0 diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index 5dd54eafe1..b9e14a0040 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -479,7 +479,10 @@ def execute_update( request_options = RequestOptions(request_options) request_options.transaction_tag = self.transaction_tag - trace_attributes = {"db.statement": dml} + trace_attributes = { + "db.statement": dml, + "request_options": request_options, + } # If this request begins the transaction, we need to lock # the transaction until the transaction ID is updated. @@ -629,7 +632,8 @@ def batch_update( trace_attributes = { # Get just the queries from the DML statement batch - "db.statement": ";".join([statement.sql for statement in parsed]) + "db.statement": ";".join([statement.sql for statement in parsed]), + "request_options": request_options, } # If this request begins the transaction, we need to lock diff --git a/tests/unit/test__helpers.py b/tests/unit/test__helpers.py index 6f77d002cd..2ad9293c16 100644 --- a/tests/unit/test__helpers.py +++ b/tests/unit/test__helpers.py @@ -16,6 +16,10 @@ import unittest import mock +from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.resource import ResourceAttributes + + from google.cloud.spanner_v1 import TransactionOptions @@ -89,6 +93,45 @@ def test_base_object_merge_dict(self): self.assertEqual(result, expected) +class Test_get_cloud_region(unittest.TestCase): + def _callFUT(self, *args, **kw): + from google.cloud.spanner_v1._helpers import _get_cloud_region + + return _get_cloud_region(*args, **kw) + + @mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect") + def test_get_location_with_region(self, mock_detect): + """Test that _get_cloud_region returns the region when detected.""" + mock_resource = Resource.create( + {ResourceAttributes.CLOUD_REGION: "us-central1"} + ) + mock_detect.return_value = mock_resource + + location = self._callFUT() + self.assertEqual(location, "us-central1") + + @mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect") + def test_get_location_without_region(self, mock_detect): + """Test that _get_cloud_region returns 'global' when no region is detected.""" + mock_resource = Resource.create({}) # No region attribute + mock_detect.return_value = mock_resource + + location = self._callFUT() + self.assertEqual(location, "global") + + @mock.patch("google.cloud.spanner_v1._helpers.GoogleCloudResourceDetector.detect") + def test_get_location_with_exception(self, mock_detect): + """Test that _get_cloud_region returns 'global' and logs a warning on exception.""" + mock_detect.side_effect = Exception("detector failed") + + with self.assertLogs( + "google.cloud.spanner_v1._helpers", level="WARNING" + ) as log: + location = self._callFUT() + self.assertEqual(location, "global") + self.assertIn("Failed to detect GCP resource location", log.output[0]) + + class Test_make_value_pb(unittest.TestCase): def _callFUT(self, *args, **kw): from google.cloud.spanner_v1._helpers import _make_value_pb diff --git a/tests/unit/test__opentelemetry_tracing.py b/tests/unit/test__opentelemetry_tracing.py index b3d49355c0..efeb4882bd 100644 --- a/tests/unit/test__opentelemetry_tracing.py +++ b/tests/unit/test__opentelemetry_tracing.py @@ -65,6 +65,7 @@ def test_trace_call(self): "db.type": "spanner", "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", + "cloud.region": "global", "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", @@ -95,6 +96,7 @@ def test_trace_error(self): "db.type": "spanner", "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", + "cloud.region": "global", "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", diff --git a/tests/unit/test_batch.py b/tests/unit/test_batch.py index 1582fcf4a9..a734c9e849 100644 --- a/tests/unit/test_batch.py +++ b/tests/unit/test_batch.py @@ -57,6 +57,7 @@ "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } enrich_with_otel_scope(BASE_ATTRIBUTES) diff --git a/tests/unit/test_pool.py b/tests/unit/test_pool.py index 409f4b043b..a616762646 100644 --- a/tests/unit/test_pool.py +++ b/tests/unit/test_pool.py @@ -155,6 +155,7 @@ class TestFixedSizePool(OpenTelemetryBase): "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } enrich_with_otel_scope(BASE_ATTRIBUTES) @@ -496,6 +497,7 @@ class TestBurstyPool(OpenTelemetryBase): "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } enrich_with_otel_scope(BASE_ATTRIBUTES) @@ -737,6 +739,7 @@ class TestPingingPool(OpenTelemetryBase): "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } enrich_with_otel_scope(BASE_ATTRIBUTES) diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index 3b08cc5c65..b03b6f0b22 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -130,6 +130,7 @@ class TestSession(OpenTelemetryBase): "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } enrich_with_otel_scope(BASE_ATTRIBUTES) diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 5e60d71bd6..0ae15ad753 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -76,6 +76,7 @@ "db.url": "spanner.googleapis.com", "db.instance": "testing", "net.host.name": "spanner.googleapis.com", + "cloud.region": "global", "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", @@ -618,23 +619,23 @@ def test_iteration_w_multiple_span_creation(self): class Test_SnapshotBase(OpenTelemetryBase): - def test_ctor(self): - session = build_session() - derived = _build_snapshot_derived(session=session) - - # Attributes from _SessionWrapper. - self.assertIs(derived._session, session) - - # Attributes from _SnapshotBase. - self.assertTrue(derived._read_only) - self.assertFalse(derived._multi_use) - self.assertEqual(derived._execute_sql_request_count, 0) - self.assertEqual(derived._read_request_count, 0) - self.assertIsNone(derived._transaction_id) - self.assertIsNone(derived._precommit_token) - self.assertIsInstance(derived._lock, type(Lock())) - - self.assertNoSpans() + # def test_ctor(self): + # session = build_session() + # derived = _build_snapshot_derived(session=session) + # + # # Attributes from _SessionWrapper. + # self.assertIs(derived._session, session) + # + # # Attributes from _SnapshotBase. + # self.assertTrue(derived._read_only) + # self.assertFalse(derived._multi_use) + # self.assertEqual(derived._execute_sql_request_count, 0) + # self.assertEqual(derived._read_request_count, 0) + # self.assertIsNone(derived._transaction_id) + # self.assertIsNone(derived._precommit_token) + # self.assertIsInstance(derived._lock, type(Lock())) + # + # self.assertNoSpans() def test__build_transaction_selector_pb_single_use(self): derived = _build_snapshot_derived(multi_use=False) @@ -966,8 +967,9 @@ def _execute_read( expected_limit = LIMIT # Transaction tag is ignored for read request. - expected_request_options = request_options - expected_request_options.transaction_tag = None + expected_request_options = RequestOptions(request_options) + if derived.transaction_tag: + expected_request_options.transaction_tag = derived.transaction_tag expected_directed_read_options = ( directed_read_options @@ -1000,15 +1002,16 @@ def _execute_read( retry=retry, timeout=timeout, ) - + expected_attributes = dict( + BASE_ATTRIBUTES, + table_id=TABLE_NAME, + columns=tuple(COLUMNS), + x_goog_spanner_request_id=req_id, + ) + if request_options and request_options.request_tag: + expected_attributes["spanner.request_tag"] = request_options.request_tag self.assertSpanAttributes( - "CloudSpanner._Derived.read", - attributes=dict( - BASE_ATTRIBUTES, - table_id=TABLE_NAME, - columns=tuple(COLUMNS), - x_goog_spanner_request_id=req_id, - ), + "CloudSpanner._Derived.read", attributes=expected_attributes ) if first: @@ -1021,22 +1024,15 @@ def test_read_wo_multi_use(self): self._execute_read(multi_use=False) def test_read_w_request_tag_success(self): - request_options = RequestOptions( - request_tag="tag-1", - ) + request_options = {"request_tag": "tag-1"} self._execute_read(multi_use=False, request_options=request_options) def test_read_w_transaction_tag_success(self): - request_options = RequestOptions( - transaction_tag="tag-1-1", - ) + request_options = {"transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) def test_read_w_request_and_transaction_tag_success(self): - request_options = RequestOptions( - request_tag="tag-1", - transaction_tag="tag-1-1", - ) + request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) def test_read_w_request_and_transaction_tag_dictionary_success(self): @@ -1243,10 +1239,11 @@ def _execute_sql_helper( expected_query_options, query_options ) - if derived._read_only: - # Transaction tag is ignored for read only requests. - expected_request_options = request_options - expected_request_options.transaction_tag = None + expected_request_options = RequestOptions(request_options) + if derived.transaction_tag: + expected_request_options.transaction_tag = derived.transaction_tag + if not derived._read_only and request_options.request_tag: + expected_request_options.request_tag = request_options.request_tag expected_directed_read_options = ( directed_read_options @@ -1283,16 +1280,17 @@ def _execute_sql_helper( self.assertEqual(derived._execute_sql_request_count, sql_count + 1) + expected_attributes = dict( + BASE_ATTRIBUTES, + **{"db.statement": SQL_QUERY_WITH_PARAM, "x_goog_spanner_request_id": req_id}, + ) + if request_options and request_options.request_tag: + expected_attributes["spanner.request_tag"] = request_options.request_tag + self.assertSpanAttributes( "CloudSpanner._Derived.execute_sql", status=StatusCode.OK, - attributes=dict( - BASE_ATTRIBUTES, - **{ - "db.statement": SQL_QUERY_WITH_PARAM, - "x_goog_spanner_request_id": req_id, - }, - ), + attributes=expected_attributes, ) if first: @@ -1344,22 +1342,15 @@ def test_execute_sql_w_request_options(self): ) def test_execute_sql_w_request_tag_success(self): - request_options = RequestOptions( - request_tag="tag-1", - ) + request_options = {"request_tag": "tag-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) def test_execute_sql_w_transaction_tag_success(self): - request_options = RequestOptions( - transaction_tag="tag-1-1", - ) + request_options = {"transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) def test_execute_sql_w_request_and_transaction_tag_success(self): - request_options = RequestOptions( - request_tag="tag-1", - transaction_tag="tag-1-1", - ) + request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) def test_execute_sql_w_request_and_transaction_tag_dictionary_success(self): @@ -1984,21 +1975,24 @@ def _build_snapshot_derived(session=None, multi_use=False, read_only=True) -> _D return derived -def _build_span_attributes(database: Database, attempt: int = 1) -> Mapping[str, str]: +def _build_span_attributes( + database: Database, attempt: int = 1, **extra_attributes +) -> Mapping[str, str]: """Builds the attributes for spans using the given database and extra attributes.""" - return enrich_with_otel_scope( - { - "db.type": "spanner", - "db.url": "spanner.googleapis.com", - "db.instance": database.name, - "net.host.name": "spanner.googleapis.com", - "gcp.client.service": "spanner", - "gcp.client.version": LIB_VERSION, - "gcp.client.repo": "googleapis/python-spanner", - "x_goog_spanner_request_id": _build_request_id(database, attempt), - } - ) + attributes = { + "db.type": "spanner", + "db.url": "spanner.googleapis.com", + "db.instance": database.name, + "net.host.name": "spanner.googleapis.com", + "cloud.region": "global", + "gcp.client.service": "spanner", + "gcp.client.version": LIB_VERSION, + "gcp.client.repo": "googleapis/python-spanner", + "x_goog_spanner_request_id": _build_request_id(database, attempt), + } + attributes.update(extra_attributes) + return enrich_with_otel_scope(attributes) def _build_request_id(database: Database, attempt: int) -> str: diff --git a/tests/unit/test_spanner_metrics_tracer_factory.py b/tests/unit/test_spanner_metrics_tracer_factory.py index 48fe1b4837..47ebdb9b0c 100644 --- a/tests/unit/test_spanner_metrics_tracer_factory.py +++ b/tests/unit/test_spanner_metrics_tracer_factory.py @@ -16,8 +16,6 @@ import pytest import unittest from unittest import mock - -from google.cloud.spanner_v1.metrics.constants import GOOGLE_CLOUD_REGION_KEY from google.cloud.spanner_v1.metrics.spanner_metrics_tracer_factory import ( SpannerMetricsTracerFactory, ) @@ -50,48 +48,3 @@ def test_get_instance_config(self): def test_get_client_name(self): client_name = SpannerMetricsTracerFactory._get_client_name() assert isinstance(client_name, str) - assert "spanner-python" in client_name - - def test_get_location(self): - location = SpannerMetricsTracerFactory._get_location() - assert isinstance(location, str) - assert location # Simply asserting for non empty as this can change depending on the instance this test runs in. - - -class TestSpannerMetricsTracerFactoryGetLocation(unittest.TestCase): - @mock.patch( - "opentelemetry.resourcedetector.gcp_resource_detector.GoogleCloudResourceDetector.detect" - ) - def test_get_location_with_region(self, mock_detect): - """Test that _get_location returns the region when detected.""" - mock_resource = Resource.create({GOOGLE_CLOUD_REGION_KEY: "us-central1"}) - mock_detect.return_value = mock_resource - - location = SpannerMetricsTracerFactory._get_location() - assert location == "us-central1" - - @mock.patch( - "opentelemetry.resourcedetector.gcp_resource_detector.GoogleCloudResourceDetector.detect" - ) - def test_get_location_without_region(self, mock_detect): - """Test that _get_location returns 'global' when no region is detected.""" - mock_resource = Resource.create({}) # No region attribute - mock_detect.return_value = mock_resource - - location = SpannerMetricsTracerFactory._get_location() - assert location == "global" - - @mock.patch( - "opentelemetry.resourcedetector.gcp_resource_detector.GoogleCloudResourceDetector.detect" - ) - def test_get_location_with_exception(self, mock_detect): - """Test that _get_location returns 'global' and logs a warning on exception.""" - mock_detect.side_effect = Exception("detector failed") - - with self.assertLogs( - "google.cloud.spanner_v1.metrics.spanner_metrics_tracer_factory", - level="WARNING", - ) as log: - location = SpannerMetricsTracerFactory._get_location() - assert location == "global" - self.assertIn("Failed to detect GCP resource location", log.output[0]) diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 7a33372dae..8ed5d92a0c 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -752,8 +752,9 @@ def _execute_update_helper( expected_query_options = _merge_query_options( expected_query_options, query_options ) - expected_request_options = request_options - expected_request_options.transaction_tag = TRANSACTION_TAG + expected_request_options = RequestOptions(request_options) + if request_options.request_tag: + expected_request_options.request_tag = request_options.request_tag expected_request = ExecuteSqlRequest( session=self.SESSION_NAME, @@ -763,7 +764,7 @@ def _execute_update_helper( param_types=PARAM_TYPES, query_mode=MODE, query_options=expected_query_options, - request_options=request_options, + request_options=expected_request_options, seqno=count, ) api.execute_sql.assert_called_once_with( @@ -780,11 +781,13 @@ def _execute_update_helper( ], ) + expected_attributes = self._build_span_attributes( + database, **{"db.statement": DML_QUERY_WITH_PARAM} + ) + if request_options.request_tag: + expected_attributes["spanner.request_tag"] = request_options.request_tag self.assertSpanAttributes( - "CloudSpanner.Transaction.execute_update", - attributes=self._build_span_attributes( - database, **{"db.statement": DML_QUERY_WITH_PARAM} - ), + "CloudSpanner.Transaction.execute_update", attributes=expected_attributes ) self.assertEqual(transaction._transaction_id, TRANSACTION_ID) @@ -1163,7 +1166,7 @@ def test_context_mgr_failure(self): def _build_span_attributes( database: Database, **extra_attributes ) -> Mapping[str, str]: - """Builds the attributes for spans using the given database and extra attributes.""" + """Builds the attributes for spans using the given database and attempt number.""" attributes = enrich_with_otel_scope( { @@ -1174,6 +1177,7 @@ def _build_span_attributes( "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", + "cloud.region": "global", } ) From af658495d0880fdbfb671d9a9ab94b753e764834 Mon Sep 17 00:00:00 2001 From: Subham Sinha Date: Mon, 27 Oct 2025 11:25:35 +0530 Subject: [PATCH 2/6] feat(opentelemetry): add request_tag to span attributes --- examples/trace.py | 30 ++++---------- .../spanner_v1/_opentelemetry_tracing.py | 5 +++ google/cloud/spanner_v1/snapshot.py | 8 +++- tests/unit/test_snapshot.py | 41 +++++++++++-------- .../test_spanner_metrics_tracer_factory.py | 3 -- 5 files changed, 43 insertions(+), 44 deletions(-) diff --git a/examples/trace.py b/examples/trace.py index 58db7a1fe7..5b826ca5ad 100644 --- a/examples/trace.py +++ b/examples/trace.py @@ -27,7 +27,7 @@ from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator # Setup common variables that'll be used between Spanner and traces. -project_id = os.environ.get('SPANNER_PROJECT_ID', 'span-cloud-testing') +project_id = os.environ.get('SPANNER_PROJECT_ID', 'test-project') def spanner_with_cloud_trace(): # [START spanner_opentelemetry_traces_cloudtrace_usage] @@ -62,13 +62,16 @@ def spanner_with_otlp(): def main(): + # Setup OpenTelemetry, trace and Cloud Trace exporter. + tracer_provider = TracerProvider(sampler=ALWAYS_ON) + trace_exporter = CloudTraceSpanExporter(project_id=project_id) + tracer_provider.add_span_processor(BatchSpanProcessor(trace_exporter)) + # Setup the Cloud Spanner Client. # Change to "spanner_client = spanner_with_otlp" to use OTLP exporter spanner_client = spanner_with_cloud_trace() - instance = spanner_client.instance('suvham-testing') - instance.reload() - database = instance.database('gildb') - tracer_provider = spanner_client.observability_options["tracer_provider"] + instance = spanner_client.instance('test-instance') + database = instance.database('test-db') # Set W3C Trace Context as the global propagator for end to end tracing. set_global_textmap(TraceContextTextMapPropagator()) @@ -90,27 +93,12 @@ def main(): # Purposefully issue a bad SQL statement to examine exceptions # that get recorded and a ERROR span status. try: - data = snapshot.execute_sql('SELECT CURRENT_TIMESTAMP()') + data = snapshot.execute_sql('SELECT CURRENT_TIMESTAMPx()') for row in data: print(row) except Exception as e: print(e) - # Example of a read-write transaction with a transaction tag - with tracer.start_as_current_span('TaggedTransaction'): - def update_singer_name(transaction): - transaction.execute_update( - "UPDATE Singers SET FirstName = 'Timothy' WHERE SingerId = 1", - request_options={ - "request_tag": "app=concert,env=dev,action=update" - }, - ) - print("Updated singer's name.") - - database.run_in_transaction( - update_singer_name, transaction_tag="app=concert,env=dev" - ) - if __name__ == '__main__': main() diff --git a/google/cloud/spanner_v1/_opentelemetry_tracing.py b/google/cloud/spanner_v1/_opentelemetry_tracing.py index 7cefa7e736..4a4f45552e 100644 --- a/google/cloud/spanner_v1/_opentelemetry_tracing.py +++ b/google/cloud/spanner_v1/_opentelemetry_tracing.py @@ -122,6 +122,11 @@ def trace_call( if extra_attributes: attributes.update(extra_attributes) + if "request_options" in attributes: + request_options = attributes.pop("request_options") + if request_options and request_options.request_tag: + attributes["spanner.request_tag"] = request_options.request_tag + if extended_tracing_globally_disabled: enable_extended_tracing = False diff --git a/google/cloud/spanner_v1/snapshot.py b/google/cloud/spanner_v1/snapshot.py index 5633cd4486..46b0f5af8d 100644 --- a/google/cloud/spanner_v1/snapshot.py +++ b/google/cloud/spanner_v1/snapshot.py @@ -409,7 +409,11 @@ def read( method=streaming_read_method, request=read_request, metadata=metadata, - trace_attributes={"table_id": table, "columns": columns}, + trace_attributes={ + "table_id": table, + "columns": columns, + "request_options": request_options, + }, column_info=column_info, lazy_decode=lazy_decode, ) @@ -601,7 +605,7 @@ def execute_sql( method=execute_streaming_sql_method, request=execute_sql_request, metadata=metadata, - trace_attributes={"db.statement": sql}, + trace_attributes={"db.statement": sql, "request_options": request_options}, column_info=column_info, lazy_decode=lazy_decode, ) diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 0ae15ad753..da0f08ca36 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -116,6 +116,8 @@ class _Derived(_SnapshotBase): """A minimally-implemented _SnapshotBase-derived class for testing""" + transaction_tag = None + # Use a simplified implementation of _build_transaction_options_pb # that always returns the same transaction options. TRANSACTION_OPTIONS = TransactionOptions() @@ -619,23 +621,23 @@ def test_iteration_w_multiple_span_creation(self): class Test_SnapshotBase(OpenTelemetryBase): - # def test_ctor(self): - # session = build_session() - # derived = _build_snapshot_derived(session=session) - # - # # Attributes from _SessionWrapper. - # self.assertIs(derived._session, session) - # - # # Attributes from _SnapshotBase. - # self.assertTrue(derived._read_only) - # self.assertFalse(derived._multi_use) - # self.assertEqual(derived._execute_sql_request_count, 0) - # self.assertEqual(derived._read_request_count, 0) - # self.assertIsNone(derived._transaction_id) - # self.assertIsNone(derived._precommit_token) - # self.assertIsInstance(derived._lock, type(Lock())) - # - # self.assertNoSpans() + def test_ctor(self): + session = build_session() + derived = _build_snapshot_derived(session=session) + + # Attributes from _SessionWrapper. + self.assertIs(derived._session, session) + + # Attributes from _SnapshotBase. + self.assertTrue(derived._read_only) + self.assertFalse(derived._multi_use) + self.assertEqual(derived._execute_sql_request_count, 0) + self.assertEqual(derived._read_request_count, 0) + self.assertIsNone(derived._transaction_id) + self.assertIsNone(derived._precommit_token) + self.assertIsInstance(derived._lock, type(Lock())) + + self.assertNoSpans() def test__build_transaction_selector_pb_single_use(self): derived = _build_snapshot_derived(multi_use=False) @@ -1282,7 +1284,10 @@ def _execute_sql_helper( expected_attributes = dict( BASE_ATTRIBUTES, - **{"db.statement": SQL_QUERY_WITH_PARAM, "x_goog_spanner_request_id": req_id}, + **{ + "db.statement": SQL_QUERY_WITH_PARAM, + "x_goog_spanner_request_id": req_id, + }, ) if request_options and request_options.request_tag: expected_attributes["spanner.request_tag"] = request_options.request_tag diff --git a/tests/unit/test_spanner_metrics_tracer_factory.py b/tests/unit/test_spanner_metrics_tracer_factory.py index 47ebdb9b0c..8ae7bfc694 100644 --- a/tests/unit/test_spanner_metrics_tracer_factory.py +++ b/tests/unit/test_spanner_metrics_tracer_factory.py @@ -14,12 +14,9 @@ # limitations under the License. import pytest -import unittest -from unittest import mock from google.cloud.spanner_v1.metrics.spanner_metrics_tracer_factory import ( SpannerMetricsTracerFactory, ) -from opentelemetry.sdk.resources import Resource pytest.importorskip("opentelemetry") From db90a4712409f3293fddfd0122c1ad8b3452f45e Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 27 Oct 2025 06:54:41 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- tests/unit/test_snapshot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index da0f08ca36..5c42627ef2 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -624,10 +624,10 @@ class Test_SnapshotBase(OpenTelemetryBase): def test_ctor(self): session = build_session() derived = _build_snapshot_derived(session=session) - + # Attributes from _SessionWrapper. self.assertIs(derived._session, session) - + # Attributes from _SnapshotBase. self.assertTrue(derived._read_only) self.assertFalse(derived._multi_use) @@ -636,7 +636,7 @@ def test_ctor(self): self.assertIsNone(derived._transaction_id) self.assertIsNone(derived._precommit_token) self.assertIsInstance(derived._lock, type(Lock())) - + self.assertNoSpans() def test__build_transaction_selector_pb_single_use(self): From 1bd0a2c7495cd7feb183678b7a1db2b743a7d9b8 Mon Sep 17 00:00:00 2001 From: Subham Sinha Date: Mon, 27 Oct 2025 11:25:35 +0530 Subject: [PATCH 4/6] feat(opentelemetry): add request_tag to span attributes --- google/cloud/spanner_v1/_helpers.py | 8 +- tests/system/test_session_api.py | 1 + tests/unit/test__opentelemetry_tracing.py | 11 +- tests/unit/test_batch.py | 70 ++++++--- tests/unit/test_pool.py | 123 ++++++++++----- tests/unit/test_session.py | 51 ++++-- tests/unit/test_snapshot.py | 180 +++++++++++++++------- tests/unit/test_transaction.py | 129 +++++++++++----- 8 files changed, 385 insertions(+), 188 deletions(-) diff --git a/google/cloud/spanner_v1/_helpers.py b/google/cloud/spanner_v1/_helpers.py index 0d2f476a92..9f5d72fe51 100644 --- a/google/cloud/spanner_v1/_helpers.py +++ b/google/cloud/spanner_v1/_helpers.py @@ -35,16 +35,16 @@ from google.cloud.spanner_v1.data_types import JsonObject, Interval from google.cloud.spanner_v1.request_id_header import with_request_id from google.cloud.spanner_v1.types import TypeCode -from opentelemetry.semconv.resource import ResourceAttributes -from opentelemetry.resourcedetector.gcp_resource_detector import ( - GoogleCloudResourceDetector, -) from google.rpc.error_details_pb2 import RetryInfo try: from opentelemetry.propagate import inject from opentelemetry.propagators.textmap import Setter + from opentelemetry.semconv.resource import ResourceAttributes + from opentelemetry.resourcedetector.gcp_resource_detector import ( + GoogleCloudResourceDetector, + ) HAS_OPENTELEMETRY_INSTALLED = True except ImportError: diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 04d8ad799a..12f2625fd2 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -354,6 +354,7 @@ def _make_attributes(db_instance, **kwargs): "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", "db.instance": db_instance, + "cloud.region": "global", "gcp.client.service": "spanner", "gcp.client.version": ot_helpers.LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", diff --git a/tests/unit/test__opentelemetry_tracing.py b/tests/unit/test__opentelemetry_tracing.py index efeb4882bd..9d8f0baaef 100644 --- a/tests/unit/test__opentelemetry_tracing.py +++ b/tests/unit/test__opentelemetry_tracing.py @@ -10,6 +10,7 @@ pass from google.api_core.exceptions import GoogleAPICallError +from google.cloud.spanner_v1._helpers import GOOGLE_CLOUD_REGION_GLOBAL from google.cloud.spanner_v1 import _opentelemetry_tracing from tests._helpers import ( @@ -53,7 +54,8 @@ def test_no_trace_call(self): self.assertIsNone(no_span) class TestTracing(OpenTelemetryBase): - def test_trace_call(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_trace_call(self, mock_region): extra_attributes = { "attribute1": "value1", # Since our database is mocked, we have to override the db.instance parameter so it is a string @@ -65,7 +67,7 @@ def test_trace_call(self): "db.type": "spanner", "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", - "cloud.region": "global", + "cloud.region": GOOGLE_CLOUD_REGION_GLOBAL, "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", @@ -88,7 +90,8 @@ def test_trace_call(self): self.assertEqual(span.name, "CloudSpanner.Test") self.assertEqual(span.status.status_code, StatusCode.OK) - def test_trace_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_trace_error(self, mock_region): extra_attributes = {"db.instance": "database_name"} expected_attributes = enrich_with_otel_scope( @@ -96,7 +99,7 @@ def test_trace_error(self): "db.type": "spanner", "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", - "cloud.region": "global", + "cloud.region": GOOGLE_CLOUD_REGION_GLOBAL, "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", diff --git a/tests/unit/test_batch.py b/tests/unit/test_batch.py index a734c9e849..bed3ccf984 100644 --- a/tests/unit/test_batch.py +++ b/tests/unit/test_batch.py @@ -30,6 +30,7 @@ BatchWriteResponse, DefaultTransactionOptions, ) +import mock from google.cloud._helpers import UTC, _datetime_to_pb_timestamp import datetime from google.api_core.exceptions import Aborted, Unknown @@ -199,7 +200,8 @@ def test_commit_already_committed(self): self.assertNoSpans() - def test_commit_grpc_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_grpc_error(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) database = _Database() @@ -220,7 +222,8 @@ def test_commit_grpc_error(self): ), ) - def test_commit_ok(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_ok(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) response = CommitResponse(commit_timestamp=now_pb) @@ -377,35 +380,41 @@ def _test_commit_with_options( self.assertEqual(max_commit_delay_in, max_commit_delay) - def test_commit_w_request_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._test_commit_with_options(request_options=request_options) - def test_commit_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._test_commit_with_options(request_options=request_options) - def test_commit_w_request_and_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", transaction_tag="tag-1-1", ) self._test_commit_with_options(request_options=request_options) - def test_commit_w_request_and_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_request_and_transaction_tag_dictionary_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._test_commit_with_options(request_options=request_options) - def test_commit_w_incorrect_tag_dictionary_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._test_commit_with_options(request_options=request_options) - def test_commit_w_max_commit_delay(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_max_commit_delay(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) @@ -414,7 +423,8 @@ def test_commit_w_max_commit_delay(self): max_commit_delay_in=datetime.timedelta(milliseconds=100), ) - def test_commit_w_exclude_txn_from_change_streams(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_exclude_txn_from_change_streams(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) @@ -422,7 +432,8 @@ def test_commit_w_exclude_txn_from_change_streams(self): request_options=request_options, exclude_txn_from_change_streams=True ) - def test_commit_w_isolation_level(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_isolation_level(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) @@ -431,7 +442,8 @@ def test_commit_w_isolation_level(self): isolation_level=TransactionOptions.IsolationLevel.REPEATABLE_READ, ) - def test_commit_w_read_lock_mode(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_read_lock_mode(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) @@ -440,7 +452,8 @@ def test_commit_w_read_lock_mode(self): read_lock_mode=TransactionOptions.ReadWrite.ReadLockMode.OPTIMISTIC, ) - def test_commit_w_isolation_level_and_read_lock_mode(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_isolation_level_and_read_lock_mode(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) @@ -450,7 +463,8 @@ def test_commit_w_isolation_level_and_read_lock_mode(self): read_lock_mode=TransactionOptions.ReadWrite.ReadLockMode.PESSIMISTIC, ) - def test_context_mgr_already_committed(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_context_mgr_already_committed(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) database = _Database() api = database.spanner_api = _FauxSpannerAPI() @@ -464,7 +478,8 @@ def test_context_mgr_already_committed(self): self.assertEqual(api._committed, None) - def test_context_mgr_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_context_mgr_success(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) response = CommitResponse(commit_timestamp=now_pb) @@ -511,7 +526,8 @@ def test_context_mgr_success(self): ), ) - def test_context_mgr_failure(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_context_mgr_failure(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) response = CommitResponse(commit_timestamp=now_pb) @@ -542,7 +558,8 @@ def test_ctor(self): groups = self._make_one(session) self.assertIs(groups._session, session) - def test_batch_write_already_committed(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_already_committed(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) database = _Database() @@ -565,7 +582,8 @@ def test_batch_write_already_committed(self): with self.assertRaises(ValueError): groups.batch_write() - def test_batch_write_grpc_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_grpc_error(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) database = _Database() @@ -663,25 +681,31 @@ def _test_batch_write_with_request_options( ), ) - def test_batch_write_no_request_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_no_request_options(self, mock_region): self._test_batch_write_with_request_options() - def test_batch_write_end_to_end_tracing_enabled(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_end_to_end_tracing_enabled(self, mock_region): self._test_batch_write_with_request_options(enable_end_to_end_tracing=True) - def test_batch_write_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_w_transaction_tag_success(self, mock_region): self._test_batch_write_with_request_options( RequestOptions(transaction_tag="tag-1-1") ) - def test_batch_write_w_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_w_transaction_tag_dictionary_success(self, mock_region): self._test_batch_write_with_request_options({"transaction_tag": "tag-1-1"}) - def test_batch_write_w_incorrect_tag_dictionary_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_w_incorrect_tag_dictionary_error(self, mock_region): with self.assertRaises(ValueError): self._test_batch_write_with_request_options({"incorrect_tag": "tag-1-1"}) - def test_batch_write_w_exclude_txn_from_change_streams(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_write_w_exclude_txn_from_change_streams(self, mock_region): self._test_batch_write_with_request_options( exclude_txn_from_change_streams=True ) diff --git a/tests/unit/test_pool.py b/tests/unit/test_pool.py index a616762646..fd0e82aa9b 100644 --- a/tests/unit/test_pool.py +++ b/tests/unit/test_pool.py @@ -176,7 +176,8 @@ def test_ctor_defaults(self): self.assertEqual(pool.labels, {}) self.assertIsNone(pool.database_role) - def test_ctor_explicit(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ctor_explicit(self, mock_region): labels = {"foo": "bar"} database_role = "dummy-role" pool = self._make_one( @@ -189,7 +190,8 @@ def test_ctor_explicit(self): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - def test_bind(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_bind(self, mock_region): database_role = "dummy-role" pool = self._make_one() database = _Database("name") @@ -210,7 +212,8 @@ def test_bind(self): for session in SESSIONS: session.create.assert_not_called() - def test_get_active(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_active(self, mock_region): pool = self._make_one(size=4) database = _Database("name") SESSIONS = sorted([_Session(database) for i in range(0, 4)]) @@ -224,7 +227,8 @@ def test_get_active(self): self.assertFalse(session._exists_checked) self.assertFalse(pool._sessions.full()) - def test_get_non_expired(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_non_expired(self, mock_region): pool = self._make_one(size=4) database = _Database("name") last_use_time = datetime.utcnow() - timedelta(minutes=56) @@ -241,7 +245,8 @@ def test_get_non_expired(self): self.assertTrue(session._exists_checked) self.assertFalse(pool._sessions.full()) - def test_spans_bind_get(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_bind_get(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -286,7 +291,8 @@ def test_spans_bind_get(self): ] self.assertSpanEvents("pool.Get", wantEventNames, span_list[-1]) - def test_spans_bind_get_empty_pool(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_bind_get_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -330,7 +336,8 @@ def test_spans_bind_get_empty_pool(self): ] assert got_all_events == want_all_events - def test_spans_pool_bind(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_pool_bind(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -404,7 +411,8 @@ def test_spans_pool_bind(self): ] assert got_all_events == want_all_events - def test_get_expired(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_expired(self, mock_region): pool = self._make_one(size=4) database = _Database("name") last_use_time = datetime.utcnow() - timedelta(minutes=65) @@ -420,7 +428,8 @@ def test_get_expired(self): self.assertTrue(SESSIONS[0]._exists_checked) self.assertFalse(pool._sessions.full()) - def test_get_empty_default_timeout(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_empty_default_timeout(self, mock_region): import queue pool = self._make_one(size=1) @@ -431,7 +440,8 @@ def test_get_empty_default_timeout(self): self.assertEqual(session_queue._got, {"block": True, "timeout": 10}) - def test_get_empty_explicit_timeout(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_empty_explicit_timeout(self, mock_region): import queue pool = self._make_one(size=1, default_timeout=0.1) @@ -442,7 +452,8 @@ def test_get_empty_explicit_timeout(self): self.assertEqual(session_queue._got, {"block": True, "timeout": 1}) - def test_put_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_full(self, mock_region): import queue pool = self._make_one(size=4) @@ -457,7 +468,8 @@ def test_put_full(self): self.assertTrue(pool._sessions.full()) - def test_put_non_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_non_full(self, mock_region): pool = self._make_one(size=4) database = _Database("name") SESSIONS = [_Session(database)] * 4 @@ -469,7 +481,8 @@ def test_put_non_full(self): self.assertTrue(pool._sessions.full()) - def test_clear(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") SESSIONS = [_Session(database)] * 10 @@ -527,7 +540,8 @@ def test_ctor_explicit(self): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - def test_ctor_explicit_w_database_role_in_db(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ctor_explicit_w_database_role_in_db(self, mock_region): database_role = "dummy-role" pool = self._make_one() database = pool._database = _Database("name") @@ -535,7 +549,8 @@ def test_ctor_explicit_w_database_role_in_db(self): pool.bind(database) self.assertEqual(pool.database_role, database_role) - def test_get_empty(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_empty(self, mock_region): pool = self._make_one() database = _Database("name") pool._new_session = mock.Mock(return_value=_Session(database)) @@ -548,7 +563,8 @@ def test_get_empty(self): session.create.assert_called() self.assertTrue(pool._sessions.empty()) - def test_spans_get_empty_pool(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_get_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -586,7 +602,8 @@ def test_spans_get_empty_pool(self): ] self.assertSpanEvents("pool.Get", wantEventNames, span=create_span) - def test_get_non_empty_session_exists(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_non_empty_session_exists(self, mock_region): pool = self._make_one() database = _Database("name") previous = _Session(database) @@ -600,7 +617,8 @@ def test_get_non_empty_session_exists(self): self.assertTrue(session._exists_checked) self.assertTrue(pool._sessions.empty()) - def test_spans_get_non_empty_session_exists(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_get_non_empty_session_exists(self, mock_region): # Tests the spans produces when you invoke pool.bind # and then insert a session into the pool. pool = self._make_one() @@ -624,7 +642,8 @@ def test_spans_get_non_empty_session_exists(self): ["Acquiring session", "Waiting for a session to become available"], ) - def test_get_non_empty_session_expired(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_non_empty_session_expired(self, mock_region): pool = self._make_one() database = _Database("name") previous = _Session(database, exists=False) @@ -641,7 +660,8 @@ def test_get_non_empty_session_expired(self): self.assertFalse(session._exists_checked) self.assertTrue(pool._sessions.empty()) - def test_put_empty(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_empty(self, mock_region): pool = self._make_one() database = _Database("name") pool.bind(database) @@ -651,7 +671,8 @@ def test_put_empty(self): self.assertFalse(pool._sessions.empty()) - def test_spans_put_empty(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_put_empty(self, mock_region): # Tests the spans produced when you put sessions into an empty pool. pool = self._make_one() database = _Database("name") @@ -667,7 +688,8 @@ def test_spans_put_empty(self): attributes=TestBurstyPool.BASE_ATTRIBUTES, ) - def test_put_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_full(self, mock_region): pool = self._make_one(target_size=1) database = _Database("name") pool.bind(database) @@ -681,7 +703,8 @@ def test_put_full(self): self.assertTrue(younger._deleted) self.assertIs(pool.get(), older) - def test_spans_put_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_put_full(self, mock_region): # This scenario tests the spans produced from putting an older # session into a pool that is already full. pool = self._make_one(target_size=1) @@ -703,7 +726,8 @@ def test_spans_put_full(self): attributes=TestBurstyPool.BASE_ATTRIBUTES, ) - def test_put_full_expired(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_full_expired(self, mock_region): pool = self._make_one(target_size=1) database = _Database("name") pool.bind(database) @@ -717,7 +741,8 @@ def test_put_full_expired(self): self.assertTrue(younger._deleted) self.assertIs(pool.get(), older) - def test_clear(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") pool.bind(database) @@ -779,7 +804,8 @@ def test_ctor_explicit(self): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - def test_ctor_explicit_w_database_role_in_db(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ctor_explicit_w_database_role_in_db(self, mock_region): database_role = "dummy-role" pool = self._make_one() database = pool._database = _Database("name") @@ -789,7 +815,8 @@ def test_ctor_explicit_w_database_role_in_db(self): pool.bind(database) self.assertEqual(pool.database_role, database_role) - def test_bind(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_bind(self, mock_region): pool = self._make_one() database = _Database("name") SESSIONS = [_Session(database)] * 10 @@ -807,7 +834,8 @@ def test_bind(self): for session in SESSIONS: session.create.assert_not_called() - def test_get_hit_no_ping(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_hit_no_ping(self, mock_region): pool = self._make_one(size=4) database = _Database("name") SESSIONS = [_Session(database)] * 4 @@ -822,7 +850,8 @@ def test_get_hit_no_ping(self): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - def test_get_hit_w_ping(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_hit_w_ping(self, mock_region): import datetime from google.cloud._testing import _Monkey from google.cloud.spanner_v1 import pool as MUT @@ -846,7 +875,8 @@ def test_get_hit_w_ping(self): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - def test_get_hit_w_ping_expired(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_hit_w_ping_expired(self, mock_region): import datetime from google.cloud._testing import _Monkey from google.cloud.spanner_v1 import pool as MUT @@ -871,7 +901,8 @@ def test_get_hit_w_ping_expired(self): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - def test_get_empty_default_timeout(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_empty_default_timeout(self, mock_region): import queue pool = self._make_one(size=1) @@ -883,7 +914,8 @@ def test_get_empty_default_timeout(self): self.assertEqual(session_queue._got, {"block": True, "timeout": 10}) self.assertNoSpans() - def test_get_empty_explicit_timeout(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_get_empty_explicit_timeout(self, mock_region): import queue pool = self._make_one(size=1, default_timeout=0.1) @@ -895,7 +927,8 @@ def test_get_empty_explicit_timeout(self): self.assertEqual(session_queue._got, {"block": True, "timeout": 1}) self.assertNoSpans() - def test_put_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_full(self, mock_region): import queue pool = self._make_one(size=4) @@ -909,7 +942,8 @@ def test_put_full(self): self.assertTrue(pool._sessions.full()) - def test_spans_put_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_put_full(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -949,7 +983,8 @@ def test_spans_put_full(self): "CloudSpanner.PingingPool.BatchCreateSessions", wantEventNames ) - def test_put_non_full(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_put_non_full(self, mock_region): import datetime from google.cloud._testing import _Monkey from google.cloud.spanner_v1 import pool as MUT @@ -970,7 +1005,8 @@ def test_put_non_full(self): self.assertIs(queued, session) self.assertNoSpans() - def test_clear(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") SESSIONS = [_Session(database)] * 10 @@ -990,12 +1026,14 @@ def test_clear(self): self.assertTrue(session._deleted) self.assertNoSpans() - def test_ping_empty(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_empty(self, mock_region): pool = self._make_one(size=1) pool.ping() # Does not raise 'Empty' self.assertNoSpans() - def test_ping_oldest_fresh(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_oldest_fresh(self, mock_region): pool = self._make_one(size=1) database = _Database("name") SESSIONS = [_Session(database)] * 1 @@ -1008,7 +1046,8 @@ def test_ping_oldest_fresh(self): self.assertFalse(SESSIONS[0]._pinged) self.assertNoSpans() - def test_ping_oldest_stale_but_exists(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_oldest_stale_but_exists(self, mock_region): import datetime from google.cloud._testing import _Monkey from google.cloud.spanner_v1 import pool as MUT @@ -1025,7 +1064,8 @@ def test_ping_oldest_stale_but_exists(self): self.assertTrue(SESSIONS[0]._pinged) - def test_ping_oldest_stale_and_not_exists(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_oldest_stale_and_not_exists(self, mock_region): import datetime from google.cloud._testing import _Monkey from google.cloud.spanner_v1 import pool as MUT @@ -1046,7 +1086,8 @@ def test_ping_oldest_stale_and_not_exists(self): SESSIONS[1].create.assert_called() self.assertNoSpans() - def test_spans_get_and_leave_empty_pool(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_spans_get_and_leave_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index b03b6f0b22..b67cd5f6a3 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -223,7 +223,8 @@ def test_create_w_session_id(self): self.assertNoSpans() - def test_create_w_database_role(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_w_database_role(self, mock_region): session_pb = self._make_session_pb( self.SESSION_NAME, database_role=self.DATABASE_ROLE ) @@ -264,7 +265,8 @@ def test_create_w_database_role(self): ), ) - def test_create_session_span_annotations(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_session_span_annotations(self, mock_region): session_pb = self._make_session_pb( self.SESSION_NAME, database_role=self.DATABASE_ROLE ) @@ -302,7 +304,8 @@ def test_create_session_span_annotations(self): wantEventNames = ["Creating Session"] self.assertSpanEvents("TestSessionSpan", wantEventNames, span) - def test_create_wo_database_role(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_wo_database_role(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() gax_api.create_session.return_value = session_pb @@ -338,7 +341,8 @@ def test_create_wo_database_role(self): ), ) - def test_create_ok(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_ok(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() gax_api.create_session.return_value = session_pb @@ -374,7 +378,8 @@ def test_create_ok(self): ), ) - def test_create_w_labels(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_w_labels(self, mock_region): labels = {"foo": "bar"} session_pb = self._make_session_pb(self.SESSION_NAME, labels=labels) gax_api = self._make_spanner_api() @@ -412,7 +417,8 @@ def test_create_w_labels(self): ), ) - def test_create_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_create_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.create_session.side_effect = Unknown("error") database = self._make_database() @@ -438,7 +444,8 @@ def test_exists_wo_session_id(self): self.assertNoSpans() - def test_exists_hit(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_exists_hit(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() gax_api.get_session.return_value = session_pb @@ -475,7 +482,8 @@ def test_exists_hit(self): "google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED", False, ) - def test_exists_hit_wo_span(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_exists_hit_wo_span(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() gax_api.get_session.return_value = session_pb @@ -500,7 +508,8 @@ def test_exists_hit_wo_span(self): self.assertNoSpans() - def test_exists_miss(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_exists_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = NotFound("testing") database = self._make_database() @@ -536,7 +545,8 @@ def test_exists_miss(self): "google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED", False, ) - def test_exists_miss_wo_span(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_exists_miss_wo_span(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = NotFound("testing") database = self._make_database() @@ -560,7 +570,8 @@ def test_exists_miss_wo_span(self): self.assertNoSpans() - def test_exists_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_exists_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = Unknown("testing") database = self._make_database() @@ -598,7 +609,8 @@ def test_ping_wo_session_id(self): with self.assertRaises(ValueError): session.ping() - def test_ping_hit(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_hit(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.return_value = "1" database = self._make_database() @@ -624,7 +636,8 @@ def test_ping_hit(self): ], ) - def test_ping_miss(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.side_effect = NotFound("testing") database = self._make_database() @@ -651,7 +664,8 @@ def test_ping_miss(self): ], ) - def test_ping_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_ping_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.side_effect = Unknown("testing") database = self._make_database() @@ -687,7 +701,8 @@ def test_delete_wo_session_id(self): self.assertNoSpans() - def test_delete_hit(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_delete_hit(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.return_value = None database = self._make_database() @@ -716,7 +731,8 @@ def test_delete_hit(self): attributes=dict(attrs, x_goog_spanner_request_id=req_id), ) - def test_delete_miss(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_delete_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.side_effect = NotFound("testing") database = self._make_database() @@ -752,7 +768,8 @@ def test_delete_miss(self): attributes=attrs, ) - def test_delete_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_delete_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.side_effect = Unknown("testing") database = self._make_database() diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 5c42627ef2..9ab24f581b 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -27,6 +27,7 @@ TransactionOptions, TransactionSelector, ) +from google.cloud.spanner_v1._helpers import _get_cloud_region from google.cloud.spanner_v1.snapshot import _SnapshotBase from tests._builders import ( build_precommit_token_pb, @@ -559,7 +560,8 @@ def test_iteration_w_raw_raising_non_retryable_internal_error_after_token(self): ) self.assertNoSpans() - def test_iteration_w_span_creation(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_iteration_w_span_creation(self, mock_region): name = "TestSpan" extra_atts = {"test_att": 1} raw = _MockIterator() @@ -581,7 +583,8 @@ def test_iteration_w_span_creation(self): ), ) - def test_iteration_w_multiple_span_creation(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_iteration_w_multiple_span_creation(self, mock_region): from google.api_core.exceptions import ServiceUnavailable if HAS_OPENTELEMETRY_INSTALLED: @@ -683,7 +686,8 @@ def test_begin_error_already_begun(self): self.assertNoSpans() - def test_begin_error_other(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_error_other(self, mock_region): derived = _build_snapshot_derived(multi_use=True) database = derived._session._database @@ -702,7 +706,8 @@ def test_begin_error_other(self): attributes=_build_span_attributes(database), ) - def test_begin_read_write(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_read_write(self, mock_region): derived = _build_snapshot_derived(multi_use=True, read_only=False) begin_transaction = derived._session._database.spanner_api.begin_transaction @@ -710,7 +715,8 @@ def test_begin_read_write(self): self._execute_begin(derived) - def test_begin_read_only(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_read_only(self, mock_region): derived = _build_snapshot_derived(multi_use=True, read_only=True) begin_transaction = derived._session._database.spanner_api.begin_transaction @@ -718,7 +724,8 @@ def test_begin_read_only(self): self._execute_begin(derived) - def test_begin_precommit_token(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_precommit_token(self, mock_region): derived = _build_snapshot_derived(multi_use=True) begin_transaction = derived._session._database.spanner_api.begin_transaction @@ -728,7 +735,8 @@ def test_begin_precommit_token(self): self._execute_begin(derived) - def test_begin_retry_for_internal_server_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_retry_for_internal_server_error(self, mock_region): derived = _build_snapshot_derived(multi_use=True) begin_transaction = derived._session._database.spanner_api.begin_transaction @@ -748,7 +756,8 @@ def test_begin_retry_for_internal_server_error(self): actual_statuses = self.finished_spans_events_statuses() self.assertEqual(expected_statuses, actual_statuses) - def test_begin_retry_for_aborted(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_begin_retry_for_aborted(self, mock_region): derived = _build_snapshot_derived(multi_use=True) begin_transaction = derived._session._database.spanner_api.begin_transaction @@ -816,7 +825,8 @@ def _execute_begin(self, derived: _Derived, attempts: int = 1): attributes=_build_span_attributes(database, attempt=attempts), ) - def test_read_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_other_error(self, mock_region): from google.cloud.spanner_v1.keyset import KeySet keyset = KeySet(all_=True) @@ -1022,82 +1032,102 @@ def _execute_read( if use_multiplexed: self.assertEqual(derived._precommit_token, PRECOMMIT_TOKEN_2) - def test_read_wo_multi_use(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_wo_multi_use(self, mock_region): self._execute_read(multi_use=False) - def test_read_w_request_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_request_tag_success(self, mock_region): request_options = {"request_tag": "tag-1"} self._execute_read(multi_use=False, request_options=request_options) - def test_read_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_transaction_tag_success(self, mock_region): request_options = {"transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - def test_read_w_request_and_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_request_and_transaction_tag_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - def test_read_w_request_and_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_request_and_transaction_tag_dictionary_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - def test_read_w_incorrect_tag_dictionary_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._execute_read(multi_use=False, request_options=request_options) - def test_read_wo_multi_use_w_read_request_count_gt_0(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_wo_multi_use_w_read_request_count_gt_0(self, mock_region): with self.assertRaises(ValueError): self._execute_read(multi_use=False, count=1) - def test_read_w_multi_use_w_first(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_multi_use_w_first(self, mock_region): self._execute_read(multi_use=True, first=True) - def test_read_w_multi_use_wo_first(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_multi_use_wo_first(self, mock_region): self._execute_read(multi_use=True, first=False) - def test_read_w_multi_use_wo_first_w_count_gt_0(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_multi_use_wo_first_w_count_gt_0(self, mock_region): self._execute_read(multi_use=True, first=False, count=1) - def test_read_w_multi_use_w_first_w_partition(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_multi_use_w_first_w_partition(self, mock_region): PARTITION = b"FADEABED" self._execute_read(multi_use=True, first=True, partition=PARTITION) - def test_read_w_multi_use_w_first_w_count_gt_0(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_multi_use_w_first_w_count_gt_0(self, mock_region): with self.assertRaises(ValueError): self._execute_read(multi_use=True, first=True, count=1) - def test_read_w_timeout_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_timeout_param(self, mock_region): self._execute_read(multi_use=True, first=False, timeout=2.0) - def test_read_w_retry_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_retry_param(self, mock_region): self._execute_read(multi_use=True, first=False, retry=Retry(deadline=60)) - def test_read_w_timeout_and_retry_params(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_timeout_and_retry_params(self, mock_region): self._execute_read( multi_use=True, first=False, retry=Retry(deadline=60), timeout=2.0 ) - def test_read_w_directed_read_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_directed_read_options(self, mock_region): self._execute_read(multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS) - def test_read_w_directed_read_options_at_client_level(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_directed_read_options_at_client_level(self, mock_region): self._execute_read( multi_use=False, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - def test_read_w_directed_read_options_override(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_directed_read_options_override(self, mock_region): self._execute_read( multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - def test_read_w_precommit_tokens(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_read_w_precommit_tokens(self, mock_region): self._execute_read(multi_use=True, use_multiplexed=True) - def test_execute_sql_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_other_error(self, mock_region): database = _Database() database.spanner_api = build_spanner_api() database.spanner_api.execute_streaming_sql.side_effect = RuntimeError() @@ -1304,33 +1334,40 @@ def _execute_sql_helper( if use_multiplexed: self.assertEqual(derived._precommit_token, PRECOMMIT_TOKEN_2) - def test_execute_sql_wo_multi_use(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_wo_multi_use(self, mock_region): self._execute_sql_helper(multi_use=False) def test_execute_sql_wo_multi_use_w_read_request_count_gt_0(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=False, count=1) - def test_execute_sql_w_multi_use_wo_first(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_multi_use_wo_first(self, mock_region): self._execute_sql_helper(multi_use=True, first=False, sql_count=1) - def test_execute_sql_w_multi_use_wo_first_w_count_gt_0(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_multi_use_wo_first_w_count_gt_0(self, mock_region): self._execute_sql_helper(multi_use=True, first=False, count=1) - def test_execute_sql_w_multi_use_w_first(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_multi_use_w_first(self, mock_region): self._execute_sql_helper(multi_use=True, first=True) def test_execute_sql_w_multi_use_w_first_w_count_gt_0(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=True, first=True, count=1) - def test_execute_sql_w_retry(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_retry(self, mock_region): self._execute_sql_helper(multi_use=False, retry=None) - def test_execute_sql_w_timeout(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_timeout(self, mock_region): self._execute_sql_helper(multi_use=False, timeout=None) - def test_execute_sql_w_query_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_query_options(self, mock_region): from google.cloud.spanner_v1 import ExecuteSqlRequest self._execute_sql_helper( @@ -1338,7 +1375,8 @@ def test_execute_sql_w_query_options(self): query_options=ExecuteSqlRequest.QueryOptions(optimizer_version="3"), ) - def test_execute_sql_w_request_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_request_options(self, mock_region): self._execute_sql_helper( multi_use=False, request_options=RequestOptions( @@ -1346,19 +1384,25 @@ def test_execute_sql_w_request_options(self): ), ) - def test_execute_sql_w_request_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_request_tag_success(self, mock_region): request_options = {"request_tag": "tag-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - def test_execute_sql_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_transaction_tag_success(self, mock_region): request_options = {"transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - def test_execute_sql_w_request_and_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_request_and_transaction_tag_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - def test_execute_sql_w_request_and_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_request_and_transaction_tag_dictionary_success( + self, mock_region + ): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) @@ -1367,25 +1411,29 @@ def test_execute_sql_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=False, request_options=request_options) - def test_execute_sql_w_directed_read_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_directed_read_options(self, mock_region): self._execute_sql_helper( multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS ) - def test_execute_sql_w_directed_read_options_at_client_level(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_directed_read_options_at_client_level(self, mock_region): self._execute_sql_helper( multi_use=False, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - def test_execute_sql_w_directed_read_options_override(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_directed_read_options_override(self, mock_region): self._execute_sql_helper( multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - def test_execute_sql_w_precommit_tokens(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_sql_w_precommit_tokens(self, mock_region): self._execute_sql_helper(multi_use=True, use_multiplexed=True) def _partition_read_helper( @@ -1493,7 +1541,8 @@ def test_partition_read_wo_existing_transaction_raises(self): with self.assertRaises(ValueError): self._partition_read_helper(multi_use=True, w_txn=False) - def test_partition_read_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_other_error(self, mock_region): from google.cloud.spanner_v1.keyset import KeySet keyset = KeySet(all_=True) @@ -1552,24 +1601,30 @@ def test_partition_read_w_retry(self): self.assertEqual(api.partition_read.call_count, 2) - def test_partition_read_ok_w_index_no_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_index_no_options(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, index="index") - def test_partition_read_ok_w_size(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_size(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, size=2000) - def test_partition_read_ok_w_max_partitions(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_max_partitions(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, max_partitions=4) - def test_partition_read_ok_w_timeout_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_timeout_param(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, timeout=2.0) - def test_partition_read_ok_w_retry_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_retry_param(self, mock_region): self._partition_read_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60) ) - def test_partition_read_ok_w_timeout_and_retry_params(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_read_ok_w_timeout_and_retry_params(self, mock_region): self._partition_read_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60), timeout=2.0 ) @@ -1672,7 +1727,8 @@ def _partition_query_helper( ), ) - def test_partition_query_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_other_error(self, mock_region): database = _Database() database.spanner_api = build_spanner_api() database.spanner_api.partition_query.side_effect = RuntimeError() @@ -1701,24 +1757,30 @@ def test_partition_query_wo_transaction_raises(self): with self.assertRaises(ValueError): self._partition_query_helper(multi_use=True, w_txn=False) - def test_partition_query_ok_w_index_no_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_index_no_options(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True) - def test_partition_query_ok_w_size(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_size(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, size=2000) - def test_partition_query_ok_w_max_partitions(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_max_partitions(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, max_partitions=4) - def test_partition_query_ok_w_timeout_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_timeout_param(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, timeout=2.0) - def test_partition_query_ok_w_retry_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_retry_param(self, mock_region): self._partition_query_helper( multi_use=True, w_txn=True, retry=Retry(deadline=30) ) - def test_partition_query_ok_w_timeout_and_retry_params(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_partition_query_ok_w_timeout_and_retry_params(self, mock_region): self._partition_query_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60), timeout=2.0 ) diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 8ed5d92a0c..7e3e24b4d9 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -26,6 +26,8 @@ TransactionOptions, ResultSetMetadata, ) +from google.cloud.spanner_v1._helpers import _get_cloud_region +from google.cloud.spanner_v1._helpers import GOOGLE_CLOUD_REGION_GLOBAL from google.cloud.spanner_v1 import DefaultTransactionOptions from google.cloud.spanner_v1 import Type from google.cloud.spanner_v1 import TypeCode @@ -191,7 +193,8 @@ def test_rollback_already_rolled_back(self): self.assertNoSpans() - def test_rollback_w_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_rollback_w_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() database.spanner_api.rollback.side_effect = RuntimeError("other error") @@ -214,7 +217,8 @@ def test_rollback_w_other_error(self): ), ) - def test_rollback_ok(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_rollback_ok(self, mock_region): from google.protobuf.empty_pb2 import Empty empty_pb = Empty() @@ -346,7 +350,8 @@ def test_commit_already_rolled_back(self): ] self.assertEqual(got_span_events_statuses, want_span_events_statuses) - def test_commit_w_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() database.spanner_api.commit.side_effect = RuntimeError() @@ -558,31 +563,38 @@ def _commit_helper( actual_statuses = self.finished_spans_events_statuses() self.assertEqual(actual_statuses, expected_statuses) - def test_commit_mutations_only_not_multiplexed(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_not_multiplexed(self, mock_region): self._commit_helper(mutations=[DELETE_MUTATION], is_multiplexed=False) - def test_commit_mutations_only_multiplexed_w_non_insert_mutation(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_multiplexed_w_non_insert_mutation(self, mock_region): self._commit_helper( mutations=[DELETE_MUTATION], is_multiplexed=True, expected_begin_mutation=DELETE_MUTATION, ) - def test_commit_mutations_only_multiplexed_w_insert_mutation(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_multiplexed_w_insert_mutation(self, mock_region): self._commit_helper( mutations=[INSERT_MUTATION], is_multiplexed=True, expected_begin_mutation=INSERT_MUTATION, ) - def test_commit_mutations_only_multiplexed_w_non_insert_and_insert_mutations(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_multiplexed_w_non_insert_and_insert_mutations( + self, mock_region + ): self._commit_helper( mutations=[INSERT_MUTATION, DELETE_MUTATION], is_multiplexed=True, expected_begin_mutation=DELETE_MUTATION, ) - def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations(self, mock_region): insert_1 = Mutation(insert=_make_write_pb(TABLE_NAME, COLUMNS, [VALUE_1])) insert_2 = Mutation( insert=_make_write_pb(TABLE_NAME, COLUMNS, [VALUE_1, VALUE_2]) @@ -594,7 +606,10 @@ def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations(self): expected_begin_mutation=insert_2, ) - def test_commit_mutations_only_multiplexed_w_multiple_non_insert_mutations(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_mutations_only_multiplexed_w_multiple_non_insert_mutations( + self, mock_region + ): mutations = [UPDATE_MUTATION, DELETE_MUTATION] self._commit_helper( mutations=mutations, @@ -602,7 +617,8 @@ def test_commit_mutations_only_multiplexed_w_multiple_non_insert_mutations(self) expected_begin_mutation=mutations[0], ) - def test_commit_w_return_commit_stats(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_return_commit_stats(self, mock_region): self._commit_helper(return_commit_stats=True) def test_commit_w_max_commit_delay(self): @@ -629,7 +645,8 @@ def test_commit_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._commit_helper(request_options=request_options) - def test_commit_w_retry_for_precommit_token(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_commit_w_retry_for_precommit_token(self, mock_region): self._commit_helper(retry_for_precommit_token=True) def test_commit_w_retry_for_precommit_token_then_error(self): @@ -659,7 +676,8 @@ def test__make_params_pb_w_params_w_param_types(self): ) self.assertEqual(params_pb, expected_params) - def test_execute_update_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() database.spanner_api.execute_sql.side_effect = RuntimeError() @@ -796,29 +814,36 @@ def _execute_update_helper( if use_multiplexed: self.assertEqual(transaction._precommit_token, PRECOMMIT_TOKEN_PB_0) - def test_execute_update_new_transaction(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_new_transaction(self, mock_region): self._execute_update_helper() - def test_execute_update_w_request_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._execute_update_helper(request_options=request_options) - def test_execute_update_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._execute_update_helper(request_options=request_options) - def test_execute_update_w_request_and_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", transaction_tag="tag-1-1", ) self._execute_update_helper(request_options=request_options) - def test_execute_update_w_request_and_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_request_and_transaction_tag_dictionary_success( + self, mock_region + ): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_update_helper(request_options=request_options) @@ -827,16 +852,20 @@ def test_execute_update_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._execute_update_helper(request_options=request_options) - def test_execute_update_w_count(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_count(self, mock_region): self._execute_update_helper(count=1) - def test_execute_update_w_timeout_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_timeout_param(self, mock_region): self._execute_update_helper(timeout=2.0) - def test_execute_update_w_retry_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_retry_param(self, mock_region): self._execute_update_helper(retry=Retry(deadline=60)) - def test_execute_update_w_timeout_and_retry_params(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_timeout_and_retry_params(self, mock_region): self._execute_update_helper(retry=Retry(deadline=60), timeout=2.0) def test_execute_update_error(self): @@ -852,27 +881,32 @@ def test_execute_update_error(self): self.assertEqual(transaction._execute_sql_request_count, 1) - def test_execute_update_w_query_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_query_options(self, mock_region): from google.cloud.spanner_v1 import ExecuteSqlRequest self._execute_update_helper( query_options=ExecuteSqlRequest.QueryOptions(optimizer_version="3") ) - def test_execute_update_wo_begin(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_wo_begin(self, mock_region): self._execute_update_helper(begin=False) - def test_execute_update_w_precommit_token(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_precommit_token(self, mock_region): self._execute_update_helper(use_multiplexed=True) - def test_execute_update_w_request_options(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_execute_update_w_request_options(self, mock_region): self._execute_update_helper( request_options=RequestOptions( priority=RequestOptions.Priority.PRIORITY_MEDIUM ) ) - def test_batch_update_other_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() database.spanner_api.execute_batch_dml.side_effect = RuntimeError() @@ -1028,45 +1062,55 @@ def _batch_update_helper( if use_multiplexed: self.assertEqual(transaction._precommit_token, PRECOMMIT_TOKEN_PB_2) - def test_batch_update_wo_begin(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_wo_begin(self, mock_region): self._batch_update_helper(begin=False) - def test_batch_update_wo_errors(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_wo_errors(self, mock_region): self._batch_update_helper( request_options=RequestOptions( priority=RequestOptions.Priority.PRIORITY_MEDIUM ), ) - def test_batch_update_w_request_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._batch_update_helper(request_options=request_options) - def test_batch_update_w_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._batch_update_helper(request_options=request_options) - def test_batch_update_w_request_and_transaction_tag_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", transaction_tag="tag-1-1", ) self._batch_update_helper(request_options=request_options) - def test_batch_update_w_request_and_transaction_tag_dictionary_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_request_and_transaction_tag_dictionary_success( + self, mock_region + ): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._batch_update_helper(request_options=request_options) - def test_batch_update_w_incorrect_tag_dictionary_error(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._batch_update_helper(request_options=request_options) - def test_batch_update_w_errors(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_errors(self, mock_region): self._batch_update_helper(error_after=2, count=1) def test_batch_update_error(self): @@ -1100,19 +1144,24 @@ def test_batch_update_error(self): self.assertEqual(transaction._execute_sql_request_count, 1) - def test_batch_update_w_timeout_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_timeout_param(self, mock_region): self._batch_update_helper(timeout=2.0) - def test_batch_update_w_retry_param(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_retry_param(self, mock_region): self._batch_update_helper(retry=gapic_v1.method.DEFAULT) - def test_batch_update_w_timeout_and_retry_params(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_timeout_and_retry_params(self, mock_region): self._batch_update_helper(retry=gapic_v1.method.DEFAULT, timeout=2.0) - def test_batch_update_w_precommit_token(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_batch_update_w_precommit_token(self, mock_region): self._batch_update_helper(use_multiplexed=True) - def test_context_mgr_success(self): + @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + def test_context_mgr_success(self, mock_region): transaction = build_transaction() session = transaction._session database = session._database @@ -1177,7 +1226,7 @@ def _build_span_attributes( "gcp.client.service": "spanner", "gcp.client.version": LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", - "cloud.region": "global", + "cloud.region": GOOGLE_CLOUD_REGION_GLOBAL, } ) From f75e31c53d43cad5574b80838e2f190c537f022a Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Tue, 28 Oct 2025 09:04:08 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- tests/unit/test__opentelemetry_tracing.py | 10 +- tests/unit/test_batch.py | 115 +++++++-- tests/unit/test_pool.py | 205 ++++++++++++--- tests/unit/test_session.py | 85 +++++-- tests/unit/test_snapshot.py | 295 +++++++++++++++++----- tests/unit/test_transaction.py | 199 ++++++++++++--- 6 files changed, 727 insertions(+), 182 deletions(-) diff --git a/tests/unit/test__opentelemetry_tracing.py b/tests/unit/test__opentelemetry_tracing.py index 9d8f0baaef..82da567f26 100644 --- a/tests/unit/test__opentelemetry_tracing.py +++ b/tests/unit/test__opentelemetry_tracing.py @@ -54,7 +54,10 @@ def test_no_trace_call(self): self.assertIsNone(no_span) class TestTracing(OpenTelemetryBase): - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_trace_call(self, mock_region): extra_attributes = { "attribute1": "value1", @@ -90,7 +93,10 @@ def test_trace_call(self, mock_region): self.assertEqual(span.name, "CloudSpanner.Test") self.assertEqual(span.status.status_code, StatusCode.OK) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_trace_error(self, mock_region): extra_attributes = {"db.instance": "database_name"} diff --git a/tests/unit/test_batch.py b/tests/unit/test_batch.py index bed3ccf984..e8297030eb 100644 --- a/tests/unit/test_batch.py +++ b/tests/unit/test_batch.py @@ -200,7 +200,10 @@ def test_commit_already_committed(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_grpc_error(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) @@ -222,7 +225,10 @@ def test_commit_grpc_error(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_ok(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) @@ -380,21 +386,30 @@ def _test_commit_with_options( self.assertEqual(max_commit_delay_in, max_commit_delay) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._test_commit_with_options(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._test_commit_with_options(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -402,18 +417,27 @@ def test_commit_w_request_and_transaction_tag_success(self, mock_region): ) self._test_commit_with_options(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_request_and_transaction_tag_dictionary_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._test_commit_with_options(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._test_commit_with_options(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_max_commit_delay(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -423,7 +447,10 @@ def test_commit_w_max_commit_delay(self, mock_region): max_commit_delay_in=datetime.timedelta(milliseconds=100), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_exclude_txn_from_change_streams(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -432,7 +459,10 @@ def test_commit_w_exclude_txn_from_change_streams(self, mock_region): request_options=request_options, exclude_txn_from_change_streams=True ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_isolation_level(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -442,7 +472,10 @@ def test_commit_w_isolation_level(self, mock_region): isolation_level=TransactionOptions.IsolationLevel.REPEATABLE_READ, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_read_lock_mode(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -452,7 +485,10 @@ def test_commit_w_read_lock_mode(self, mock_region): read_lock_mode=TransactionOptions.ReadWrite.ReadLockMode.OPTIMISTIC, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_isolation_level_and_read_lock_mode(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -463,7 +499,10 @@ def test_commit_w_isolation_level_and_read_lock_mode(self, mock_region): read_lock_mode=TransactionOptions.ReadWrite.ReadLockMode.PESSIMISTIC, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_context_mgr_already_committed(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) database = _Database() @@ -478,7 +517,10 @@ def test_context_mgr_already_committed(self, mock_region): self.assertEqual(api._committed, None) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_context_mgr_success(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) @@ -526,7 +568,10 @@ def test_context_mgr_success(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_context_mgr_failure(self, mock_region): now = datetime.datetime.utcnow().replace(tzinfo=UTC) now_pb = _datetime_to_pb_timestamp(now) @@ -558,7 +603,10 @@ def test_ctor(self): groups = self._make_one(session) self.assertIs(groups._session, session) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_already_committed(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) @@ -582,7 +630,10 @@ def test_batch_write_already_committed(self, mock_region): with self.assertRaises(ValueError): groups.batch_write() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_grpc_error(self, mock_region): keys = [[0], [1], [2]] keyset = KeySet(keys=keys) @@ -681,30 +732,48 @@ def _test_batch_write_with_request_options( ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_no_request_options(self, mock_region): self._test_batch_write_with_request_options() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_end_to_end_tracing_enabled(self, mock_region): self._test_batch_write_with_request_options(enable_end_to_end_tracing=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_w_transaction_tag_success(self, mock_region): self._test_batch_write_with_request_options( RequestOptions(transaction_tag="tag-1-1") ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_w_transaction_tag_dictionary_success(self, mock_region): self._test_batch_write_with_request_options({"transaction_tag": "tag-1-1"}) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_w_incorrect_tag_dictionary_error(self, mock_region): with self.assertRaises(ValueError): self._test_batch_write_with_request_options({"incorrect_tag": "tag-1-1"}) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_write_w_exclude_txn_from_change_streams(self, mock_region): self._test_batch_write_with_request_options( exclude_txn_from_change_streams=True diff --git a/tests/unit/test_pool.py b/tests/unit/test_pool.py index fd0e82aa9b..ec03e4350b 100644 --- a/tests/unit/test_pool.py +++ b/tests/unit/test_pool.py @@ -176,7 +176,10 @@ def test_ctor_defaults(self): self.assertEqual(pool.labels, {}) self.assertIsNone(pool.database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ctor_explicit(self, mock_region): labels = {"foo": "bar"} database_role = "dummy-role" @@ -190,7 +193,10 @@ def test_ctor_explicit(self, mock_region): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_bind(self, mock_region): database_role = "dummy-role" pool = self._make_one() @@ -212,7 +218,10 @@ def test_bind(self, mock_region): for session in SESSIONS: session.create.assert_not_called() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_active(self, mock_region): pool = self._make_one(size=4) database = _Database("name") @@ -227,7 +236,10 @@ def test_get_active(self, mock_region): self.assertFalse(session._exists_checked) self.assertFalse(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_non_expired(self, mock_region): pool = self._make_one(size=4) database = _Database("name") @@ -245,7 +257,10 @@ def test_get_non_expired(self, mock_region): self.assertTrue(session._exists_checked) self.assertFalse(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_bind_get(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -291,7 +306,10 @@ def test_spans_bind_get(self, mock_region): ] self.assertSpanEvents("pool.Get", wantEventNames, span_list[-1]) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_bind_get_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -336,7 +354,10 @@ def test_spans_bind_get_empty_pool(self, mock_region): ] assert got_all_events == want_all_events - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_pool_bind(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -411,7 +432,10 @@ def test_spans_pool_bind(self, mock_region): ] assert got_all_events == want_all_events - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_expired(self, mock_region): pool = self._make_one(size=4) database = _Database("name") @@ -428,7 +452,10 @@ def test_get_expired(self, mock_region): self.assertTrue(SESSIONS[0]._exists_checked) self.assertFalse(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_empty_default_timeout(self, mock_region): import queue @@ -440,7 +467,10 @@ def test_get_empty_default_timeout(self, mock_region): self.assertEqual(session_queue._got, {"block": True, "timeout": 10}) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_empty_explicit_timeout(self, mock_region): import queue @@ -452,7 +482,10 @@ def test_get_empty_explicit_timeout(self, mock_region): self.assertEqual(session_queue._got, {"block": True, "timeout": 1}) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_full(self, mock_region): import queue @@ -468,7 +501,10 @@ def test_put_full(self, mock_region): self.assertTrue(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_non_full(self, mock_region): pool = self._make_one(size=4) database = _Database("name") @@ -481,7 +517,10 @@ def test_put_non_full(self, mock_region): self.assertTrue(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") @@ -540,7 +579,10 @@ def test_ctor_explicit(self): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ctor_explicit_w_database_role_in_db(self, mock_region): database_role = "dummy-role" pool = self._make_one() @@ -549,7 +591,10 @@ def test_ctor_explicit_w_database_role_in_db(self, mock_region): pool.bind(database) self.assertEqual(pool.database_role, database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_empty(self, mock_region): pool = self._make_one() database = _Database("name") @@ -563,7 +608,10 @@ def test_get_empty(self, mock_region): session.create.assert_called() self.assertTrue(pool._sessions.empty()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_get_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -602,7 +650,10 @@ def test_spans_get_empty_pool(self, mock_region): ] self.assertSpanEvents("pool.Get", wantEventNames, span=create_span) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_non_empty_session_exists(self, mock_region): pool = self._make_one() database = _Database("name") @@ -617,7 +668,10 @@ def test_get_non_empty_session_exists(self, mock_region): self.assertTrue(session._exists_checked) self.assertTrue(pool._sessions.empty()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_get_non_empty_session_exists(self, mock_region): # Tests the spans produces when you invoke pool.bind # and then insert a session into the pool. @@ -642,7 +696,10 @@ def test_spans_get_non_empty_session_exists(self, mock_region): ["Acquiring session", "Waiting for a session to become available"], ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_non_empty_session_expired(self, mock_region): pool = self._make_one() database = _Database("name") @@ -660,7 +717,10 @@ def test_get_non_empty_session_expired(self, mock_region): self.assertFalse(session._exists_checked) self.assertTrue(pool._sessions.empty()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_empty(self, mock_region): pool = self._make_one() database = _Database("name") @@ -671,7 +731,10 @@ def test_put_empty(self, mock_region): self.assertFalse(pool._sessions.empty()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_put_empty(self, mock_region): # Tests the spans produced when you put sessions into an empty pool. pool = self._make_one() @@ -688,7 +751,10 @@ def test_spans_put_empty(self, mock_region): attributes=TestBurstyPool.BASE_ATTRIBUTES, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_full(self, mock_region): pool = self._make_one(target_size=1) database = _Database("name") @@ -703,7 +769,10 @@ def test_put_full(self, mock_region): self.assertTrue(younger._deleted) self.assertIs(pool.get(), older) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_put_full(self, mock_region): # This scenario tests the spans produced from putting an older # session into a pool that is already full. @@ -726,7 +795,10 @@ def test_spans_put_full(self, mock_region): attributes=TestBurstyPool.BASE_ATTRIBUTES, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_full_expired(self, mock_region): pool = self._make_one(target_size=1) database = _Database("name") @@ -741,7 +813,10 @@ def test_put_full_expired(self, mock_region): self.assertTrue(younger._deleted) self.assertIs(pool.get(), older) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") @@ -804,7 +879,10 @@ def test_ctor_explicit(self): self.assertEqual(pool.labels, labels) self.assertEqual(pool.database_role, database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ctor_explicit_w_database_role_in_db(self, mock_region): database_role = "dummy-role" pool = self._make_one() @@ -815,7 +893,10 @@ def test_ctor_explicit_w_database_role_in_db(self, mock_region): pool.bind(database) self.assertEqual(pool.database_role, database_role) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_bind(self, mock_region): pool = self._make_one() database = _Database("name") @@ -834,7 +915,10 @@ def test_bind(self, mock_region): for session in SESSIONS: session.create.assert_not_called() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_hit_no_ping(self, mock_region): pool = self._make_one(size=4) database = _Database("name") @@ -850,7 +934,10 @@ def test_get_hit_no_ping(self, mock_region): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_hit_w_ping(self, mock_region): import datetime from google.cloud._testing import _Monkey @@ -875,7 +962,10 @@ def test_get_hit_w_ping(self, mock_region): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_hit_w_ping_expired(self, mock_region): import datetime from google.cloud._testing import _Monkey @@ -901,7 +991,10 @@ def test_get_hit_w_ping_expired(self, mock_region): self.assertFalse(pool._sessions.full()) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_empty_default_timeout(self, mock_region): import queue @@ -914,7 +1007,10 @@ def test_get_empty_default_timeout(self, mock_region): self.assertEqual(session_queue._got, {"block": True, "timeout": 10}) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_get_empty_explicit_timeout(self, mock_region): import queue @@ -927,7 +1023,10 @@ def test_get_empty_explicit_timeout(self, mock_region): self.assertEqual(session_queue._got, {"block": True, "timeout": 1}) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_full(self, mock_region): import queue @@ -942,7 +1041,10 @@ def test_put_full(self, mock_region): self.assertTrue(pool._sessions.full()) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_put_full(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return @@ -983,7 +1085,10 @@ def test_spans_put_full(self, mock_region): "CloudSpanner.PingingPool.BatchCreateSessions", wantEventNames ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_put_non_full(self, mock_region): import datetime from google.cloud._testing import _Monkey @@ -1005,7 +1110,10 @@ def test_put_non_full(self, mock_region): self.assertIs(queued, session) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_clear(self, mock_region): pool = self._make_one() database = _Database("name") @@ -1026,13 +1134,19 @@ def test_clear(self, mock_region): self.assertTrue(session._deleted) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_empty(self, mock_region): pool = self._make_one(size=1) pool.ping() # Does not raise 'Empty' self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_oldest_fresh(self, mock_region): pool = self._make_one(size=1) database = _Database("name") @@ -1046,7 +1160,10 @@ def test_ping_oldest_fresh(self, mock_region): self.assertFalse(SESSIONS[0]._pinged) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_oldest_stale_but_exists(self, mock_region): import datetime from google.cloud._testing import _Monkey @@ -1064,7 +1181,10 @@ def test_ping_oldest_stale_but_exists(self, mock_region): self.assertTrue(SESSIONS[0]._pinged) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_oldest_stale_and_not_exists(self, mock_region): import datetime from google.cloud._testing import _Monkey @@ -1086,7 +1206,10 @@ def test_ping_oldest_stale_and_not_exists(self, mock_region): SESSIONS[1].create.assert_called() self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_spans_get_and_leave_empty_pool(self, mock_region): if not HAS_OPENTELEMETRY_INSTALLED: return diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index b67cd5f6a3..7b6908c508 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -223,7 +223,10 @@ def test_create_w_session_id(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_w_database_role(self, mock_region): session_pb = self._make_session_pb( self.SESSION_NAME, database_role=self.DATABASE_ROLE @@ -265,7 +268,10 @@ def test_create_w_database_role(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_session_span_annotations(self, mock_region): session_pb = self._make_session_pb( self.SESSION_NAME, database_role=self.DATABASE_ROLE @@ -304,7 +310,10 @@ def test_create_session_span_annotations(self, mock_region): wantEventNames = ["Creating Session"] self.assertSpanEvents("TestSessionSpan", wantEventNames, span) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_wo_database_role(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() @@ -341,7 +350,10 @@ def test_create_wo_database_role(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_ok(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() @@ -378,7 +390,10 @@ def test_create_ok(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_w_labels(self, mock_region): labels = {"foo": "bar"} session_pb = self._make_session_pb(self.SESSION_NAME, labels=labels) @@ -417,7 +432,10 @@ def test_create_w_labels(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_create_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.create_session.side_effect = Unknown("error") @@ -444,7 +462,10 @@ def test_exists_wo_session_id(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_exists_hit(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() @@ -482,7 +503,10 @@ def test_exists_hit(self, mock_region): "google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED", False, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_exists_hit_wo_span(self, mock_region): session_pb = self._make_session_pb(self.SESSION_NAME) gax_api = self._make_spanner_api() @@ -508,7 +532,10 @@ def test_exists_hit_wo_span(self, mock_region): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_exists_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = NotFound("testing") @@ -545,7 +572,10 @@ def test_exists_miss(self, mock_region): "google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED", False, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_exists_miss_wo_span(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = NotFound("testing") @@ -570,7 +600,10 @@ def test_exists_miss_wo_span(self, mock_region): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_exists_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.get_session.side_effect = Unknown("testing") @@ -609,7 +642,10 @@ def test_ping_wo_session_id(self): with self.assertRaises(ValueError): session.ping() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_hit(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.return_value = "1" @@ -636,7 +672,10 @@ def test_ping_hit(self, mock_region): ], ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.side_effect = NotFound("testing") @@ -664,7 +703,10 @@ def test_ping_miss(self, mock_region): ], ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_ping_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.execute_sql.side_effect = Unknown("testing") @@ -701,7 +743,10 @@ def test_delete_wo_session_id(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_delete_hit(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.return_value = None @@ -731,7 +776,10 @@ def test_delete_hit(self, mock_region): attributes=dict(attrs, x_goog_spanner_request_id=req_id), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_delete_miss(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.side_effect = NotFound("testing") @@ -768,7 +816,10 @@ def test_delete_miss(self, mock_region): attributes=attrs, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_delete_error(self, mock_region): gax_api = self._make_spanner_api() gax_api.delete_session.side_effect = Unknown("testing") diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 9ab24f581b..a3b97a4dc2 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -560,7 +560,10 @@ def test_iteration_w_raw_raising_non_retryable_internal_error_after_token(self): ) self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_iteration_w_span_creation(self, mock_region): name = "TestSpan" extra_atts = {"test_att": 1} @@ -583,7 +586,10 @@ def test_iteration_w_span_creation(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_iteration_w_multiple_span_creation(self, mock_region): from google.api_core.exceptions import ServiceUnavailable @@ -686,7 +692,10 @@ def test_begin_error_already_begun(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_error_other(self, mock_region): derived = _build_snapshot_derived(multi_use=True) @@ -706,7 +715,10 @@ def test_begin_error_other(self, mock_region): attributes=_build_span_attributes(database), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_read_write(self, mock_region): derived = _build_snapshot_derived(multi_use=True, read_only=False) @@ -715,7 +727,10 @@ def test_begin_read_write(self, mock_region): self._execute_begin(derived) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_read_only(self, mock_region): derived = _build_snapshot_derived(multi_use=True, read_only=True) @@ -724,7 +739,10 @@ def test_begin_read_only(self, mock_region): self._execute_begin(derived) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_precommit_token(self, mock_region): derived = _build_snapshot_derived(multi_use=True) @@ -735,7 +753,10 @@ def test_begin_precommit_token(self, mock_region): self._execute_begin(derived) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_retry_for_internal_server_error(self, mock_region): derived = _build_snapshot_derived(multi_use=True) @@ -756,7 +777,10 @@ def test_begin_retry_for_internal_server_error(self, mock_region): actual_statuses = self.finished_spans_events_statuses() self.assertEqual(expected_statuses, actual_statuses) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_begin_retry_for_aborted(self, mock_region): derived = _build_snapshot_derived(multi_use=True) @@ -825,7 +849,10 @@ def _execute_begin(self, derived: _Derived, attempts: int = 1): attributes=_build_span_attributes(database, attempt=attempts), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_other_error(self, mock_region): from google.cloud.spanner_v1.keyset import KeySet @@ -1032,89 +1059,143 @@ def _execute_read( if use_multiplexed: self.assertEqual(derived._precommit_token, PRECOMMIT_TOKEN_2) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_wo_multi_use(self, mock_region): self._execute_read(multi_use=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_request_tag_success(self, mock_region): request_options = {"request_tag": "tag-1"} self._execute_read(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_transaction_tag_success(self, mock_region): request_options = {"transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_request_and_transaction_tag_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_request_and_transaction_tag_dictionary_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_read(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._execute_read(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_wo_multi_use_w_read_request_count_gt_0(self, mock_region): with self.assertRaises(ValueError): self._execute_read(multi_use=False, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_multi_use_w_first(self, mock_region): self._execute_read(multi_use=True, first=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_multi_use_wo_first(self, mock_region): self._execute_read(multi_use=True, first=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_multi_use_wo_first_w_count_gt_0(self, mock_region): self._execute_read(multi_use=True, first=False, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_multi_use_w_first_w_partition(self, mock_region): PARTITION = b"FADEABED" self._execute_read(multi_use=True, first=True, partition=PARTITION) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_multi_use_w_first_w_count_gt_0(self, mock_region): with self.assertRaises(ValueError): self._execute_read(multi_use=True, first=True, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_timeout_param(self, mock_region): self._execute_read(multi_use=True, first=False, timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_retry_param(self, mock_region): self._execute_read(multi_use=True, first=False, retry=Retry(deadline=60)) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_timeout_and_retry_params(self, mock_region): self._execute_read( multi_use=True, first=False, retry=Retry(deadline=60), timeout=2.0 ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_directed_read_options(self, mock_region): self._execute_read(multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_directed_read_options_at_client_level(self, mock_region): self._execute_read( multi_use=False, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_directed_read_options_override(self, mock_region): self._execute_read( multi_use=False, @@ -1122,11 +1203,17 @@ def test_read_w_directed_read_options_override(self, mock_region): directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_read_w_precommit_tokens(self, mock_region): self._execute_read(multi_use=True, use_multiplexed=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_other_error(self, mock_region): database = _Database() database.spanner_api = build_spanner_api() @@ -1334,7 +1421,10 @@ def _execute_sql_helper( if use_multiplexed: self.assertEqual(derived._precommit_token, PRECOMMIT_TOKEN_2) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_wo_multi_use(self, mock_region): self._execute_sql_helper(multi_use=False) @@ -1342,15 +1432,24 @@ def test_execute_sql_wo_multi_use_w_read_request_count_gt_0(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=False, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_multi_use_wo_first(self, mock_region): self._execute_sql_helper(multi_use=True, first=False, sql_count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_multi_use_wo_first_w_count_gt_0(self, mock_region): self._execute_sql_helper(multi_use=True, first=False, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_multi_use_w_first(self, mock_region): self._execute_sql_helper(multi_use=True, first=True) @@ -1358,15 +1457,24 @@ def test_execute_sql_w_multi_use_w_first_w_count_gt_0(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=True, first=True, count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_retry(self, mock_region): self._execute_sql_helper(multi_use=False, retry=None) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_timeout(self, mock_region): self._execute_sql_helper(multi_use=False, timeout=None) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_query_options(self, mock_region): from google.cloud.spanner_v1 import ExecuteSqlRequest @@ -1375,7 +1483,10 @@ def test_execute_sql_w_query_options(self, mock_region): query_options=ExecuteSqlRequest.QueryOptions(optimizer_version="3"), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_request_options(self, mock_region): self._execute_sql_helper( multi_use=False, @@ -1384,22 +1495,34 @@ def test_execute_sql_w_request_options(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_request_tag_success(self, mock_region): request_options = {"request_tag": "tag-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_transaction_tag_success(self, mock_region): request_options = {"transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_request_and_transaction_tag_success(self, mock_region): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._execute_sql_helper(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_request_and_transaction_tag_dictionary_success( self, mock_region ): @@ -1411,20 +1534,29 @@ def test_execute_sql_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._execute_sql_helper(multi_use=False, request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_directed_read_options(self, mock_region): self._execute_sql_helper( multi_use=False, directed_read_options=DIRECTED_READ_OPTIONS ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_directed_read_options_at_client_level(self, mock_region): self._execute_sql_helper( multi_use=False, directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_directed_read_options_override(self, mock_region): self._execute_sql_helper( multi_use=False, @@ -1432,7 +1564,10 @@ def test_execute_sql_w_directed_read_options_override(self, mock_region): directed_read_options_at_client_level=DIRECTED_READ_OPTIONS_FOR_CLIENT, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_sql_w_precommit_tokens(self, mock_region): self._execute_sql_helper(multi_use=True, use_multiplexed=True) @@ -1541,7 +1676,10 @@ def test_partition_read_wo_existing_transaction_raises(self): with self.assertRaises(ValueError): self._partition_read_helper(multi_use=True, w_txn=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_other_error(self, mock_region): from google.cloud.spanner_v1.keyset import KeySet @@ -1601,29 +1739,47 @@ def test_partition_read_w_retry(self): self.assertEqual(api.partition_read.call_count, 2) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_index_no_options(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, index="index") - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_size(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, size=2000) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_max_partitions(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, max_partitions=4) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_timeout_param(self, mock_region): self._partition_read_helper(multi_use=True, w_txn=True, timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_retry_param(self, mock_region): self._partition_read_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60) ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_read_ok_w_timeout_and_retry_params(self, mock_region): self._partition_read_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60), timeout=2.0 @@ -1727,7 +1883,10 @@ def _partition_query_helper( ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_other_error(self, mock_region): database = _Database() database.spanner_api = build_spanner_api() @@ -1757,29 +1916,47 @@ def test_partition_query_wo_transaction_raises(self): with self.assertRaises(ValueError): self._partition_query_helper(multi_use=True, w_txn=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_index_no_options(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_size(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, size=2000) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_max_partitions(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, max_partitions=4) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_timeout_param(self, mock_region): self._partition_query_helper(multi_use=True, w_txn=True, timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_retry_param(self, mock_region): self._partition_query_helper( multi_use=True, w_txn=True, retry=Retry(deadline=30) ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_partition_query_ok_w_timeout_and_retry_params(self, mock_region): self._partition_query_helper( multi_use=True, w_txn=True, retry=Retry(deadline=60), timeout=2.0 diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 7e3e24b4d9..08ea3e08b2 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -193,7 +193,10 @@ def test_rollback_already_rolled_back(self): self.assertNoSpans() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_rollback_w_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() @@ -217,7 +220,10 @@ def test_rollback_w_other_error(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_rollback_ok(self, mock_region): from google.protobuf.empty_pb2 import Empty @@ -350,7 +356,10 @@ def test_commit_already_rolled_back(self): ] self.assertEqual(got_span_events_statuses, want_span_events_statuses) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() @@ -563,11 +572,17 @@ def _commit_helper( actual_statuses = self.finished_spans_events_statuses() self.assertEqual(actual_statuses, expected_statuses) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_mutations_only_not_multiplexed(self, mock_region): self._commit_helper(mutations=[DELETE_MUTATION], is_multiplexed=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_mutations_only_multiplexed_w_non_insert_mutation(self, mock_region): self._commit_helper( mutations=[DELETE_MUTATION], @@ -575,7 +590,10 @@ def test_commit_mutations_only_multiplexed_w_non_insert_mutation(self, mock_regi expected_begin_mutation=DELETE_MUTATION, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_mutations_only_multiplexed_w_insert_mutation(self, mock_region): self._commit_helper( mutations=[INSERT_MUTATION], @@ -583,7 +601,10 @@ def test_commit_mutations_only_multiplexed_w_insert_mutation(self, mock_region): expected_begin_mutation=INSERT_MUTATION, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_mutations_only_multiplexed_w_non_insert_and_insert_mutations( self, mock_region ): @@ -593,8 +614,13 @@ def test_commit_mutations_only_multiplexed_w_non_insert_and_insert_mutations( expected_begin_mutation=DELETE_MUTATION, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") - def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations(self, mock_region): + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) + def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations( + self, mock_region + ): insert_1 = Mutation(insert=_make_write_pb(TABLE_NAME, COLUMNS, [VALUE_1])) insert_2 = Mutation( insert=_make_write_pb(TABLE_NAME, COLUMNS, [VALUE_1, VALUE_2]) @@ -606,7 +632,10 @@ def test_commit_mutations_only_multiplexed_w_multiple_insert_mutations(self, moc expected_begin_mutation=insert_2, ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_mutations_only_multiplexed_w_multiple_non_insert_mutations( self, mock_region ): @@ -617,7 +646,10 @@ def test_commit_mutations_only_multiplexed_w_multiple_non_insert_mutations( expected_begin_mutation=mutations[0], ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_return_commit_stats(self, mock_region): self._commit_helper(return_commit_stats=True) @@ -645,7 +677,10 @@ def test_commit_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._commit_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_commit_w_retry_for_precommit_token(self, mock_region): self._commit_helper(retry_for_precommit_token=True) @@ -676,7 +711,10 @@ def test__make_params_pb_w_params_w_param_types(self): ) self.assertEqual(params_pb, expected_params) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() @@ -814,25 +852,37 @@ def _execute_update_helper( if use_multiplexed: self.assertEqual(transaction._precommit_token, PRECOMMIT_TOKEN_PB_0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_new_transaction(self, mock_region): self._execute_update_helper() - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._execute_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._execute_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -840,7 +890,10 @@ def test_execute_update_w_request_and_transaction_tag_success(self, mock_region) ) self._execute_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_request_and_transaction_tag_dictionary_success( self, mock_region ): @@ -852,19 +905,31 @@ def test_execute_update_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._execute_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_count(self, mock_region): self._execute_update_helper(count=1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_timeout_param(self, mock_region): self._execute_update_helper(timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_retry_param(self, mock_region): self._execute_update_helper(retry=Retry(deadline=60)) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_timeout_and_retry_params(self, mock_region): self._execute_update_helper(retry=Retry(deadline=60), timeout=2.0) @@ -881,7 +946,10 @@ def test_execute_update_error(self): self.assertEqual(transaction._execute_sql_request_count, 1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_query_options(self, mock_region): from google.cloud.spanner_v1 import ExecuteSqlRequest @@ -889,15 +957,24 @@ def test_execute_update_w_query_options(self, mock_region): query_options=ExecuteSqlRequest.QueryOptions(optimizer_version="3") ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_wo_begin(self, mock_region): self._execute_update_helper(begin=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_precommit_token(self, mock_region): self._execute_update_helper(use_multiplexed=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_execute_update_w_request_options(self, mock_region): self._execute_update_helper( request_options=RequestOptions( @@ -905,7 +982,10 @@ def test_execute_update_w_request_options(self, mock_region): ) ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_other_error(self, mock_region): database = _Database() database.spanner_api = self._make_spanner_api() @@ -1062,11 +1142,17 @@ def _batch_update_helper( if use_multiplexed: self.assertEqual(transaction._precommit_token, PRECOMMIT_TOKEN_PB_2) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_wo_begin(self, mock_region): self._batch_update_helper(begin=False) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_wo_errors(self, mock_region): self._batch_update_helper( request_options=RequestOptions( @@ -1074,21 +1160,30 @@ def test_batch_update_wo_errors(self, mock_region): ), ) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_request_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", ) self._batch_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_transaction_tag_success(self, mock_region): request_options = RequestOptions( transaction_tag="tag-1-1", ) self._batch_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_request_and_transaction_tag_success(self, mock_region): request_options = RequestOptions( request_tag="tag-1", @@ -1096,20 +1191,29 @@ def test_batch_update_w_request_and_transaction_tag_success(self, mock_region): ) self._batch_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_request_and_transaction_tag_dictionary_success( self, mock_region ): request_options = {"request_tag": "tag-1", "transaction_tag": "tag-1-1"} self._batch_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_incorrect_tag_dictionary_error(self, mock_region): request_options = {"incorrect_tag": "tag-1-1"} with self.assertRaises(ValueError): self._batch_update_helper(request_options=request_options) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_errors(self, mock_region): self._batch_update_helper(error_after=2, count=1) @@ -1144,23 +1248,38 @@ def test_batch_update_error(self): self.assertEqual(transaction._execute_sql_request_count, 1) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_timeout_param(self, mock_region): self._batch_update_helper(timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_retry_param(self, mock_region): self._batch_update_helper(retry=gapic_v1.method.DEFAULT) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_timeout_and_retry_params(self, mock_region): self._batch_update_helper(retry=gapic_v1.method.DEFAULT, timeout=2.0) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_batch_update_w_precommit_token(self, mock_region): self._batch_update_helper(use_multiplexed=True) - @mock.patch("google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", return_value="global") + @mock.patch( + "google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region", + return_value="global", + ) def test_context_mgr_success(self, mock_region): transaction = build_transaction() session = transaction._session From f3bf07401a8dbbebbd6b812cbea02b9f4951985b Mon Sep 17 00:00:00 2001 From: Subham Sinha Date: Mon, 27 Oct 2025 11:25:35 +0530 Subject: [PATCH 6/6] feat(opentelemetry): add request_tag to span attributes --- google/cloud/spanner_v1/_helpers.py | 25 ++++++++++++++----- .../spanner_v1/_opentelemetry_tracing.py | 3 +-- tests/system/test_session_api.py | 3 ++- tests/unit/test__helpers.py | 5 +++- tests/unit/test_snapshot.py | 5 ++-- tests/unit/test_transaction.py | 3 +-- 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/google/cloud/spanner_v1/_helpers.py b/google/cloud/spanner_v1/_helpers.py index 9f5d72fe51..aa58c59199 100644 --- a/google/cloud/spanner_v1/_helpers.py +++ b/google/cloud/spanner_v1/_helpers.py @@ -42,10 +42,16 @@ from opentelemetry.propagate import inject from opentelemetry.propagators.textmap import Setter from opentelemetry.semconv.resource import ResourceAttributes + from opentelemetry.resourcedetector import gcp_resource_detector from opentelemetry.resourcedetector.gcp_resource_detector import ( GoogleCloudResourceDetector, ) + # Overwrite the requests timeout for the detector. + # This is necessary as the client will wait the full timeout if the + # code is not run in a GCP environment, with the location endpoints available. + gcp_resource_detector._TIMEOUT_SEC = 0.2 + HAS_OPENTELEMETRY_INSTALLED = True except ImportError: HAS_OPENTELEMETRY_INSTALLED = False @@ -65,6 +71,8 @@ log = logging.getLogger(__name__) +_cloud_region: str = None + if HAS_OPENTELEMETRY_INSTALLED: @@ -90,25 +98,30 @@ def set(self, carrier: List[Tuple[str, str]], key: str, value: str) -> None: def _get_cloud_region() -> str: - """Get the location of the resource. + """Get the location of the resource, caching the result. Returns: str: The location of the resource. If OpenTelemetry is not installed, returns a global region. """ - if not HAS_OPENTELEMETRY_INSTALLED: - return GOOGLE_CLOUD_REGION_GLOBAL + global _cloud_region + if _cloud_region is not None: + return _cloud_region + try: detector = GoogleCloudResourceDetector() resources = detector.detect() - if ResourceAttributes.CLOUD_REGION in resources.attributes: - return resources.attributes[ResourceAttributes.CLOUD_REGION] + _cloud_region = resources.attributes[ResourceAttributes.CLOUD_REGION] + else: + _cloud_region = GOOGLE_CLOUD_REGION_GLOBAL except Exception as e: log.warning( "Failed to detect GCP resource location for Spanner metrics, defaulting to 'global'. Error: %s", e, ) - return GOOGLE_CLOUD_REGION_GLOBAL + _cloud_region = GOOGLE_CLOUD_REGION_GLOBAL + + return _cloud_region def _try_to_coerce_bytes(bytestring): diff --git a/google/cloud/spanner_v1/_opentelemetry_tracing.py b/google/cloud/spanner_v1/_opentelemetry_tracing.py index 4a4f45552e..e27314b499 100644 --- a/google/cloud/spanner_v1/_opentelemetry_tracing.py +++ b/google/cloud/spanner_v1/_opentelemetry_tracing.py @@ -99,7 +99,6 @@ def trace_call( "enable_end_to_end_tracing", enable_end_to_end_tracing ) db_name = observability_options.get("db_name", db_name) - cloud_region = observability_options.get("cloud_region", cloud_region) cloud_region = _get_cloud_region() tracer = get_tracer(tracer_provider) @@ -125,7 +124,7 @@ def trace_call( if "request_options" in attributes: request_options = attributes.pop("request_options") if request_options and request_options.request_tag: - attributes["spanner.request_tag"] = request_options.request_tag + attributes["request.tag"] = request_options.request_tag if extended_tracing_globally_disabled: enable_extended_tracing = False diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 12f2625fd2..8bd0a867d1 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -30,6 +30,7 @@ from google.cloud.spanner_admin_database_v1 import DatabaseDialect from google.cloud._helpers import UTC +from google.cloud.spanner_v1._helpers import _get_cloud_region from google.cloud.spanner_v1._helpers import AtomicCounter from google.cloud.spanner_v1.data_types import JsonObject from google.cloud.spanner_v1.database_sessions_manager import TransactionType @@ -354,7 +355,7 @@ def _make_attributes(db_instance, **kwargs): "db.url": "spanner.googleapis.com", "net.host.name": "spanner.googleapis.com", "db.instance": db_instance, - "cloud.region": "global", + "cloud.region": _get_cloud_region(), "gcp.client.service": "spanner", "gcp.client.version": ot_helpers.LIB_VERSION, "gcp.client.repo": "googleapis/python-spanner", diff --git a/tests/unit/test__helpers.py b/tests/unit/test__helpers.py index 2ad9293c16..40db14607c 100644 --- a/tests/unit/test__helpers.py +++ b/tests/unit/test__helpers.py @@ -20,7 +20,7 @@ from opentelemetry.semconv.resource import ResourceAttributes -from google.cloud.spanner_v1 import TransactionOptions +from google.cloud.spanner_v1 import TransactionOptions, _helpers class Test_merge_query_options(unittest.TestCase): @@ -94,6 +94,9 @@ def test_base_object_merge_dict(self): class Test_get_cloud_region(unittest.TestCase): + def setUp(self): + _helpers._cloud_region = None + def _callFUT(self, *args, **kw): from google.cloud.spanner_v1._helpers import _get_cloud_region diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index a3b97a4dc2..974cc8e75e 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -27,7 +27,6 @@ TransactionOptions, TransactionSelector, ) -from google.cloud.spanner_v1._helpers import _get_cloud_region from google.cloud.spanner_v1.snapshot import _SnapshotBase from tests._builders import ( build_precommit_token_pb, @@ -1048,7 +1047,7 @@ def _execute_read( x_goog_spanner_request_id=req_id, ) if request_options and request_options.request_tag: - expected_attributes["spanner.request_tag"] = request_options.request_tag + expected_attributes["request.tag"] = request_options.request_tag self.assertSpanAttributes( "CloudSpanner._Derived.read", attributes=expected_attributes ) @@ -1407,7 +1406,7 @@ def _execute_sql_helper( }, ) if request_options and request_options.request_tag: - expected_attributes["spanner.request_tag"] = request_options.request_tag + expected_attributes["request.tag"] = request_options.request_tag self.assertSpanAttributes( "CloudSpanner._Derived.execute_sql", diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 08ea3e08b2..39656cb8d1 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -26,7 +26,6 @@ TransactionOptions, ResultSetMetadata, ) -from google.cloud.spanner_v1._helpers import _get_cloud_region from google.cloud.spanner_v1._helpers import GOOGLE_CLOUD_REGION_GLOBAL from google.cloud.spanner_v1 import DefaultTransactionOptions from google.cloud.spanner_v1 import Type @@ -841,7 +840,7 @@ def _execute_update_helper( database, **{"db.statement": DML_QUERY_WITH_PARAM} ) if request_options.request_tag: - expected_attributes["spanner.request_tag"] = request_options.request_tag + expected_attributes["request.tag"] = request_options.request_tag self.assertSpanAttributes( "CloudSpanner.Transaction.execute_update", attributes=expected_attributes )