Skip to content

Commit e1f4a4b

Browse files
committed
Updating system tests so configuration is done at runtime.
In a set-up where the tests are not intended to be run (e.g. a PR build for Travis), just importing these modules caused errors due to lack of implicit variables being set. So, all configuration done at import time was moved into `setUpClass` if there was only one `TestCase` or moved to `setUpModule` with some mutable global if there were multiple `TestCase`s.
1 parent 3e4cb7f commit e1f4a4b

5 files changed

Lines changed: 104 additions & 78 deletions

File tree

system_tests/bigquery.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323

2424

2525
_helpers.PROJECT = TESTS_PROJECT
26-
CLIENT = bigquery.Client()
2726
DATASET_NAME = 'system_tests_%012d' % (1000 * time.time(),)
2827

2928

3029
class TestBigQuery(unittest2.TestCase):
3130

31+
@classmethod
32+
def setUpClass(cls):
33+
cls.client = bigquery.Client()
34+
3235
def setUp(self):
3336
self.to_delete = []
3437

@@ -37,26 +40,26 @@ def tearDown(self):
3740
doomed.delete()
3841

3942
def test_create_dataset(self):
40-
dataset = CLIENT.dataset(DATASET_NAME)
43+
dataset = self.client.dataset(DATASET_NAME)
4144
self.assertFalse(dataset.exists())
4245
dataset.create()
4346
self.to_delete.append(dataset)
4447
self.assertTrue(dataset.exists())
4548
self.assertEqual(dataset.name, DATASET_NAME)
4649

4750
def test_reload_dataset(self):
48-
dataset = CLIENT.dataset(DATASET_NAME)
51+
dataset = self.client.dataset(DATASET_NAME)
4952
dataset.friendly_name = 'Friendly'
5053
dataset.description = 'Description'
5154
dataset.create()
5255
self.to_delete.append(dataset)
53-
other = CLIENT.dataset(DATASET_NAME)
56+
other = self.client.dataset(DATASET_NAME)
5457
other.reload()
5558
self.assertEqual(other.friendly_name, 'Friendly')
5659
self.assertEqual(other.description, 'Description')
5760

5861
def test_patch_dataset(self):
59-
dataset = CLIENT.dataset(DATASET_NAME)
62+
dataset = self.client.dataset(DATASET_NAME)
6063
self.assertFalse(dataset.exists())
6164
dataset.create()
6265
self.to_delete.append(dataset)
@@ -68,7 +71,7 @@ def test_patch_dataset(self):
6871
self.assertEqual(dataset.description, 'Description')
6972

7073
def test_update_dataset(self):
71-
dataset = CLIENT.dataset(DATASET_NAME)
74+
dataset = self.client.dataset(DATASET_NAME)
7275
self.assertFalse(dataset.exists())
7376
dataset.create()
7477
self.to_delete.append(dataset)
@@ -90,20 +93,20 @@ def test_list_datasets(self):
9093
'newest%d' % (1000 * time.time(),),
9194
]
9295
for dataset_name in datasets_to_create:
93-
dataset = CLIENT.dataset(dataset_name)
96+
dataset = self.client.dataset(dataset_name)
9497
dataset.create()
9598
self.to_delete.append(dataset)
9699

97100
# Retrieve the datasets.
98-
all_datasets, token = CLIENT.list_datasets()
101+
all_datasets, token = self.client.list_datasets()
99102
self.assertTrue(token is None)
100103
created = [dataset for dataset in all_datasets
101104
if dataset.name in datasets_to_create and
102-
dataset.project == CLIENT.project]
105+
dataset.project == self.client.project]
103106
self.assertEqual(len(created), len(datasets_to_create))
104107

105108
def test_create_table(self):
106-
dataset = CLIENT.dataset(DATASET_NAME)
109+
dataset = self.client.dataset(DATASET_NAME)
107110
self.assertFalse(dataset.exists())
108111
dataset.create()
109112
self.to_delete.append(dataset)
@@ -120,7 +123,7 @@ def test_create_table(self):
120123
self.assertTrue(table._dataset is dataset)
121124

