Commit 026c3746 authored by Jeremy Hylton's avatar Jeremy Hylton

Rename transactionalUndo() to undo().

The old undo was not used by Zope and shouldn't have been used by any
other client.  The newly named undo() is the preferred version of
undo.

XXX DemoStorage didn't implement transactionalUndo, so now it doesn't
implementation undo() at all.  We need to replace it with the demo
storage from ZODB4.

There are a few changes related to ZODB4 removal in this checkin.
parent ce3f3048
...@@ -994,7 +994,7 @@ class ClientStorage(object): ...@@ -994,7 +994,7 @@ class ClientStorage(object):
self._cache.store(oid, version, s, None, data) self._cache.store(oid, version, s, None, data)
self._tbuf.clear() self._tbuf.clear()
def transactionalUndo(self, trans_id, txn): def undo(self, trans_id, txn):
"""Storage API: undo a transaction. """Storage API: undo a transaction.
This is executed in a transactional context. It has no effect This is executed in a transactional context. It has no effect
...@@ -1004,7 +1004,7 @@ class ClientStorage(object): ...@@ -1004,7 +1004,7 @@ class ClientStorage(object):
a storage. a storage.
""" """
self._check_trans(txn) self._check_trans(txn)
tid, oids = self._server.transactionalUndo(trans_id, id(txn)) tid, oids = self._server.undo(trans_id, id(txn))
for oid in oids: for oid in oids:
self._tbuf.invalidate(oid, '') self._tbuf.invalidate(oid, '')
return tid, oids return tid, oids
......
...@@ -268,11 +268,8 @@ class StorageServer: ...@@ -268,11 +268,8 @@ class StorageServer:
def store(self, oid, serial, data, version, trans): def store(self, oid, serial, data, version, trans):
return self.rpc.call('store', oid, serial, data, version, trans) return self.rpc.call('store', oid, serial, data, version, trans)
def transactionalUndo(self, trans_id, trans): def undo(self, trans_id, trans):
return self.rpc.call('transactionalUndo', trans_id, trans) return self.rpc.call('undo', trans_id, trans)
def undo(self, trans_id):
return self.rpc.call('undo', trans_id)
def undoLog(self, first, last): def undoLog(self, first, last):
return self.rpc.call('undoLog', first, last) return self.rpc.call('undoLog', first, last)
......
...@@ -222,8 +222,6 @@ class ZEOStorage: ...@@ -222,8 +222,6 @@ class ZEOStorage:
'name': self.storage.getName(), 'name': self.storage.getName(),
'supportsUndo': self.storage.supportsUndo(), 'supportsUndo': self.storage.supportsUndo(),
'supportsVersions': self.storage.supportsVersions(), 'supportsVersions': self.storage.supportsVersions(),
'supportsTransactionalUndo':
self.storage.supportsTransactionalUndo(),
'extensionMethods': self.getExtensionMethods(), 'extensionMethods': self.getExtensionMethods(),
} }
...@@ -348,16 +346,6 @@ class ZEOStorage: ...@@ -348,16 +346,6 @@ class ZEOStorage:
n = 1 n = 1
return [self.storage.new_oid() for i in range(n)] return [self.storage.new_oid() for i in range(n)]
def undo(self, transaction_id):
if self.read_only:
raise ReadOnlyError()
oids = self.storage.undo(transaction_id)
if oids:
self.server.invalidate(self, self.storage_id, None,
map(lambda oid: (oid, ''), oids))
return oids
return ()
# undoLog and undoInfo are potentially slow methods # undoLog and undoInfo are potentially slow methods
def undoInfo(self, first, last, spec): def undoInfo(self, first, last, spec):
...@@ -480,12 +468,12 @@ class ZEOStorage: ...@@ -480,12 +468,12 @@ class ZEOStorage:
else: else:
return self._wait(lambda: self._commitVersion(src, dest)) return self._wait(lambda: self._commitVersion(src, dest))
def transactionalUndo(self, trans_id, id): def undo(self, trans_id, id):
self._check_tid(id, exc=StorageTransactionError) self._check_tid(id, exc=StorageTransactionError)
if self.locked: if self.locked:
return self._transactionalUndo(trans_id) return self._undo(trans_id)
else: else:
return self._wait(lambda: self._transactionalUndo(trans_id)) return self._wait(lambda: self._undo(trans_id))
def _tpc_begin(self, txn, tid, status): def _tpc_begin(self, txn, tid, status):
self.locked = 1 self.locked = 1
...@@ -557,8 +545,8 @@ class ZEOStorage: ...@@ -557,8 +545,8 @@ class ZEOStorage:
self.invalidated.extend(inv) self.invalidated.extend(inv)
return tid, oids return tid, oids
def _transactionalUndo(self, trans_id): def _undo(self, trans_id):
tid, oids = self.storage.transactionalUndo(trans_id, self.transaction) tid, oids = self.storage.undo(trans_id, self.transaction)
inv = [(oid, None) for oid in oids] inv = [(oid, None) for oid in oids]
self.invalidated.extend(inv) self.invalidated.extend(inv)
return tid, oids return tid, oids
......
...@@ -130,13 +130,6 @@ test_classes = [FileStorageConnectionTests, ...@@ -130,13 +130,6 @@ test_classes = [FileStorageConnectionTests,
MappingStorageConnectionTests, MappingStorageConnectionTests,
MappingStorageTimeoutTests] MappingStorageTimeoutTests]
import BDBStorage
if BDBStorage.is_available:
test_classes += [BDBConnectionTests,
BDBReconnectionTests,
BDBInvqTests,
BDBTimeoutTests]
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
for klass in test_classes: for klass in test_classes:
......
...@@ -209,11 +209,6 @@ class MappingStorageTests(GenericTests): ...@@ -209,11 +209,6 @@ class MappingStorageTests(GenericTests):
test_classes = [FileStorageTests, MappingStorageTests] test_classes = [FileStorageTests, MappingStorageTests]
import BDBStorage
if BDBStorage.is_available:
test_classes.append(BDBTests)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
for klass in test_classes: for klass in test_classes:
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
############################################################################## ##############################################################################
"""Handy standard storage machinery """Handy standard storage machinery
$Id: BaseStorage.py,v 1.40 2004/01/06 21:43:04 jeremy Exp $ $Id: BaseStorage.py,v 1.41 2004/02/18 01:13:01 jeremy Exp $
""" """
import cPickle import cPickle
import threading import threading
...@@ -120,9 +120,6 @@ class BaseStorage(UndoLogCompatible): ...@@ -120,9 +120,6 @@ class BaseStorage(UndoLogCompatible):
def supportsUndo(self): def supportsUndo(self):
return 0 return 0
def supportsTransactionalUndo(self):
return 0
def supportsVersions(self): def supportsVersions(self):
return 0 return 0
...@@ -221,7 +218,7 @@ class BaseStorage(UndoLogCompatible): ...@@ -221,7 +218,7 @@ class BaseStorage(UndoLogCompatible):
""" """
pass pass
def undo(self, transaction_id): def undo(self, transaction_id, txn):
if self._is_read_only: if self._is_read_only:
raise POSException.ReadOnlyError() raise POSException.ReadOnlyError()
raise POSException.UndoError, 'non-undoable transaction' raise POSException.UndoError, 'non-undoable transaction'
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
############################################################################## ##############################################################################
"""Database objects """Database objects
$Id: DB.py,v 1.59 2004/01/06 21:44:25 jeremy Exp $""" $Id: DB.py,v 1.60 2004/02/18 01:13:00 jeremy Exp $"""
__version__='$Revision: 1.59 $'[11:-2] __version__='$Revision: 1.60 $'[11:-2]
import cPickle, cStringIO, sys, POSException, UndoLogCompatible import cPickle, cStringIO, sys, POSException, UndoLogCompatible
from Connection import Connection from Connection import Connection
...@@ -574,82 +574,70 @@ class DB(UndoLogCompatible.UndoLogCompatible, object): ...@@ -574,82 +574,70 @@ class DB(UndoLogCompatible.UndoLogCompatible, object):
def cacheStatistics(self): return () # :( def cacheStatistics(self): return () # :(
def undo(self, id, transaction=None): def undo(self, id, transaction=None):
storage=self._storage
try: supportsTransactionalUndo = storage.supportsTransactionalUndo
except AttributeError:
supportsTransactionalUndo=0
else:
supportsTransactionalUndo=supportsTransactionalUndo()
if supportsTransactionalUndo:
# new style undo
if transaction is None: if transaction is None:
transaction = get_transaction() transaction = get_transaction()
transaction.register(TransactionalUndo(self, id)) transaction.register(TransactionalUndo(self, id))
else:
# fall back to old undo
d = {}
for oid in storage.undo(id):
d[oid] = 1
# XXX I think we need to remove old undo to use mvcc
self.invalidate(None, d)
def versionEmpty(self, version): def versionEmpty(self, version):
return self._storage.versionEmpty(version) return self._storage.versionEmpty(version)
class CommitVersion: class ResourceManager(object):
"""An object that will see to version commit """Transaction participation for a version or undo resource."""
in cooperation with a transaction manager. def __init__(self, db):
""" self._db = db
def __init__(self, db, version, dest=''): # Delegate the actual 2PC methods to the storage
self._db=db self.tpc_begin = self._db._storage.tpc_begin
s=db._storage self.tpc_vote = self._db._storage.tpc_vote
self._version=version self.tpc_finish = self._db._storage.tpc_finish
self._dest=dest self.tpc_abort = self._db._storage.tpc_abort
self.tpc_abort=s.tpc_abort
self.tpc_begin=s.tpc_begin
self.tpc_vote=s.tpc_vote
self.tpc_finish=s.tpc_finish
self._sortKey=s.sortKey
def sortKey(self): def sortKey(self):
return "%s:%s" % (self._sortKey(), id(self)) return "%s:%s" % (self._db._storage.sortKey(), id(self))
# The object registers itself with the txn manager, so the ob
# argument to the methods below is self.
def abort(self, reallyme, t): pass def abort(self, ob, t):
pass
def commit(self, reallyme, t): def commit(self, ob, t):
pass
class CommitVersion(ResourceManager):
def __init__(self, db, version, dest=''):
super(CommitVersion, self).__init__(db)
self._version = version
self._dest = dest
def commit(self, ob, t):
dest=self._dest dest=self._dest
tid, oids = self._db._storage.commitVersion(self._version, dest, t) tid, oids = self._db._storage.commitVersion(self._version, self._dest,
t)
oids = list2dict(oids) oids = list2dict(oids)
self._db.invalidate(tid, oids, version=dest) self._db.invalidate(tid, oids, version=self._dest)
if dest: if self._dest:
# the code above just invalidated the dest version. # the code above just invalidated the dest version.
# now we need to invalidate the source! # now we need to invalidate the source!
self._db.invalidate(tid, oids, version=self._version) self._db.invalidate(tid, oids, version=self._version)
class AbortVersion(CommitVersion): class AbortVersion(ResourceManager):
"""An object that will see to version abortion
in cooperation with a transaction manager. def __init__(self, db, version):
""" super(AbortVersion, self).__init__(db)
self._version = version
def commit(self, reallyme, t):
version = self._version
tid, oids = self._db._storage.abortVersion(version, t)
self._db.invalidate(tid, list2dict(oids), version=version)
def commit(self, ob, t):
tid, oids = self._db._storage.abortVersion(self._version, t)
self._db.invalidate(tid, list2dict(oids), version=self._version)
class TransactionalUndo(CommitVersion): class TransactionalUndo(ResourceManager):
"""An object that will see to transactional undo
in cooperation with a transaction manager.
"""
# I (Jim) am lazy. I'm reusing __init__ and abort and reusing the def __init__(self, db, tid):
# version attr for the transaction id. There's such a strong super(TransactionalUndo, self).__init__(db)
# similarity of rhythm that I think it's justified. self._tid = tid
def commit(self, reallyme, t): def commit(self, ob, t):
tid, oids = self._db._storage.transactionalUndo(self._version, t) tid, oids = self._db._storage.undo(self._tid, t)
self._db.invalidate(tid, list2dict(oids)) self._db.invalidate(tid, list2dict(oids))
...@@ -79,7 +79,7 @@ method:: ...@@ -79,7 +79,7 @@ method::
and call it to monitor the storage. and call it to monitor the storage.
""" """
__version__='$Revision: 1.23 $'[11:-2] __version__='$Revision: 1.24 $'[11:-2]
import base64, time, string import base64, time, string
from ZODB import POSException, BaseStorage, utils from ZODB import POSException, BaseStorage, utils
...@@ -277,9 +277,6 @@ class DemoStorage(BaseStorage.BaseStorage): ...@@ -277,9 +277,6 @@ class DemoStorage(BaseStorage.BaseStorage):
finally: self._lock_release() finally: self._lock_release()
return self._tid return self._tid
def supportsUndo(self):
return 1
def supportsVersions(self): def supportsVersions(self):
return 1 return 1
...@@ -321,57 +318,6 @@ class DemoStorage(BaseStorage.BaseStorage): ...@@ -321,57 +318,6 @@ class DemoStorage(BaseStorage.BaseStorage):
v[oid] = r v[oid] = r
self._ltid = self._tid self._ltid = self._tid
def undo(self, transaction_id):
self._lock_acquire()
try:
transaction_id=base64.decodestring(transaction_id+'\n')
try: t=self._data[transaction_id][4]
except KeyError:
raise UndoError, 'Invalid undo transaction id'
index=self._index
vindex=self._vindex
vindex_get=self._vindex.get
for r in t:
if index[r[0]] is not r:
raise POSException.UndoError, 'non-undoable transaction'
oids=[]
for r in t:
oid, pre, vdata, p, tid = r
if pre:
index[oid] = pre
oids.append(oid)
# Delete old version data
if vdata:
version=vdata[0]
v=vindex.get(version, None)
if v: del v[oid]
# Add new version data (from pre):
oid, prepre, vdata, p, tid = pre
if vdata:
version=vdata[0]
v=vindex.get(version, None)
if v is None: v=vindex[version]={}
v[oid]=pre
else:
del index[oid]
if vdata:
version=vdata[0]
v=vindex.get(version, None)
if v: del v[oid]
if not v: del vindex[version]
del self._data[transaction_id]
return oids
finally: self._lock_release()
def undoLog(self, first, last, filter=None): def undoLog(self, first, last, filter=None):
if last < 0: if last < 0:
last = first - last + 1 last = first - last + 1
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
############################################################################## ##############################################################################
"""Storage implementation using a log written to a single file. """Storage implementation using a log written to a single file.
$Revision: 1.3 $ $Revision: 1.4 $
""" """
import base64 import base64
...@@ -1076,7 +1076,7 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -1076,7 +1076,7 @@ class FileStorage(BaseStorage.BaseStorage,
finally: finally:
self._lock_release() self._lock_release()
def transactionalUndo(self, transaction_id, transaction): def undo(self, transaction_id, transaction):
"""Undo a transaction, given by transaction_id. """Undo a transaction, given by transaction_id.
Do so by writing new data that reverses the action taken by Do so by writing new data that reverses the action taken by
......
...@@ -162,7 +162,7 @@ class ConflictResolvingTransUndoStorage: ...@@ -162,7 +162,7 @@ class ConflictResolvingTransUndoStorage:
tid = info[1]['id'] tid = info[1]['id']
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
self._storage.transactionalUndo(tid, t) self._storage.undo(tid, t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
def checkUndoUnresolvable(self): def checkUndoUnresolvable(self):
...@@ -183,6 +183,6 @@ class ConflictResolvingTransUndoStorage: ...@@ -183,6 +183,6 @@ class ConflictResolvingTransUndoStorage:
tid = info[1]['id'] tid = info[1]['id']
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
self.assertRaises(UndoError, self._storage.transactionalUndo, self.assertRaises(UndoError, self._storage.undo,
tid, t) tid, t)
self._storage.tpc_abort(t) self._storage.tpc_abort(t)
...@@ -100,7 +100,7 @@ class IteratorStorage(IteratorCompare): ...@@ -100,7 +100,7 @@ class IteratorStorage(IteratorCompare):
# Undo the creation of the object, rendering it a zombie # Undo the creation of the object, rendering it a zombie
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
oids = self._storage.transactionalUndo(tid, t) oids = self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
# Now attempt to iterator over the storage # Now attempt to iterator over the storage
......
...@@ -60,5 +60,5 @@ class ReadOnlyStorage: ...@@ -60,5 +60,5 @@ class ReadOnlyStorage:
'\000' * 8, None, '', '', t) '\000' * 8, None, '', '', t)
if self._storage.supportsTransactionalUndo(): if self._storage.supportsTransactionalUndo():
self.assertRaises(ReadOnlyError, self._storage.transactionalUndo, self.assertRaises(ReadOnlyError, self._storage.undo,
'\000' * 8, t) '\000' * 8, t)
...@@ -209,7 +209,7 @@ class StorageTestBase(unittest.TestCase): ...@@ -209,7 +209,7 @@ class StorageTestBase(unittest.TestCase):
t = Transaction() t = Transaction()
t.note(note or "undo") t.note(note or "undo")
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
tid, oids = self._storage.transactionalUndo(tid, t) tid, oids = self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
if expected_oids is not None: if expected_oids is not None:
......
...@@ -41,7 +41,7 @@ substantially simplified. ...@@ -41,7 +41,7 @@ substantially simplified.
New and/or unspecified methods: New and/or unspecified methods:
tpc_vote(): handled like tpc_abort tpc_vote(): handled like tpc_abort
transactionalUndo(): handled like undo() (which is how?) undo(): how's that handled?
Methods that have nothing to do with committing/non-committing: Methods that have nothing to do with committing/non-committing:
load(), loadSerial(), getName(), getSize(), __len__(), history(), load(), loadSerial(), getName(), getSize(), __len__(), history(),
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
# FOR A PARTICULAR PURPOSE. # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Check transactionalUndo(). """Check undo().
Any storage that supports transactionalUndo() must pass these tests. Any storage that supports undo() must pass these tests.
""" """
import time import time
...@@ -102,7 +102,7 @@ class TransactionalUndoStorage: ...@@ -102,7 +102,7 @@ class TransactionalUndoStorage:
t = Transaction() t = Transaction()
t.note(note) t.note(note)
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
oids = self._storage.transactionalUndo(tid, t) oids = self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
return oids return oids
...@@ -150,7 +150,7 @@ class TransactionalUndoStorage: ...@@ -150,7 +150,7 @@ class TransactionalUndoStorage:
t = Transaction() t = Transaction()
t.note('undo1') t.note('undo1')
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
self._storage.transactionalUndo(tid, t) self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
# Check that calling getSerial on an uncreated object raises a KeyError # Check that calling getSerial on an uncreated object raises a KeyError
...@@ -279,8 +279,8 @@ class TransactionalUndoStorage: ...@@ -279,8 +279,8 @@ class TransactionalUndoStorage:
tid1 = info[1]['id'] tid1 = info[1]['id']
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
tid, oids = self._storage.transactionalUndo(tid, t) tid, oids = self._storage.undo(tid, t)
tid, oids1 = self._storage.transactionalUndo(tid1, t) tid, oids1 = self._storage.undo(tid1, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
# We get the finalization stuff called an extra time: # We get the finalization stuff called an extra time:
...@@ -353,7 +353,7 @@ class TransactionalUndoStorage: ...@@ -353,7 +353,7 @@ class TransactionalUndoStorage:
tid = info[1]['id'] tid = info[1]['id']
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
tid, oids = self._storage.transactionalUndo(tid, t) tid, oids = self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
eq(len(oids), 1) eq(len(oids), 1)
...@@ -379,7 +379,7 @@ class TransactionalUndoStorage: ...@@ -379,7 +379,7 @@ class TransactionalUndoStorage:
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
self.assertRaises(POSException.UndoError, self.assertRaises(POSException.UndoError,
self._storage.transactionalUndo, self._storage.undo,
tid, t) tid, t)
self._storage.tpc_abort(t) self._storage.tpc_abort(t)
# Now have more fun: object1 and object2 are in the same transaction, # Now have more fun: object1 and object2 are in the same transaction,
...@@ -418,7 +418,7 @@ class TransactionalUndoStorage: ...@@ -418,7 +418,7 @@ class TransactionalUndoStorage:
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
self.assertRaises(POSException.UndoError, self.assertRaises(POSException.UndoError,
self._storage.transactionalUndo, self._storage.undo,
tid, t) tid, t)
self._storage.tpc_abort(t) self._storage.tpc_abort(t)
self._iterate() self._iterate()
...@@ -446,7 +446,7 @@ class TransactionalUndoStorage: ...@@ -446,7 +446,7 @@ class TransactionalUndoStorage:
# And now attempt to undo the last transaction # And now attempt to undo the last transaction
t = Transaction() t = Transaction()
self._storage.tpc_begin(t) self._storage.tpc_begin(t)
tid, oids = self._storage.transactionalUndo(tid, t) tid, oids = self._storage.undo(tid, t)
self._storage.tpc_vote(t) self._storage.tpc_vote(t)
self._storage.tpc_finish(t) self._storage.tpc_finish(t)
eq(len(oids), 1) eq(len(oids), 1)
...@@ -652,7 +652,7 @@ class TransactionalUndoStorage: ...@@ -652,7 +652,7 @@ class TransactionalUndoStorage:
base = i * OBJECTS + i base = i * OBJECTS + i
for j in range(OBJECTS): for j in range(OBJECTS):
tid = info[base + j]['id'] tid = info[base + j]['id']
s.transactionalUndo(tid, t) s.undo(tid, t)
s.tpc_vote(t) s.tpc_vote(t)
s.tpc_finish(t) s.tpc_finish(t)
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
# FOR A PARTICULAR PURPOSE. # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
# Check interactions between transactionalUndo() and versions. Any storage # Check interactions between undo() and versions. Any storage that
# that supports both transactionalUndo() and versions must pass these tests. # supports both undo() and versions must pass these tests.
import time import time
......
...@@ -43,6 +43,17 @@ class DemoStorageTests(StorageTestBase.StorageTestBase, ...@@ -43,6 +43,17 @@ class DemoStorageTests(StorageTestBase.StorageTestBase,
# XXX Need to implement a real loadBefore for DemoStorage? # XXX Need to implement a real loadBefore for DemoStorage?
pass pass
# the next three pack tests depend on undo
def checkPackVersionReachable(self):
pass
def checkPackVersions(self):
pass
def checkPackVersionsInPast(self):
pass
def test_suite(): def test_suite():
suite = unittest.makeSuite(DemoStorageTests, 'check') suite = unittest.makeSuite(DemoStorageTests, 'check')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment