[Checkins] SVN: zc.bsddbstorage/branches/dev/ checkpoint

Jim Fulton jim at zope.com
Wed Nov 18 18:04:20 EST 2009


Log message for revision 105840:
  checkpoint
  

Changed:
  U   zc.bsddbstorage/branches/dev/buildout.cfg
  U   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/__init__.py
  A   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/blob_packing.txt
  A   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/component.xml
  A   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/configure.txt
  U   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/tests.py
  A   zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/zconfig.py

-=-
Modified: zc.bsddbstorage/branches/dev/buildout.cfg
===================================================================
--- zc.bsddbstorage/branches/dev/buildout.cfg	2009-11-18 19:14:07 UTC (rev 105839)
+++ zc.bsddbstorage/branches/dev/buildout.cfg	2009-11-18 23:04:19 UTC (rev 105840)
@@ -1,5 +1,5 @@
 [buildout]
-develop = .
+develop = . 3.9
 parts = test py
 
 [test]

Modified: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/__init__.py
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/__init__.py	2009-11-18 19:14:07 UTC (rev 105839)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/__init__.py	2009-11-18 23:04:19 UTC (rev 105840)
@@ -15,6 +15,7 @@
 from bsddb3 import db
 from ZODB.utils import p64, u64, z64
 import cPickle
+import logging
 import marshal
 import os
 import tempfile
@@ -48,6 +49,15 @@
 
     return func
 
+def DB(path, blob_dir=None, pack=3*86400,
+       read_only=False, create=False,
+       detect_deadlocks = True,
+       remove_logs = True,
+       **kw):
+    return ZODB.DB(BSDDBStorage(path, blob_dir, pack, create, read_only,
+                                detect_deadlocks, remove_logs),
+                   **kw)
+
 class BSDDBStorage(
     ZODB.blob.BlobStorageMixin,
     ZODB.ConflictResolution.ConflictResolvingStorage,
@@ -65,8 +75,10 @@
                  pack = 3*86400,
                  create = False,
                  read_only = False,
-                 detect_locks = True,
+                 detect_deadlocks = True,
                  remove_logs = True,
+                 checkpoint = 60,
+                 autopack = 0,
                  ):
         self.__name__ = envpath
         envpath = os.path.abspath(envpath)
@@ -95,7 +107,7 @@
         self.blob_dir = blob_dir
 
         self.env = db.DBEnv()
-        if detect_locks:
+        if detect_deadlocks:
             self.env.set_lk_detect(db.DB_LOCK_MINWRITE)
         if remove_logs:
             self.env.log_set_config(db.DB_LOG_AUTO_REMOVE, 1)
@@ -161,8 +173,17 @@
         # - another thread updates data via tpc_finish and sends invalidations
         # - The first thread's load returns the old data after the
         #   invalidations have been processed.
-        self._current_lock = RWLock() 
+        self._current_lock = RWLock()
 
+        if checkpoint > 0:
+            self.finish_checkpointing = interval_thread(
+                self.env.txn_checkpoint, checkpoint)
+        if autopack > 0:
+            event = threading.Event()
+            self.finish_packing = interval_thread(
+                (lambda : self.pack(should_stop=event.is_set)),
+                autopack, event)
+
     def txn(self, flags=0):
         return TransactionContext(self.env.txn_begin(flags=flags))
 
@@ -170,6 +191,8 @@
         return CursorContext(database.cursor(txn, flags))
 
     def close(self):
+        self.finish_packing()
+        self.finish_checkpointing()
         self.data.close()
         self.transaction_oids.close()
         self.transactions.close()
@@ -177,6 +200,10 @@
         if not self._read_only:
             self._lock_file.close()
 
+    def finish_checkpointing(self):
+        pass
+    finish_packing = finish_checkpointing
+
     def getName(self):
         return self.__name__
 
@@ -243,7 +270,7 @@
 #         pass # XXX
 
     def lastTransaction(self):
-        with self.txn() as txn:
+        with self.txn(db.DB_TXN_SNAPSHOT) as txn:
             with self.cursor(self.transactions, txn) as cursor:
                 kv = cursor.get(db.DB_LAST)
                 if kv is None:
@@ -252,14 +279,14 @@
 
     def __len__(self):
         # XXX this is probably very expensive, but we need this for the
