Skip to content

Commit 6bbac87

Browse files
committed
moved all fixtures into one place
1 parent 1832824 commit 6bbac87

File tree

4 files changed

+185
-215
lines changed

4 files changed

+185
-215
lines changed

tests/system/conftest.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
script_path = os.path.dirname(os.path.realpath(__file__))
2424
sys.path.append(script_path)
2525

26-
pytest_plugins = [
27-
"data.setup_fixtures",
28-
]
29-
3026

3127
@pytest.fixture(scope="session")
3228
def event_loop():

tests/system/data/__init__.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414
# limitations under the License.
1515
#
1616
import pytest
17+
import os
1718
import uuid
1819

1920
TEST_FAMILY = "test-family"
2021
TEST_FAMILY_2 = "test-family-2"
2122
TEST_AGGREGATE_FAMILY = "test-aggregate-family"
2223

24+
# authorized view subset to allow all qualifiers
25+
ALLOW_ALL = ""
26+
ALL_QUALIFIERS = {"qualifier_prefixes": [ALLOW_ALL]}
27+
2328

2429
class SystemTestRunner:
2530
"""
@@ -68,3 +73,182 @@ def column_family_config(self):
6873
value_type=types.Type(aggregate_type=int_aggregate_type)
6974
),
7075
}
76+
77+
@pytest.fixture(scope="session")
78+
def admin_client(self):
79+
"""
80+
Client for interacting with Table and Instance admin APIs
81+
"""
82+
from google.cloud.bigtable.client import Client
83+
84+
client = Client(admin=True)
85+
yield client
86+
87+
@pytest.fixture(scope="session")
88+
def instance_id(self, admin_client, project_id, cluster_config):
89+
"""
90+
Returns BIGTABLE_TEST_INSTANCE if set, otherwise creates a new temporary instance for the test session
91+
"""
92+
from google.cloud.bigtable_admin_v2 import types
93+
from google.api_core import exceptions
94+
from google.cloud.environment_vars import BIGTABLE_EMULATOR
95+
96+
# use user-specified instance if available
97+
user_specified_instance = os.getenv("BIGTABLE_TEST_INSTANCE")
98+
if user_specified_instance:
99+
print("Using user-specified instance: {}".format(user_specified_instance))
100+
yield user_specified_instance
101+
return
102+
103+
# create a new temporary test instance
104+
instance_id = f"python-bigtable-tests-{uuid.uuid4().hex[:6]}"
105+
if os.getenv(BIGTABLE_EMULATOR):
106+
# don't create instance if in emulator mode
107+
yield instance_id
108+
else:
109+
try:
110+
operation = admin_client.instance_admin_client.create_instance(
111+
parent=f"projects/{project_id}",
112+
instance_id=instance_id,
113+
instance=types.Instance(
114+
display_name="Test Instance",
115+
# labels={"python-system-test": "true"},
116+
),
117+
clusters=cluster_config,
118+
)
119+
operation.result(timeout=240)
120+
except exceptions.AlreadyExists:
121+
pass
122+
yield instance_id
123+
admin_client.instance_admin_client.delete_instance(
124+
name=f"projects/{project_id}/instances/{instance_id}"
125+
)
126+
127+
@pytest.fixture(scope="session")
128+
def column_split_config(self):
129+
"""
130+
specify initial splits to create when creating a new test table
131+
"""
132+
return [(num * 1000).to_bytes(8, "big") for num in range(1, 10)]
133+
134+
@pytest.fixture(scope="session")
135+
def table_id(
136+
self,
137+
admin_client,
138+
project_id,
139+
instance_id,
140+
column_family_config,
141+
init_table_id,
142+
column_split_config,
143+
):
144+
"""
145+
Returns BIGTABLE_TEST_TABLE if set, otherwise creates a new temporary table for the test session
146+
147+
Args:
148+
- admin_client: Client for interacting with the Table Admin API. Supplied by the admin_client fixture.
149+
- project_id: The project ID of the GCP project to test against. Supplied by the project_id fixture.
150+
- instance_id: The ID of the Bigtable instance to test against. Supplied by the instance_id fixture.
151+
- init_column_families: A list of column families to initialize the table with, if pre-initialized table is not given with BIGTABLE_TEST_TABLE.
152+
Supplied by the init_column_families fixture.
153+
- init_table_id: The table ID to give to the test table, if pre-initialized table is not given with BIGTABLE_TEST_TABLE.
154+
Supplied by the init_table_id fixture.
155+
- column_split_config: A list of row keys to use as initial splits when creating the test table.
156+
"""
157+
from google.api_core import exceptions
158+
from google.api_core import retry
159+
160+
# use user-specified instance if available
161+
user_specified_table = os.getenv("BIGTABLE_TEST_TABLE")
162+
if user_specified_table:
163+
print("Using user-specified table: {}".format(user_specified_table))
164+
yield user_specified_table
165+
return
166+
167+
retry = retry.Retry(
168+
predicate=retry.if_exception_type(exceptions.FailedPrecondition)
169+
)
170+
try:
171+
parent_path = f"projects/{project_id}/instances/{instance_id}"
172+
print(f"Creating table: {parent_path}/tables/{init_table_id}")
173+
admin_client.table_admin_client.create_table(
174+
request={
175+
"parent": parent_path,
176+
"table_id": init_table_id,
177+
"table": {"column_families": column_family_config},
178+
"initial_splits": [{"key": key} for key in column_split_config],
179+
},
180+
retry=retry,
181+
)
182+
except exceptions.AlreadyExists:
183+
pass
184+
yield init_table_id
185+
print(f"Deleting table: {parent_path}/tables/{init_table_id}")
186+
try:
187+
admin_client.table_admin_client.delete_table(
188+
name=f"{parent_path}/tables/{init_table_id}"
189+
)
190+
except exceptions.NotFound:
191+
print(f"Table {init_table_id} not found, skipping deletion")
192+
193+
@pytest.fixture(scope="session")
194+
def authorized_view_id(
195+
self,
196+
admin_client,
197+
project_id,
198+
instance_id,
199+
table_id,
200+
):
201+
"""
202+
Creates and returns a new temporary authorized view for the test session
203+
204+
Args:
205+
- admin_client: Client for interacting with the Table Admin API. Supplied by the admin_client fixture.
206+
- project_id: The project ID of the GCP project to test against. Supplied by the project_id fixture.
207+
- instance_id: The ID of the Bigtable instance to test against. Supplied by the instance_id fixture.
208+
- table_id: The ID of the table to create the authorized view for. Supplied by the table_id fixture.
209+
"""
210+
from google.api_core import exceptions
211+
from google.api_core import retry
212+
213+
retry = retry.Retry(
214+
predicate=retry.if_exception_type(exceptions.FailedPrecondition)
215+
)
216+
new_view_id = uuid.uuid4().hex[:8]
217+
parent_path = f"projects/{project_id}/instances/{instance_id}/tables/{table_id}"
218+
new_path = f"{parent_path}/authorizedViews/{new_view_id}"
219+
try:
220+
print(f"Creating view: {new_path}")
221+
admin_client.table_admin_client.create_authorized_view(
222+
request={
223+
"parent": parent_path,
224+
"authorized_view_id": new_view_id,
225+
"authorized_view": {
226+
"subset_view": {
227+
"row_prefixes": [ALLOW_ALL],
228+
"family_subsets": {
229+
TEST_FAMILY: ALL_QUALIFIERS,
230+
TEST_FAMILY_2: ALL_QUALIFIERS,
231+
TEST_AGGREGATE_FAMILY: ALL_QUALIFIERS,
232+
},
233+
},
234+
},
235+
},
236+
retry=retry,
237+
)
238+
except exceptions.AlreadyExists:
239+
pass
240+
except exceptions.MethodNotImplemented:
241+
# will occur when run in emulator. Pass empty id
242+
new_view_id = None
243+
yield new_view_id
244+
if new_view_id:
245+
print(f"Deleting view: {new_path}")
246+
try:
247+
admin_client.table_admin_client.delete_authorized_view(name=new_path)
248+
except exceptions.NotFound:
249+
print(f"View {new_view_id} not found, skipping deletion")
250+
251+
@pytest.fixture(scope="session")
252+
def project_id(self, client):
253+
"""Returns the project ID from the client."""
254+
yield client.project

0 commit comments

Comments
 (0)