Skip to content

Commit 221c094

Browse files
authored
tests: refactor systests to use pytest fixtures / idioms (#210)
Use pytest fixtures / idioms, rather than legacy setup / teardown. Also, remove fossilized doctest setup code: Closes #208.
1 parent 4620481 commit 221c094

File tree

11 files changed

+759
-720
lines changed

11 files changed

+759
-720
lines changed

packages/google-cloud-datastore/google/cloud/datastore/client.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -784,28 +784,6 @@ def do_something(entity):
784784
785785
or manually page through results
786786
787-
.. testsetup:: query-page
788-
789-
import os
790-
import uuid
791-
792-
from google.cloud import datastore
793-
from tests.system.test_system import Config # system tests
794-
795-
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
796-
client = datastore.Client(namespace='ns{}'.format(unique))
797-
798-
key = client.key('_Doctest')
799-
entity1 = datastore.Entity(key=key)
800-
entity1['foo'] = 1337
801-
entity2 = datastore.Entity(key=key)
802-
entity2['foo'] = 42
803-
Config.TO_DELETE.extend([entity1, entity2])
804-
client.put_multi([entity1, entity2])
805-
806-
query = client.query(kind='_Doctest')
807-
cursor = None
808-
809787
.. doctest:: query-page
810788
811789
>>> query_iter = query.fetch(start_cursor=cursor)

packages/google-cloud-datastore/google/cloud/datastore/entity.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,6 @@ class Entity(dict):
4040
Use :meth:`~google.cloud.datastore.client.Client.get` to retrieve an
4141
existing entity:
4242
43-
.. testsetup:: entity-ctor
44-
45-
import os
46-
import uuid
47-
48-
from google.cloud import datastore
49-
from tests.system.test_system import Config # system tests
50-
51-
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
52-
client = datastore.Client(namespace='ns{}'.format(unique))
53-
key = client.key('EntityKind', 1234, namespace='_Doctest')
54-
entity = datastore.Entity(key=key)
55-
entity['property'] = 'value'
56-
Config.TO_DELETE.append(entity)
57-
58-
client.put(entity)
59-
6043
.. doctest:: entity-ctor
6144
6245
>>> client.get(key)

packages/google-cloud-datastore/google/cloud/datastore/transaction.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -41,26 +41,6 @@ class Transaction(Batch):
4141
operations (either ``insert`` or ``upsert``) into the same
4242
mutation, and execute those within a transaction:
4343
44-
.. testsetup:: txn-put-multi, txn-api
45-
46-
import os
47-
import uuid
48-
49-
from google.cloud import datastore
50-
from tests.system.test_system import Config # system tests
51-
52-
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
53-
client = datastore.Client(namespace='ns{}'.format(unique))
54-
key1 = client.key('_Doctest')
55-
entity1 = datastore.Entity(key=key1)
56-
entity1['foo'] = 1337
57-
58-
key2 = client.key('_Doctest', 'abcd1234')
59-
entity2 = datastore.Entity(key=key2)
60-
entity2['foo'] = 42
61-
62-
Config.TO_DELETE.extend([entity1, entity2])
63-
6444
.. doctest:: txn-put-multi
6545
6646
>>> with client.transaction():
@@ -112,22 +92,6 @@ class SomeException(Exception):
11292
entities will not be available at save time! That means, if you
11393
try:
11494
115-
.. testsetup:: txn-entity-key, txn-entity-key-after, txn-manual
116-
117-
import os
118-
import uuid
119-
120-
from google.cloud import datastore
121-
from tests.system.test_system import Config # system tests
122-
123-
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
124-
client = datastore.Client(namespace='ns{}'.format(unique))
125-
126-
def Entity(*args, **kwargs):
127-
entity = datastore.Entity(*args, **kwargs)
128-
Config.TO_DELETE.append(entity)
129-
return entity
130-
13195
.. doctest:: txn-entity-key
13296
13397
>>> with client.transaction():
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2021 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+
17+
from google.cloud import datastore
18+
from google.cloud.datastore.client import DATASTORE_DATASET
19+
from test_utils.system import unique_resource_id
20+
21+
EMULATOR_DATASET = os.getenv(DATASTORE_DATASET)
22+
23+
24+
def unique_id(prefix, separator="-"):
25+
return f"{prefix}{unique_resource_id(separator)}"
26+
27+
28+
_SENTINEL = object()
29+
30+
31+
def clone_client(base_client, namespace=_SENTINEL):
32+
if namespace is _SENTINEL:
33+
namespace = base_client.namespace
34+
35+
kwargs = {}
36+
if EMULATOR_DATASET is None:
37+
kwargs["credentials"] = base_client._credentials
38+
39+
return datastore.Client(
40+
project=base_client.project,
41+
namespace=namespace,
42+
_http=base_client._http,
43+
**kwargs,
44+
)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2021 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 pytest
16+
import requests
17+
18+
from google.cloud import datastore
19+
from . import _helpers
20+
21+
22+
@pytest.fixture(scope="session")
23+
def in_emulator():
24+
return _helpers.EMULATOR_DATASET is not None
25+
26+
27+
@pytest.fixture(scope="session")
28+
def test_namespace():
29+
return _helpers.unique_id("ns")
30+
31+
32+
@pytest.fixture(scope="session")
33+
def datastore_client(test_namespace):
34+
if _helpers.EMULATOR_DATASET is not None:
35+
http = requests.Session() # Un-authorized.
36+
return datastore.Client(
37+
project=_helpers.EMULATOR_DATASET, namespace=test_namespace, _http=http,
38+
)
39+
else:
40+
return datastore.Client(namespace=test_namespace)
41+
42+
43+
@pytest.fixture(scope="function")
44+
def entities_to_delete(datastore_client):
45+
entities_to_delete = []
46+
47+
yield entities_to_delete
48+
49+
with datastore_client.transaction():
50+
datastore_client.delete_multi(entities_to_delete)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2011 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 warnings
16+
17+
18+
def test_client_allocate_ids(datastore_client):
19+
num_ids = 10
20+
allocated_keys = datastore_client.allocate_ids(
21+
datastore_client.key("Kind"), num_ids,
22+
)
23+
assert len(allocated_keys) == num_ids
24+
25+
unique_ids = set()
26+
for key in allocated_keys:
27+
unique_ids.add(key.id)
28+
assert key.name is None
29+
assert key.id is not None
30+
31+
assert len(unique_ids) == num_ids
32+
33+
34+
def test_client_reserve_ids_sequential(datastore_client):
35+
num_ids = 10
36+
key = datastore_client.key("Kind", 1234)
37+
38+
# Smoke test to make sure it doesn't blow up. No return value or
39+
# verifiable side effect to verify.
40+
datastore_client.reserve_ids_sequential(key, num_ids)
41+
42+
43+
def test_client_reserve_ids_deprecated(datastore_client):
44+
num_ids = 10
45+
key = datastore_client.key("Kind", 1234)
46+
47+
with warnings.catch_warnings(record=True) as warned:
48+
datastore_client.reserve_ids(key, num_ids)
49+
50+
assert len(warned) == 1
51+
assert warned[0].category is DeprecationWarning
52+
assert "reserve_ids_sequential" in str(warned[0].message)
53+
54+
55+
def test_client_reserve_ids_multi(datastore_client):
56+
key1 = datastore_client.key("Kind", 1234)
57+
key2 = datastore_client.key("Kind", 1235)
58+
59+
# Smoke test to make sure it doesn't blow up. No return value or
60+
# verifiable side effect to verify.
61+
datastore_client.reserve_ids_multi([key1, key2])

0 commit comments

Comments
 (0)