-        # tests. :(  Need to check this out with a big db to decode what the
+        # tests. :(  Need to check this out with a big db to decide what the
         # cost is.  Usually, accuracy isn't that important.
         return self.data.stat()['nkeys']
         #return self.data.stat(db.DB_FAST_STAT)['nkeys']
 
     def load(self, oid, version=''):
         with self._current_lock.read():
-            with self.txn() as txn:
+            with self.txn(db.DB_TXN_SNAPSHOT) as txn:
                 with self.cursor(self.data, txn) as cursor:
                     kv = cursor.get(oid, db.DB_SET)
                     if kv:
@@ -269,7 +296,7 @@
                             return data, n64(record[:8])
 
                     raise ZODB.POSException.POSKeyError(oid)
-
+    
     def loadBefore(self, oid, tid):
         ntid = p64(868082074056920076L-(u64(tid)-1))
         with self.txn(db.DB_TXN_SNAPSHOT) as txn:
@@ -322,12 +349,13 @@
             self.misc.put('oid', oid, txn)
             return oid
 
-    def pack(self, pack_time=None, referencesf=None, gc=False):
+    def pack(self, pack_time=None, referencesf=None, gc=False,
+             should_stop=lambda : 0):
         assert not gc, "BSDDBStorage doesn't do garbage collection."
         if pack_time is None:
             pack_time = time.time()-self._pack
         pack_tid = timetime2tid(pack_time)
-        while self._pack1(pack_tid):
+        while self._pack1(pack_tid) and not should_stop():
             pass
         if self.blob_dir:
             self._remove_empty_notlast_blob_directories(self.blob_dir)
@@ -542,6 +570,7 @@
 
         if self._transaction is transaction:
             return
+
         self._commit_lock.acquire()
         self._transaction = transaction
 
@@ -560,21 +589,24 @@
             self._ts = ZODB.TimeStamp.TimeStamp(tid)
             self._tid = tid
 
-        fd, path = tempfile.mkstemp('bsddb')
-        self._log_file = open(path, 'r+b')
+        fd, self._log_path = tempfile.mkstemp('bsddb')
+        self._log_file = open(self._log_path, 'r+b')
         os.close(fd)
         marshal.dump((tid, ext), self._log_file)
 
+    def _tpc_cleanup(self):
+        self._transaction = self._txn = None
+        self._log_file.close()
+        os.remove(self._log_path)
+        self._commit_lock.release()
+
     def tpc_abort(self, transaction):
         if transaction is not self._transaction:
             return
-        try:
-            if self._txn is not None:
-                self._txn.abort()
-            self._blob_tpc_abort()
-            self._transaction = self._txn = None
-        finally:
-            self._commit_lock.release()
+        if self._txn is not None:
+            self._txn.abort()
+        self._blob_tpc_abort()
+        self._tpc_cleanup()
 
     def tpc_finish(self, transaction, func = lambda tid: None):
         if transaction is not self._transaction:
@@ -584,9 +616,8 @@
             func(self._tid)
             self._txn.commit()
             self._blob_tpc_finish()
-            self._transaction = self._txn = None
-            self._commit_lock.release()
-
+            self._tpc_cleanup()
+            
     _transaction_id_suffix = 'x' * (db.DB_GID_SIZE - 8)
     def tpc_vote(self, transaction):
         self._txn = txn = self.env.txn_begin()
@@ -598,6 +629,32 @@
             self.transaction_oids.put(tid, oid, txn=txn)
         txn.prepare(self._tid+self._transaction_id_suffix)
 
+    ##############################################################
+    # ZEO support
+    
+    def getTid(self, oid):
+        """The last transaction to change an object
+
+        Return the transaction id of the last transaction that committed a
+        change to an object with the given object id.
+        
+        """
+        with self._current_lock.read():
+            with self.txn(db.DB_TXN_SNAPSHOT) as txn:
+                kv = self.data.get(oid, doff=0, dlen=8)
+                if not kv or len(kv[1]) == 8:
+                    raise ZODB.POSException.POSKeyError(oid)
+                return kv[1]
+
+
+    def tpc_transaction(self):
+        return self._transaction
+
+    #
+    ##############################################################
+
+Storage = BSDDBStorage # easier to type alias :)
+
 def marhal_iterate(f):
     while 1:
         try:
@@ -636,15 +693,6 @@
         +(time.gmtime(timetime)[5]+divmod(timetime,1)[1],)
         ))
 
