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

Commit a4746f0

Browse files
committed
added new file for system tests
1 parent bb55c46 commit a4746f0

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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+
import asyncio
15+
import os
16+
import pytest
17+
import uuid
18+
19+
from google.cloud.bigtable.data._metrics.handlers._base import MetricsHandler
20+
from google.cloud.bigtable.data._metrics.data_model import CompletedOperationMetric
21+
22+
from google.cloud.bigtable.data._cross_sync import CrossSync
23+
24+
25+
from . import TEST_FAMILY
26+
27+
__CROSS_SYNC_OUTPUT__ = "tests.system.data.test_metrics_autogen"
28+
29+
30+
class _MetricsTestHandler(MetricsHandler):
31+
"""
32+
Store completed metrics events in internal lists for testing
33+
"""
34+
35+
def __init__(self, **kwargs):
36+
self.completed_operations = []
37+
self.completed_attempts = []
38+
self.cancelled_operations = []
39+
40+
def on_operation_complete(self, op):
41+
self.completed_operations.append(op)
42+
43+
def on_operation_cancelled(self, op):
44+
self.cancelled_operations.append(op)
45+
46+
def on_attempt_complete(self, attempt, op):
47+
self.completed_attempts.append((attempt, op))
48+
49+
def total(self):
50+
return len(self.completed_operations) + len(self._ancelled_operations) + len(self.completed_attempts)
51+
52+
def clear(self):
53+
self.cancelled_operations.clear()
54+
self.completed_operations.clear()
55+
self.completed_attempts.clear()
56+
57+
58+
@CrossSync.convert_class(sync_name="TestSystem")
59+
class TestMetricsAsync:
60+
61+
@CrossSync.drop
62+
@pytest.fixture(scope="session")
63+
def event_loop(self):
64+
loop = asyncio.get_event_loop()
65+
yield loop
66+
loop.stop()
67+
loop.close()
68+
69+
@pytest.fixture(scope="session")
70+
def init_table_id(self):
71+
"""
72+
The table_id to use when creating a new test table
73+
"""
74+
return f"test-metrics-{uuid.uuid4().hex}"
75+
76+
@pytest.fixture(scope="session")
77+
def cluster_config(self, project_id):
78+
"""
79+
Configuration for the clusters to use when creating a new instance
80+
"""
81+
from google.cloud.bigtable_admin_v2 import types
82+
83+
cluster = {
84+
"test-cluster": types.Cluster(
85+
location=f"projects/{project_id}/locations/us-central1-b",
86+
serve_nodes=1,
87+
)
88+
}
89+
return cluster
90+
91+
@pytest.fixture(scope="session")
92+
def column_family_config(self):
93+
"""
94+
specify column families to create when creating a new test table
95+
"""
96+
from google.cloud.bigtable_admin_v2 import types
97+
98+
return {TEST_FAMILY: types.ColumnFamily()}
99+
100+
def _make_client(self):
101+
project = os.getenv("GOOGLE_CLOUD_PROJECT") or None
102+
return CrossSync.DataClient(project=project)
103+
104+
@pytest.fixture(scope="session")
105+
def handler(self):
106+
return _MetricsTestHandler()
107+
108+
@CrossSync.convert
109+
@CrossSync.pytest_fixture(scope="function", autouse=True)
110+
async def _clear_handler(self, handler):
111+
"""Clear handler between each test"""
112+
handler.clear()
113+
114+
@CrossSync.convert
115+
@CrossSync.pytest_fixture(scope="session")
116+
async def client(self):
117+
async with self._make_client() as client:
118+
yield client
119+
120+
@CrossSync.convert
121+
@CrossSync.pytest_fixture(scope="function")
122+
async def temp_rows(self, target):
123+
builder = CrossSync.TempRowBuilder(target)
124+
yield builder
125+
await builder.delete_rows()
126+
127+
@CrossSync.convert
128+
@CrossSync.pytest_fixture(scope="session")
129+
async def target(self, client, table_id, instance_id, handler):
130+
"""
131+
This fixture runs twice: once for a standard table, and once with an authorized view
132+
133+
Note: emulator doesn't support authorized views. Only use target
134+
"""
135+
async with client.get_table(instance_id, table_id) as table:
136+
table._metrics.add_handler(handler)
137+
yield table
138+
139+
async def test_read_modify_write(self, target, temp_rows):
140+
from google.cloud.bigtable.data.read_modify_write_rules import IncrementRule
141+
142+
row_key = b"test-row-key"
143+
family = TEST_FAMILY
144+
qualifier = b"test-qualifier"
145+
await temp_rows.add_row(
146+
row_key, value=0, family=family, qualifier=qualifier
147+
)
148+
rule = IncrementRule(family, qualifier, 1)
149+
result = await target.read_modify_write_row(row_key, rule)
150+
breakpoint()
151+
print(result)

0 commit comments

Comments
 (0)