122125
def test_list_tables(self):
123-
dataset = CLIENT.dataset(DATASET_NAME)
126+
dataset = self.client.dataset(DATASET_NAME)
124127
self.assertFalse(dataset.exists())
125128
dataset.create()
126129
self.to_delete.append(dataset)
@@ -146,7 +149,7 @@ def test_list_tables(self):
146149
self.assertEqual(len(created), len(tables_to_create))
147150

148151
def test_patch_table(self):
149-
dataset = CLIENT.dataset(DATASET_NAME)
152+
dataset = self.client.dataset(DATASET_NAME)
150153
self.assertFalse(dataset.exists())
151154
dataset.create()
152155
self.to_delete.append(dataset)
@@ -166,7 +169,7 @@ def test_patch_table(self):
166169
self.assertEqual(table.description, 'Description')
167170

168171
def test_update_table(self):
169-
dataset = CLIENT.dataset(DATASET_NAME)
172+
dataset = self.client.dataset(DATASET_NAME)
170173
self.assertFalse(dataset.exists())
171174
dataset.create()
172175
self.to_delete.append(dataset)
@@ -204,7 +207,7 @@ def test_load_table_then_dump_table(self):
204207
('Bhettye Rhubble', 27, None),
205208
]
206209
ROW_IDS = range(len(ROWS))
207-
dataset = CLIENT.dataset(DATASET_NAME)
210+
dataset = self.client.dataset(DATASET_NAME)
208211
self.assertFalse(dataset.exists())
209212
dataset.create()
210213
self.to_delete.append(dataset)
@@ -271,7 +274,7 @@ def test_load_table_from_storage_then_dump_table(self):
271274

272275
self.to_delete.insert(0, blob)
273276

274-
dataset = CLIENT.dataset(DATASET_NAME)
277+
dataset = self.client.dataset(DATASET_NAME)
275278
dataset.create()
276279
self.to_delete.append(dataset)
277280

@@ -282,7 +285,7 @@ def test_load_table_from_storage_then_dump_table(self):
282285
table.create()
283286
self.to_delete.insert(0, table)
284287

