Skip to content

Commit d04da8a

Browse files
committed
Adding system test for datastore failed transactions.
This intentionally forces data contention in a transaction (by updating the entity outside of the transaction). This is to prevent regressions like #903.
1 parent 6a47028 commit d04da8a

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

system_tests/datastore.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from gcloud import datastore
2020
from gcloud.datastore import client
2121
from gcloud.environment_vars import TESTS_DATASET
22+
from gcloud.exceptions import Conflict
2223
# This assumes the command is being run via tox hence the
2324
# repository root is the current directory.
2425
from system_tests import populate_datastore
@@ -341,3 +342,31 @@ def test_transaction(self):
341342
retrieved_entity = CLIENT.get(entity.key)
342343
self.case_entities_to_delete.append(retrieved_entity)
343344
self.assertEqual(retrieved_entity, entity)
345+
346+
def test_failure_with_contention(self):
347+
contention_key = 'baz'
348+
# Fool the Client constructor to avoid creating a new connection.
349+
local_client = datastore.Client(dataset_id=CLIENT.dataset_id,
350+
http=object())
351+
local_client.connection = CLIENT.connection
352+
353+
# Insert an entity which will be retrieved in a transaction
354+
# and updated outside it with a contentious value.
355+
key = local_client.key('BreakTxn', 1234)
356+
orig_entity = datastore.Entity(key=key)
357+
orig_entity['foo'] = u'bar'
358+
local_client.put(orig_entity)
359+
self.case_entities_to_delete.append(orig_entity)
360+
361+
with self.assertRaises(Conflict):
362+
with local_client.transaction() as txn:
363+
entity_in_txn = local_client.get(key)
364+
365+
# Update the original entity outside the transaction.
366+
orig_entity[contention_key] = u'outside'
367+
CLIENT.put(orig_entity)
368+
369+
# Try to update the entity which we already updated outside the
370+
# transaction.
371+
entity_in_txn[contention_key] = u'inside'
372+
txn.put(entity_in_txn)

0 commit comments

Comments
 (0)