-def DB(path, blob_dir=None, pack=3*86400,
-       read_only=False, create=False,
-       detect_locks = True,
-       remove_logs = True,
-       **kw):
-    return ZODB.DB(BSDDBStorage(path, blob_dir, pack, create, read_only,
-                                detect_locks, remove_logs),
-                   **kw)
-
 class StorageIterator(object):
 
     def __init__(self, it):
@@ -798,3 +846,34 @@
     def __exit__(self, *args):
         self.lock.release_read()
         
+def interval_thread(func, interval, event=None):
+
+    if event is None:
+        event = threading.Event()
+    name = __name__+'.%s' % func.__name__
+    logger = logging.getLogger(name)
+
+    def run(func):
+        status = None
+        while not event.is_set():
+            try:
+                func()
+            except Exception:
+                if status != 'failed':
+                    logger.critical("failed", exc_info=sys.exc_info)
+                    status = 'failed'
+            else:
+                if status == 'failed':
+                    logger.info("succeeded")
+                    status = None
+            event.wait(interval)
+            
+    thread = threading.Thread(target=run, args=(func, ), name=name)
+    thread.setDaemon(True)
+    thread.start()
+
+    def join(*args):
+        event.set()
+        thread.join(*args)
+
+    return join

Added: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/blob_packing.txt
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/blob_packing.txt	                        (rev 0)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/blob_packing.txt	2009-11-18 23:04:19 UTC (rev 105840)
@@ -0,0 +1,126 @@
+Packing support for blob data
+=============================
+
+Set up:
+
+    >>> from ZODB.serialize import referencesf
+    >>> from ZODB.blob import Blob
+    >>> from ZODB import utils
+    >>> from ZODB.DB import DB
+    >>> import transaction
+
+A helper method to assure a unique timestamp across multiple platforms:
+
+    >>> from ZODB.tests.testblob import new_time
+
+    >>> import zc.bsddbstorage
+    >>> blob_storage = zc.bsddbstorage.Storage('data', 'blobs', checkpoint=1)
+    >>> database = DB(blob_storage)
+
+Create our root object:
+
+    >>> connection1 = database.open()
+    >>> root = connection1.root()
+
+Put some revisions of a blob object in our database and on the filesystem:
+
+    >>> import os
+    >>> tids = []
+    >>> times = []
+    >>> nothing = transaction.begin()
+    >>> times.append(new_time())
+    >>> blob = Blob()
+    >>> blob.open('w').write('this is blob data 0')
+    >>> root['blob'] = blob
+    >>> transaction.commit()
+    >>> tids.append(blob._p_serial)
+
+    >>> nothing = transaction.begin()
+    >>> times.append(new_time())
+    >>> root['blob'].open('w').write('this is blob data 1')
+    >>> transaction.commit()
+    >>> tids.append(blob._p_serial)
+
+    >>> nothing = transaction.begin()
+    >>> times.append(new_time())
+    >>> root['blob'].open('w').write('this is blob data 2')
+    >>> transaction.commit()
+    >>> tids.append(blob._p_serial)
+
+    >>> nothing = transaction.begin()
+    >>> times.append(new_time())
+    >>> root['blob'].open('w').write('this is blob data 3')
+    >>> transaction.commit()
+    >>> tids.append(blob._p_serial)
+
+    >>> nothing = transaction.begin()
+    >>> times.append(new_time())
+    >>> root['blob'].open('w').write('this is blob data 4')
+    >>> transaction.commit()
+    >>> tids.append(blob._p_serial)
+
+    >>> oid = root['blob']._p_oid
+    >>> fns = [ blob_storage.fshelper.getBlobFilename(oid, x) for x in tids ]
+    >>> [ os.path.exists(x) for x in fns ]
+    [True, True, True, True, True]
+
+Do a pack to the slightly before the first revision was written:
+
+    >>> packtime = times[0]
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [True, True, True, True, True]
+    
+Do a pack to the slightly before the second revision was written:
+
+    >>> packtime = times[1]
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [True, True, True, True, True]
+
+Do a pack to the slightly before the third revision was written:
+
+    >>> packtime = times[2]
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [False, True, True, True, True]
+
+Do a pack to the slightly before the fourth revision was written:
+
+    >>> packtime = times[3]
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [False, False, True, True, True]
+
+Do a pack to the slightly before the fifth revision was written:
+
+    >>> packtime = times[4]
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [False, False, False, True, True]
+
+Do a pack to now:
+
+    >>> packtime = new_time()
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [False, False, False, False, True]
+
+Delete the object and do a pack, it should get rid of the most current
+revision as well as the entire directory:
+
+    >>> t = transaction.begin()
+    >>> blob_storage.tpc_begin(t)
+    >>> blob_storage.deleteObject(oid, tids[-1], t)
+    >>> blob_storage.tpc_vote(t)
+    >>> blob_storage.tpc_finish(t)
+    >>> packtime = new_time()
+    >>> blob_storage.pack(packtime, referencesf)
+    >>> [ os.path.exists(x) for x in fns ]
+    [False, False, False, False, False]
+    >>> os.path.exists(os.path.split(fns[0])[0])
+    False
+
+Clean up our blob directory and database:
+
+    >>> blob_storage.close()


