Skip to content
Prev Previous commit
Next Next commit
Merge branch 'main' into fix/span-attributes
  • Loading branch information
sinhasubham committed Nov 11, 2025
commit 2ff6bf1507f84191878bb581144b47028f2e9f78
91 changes: 34 additions & 57 deletions tests/unit/test__opentelemetry_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,54 +32,34 @@ def _make_session():


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
"db.instance": "database_name",
}

class TestNoTracing(unittest.TestCase):
def setUp(self):
self._temp_opentelemetry = sys.modules["opentelemetry"]

sys.modules["opentelemetry"] = None
importlib.reload(_opentelemetry_tracing)

def tearDown(self):
sys.modules["opentelemetry"] = self._temp_opentelemetry
importlib.reload(_opentelemetry_tracing)

def test_no_trace_call(self):
with _opentelemetry_tracing.trace_call("Test", _make_session()) as no_span:
self.assertIsNone(no_span)

class TestTracing(OpenTelemetryBase):
@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
"db.instance": "database_name",
expected_attributes = enrich_with_otel_scope(
{
"db.type": "spanner",
"db.url": "spanner.googleapis.com",
"net.host.name": "spanner.googleapis.com",
"cloud.region": GOOGLE_CLOUD_REGION_GLOBAL,
"gcp.client.service": "spanner",
"gcp.client.version": LIB_VERSION,
"gcp.client.repo": "googleapis/python-spanner",
}
)
expected_attributes.update(extra_attributes)

expected_attributes = enrich_with_otel_scope(
{
"db.type": "spanner",
"db.url": "spanner.googleapis.com",
"net.host.name": "spanner.googleapis.com",
"cloud.region": GOOGLE_CLOUD_REGION_GLOBAL,
"gcp.client.service": "spanner",
"gcp.client.version": LIB_VERSION,
"gcp.client.repo": "googleapis/python-spanner",
}
)
expected_attributes.update(extra_attributes)
with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
span.set_attribute("after_setup_attribute", 1)

expected_attributes["after_setup_attribute"] = 1

Expand All @@ -91,14 +71,19 @@ def test_trace_call(self, mock_region):
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(
{
"db.type": "spanner",
"db.url": "spanner.googleapis.com",
"net.host.name": "spanner.googleapis.com",
"cloud.region": GOOGLE_CLOUD_REGION_GLOBAL,
"gcp.client.service": "spanner",
"gcp.client.version": LIB_VERSION,
"gcp.client.repo": "googleapis/python-spanner",
Expand All @@ -122,25 +107,17 @@ def test_trace_error(self):
self.assertEqual(span.name, "CloudSpanner.Test")
self.assertEqual(span.status.status_code, StatusCode.ERROR)

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",
return_value="global",
def test_trace_grpc_error(self):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = enrich_with_otel_scope(
{
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
)
def test_trace_error(self, mock_region):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = enrich_with_otel_scope(
{
"db.type": "spanner",
"db.url": "spanner.googleapis.com",
"net.host.name": "spanner.googleapis.com",
"cloud.region": GOOGLE_CLOUD_REGION_GLOBAL,
"gcp.client.service": "spanner",
"gcp.client.version": LIB_VERSION,
"gcp.client.repo": "googleapis/python-spanner",
}
)
expected_attributes.update(extra_attributes)
expected_attributes.update(extra_attributes)

with self.assertRaises(GoogleAPICallError):
with _opentelemetry_tracing.trace_call(
Expand Down
76 changes: 11 additions & 65 deletions tests/unit/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,39 +499,6 @@ def test_exists_hit(self, mock_region):
),
)

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED",
False,
)
@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
database = self._make_database()
database.spanner_api = gax_api
session = self._make_one(database)
session._session_id = self.SESSION_ID

self.assertTrue(session.exists())

gax_api.get_session.assert_called_once_with(
name=self.SESSION_NAME,
metadata=[
("google-cloud-resource-prefix", database.name),
("x-goog-spanner-route-to-leader", "true"),
(
"x-goog-spanner-request-id",
f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.1.1",
),
],
)

self.assertNoSpans()

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",
return_value="global",
Expand Down Expand Up @@ -568,38 +535,6 @@ def test_exists_miss(self, mock_region):
),
)

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing.HAS_OPENTELEMETRY_INSTALLED",
False,
)
@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()
database.spanner_api = gax_api
session = self._make_one(database)
session._session_id = self.SESSION_ID

self.assertFalse(session.exists())

gax_api.get_session.assert_called_once_with(
name=self.SESSION_NAME,
metadata=[
("google-cloud-resource-prefix", database.name),
("x-goog-spanner-route-to-leader", "true"),
(
"x-goog-spanner-request-id",
f"1.{REQ_RAND_PROCESS_ID}.{database._nth_client_id}.{database._channel_id}.1.1",
),
],
)

self.assertNoSpans()

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",
return_value="global",
Expand Down Expand Up @@ -673,6 +608,11 @@ def test_ping_hit(self, mock_region):
],
)

self.assertSpanAttributes(
"CloudSpanner.Session.ping",
attributes=dict(self.BASE_ATTRIBUTES, x_goog_spanner_request_id=req_id),
)

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",
return_value="global",
Expand Down Expand Up @@ -705,6 +645,12 @@ def test_ping_miss(self, mock_region):
],
)

self.assertSpanAttributes(
"CloudSpanner.Session.ping",
status=StatusCode.ERROR,
attributes=dict(self.BASE_ATTRIBUTES, x_goog_spanner_request_id=req_id),
)

@mock.patch(
"google.cloud.spanner_v1._opentelemetry_tracing._get_cloud_region",
return_value="global",
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.