285-
job = CLIENT.load_table_from_storage(
288+
job = self.client.load_table_from_storage(
286289
'bq_load_storage_test_%d' % (TIMESTAMP,), table, GS_URL)
287290
job.create_disposition = 'CREATE_NEVER'
288291
job.skip_leading_rows = 1

system_tests/datastore.py

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,18 @@
2525
from system_tests import populate_datastore
2626

2727

28-
client.DATASET = TESTS_DATASET
29-
CLIENT = datastore.Client()
28+
class Config(object):
29+
"""Run-time configuration to be modified at set-up.
30+
31+
This is a mutable stand-in to allow test set-up to modify
32+
global state.
33+
"""
34+
CLIENT = None
35+
36+
37+
def setUpModule():
38+
client.DATASET = TESTS_DATASET
39+
Config.CLIENT = datastore.Client()
3040

3141

3242
class TestDatastore(unittest2.TestCase):
@@ -35,16 +45,17 @@ def setUp(self):
3545
self.case_entities_to_delete = []
3646

3747
def tearDown(self):
38-
with CLIENT.transaction():
48+
with Config.CLIENT.transaction():
3949
keys = [entity.key for entity in self.case_entities_to_delete]
40-
CLIENT.delete_multi(keys)
50+
Config.CLIENT.delete_multi(keys)
4151

4252

4353
class TestDatastoreAllocateIDs(TestDatastore):
4454

4555
def test_allocate_ids(self):
4656
num_ids = 10
47-
allocated_keys = CLIENT.allocate_ids(CLIENT.key('Kind'), num_ids)
57+
allocated_keys = Config.CLIENT.allocate_ids(
58+
Config.CLIENT.key('Kind'), num_ids)
4859
self.assertEqual(len(allocated_keys), num_ids)
4960

5061
unique_ids = set()
@@ -58,7 +69,10 @@ def test_allocate_ids(self):
5869

5970
class TestDatastoreSave(TestDatastore):
6071

61-
PARENT = CLIENT.key('Blog', 'PizzaMan')
72+
@classmethod
73+
def setUpClass(cls):
74+
super(TestDatastoreSave, cls).setUpClass()
75+
cls.PARENT = Config.CLIENT.key('Blog', 'PizzaMan')
6276

6377
def _get_post(self, id_or_name=None, post_content=None):
6478
post_content = post_content or {
@@ -73,7 +87,7 @@ def _get_post(self, id_or_name=None, post_content=None):
7387
# Create an entity with the given content.
7488
# NOTE: Using a parent to ensure consistency for query
7589
# in `test_empty_kind`.
76-
key = CLIENT.key('Post', parent=self.PARENT)
90+
key = Config.CLIENT.key('Post', parent=self.PARENT)
7791
entity = datastore.Entity(key=key)
7892
entity.update(post_content)
7993

@@ -85,7 +99,7 @@ def _get_post(self, id_or_name=None, post_content=None):
8599

86100
def _generic_test_post(self, name=None, key_id=None):
87101
entity = self._get_post(id_or_name=(name or key_id))
88-
CLIENT.put(entity)
102+
Config.CLIENT.put(entity)
89103

90104
# Register entity to be deleted.
91105
self.case_entities_to_delete.append(entity)
@@ -94,7 +108,7 @@ def _generic_test_post(self, name=None, key_id=None):
94108
self.assertEqual(entity.key.name, name)
95109
if key_id is not None:
96110
self.assertEqual(entity.key.id, key_id)
97-
retrieved_entity = CLIENT.get(entity.key)
111+
retrieved_entity = Config.CLIENT.get(entity.key)
98112
# Check the given and retrieved are the the same.
99113
self.assertEqual(retrieved_entity, entity)
100114

@@ -108,7 +122,7 @@ def test_post_with_generated_id(self):
108122
self._generic_test_post()
109123

110124
def test_save_multiple(self):
111-
with CLIENT.transaction() as xact:
125+
with Config.CLIENT.transaction() as xact:
112126
entity1 = self._get_post()
113127
xact.put(entity1)
114128
# Register entity to be deleted.
@@ -129,11 +143,11 @@ def test_save_multiple(self):
129143
self.case_entities_to_delete.append(entity2)
130144

131145
keys = [entity1.key, entity2.key]
132-
matches = CLIENT.get_multi(keys)
146+
matches = Config.CLIENT.get_multi(keys)
133147
self.assertEqual(len(matches), 2)
134148

135149
def test_empty_kind(self):
136-
query = CLIENT.query(kind='Post')
150+
query = Config.CLIENT.query(kind='Post')
137151
query.ancestor = self.PARENT
138152
posts = list(query.fetch(limit=2))
139153
self.assertEqual(posts, [])
@@ -142,16 +156,16 @@ def test_empty_kind(self):
142156
class TestDatastoreSaveKeys(TestDatastore):
143157

144158
def test_save_key_self_reference(self):
145-
parent_key = CLIENT.key('Residence', 'NewYork')
146-
key = CLIENT.key('Person', 'name', parent=parent_key)
159+
parent_key = Config.CLIENT.key('Residence', 'NewYork')
160+
key = Config.CLIENT.key('Person', 'name', parent=parent_key)
147161
entity = datastore.Entity(key=key)
148162
entity['fullName'] = u'Full name'
149163
entity['linkedTo'] = key # Self reference.
150164

151-
CLIENT.put(entity)
165+
Config.CLIENT.put(entity)
152166
self.case_entities_to_delete.append(entity)
153167

154-
query = CLIENT.query(kind='Person')
168+
query = Config.CLIENT.query(kind='Person')
155169
# Adding ancestor to ensure consistency.
156170
query.ancestor = parent_key
157171
query.add_filter('linkedTo', '=', key)
@@ -166,10 +180,11 @@ class TestDatastoreQuery(TestDatastore):
166180
def setUpClass(cls):
167181
super(TestDatastoreQuery, cls).setUpClass()
168182
cls.CHARACTERS = populate_datastore.CHARACTERS
169-
cls.ANCESTOR_KEY = CLIENT.key(*populate_datastore.ANCESTOR)
183+
cls.ANCESTOR_KEY = Config.CLIENT.key(*populate_datastore.ANCESTOR)
170184

171185
def _base_query(self):
172-
return CLIENT.query(kind='Character', ancestor=self.ANCESTOR_KEY)
186+
return Config.CLIENT.query(kind='Character',
187+
ancestor=self.ANCESTOR_KEY)
173188

174189
def test_limit_queries(self):
175190
limit = 5
@@ -214,7 +229,7 @@ def test_ancestor_query(self):
214229
self.assertEqual(len(entities), expected_matches)
215230

216231
def test_query___key___filter(self):
217-
rickard_key = CLIENT.key(*populate_datastore.RICKARD)
232+
rickard_key = Config.CLIENT.key(*populate_datastore.RICKARD)
218233

219234
query = self._base_query()
220235
query.add_filter('__key__', '=', rickard_key)
@@ -329,26 +344,26 @@ def test_query_group_by(self):
329344
class TestDatastoreTransaction(TestDatastore):
330345

331346
def test_transaction(self):
332-
entity = datastore.Entity(key=CLIENT.key('Company', 'Google'))
347+
entity = datastore.Entity(key=Config.CLIENT.key('Company', 'Google'))
333348
entity['url'] = u'www.google.com'
334349

335-
with CLIENT.transaction() as xact:
336-
result = CLIENT.get(entity.key)
350+
with Config.CLIENT.transaction() as xact:
351+
result = Config.CLIENT.get(entity.key)
337352
if result is None:
338353
xact.put(entity)
339354
self.case_entities_to_delete.append(entity)
340355

341356
# This will always return after the transaction.
342-
retrieved_entity = CLIENT.get(entity.key)
357+
retrieved_entity = Config.CLIENT.get(entity.key)
343358
self.case_entities_to_delete.append(retrieved_entity)
344359
self.assertEqual(retrieved_entity, entity)
345360

346361
def test_failure_with_contention(self):
347362
contention_key = 'baz'
348363
# Fool the Client constructor to avoid creating a new connection.
349-
local_client = datastore.Client(dataset_id=CLIENT.dataset_id,
364+
local_client = datastore.Client(dataset_id=Config.CLIENT.dataset_id,
350365
http=object())
351-
local_client.connection = CLIENT.connection
366+
local_client.connection = Config.CLIENT.connection
352367

353368
# Insert an entity which will be retrieved in a transaction
354369
# and updated outside it with a contentious value.
@@ -364,7 +379,7 @@ def test_failure_with_contention(self):
364379

365380
# Update the original entity outside the transaction.
366381
orig_entity[contention_key] = u'outside'
367-
CLIENT.put(orig_entity)
382+
Config.CLIENT.put(orig_entity)
368383

369384
# Try to update the entity which we already updated outside the
370385
# transaction.

system_tests/populate_datastore.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
from gcloud.environment_vars import TESTS_DATASET
2222

2323

24-
client.DATASET = TESTS_DATASET
25-
CLIENT = datastore.Client()
26-
27-
2824
ANCESTOR = ('Book', 'GoT')
2925
RICKARD = ANCESTOR + ('Character', 'Rickard')
3026
EDDARD = RICKARD + ('Character', 'Eddard')
@@ -84,12 +80,15 @@
8480

8581

8682
def add_characters():
87-
with CLIENT.transaction() as xact:
83+
# Update the environment variable used.
84+
client.DATASET = TESTS_DATASET
85+
datastore_client = datastore.Client()
86+
with datastore_client.transaction() as xact:
8887
for key_path, character in zip(KEY_PATHS, CHARACTERS):
8988
if key_path[-1] != character['name']:
9089
raise ValueError(('Character and key don\'t agree',
9190
key_path, character))
92-
entity = datastore.Entity(key=CLIENT.key(*key_path))
91+
entity = datastore.Entity(key=datastore_client.key(*key_path))
9392
entity.update(character)
9493
xact.put(entity)
9594
print('Adding Character %s %s' % (character['name'],

0 commit comments

Comments
 (0)