Property changes on: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/blob_packing.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/component.xml
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/component.xml	                        (rev 0)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/component.xml	2009-11-18 23:04:19 UTC (rev 105840)
@@ -0,0 +1,80 @@
+<component>
+  <description>
+     Definitions for BSDDBStorage storages.
+  </description>
+
+  <sectiontype name="bsddbstorage" datatype="zc.bsddbstorage.zconfig.Storage"
+               implements="ZODB.storage">
+
+    <key name="path" datatype="existing-dirpath" required="no">
+      <description>
+         The name of a Berkeley Database environment directory.
+      </description>
+    </key>
+
+    <key name="blob-dir" datatype="existing-dirpath" required="no">
+      <description>
+         If Blobs are supported, then this is the name of the
+         directory in which they should be stored.
+      </description>
+    </key>
+
+    <key name="pack" datatype="integer" required="no" default="259200">
+      <description>
+         The default number of seconds in the past to pack the database
+         to. This defaults to 3 days, 3*86400.
+      </description>
+    </key>
+
+    <key name="create" datatype="boolean" required="no" default="false">
+      <description>
+         Create a database, even if one already exists. This defaults to
+         False.
+      </description>
+    </key>
+
+    <key name="read-only" datatype="boolean" required="no" default="false">
+      <description>
+         Disallow write transactions.  The storage can still be read and
+         even packed. This defaults to False.
+      </description>
+    </key>
+
+    <key name="detect-deadlocks" datatype="boolean" required="no"
+         default="true">
+      <description>
+         Check for deadlocks whenever a thread would block trying to get a
+         Berkeley Database lock.  This defaults to True. If False, then an
+         external tool, such as the Berkeley DB db_deadlock utility should
+         be used to periodically check for locks.
+      </description>
+    </key>
+
+    <key name="remove-logs" datatype="boolean" required="no" default="true">
+      <description>
+         Automatically remove log files when they are no-longer needed.
+         This defaults to True. Set this to False to make backups using the
+         Berkeley DB db_archive utility.
+      </description>
+    </key>
+
+    <key name="checkpoint" datatype="integer" required="no" default="60">
+      <description>
+         Specify the interval, in seconds, at which database
+         checkpoints will be periodically taken.  This defaults to 60
+         seconds.  Set to 0 to use an external checkpoint utility,
+         such as Berkeley Database's db_checkpoint utility.
+      </description>
+    </key>
+
+    <key name="autopack" datatype="integer" required="no" default="0">
+      <description>
+         Sepecify the interval, in seconds, at which the database will be
+         automatically packed.  This defaults to 0, which
+         indicates no automatic packing.
+      </description>
+    </key>
+
+  </sectiontype>
+
+</component>


