[Zope3-checkins] CVS: Zope3/src/transaction/tests -
test_SampleDataManager.py:1.1.2.1
Fred L. Drake, Jr.
fred at zope.com
Thu Jan 22 11:32:21 EST 2004
Update of /cvs-repository/Zope3/src/transaction/tests
In directory cvs.zope.org:/tmp/cvs-serv31071/src/transaction/tests
Added Files:
Tag: zope3-zodb3-devel-branch
test_SampleDataManager.py
Log Message:
checking in so jim can edit
=== Added File Zope3/src/transaction/tests/test_SampleDataManager.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Sample objects for use in tests
$Id: test_SampleDataManager.py,v 1.1.2.1 2004/01/22 16:32:20 fdrake Exp $
"""
class DataManager(object):
"""Sample data manager
This class provides a trivial data-manager implementation and doc
strings to illustrate the the protocol and to provide a tool for
writing tests.
Our sample data manager has state that is updated through an inc
method and through transaction operations.
When we create a sample data manager:
>>> dm = DataManager()
It has two bits of state, state:
>>> dm.state
0
and delta:
>>> dm.delta
0
Both of which are initialized to 0. state is meant to model
committed state, while delta represents tentative changes within a
transaction. We change the state by calling inc:
>>> dm.inc()
which updates delta:
>>> dm.delta
1
but state isn't changed until we commit the transaction:
>>> dm.state
0
To commit the changes, we use 2-phase commit. We execute the first
stage by calling prepare. We need to pass a transation. Our
sample data managers don't really use the transactions for much,
so we'll be lazy and use integers for transactions:
>>> t1 = 1
>>> dm.prepare(t1)
The sample data manager updates the state when we call prepare:
>>> dm.state
1
>>> dm.delta
1
This is mainly so we can detect some affect of calling the methods.
Now if we call commit:
>>> dm.commit(t1)
Our changes are"permanent". The state reflects the changes and the
delta has been reset to 0.
>>> dm.state
1
>>> dm.delta
0
"""
def __init__(self):
self.state = 0
self.sp = 0
self.transaction = None
self.delta = 0
self.prepared = False
def inc(self, n=1):
self.delta += n
def prepare(self, transaction):
"""Prepare to commit data
>>> dm = DataManager()
>>> dm.inc()
>>> dm.prepare(1)
>>> dm.commit(1)
>>> dm.state
1
>>> dm.inc()
>>> dm.prepare(2)
>>> dm.abort(2)
>>> dm.state
1
It is en error to call prepare more than once without an intervening
commit or abort:
>>> dm.prepare(1)
Traceback (most recent call last):
TypeError: Already prepared
>>> dm.prepare(1)
>>> dm.prepare(2)
>>> dm.abort(1)
If there was a preceeding savepoint, the transaction must match:
>>> rollback = dm.savepoint(1)
>>> rollback.prepare(2)
>>> rollback.prepare(1)
"""
if self.prepared:
raise TypeError('Already prepared')
self._checkTransaction(transaction)
self.prepared = True
self.transaction = transaction
self.state += self.delta
def _checkTransaction(self, transaction):
if (transaction is not self.transaction
and self.transaction is not None):
raise TypeError("Transaction missmatch",
transaction, self.transaction)
def abort(self, transaction):
"""Abort a transaction
"""
self._checkTransaction(transaction)
if self.transaction is not None:
self.state -= self.delta
self.transaction = None
self.delta = 0
self.prepared = False
def commit(self, transaction):
if not self.prepared:
raise TypeError('Not prepared to commit')
self._checkTransaction(transaction)
self.delta = 0
self.transaction = None
self.prepared = False
def savepoint(self, transaction):
if self.prepared:
raise TypeError("Can't get savepoint during two-phase commit")
self._checkTransaction(transaction)
self.transaction = transaction
self.sp += 1
return Rollback(self)
class Rollback(object):
def __init__(self, dm):
self.dm = dm
self.sp = dm.sp
self.state = dm.state
self.transaction = dm.transaction
def rollback(self):
if self.transaction is not self.sp.transaction:
raise TypeError("Attempt to rollback stale rollback")
if self.dm.sp < self.sp:
raise TypeError("Attempt to roll back to invalid save point",
self.sp, self.dm.sp)
self.dm.sp = self.sp
self.dm.state = self.state
self.dm.delta = 0
def test_suite():
import unittest
from doctest import DocTestSuite
return unittest.TestSuite((
DocTestSuite(),
))
if __name__ == '__main__': unittest.main()
More information about the Zope3-Checkins
mailing list