Vehicle-Anti-Theft-Face-Rec.../venv/Lib/site-packages/gcloud/datastore/test_transaction.py

223 lines
7.5 KiB
Python

# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest2
class TestTransaction(unittest2.TestCase):
def _getTargetClass(self):
from gcloud.datastore.transaction import Transaction
return Transaction
def _makeOne(self, client, **kw):
return self._getTargetClass()(client, **kw)
def test_ctor_defaults(self):
from gcloud.datastore._generated import datastore_pb2
_PROJECT = 'PROJECT'
connection = _Connection()
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
self.assertEqual(xact.project, _PROJECT)
self.assertEqual(xact.connection, connection)
self.assertEqual(xact.id, None)
self.assertEqual(xact._status, self._getTargetClass()._INITIAL)
self.assertTrue(isinstance(xact._commit_request,
datastore_pb2.CommitRequest))
self.assertTrue(xact.mutations is xact._commit_request.mutations)
self.assertEqual(len(xact._partial_key_entities), 0)
def test_current(self):
from gcloud.datastore.test_client import _NoCommitBatch
_PROJECT = 'PROJECT'
connection = _Connection()
client = _Client(_PROJECT, connection)
xact1 = self._makeOne(client)
xact2 = self._makeOne(client)
self.assertTrue(xact1.current() is None)
self.assertTrue(xact2.current() is None)
with xact1:
self.assertTrue(xact1.current() is xact1)
self.assertTrue(xact2.current() is xact1)
with _NoCommitBatch(client):
self.assertTrue(xact1.current() is None)
self.assertTrue(xact2.current() is None)
with xact2:
self.assertTrue(xact1.current() is xact2)
self.assertTrue(xact2.current() is xact2)
with _NoCommitBatch(client):
self.assertTrue(xact1.current() is None)
self.assertTrue(xact2.current() is None)
self.assertTrue(xact1.current() is xact1)
self.assertTrue(xact2.current() is xact1)
self.assertTrue(xact1.current() is None)
self.assertTrue(xact2.current() is None)
def test_begin(self):
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact.begin()
self.assertEqual(xact.id, 234)
self.assertEqual(connection._begun, _PROJECT)
def test_begin_tombstoned(self):
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact.begin()
self.assertEqual(xact.id, 234)
self.assertEqual(connection._begun, _PROJECT)
xact.rollback()
self.assertEqual(xact.id, None)
self.assertRaises(ValueError, xact.begin)
def test_rollback(self):
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact.begin()
xact.rollback()
self.assertEqual(xact.id, None)
self.assertEqual(connection._rolled_back, (_PROJECT, 234))
def test_commit_no_partial_keys(self):
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact._commit_request = commit_request = object()
xact.begin()
xact.commit()
self.assertEqual(connection._committed,
(_PROJECT, commit_request, 234))
self.assertEqual(xact.id, None)
def test_commit_w_partial_keys(self):
_PROJECT = 'PROJECT'
_KIND = 'KIND'
_ID = 123
connection = _Connection(234)
connection._completed_keys = [_make_key(_KIND, _ID, _PROJECT)]
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
entity = _Entity()
xact.put(entity)
xact._commit_request = commit_request = object()
xact.begin()
xact.commit()
self.assertEqual(connection._committed,
(_PROJECT, commit_request, 234))
self.assertEqual(xact.id, None)
self.assertEqual(entity.key.path, [{'kind': _KIND, 'id': _ID}])
def test_context_manager_no_raise(self):
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact._commit_request = commit_request = object()
with xact:
self.assertEqual(xact.id, 234)
self.assertEqual(connection._begun, _PROJECT)
self.assertEqual(connection._committed,
(_PROJECT, commit_request, 234))
self.assertEqual(xact.id, None)
def test_context_manager_w_raise(self):
class Foo(Exception):
pass
_PROJECT = 'PROJECT'
connection = _Connection(234)
client = _Client(_PROJECT, connection)
xact = self._makeOne(client)
xact._mutation = object()
try:
with xact:
self.assertEqual(xact.id, 234)
self.assertEqual(connection._begun, _PROJECT)
raise Foo()
except Foo:
self.assertEqual(xact.id, None)
self.assertEqual(connection._rolled_back, (_PROJECT, 234))
self.assertEqual(connection._committed, None)
self.assertEqual(xact.id, None)
def _make_key(kind, id_, project):
from gcloud.datastore._generated import entity_pb2
key = entity_pb2.Key()
key.partition_id.project_id = project
elem = key.path.add()
elem.kind = kind
elem.id = id_
return key
class _Connection(object):
_marker = object()
_begun = _rolled_back = _committed = None
def __init__(self, xact_id=123):
self._xact_id = xact_id
self._completed_keys = []
self._index_updates = 0
def begin_transaction(self, project):
self._begun = project
return self._xact_id
def rollback(self, project, transaction_id):
self._rolled_back = project, transaction_id
def commit(self, project, commit_request, transaction_id):
self._committed = (project, commit_request, transaction_id)
return self._index_updates, self._completed_keys
class _Entity(dict):
def __init__(self):
super(_Entity, self).__init__()
from gcloud.datastore.key import Key
self.key = Key('KIND', project='PROJECT')
class _Client(object):
def __init__(self, project, connection, namespace=None):
self.project = project
self.connection = connection
self.namespace = namespace
self._batches = []
def _push_batch(self, batch):
self._batches.insert(0, batch)
def _pop_batch(self):
return self._batches.pop(0)
@property
def current_batch(self):
return self._batches and self._batches[0] or None