Property changes on: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/component.xml
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/configure.txt
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/configure.txt	                        (rev 0)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/configure.txt	2009-11-18 23:04:19 UTC (rev 105840)
@@ -0,0 +1,69 @@
+Configuring zc.bsddbstorage.BSDDBStorage
+----------------------------------------
+
+There are 2 ways to configure and instantiate the BSDDBStorage:
+
+- Python
+
+- ZConfig
+
+Berkeley database, on which BSDDBStorage is built, allows many
+settings to be provided in a DB_CONFIG file in the database directory.
+
+To create a BSDDBStorage from Python, call the constructor
+``zc.bsddbstorage.BSDDBStorage`` passing a database directory name, an
+optional blob directory name and one of the following options:
+
+pack
+   The default number of seconds in the past to pack the database
+   to. This defaults to 3 days, 3*86400.
+
+create
+   Create a database, even if one already exists. This defaults to
+   False.
+
+read_only
+   Disallow write transactions.  The storage can still be read and
+   even packed. This defaults to False.
+
+detect_deadlocks
+   Check for deadlocks whenever a thread would block trying to get a
+   Berkeley Database lock.  This defaults to True. If False, then an
+   external tool, such as the Berkeley DB db_deadlock utility should
+   be used to periodically check for locks.
+
+remove_logs
+   Automatically remove log files when they are no-longer needed.
+   This defaults to True. Set this to False to make backups using the
+   Berkeley DB db_archive utility.
+
+checkpoint
+   Specify  the interval,  in seconds,  at which  database checkpoints
+   will be periodically taken.  This defaults to 60 seconds.  Set to 0
+   to use an external  checkpoint utility, such as Berkeley Database's
+   db_checkpoint utility.
+
+autopack
+   Sepecify the interval, in seconds, at which the database will be
+   automatically packed.  This defaults to 0, which
+   indicates no automatic packing.
+
+You can also create a storage using ZConfig.  To do so, you need to
+%import zc.bsddbstorage and use the bsddbstorage tag with options
+corresponding to the options above (with '-'s substituted for '_'s)
+plus:
+
+path
+   The (required) path of the database directory
+
+blob-dir
+   The (optional) path of the blob directory.
+
+Here's an example::
+
+   %import zc.bsddbstorage
+
+   <bsddbstorage>
+      path /my/data
+      autopack 300
+   </bsddbstorage>


Property changes on: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/configure.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/tests.py
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/tests.py	2009-11-18 19:14:07 UTC (rev 105839)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/tests.py	2009-11-18 23:04:19 UTC (rev 105840)
@@ -11,12 +11,13 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-from zope.testing import doctest
+from zope.testing import doctest, setupstack
 import cPickle
 import cStringIO
 import time
 import unittest
 import zc.bsddbstorage
+import ZEO.tests.testZEO
 import ZODB.tests.BasicStorage
 import ZODB.tests.ConflictResolution
 import ZODB.tests.HistoryStorage
@@ -31,29 +32,16 @@
 import ZODB.tests.Synchronization
 import ZODB.tests.testblob
 
-class BSDDBStorageTests(
-    ZODB.tests.StorageTestBase.StorageTestBase,
-    ZODB.tests.BasicStorage.BasicStorage,
-    ZODB.tests.RevisionStorage.RevisionStorage,
-    ZODB.tests.PackableStorage.PackableStorageWithOptionalGC,
-    ZODB.tests.Synchronization.SynchronizedStorage,
-    ZODB.tests.ConflictResolution.ConflictResolvingStorage,
-    ZODB.tests.HistoryStorage.HistoryStorage,
-    ZODB.tests.IteratorStorage.IteratorStorage,
-    ZODB.tests.IteratorStorage.ExtendedIteratorStorage,
-    ZODB.tests.PersistentStorage.PersistentStorage,
-    ZODB.tests.MTStorage.MTStorage,
-    ZODB.tests.ReadOnlyStorage.ReadOnlyStorage
-    ):
+def DISABLED(self):
+    "disabled"
 
-    def __disabled(self):
-        "disabled"
+class Overrides:
 
-    checkLoadBeforeUndo = __disabled
-    checkUndoZombie = __disabled
-    checkPackWithMultiDatabaseReferences = __disabled
-    checkLoadBeforeUndo = __disabled
-    checkWriteMethods = __disabled
+    checkLoadBeforeUndo = DISABLED
+    checkUndoZombie = DISABLED
+    checkPackWithMultiDatabaseReferences = DISABLED
+    checkLoadBeforeUndo = DISABLED
+    checkWriteMethods = DISABLED
 
     # Dang it, we really need to factor the pack tests for gc or no gc
     def checkPackAllRevisions(self):
@@ -107,28 +95,88 @@
         # Commented because No GC:
         # raises(KeyError, self._storage.loadSerial, oid, revid3)
 
+class BSDDBStorageTests(
+    Overrides,
+    ZODB.tests.StorageTestBase.StorageTestBase,
+    ZODB.tests.BasicStorage.BasicStorage,
+    ZODB.tests.RevisionStorage.RevisionStorage,
+    ZODB.tests.PackableStorage.PackableStorageWithOptionalGC,
+    ZODB.tests.Synchronization.SynchronizedStorage,
+    ZODB.tests.ConflictResolution.ConflictResolvingStorage,
+    ZODB.tests.HistoryStorage.HistoryStorage,
+    ZODB.tests.IteratorStorage.IteratorStorage,
+    ZODB.tests.IteratorStorage.ExtendedIteratorStorage,
+    ZODB.tests.PersistentStorage.PersistentStorage,
+    ZODB.tests.MTStorage.MTStorage,
+    ZODB.tests.ReadOnlyStorage.ReadOnlyStorage
+    ):
+
+
     def open(self, **kwargs):
         self._storage = zc.bsddbstorage.BSDDBStorage(
-            'storage', **kwargs)
+            'storage', checkpoint=1, **kwargs)
 
     def setUp(self):
         ZODB.tests.StorageTestBase.StorageTestBase.setUp(self)
         self.open(create=1)
 
