Skip to content

Commit b13ea7b

Browse files
committed
feat(metrics): add system test for built-in metrics
1 parent 6abe73f commit b13ea7b

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

google/cloud/spanner_v1/metrics/constants.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
GOOGLE_CLOUD_REGION_KEY = "cloud.region"
2121
GOOGLE_CLOUD_REGION_GLOBAL = "global"
2222
SPANNER_METHOD_PREFIX = "/google.spanner.v1."
23-
ENABLE_SPANNER_METRICS_ENV_VAR = "SPANNER_ENABLE_BUILTIN_METRICS"
2423

2524
# Monitored resource labels
2625
MONITORED_RES_LABEL_KEY_PROJECT = "project_id"

tests/system/test_metrics.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import mock
17+
import pytest
18+
19+
from opentelemetry.sdk.metrics import MeterProvider
20+
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
21+
22+
from google.cloud.spanner_v1 import Client
23+
24+
# System tests are skipped if the environment variables are not set.
25+
PROJECT = os.environ.get("GOOGLE_CLOUD_PROJECT")
26+
INSTANCE_ID = os.environ.get("SPANNER_TEST_INSTANCE")
27+
DATABASE_ID = "test_metrics_db_system"
28+
29+
30+
pytestmark = pytest.mark.skipif(
31+
not all([PROJECT, INSTANCE_ID]), reason="System test environment variables not set."
32+
)
33+
34+
35+
@pytest.fixture(scope="module")
36+
def metrics_database():
37+
"""Create a database for the test."""
38+
client = Client(project=PROJECT)
39+
instance = client.instance(INSTANCE_ID)
40+
database = instance.database(DATABASE_ID)
41+
if database.exists(): # Clean up from previous failed run
42+
database.drop()
43+
op = database.create()
44+
op.result(timeout=300) # Wait for creation to complete
45+
yield database
46+
if database.exists():
47+
database.drop()
48+
49+
50+
def test_builtin_metrics_with_default_otel(metrics_database):
51+
"""
52+
Verifies that built-in metrics are collected by default when a
53+
transaction is executed.
54+
"""
55+
reader = InMemoryMetricReader()
56+
meter_provider = MeterProvider(metric_readers=[reader])
57+
58+
# Patch the client's metric setup to use our in-memory reader.
59+
with mock.patch(
60+
"google.cloud.spanner_v1.client.MeterProvider",
61+
return_value=meter_provider,
62+
):
63+
with mock.patch.dict(os.environ, {"SPANNER_DISABLE_BUILTIN_METRICS": "false"}):
64+
with metrics_database.snapshot() as snapshot:
65+
list(snapshot.execute_sql("SELECT 1"))
66+
67+
metric_data = reader.get_metrics_data()
68+
69+
assert len(metric_data.resource_metrics) >= 1
70+
assert len(metric_data.resource_metrics[0].scope_metrics) >= 1
71+
72+
collected_metrics = {
73+
metric.name
74+
for metric in metric_data.resource_metrics[0].scope_metrics[0].metrics
75+
}
76+
expected_metrics = {
77+
"spanner/operation_latencies",
78+
"spanner/attempt_latencies",
79+
"spanner/operation_count",
80+
"spanner/attempt_count",
81+
"spanner/gfe_latencies",
82+
}
83+
assert expected_metrics.issubset(collected_metrics)
84+
85+
for metric in metric_data.resource_metrics[0].scope_metrics[0].metrics:
86+
if metric.name == "spanner/operation_count":
87+
point = next(iter(metric.data.data_points))
88+
assert point.value == 1
89+
assert point.attributes["method"] == "ExecuteSql"
90+
return
91+
92+
pytest.fail("Metric 'spanner/operation_count' not found.")

0 commit comments

Comments
 (0)