Skip to content

Commit

Permalink
Don't use TRUNCATE in functional unittests.
Browse files Browse the repository at this point in the history
This is because we have multiple open storages holding table locks so we
livelock on each other.
  • Loading branch information
jamadden committed Jun 18, 2016
1 parent e3cd777 commit fe70e66
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
8 changes: 6 additions & 2 deletions CHANGES.txt
Expand Up @@ -44,8 +44,12 @@
Jacobs.

- PostgreSQL: ``zodbconvert --clear`` should be much faster when the
destination is a PostgreSQL schema containing lots of data. Partial
fix for `issue 16`_ reported by Chris McDonough.
destination is a PostgreSQL schema containing lots of data. *NOTE*:
There can be no other open RelStorage connections to the destination,
or any PostgreSQL connection in general that might be holding locks
on the RelStorage tables, or ``zodbconvert`` will block indefinitely
waiting for the locks to be release. Partial fix for `issue 16`_
reported by Chris McDonough.

.. _`PR 18`: https://github.com/zodb/relstorage/pull/18/
.. _`PR 20`: https://github.com/zodb/relstorage/pull/20
Expand Down
13 changes: 10 additions & 3 deletions relstorage/adapters/schema.py
Expand Up @@ -886,9 +886,16 @@ def update_schema(self, cursor, tables):

_zap_all_tbl_stmt = 'DELETE FROM %s'

def zap_all(self, reset_oid=True):
"""Clear all data out of the database."""
stmt = self._zap_all_tbl_stmt
def zap_all(self, reset_oid=True, slow=False):
"""
Clear all data out of the database.
:keyword bool slow: If True (*not* the default) then database
specific optimizations will be skipped and rows will simply be
DELETEd. This is helpful when other connections might be open and
holding some kind of locks.
"""
stmt = self._zap_all_tbl_stmt if not slow else AbstractSchemaInstaller._zap_all_tbl_stmt

def callback(_conn, cursor):
existent = set(self.list_tables(cursor))
Expand Down
4 changes: 2 additions & 2 deletions relstorage/storage.py
Expand Up @@ -362,12 +362,12 @@ def _with_store(self, f, *args, **kw):
log.info("Reconnected.")
return f(self._store_conn, self._store_cursor, *args, **kw)

def zap_all(self, reset_oid=True):
def zap_all(self, **kwargs):
"""Clear all objects and transactions out of the database.
Used by the test suite and the ZODBConvert script.
"""
self._adapter.schema.zap_all(reset_oid=reset_oid)
self._adapter.schema.zap_all(**kwargs)
self._rollback_load_connection()
self._cache.clear()

Expand Down
8 changes: 4 additions & 4 deletions relstorage/tests/reltestbase.py
Expand Up @@ -698,7 +698,7 @@ def checkPackBrokenPickle(self):
# on whether the accelerated implementation is in use. Also ,the pure-python
# version on PyPy can raise IndexError
from zodbpickle.pickle import UnpicklingError as pUnpickErr
unpick_errs = (pUnpickErr,IndexError)
unpick_errs = (pUnpickErr, IndexError)
try:
from zodbpickle.fastpickle import UnpicklingError as fUnpickErr
except ImportError:
Expand All @@ -709,7 +709,7 @@ def checkPackBrokenPickle(self):

self._dostoreNP(self._storage.new_oid(), data=b'brokenpickle')
self.assertRaises(unpick_errs, self._storage.pack,
time.time() + 10000, referencesf)
time.time() + 10000, referencesf)

def checkBackwardTimeTravelWithoutRevertWhenStale(self):
# If revert_when_stale is false (the default), when the database
Expand Down Expand Up @@ -743,7 +743,7 @@ def checkBackwardTimeTravelWithoutRevertWhenStale(self):
transaction.commit()
self.assertTrue('beta' in r)

c._storage.zap_all(reset_oid=False)
c._storage.zap_all(reset_oid=False, slow=True)
c._storage.copyTransactionsFrom(fs)

fs.close()
Expand Down Expand Up @@ -794,7 +794,7 @@ def checkBackwardTimeTravelWithRevertWhenStale(self):
transaction.commit()
self.assertTrue('beta' in r)

c._storage.zap_all(reset_oid=False)
c._storage.zap_all(reset_oid=False, slow=True)
c._storage.copyTransactionsFrom(fs)

fs.close()
Expand Down

0 comments on commit fe70e66

Please sign in to comment.