+class BSDDBStorageZEOTests(
+    Overrides,
+    ZEO.tests.testZEO.FullGenericTests,
+    ):
+
+    def getConfig(self):
+        return """\
+        %import zc.bsddbstorage
+        <bsddbstorage>
+          path data
+          checkpoint 1
+        </bsddbstorage>
+        """
+
+    checkCommitLockUndoAbort = DISABLED
+    checkCommitLockUndoClose = DISABLED
+    checkCommitLockUndoFinish = DISABLED
+    checkCreationUndoneGetTid = DISABLED
+    checkNotUndoable = DISABLED
+    checkPackAfterUndoDeletion = DISABLED
+    checkPackAfterUndoManyTimes = DISABLED
+    checkSimpleTransactionalUndo = DISABLED
+    checkTransactionalUndoIterator = DISABLED
+    checkTwoObjectUndo = DISABLED
+    checkTwoObjectUndoAgain = DISABLED
+    checkTwoObjectUndoAtOnce = DISABLED
+    checkUndoConflictResolution = DISABLED
+    checkUndoCreationBranch1 = DISABLED
+    checkUndoCreationBranch2 = DISABLED
+    checkUndoInvalidation = DISABLED
+    checkUndoUnresolvable = DISABLED
+    checkIndicesInUndoInfo = DISABLED
+    checkIndicesInUndoLog = DISABLED
+    checkPackUndoLog = DISABLED
+    checkTransactionalUndoAfterPack = DISABLED
+    checkTransactionalUndoAfterPackWithObjectUnlinkFromRoot = DISABLED
+    checkUndoLogMetadata = DISABLED
+    checkPackUnlinkedFromRoot = DISABLED
+
 def test_suite():
     suite = unittest.TestSuite()
     for klass in [
-        BSDDBStorageTests,
+        BSDDBStorageTests, BSDDBStorageZEOTests,
         ]:
         suite.addTest(unittest.makeSuite(klass, "check"))
     suite.addTest(ZODB.tests.testblob.storage_reusable_suite(
         'BlobBSDDBStorage',
         lambda name, blob_dir:
-        zc.bsddbstorage.BSDDBStorage(name, blob_dir=blob_dir),
+        zc.bsddbstorage.BSDDBStorage(name, blob_dir=blob_dir, checkpoint=1),
         test_blob_storage_recovery=True,
-        test_packing=True,
+        test_packing=False,
         test_undo=False,
         ))
+    suite.addTest(doctest.DocFileSuite(
+        "blob_packing.txt",
+        setUp=setupstack.setUpDirectory, tearDown=setupstack.tearDown,
+        ))
     suite.addTest(ZODB.tests.PackableStorage.IExternalGC_suite(
         lambda : zc.bsddbstorage.BSDDBStorage(
             'data', blob_dir='blobs')))

Added: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/zconfig.py
===================================================================
--- zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/zconfig.py	                        (rev 0)
+++ zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/zconfig.py	2009-11-18 23:04:19 UTC (rev 105840)
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# Copyright (c) Zope Corporation.  All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Visible Source
+# License, Version 1.0 (ZVSL).  A copy of the ZVSL 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
+#
+##############################################################################
+
+import zc.bsddbstorage
+
+class Storage:
+
+    def __init__(self, config):
+        self.config = config
+        self.name = config.getSectionName()
+
+    def open(self):
+        config = self.config
+        return zc.bsddbstorage.Storage(
+            config.path,
+            config.blob_dir,
+            pack=config.pack,
+            create=config.create,
+            read_only = config.read_only,
+            detect_deadlocks = config.detect_deadlocks,
+            remove_logs = config.remove_logs,
+            checkpoint = config.checkpoint,
+            autopack = config.autopack,
+            )


Property changes on: zc.bsddbstorage/branches/dev/src/zc/bsddbstorage/zconfig.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the checkins mailing list