1+ # Copyright 2025 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 asyncio
16+ import pytest
17+ import os
18+
19+ from . import TEST_FAMILY , SystemTestRunner
20+
21+ from google .cloud .bigtable .data .read_rows_query import ReadRowsQuery
22+
23+ from google .cloud .bigtable .data ._cross_sync import CrossSync
24+
25+ __CROSS_SYNC_OUTPUT__ = "tests.system.data.test_metrics_autogen"
26+
27+
28+ @CrossSync .convert_class (sync_name = "TestExportedMetrics" )
29+ class TestExportedExportedMetricsAsync (SystemTestRunner ):
30+
31+ @CrossSync .drop
32+ @pytest .fixture (scope = "session" )
33+ def event_loop (self ):
34+ loop = asyncio .get_event_loop ()
35+ yield loop
36+ loop .stop ()
37+ loop .close ()
38+
39+ def _make_client (self ):
40+ project = os .getenv ("GOOGLE_CLOUD_PROJECT" ) or None
41+ return CrossSync .DataClient (project = project )
42+
43+ @CrossSync .convert
44+ @CrossSync .pytest_fixture (scope = "session" )
45+ async def client (self ):
46+ async with self ._make_client () as client :
47+ yield client
48+
49+ @pytest .fixture (scope = "session" )
50+ def metrics_client (self , client ):
51+ yield client ._gcp_metrics_exporter .client
52+
53+
54+ @CrossSync .convert
55+ @CrossSync .pytest_fixture (scope = "function" )
56+ async def temp_rows (self , table ):
57+ builder = CrossSync .TempRowBuilder (table )
58+ yield builder
59+ await builder .delete_rows ()
60+
61+ @CrossSync .convert
62+ @CrossSync .pytest_fixture (scope = "session" )
63+ async def table (self , client , table_id , instance_id ):
64+ async with client .get_table (instance_id , table_id ) as table :
65+ yield table
66+
67+ @CrossSync .pytest
68+ async def test_read_rows (self , table , temp_rows , metrics_client ):
69+ from datetime import datetime , timedelta , timezone
70+ from google .cloud import monitoring_v3
71+
72+ await temp_rows .add_row (b"row_key_1" )
73+ await temp_rows .add_row (b"row_key_2" )
74+ row_list = await table .read_rows (ReadRowsQuery ())
75+ # read back metrics
76+
77+ # 1. Define the Time Interval
78+ now = datetime .now (timezone .utc )
79+ # The end time is inclusive
80+ end_time = now
81+ # The start time is exclusive, for an interval (startTime, endTime]
82+ start_time = now - timedelta (minutes = 5 )
83+
84+ interval = {"start_time" : start_time , "end_time" : end_time }
85+ metric_filter = (
86+ 'metric.type = "bigtable.googleapis.com/client/attempt_latencies" AND metric.labels.client_name != "go-bigtable/1.40.0"'
87+ )
88+ results = metrics_client .list_time_series (
89+ name = f"projects/{ table .client .project } " ,
90+ filter = metric_filter ,
91+ interval = interval ,
92+ view = monitoring_v3 .ListTimeSeriesRequest .TimeSeriesView .FULL ,
93+ )
94+ print (results )
0 commit comments