diff options
author | Sascha Silbe <sascha-pgp@silbe.org> | 2010-06-18 21:53:31 (GMT) |
---|---|---|
committer | Sascha Silbe <sascha-pgp@silbe.org> | 2010-06-18 21:53:31 (GMT) |
commit | 7b00e7d8155cd1989ba840d5af68fde80e24dc2f (patch) | |
tree | c99b9c8404b8ce38a356004919ca4f9a0007472c | |
parent | 21208b14bd1784313934adf0f153e133fe1ed81c (diff) |
fix freeze/thaw, add test case
-rw-r--r-- | src/carquinyol/datastore.py | 37 | ||||
-rw-r--r-- | src/carquinyol/optimizer.py | 5 | ||||
-rw-r--r-- | tests/test_freeze.py | 30 | ||||
-rw-r--r-- | tests/test_massops.py | 5 |
4 files changed, 71 insertions, 6 deletions
diff --git a/src/carquinyol/datastore.py b/src/carquinyol/datastore.py index f7befbe..d902147 100644 --- a/src/carquinyol/datastore.py +++ b/src/carquinyol/datastore.py @@ -402,33 +402,58 @@ class DataStore(dbus.service.Object): Intended for doing online backups. """ + logging.info('Starting to freeze.') self.frozen = True self._index_store.close_index() gobject.idle_add(self._freeze_wait_cb, async_cb, async_err_cb, - priority=gobject.PRIORITY_LOW) + priority=gobject.PRIORITY_LOW+100) @dbus.service.method(DS_DBUS_INTERFACE, - in_signature='', out_signature='') - def thaw(self): + in_signature='', out_signature='', + async_callbacks=('async_cb', 'async_err_cb')) + def thaw(self, async_cb, async_err_cb): """Resume normal operation after freeze. + + A full restart (including migration if required) will be done. """ - self._index_store.open_index() + if not self.frozen: + raise ValueError('Trying to thaw while we are not frozen.') + + logging.info('Starting to thaw.') + + if self._migrate(): + self._rebuild_index() + else: + try: + self._index_store.open_index() + except Exception: + logging.exception('Failed to open index, will rebuild') + self._rebuild_index() + self.frozen = False - gobject.idle_add(self._thaw_work_cb, priority=gobject.PRIORITY_DEFAULT) + gobject.idle_add(self._thaw_work_cb, async_cb, async_err_cb, + priority=gobject.PRIORITY_LOW) def _freeze_wait_cb(self, async_cb, async_err_cb): """Stall the freeze() method while asynchronous operations are in progress. """ - if self._file_store.async_running(): + if self._file_store.async_running() or self._optimizer.async_running(): return True + logging.info('Fully frozen.') async_cb() return False def _thaw_work_cb(self, async_cb, async_err_cb): """Process requests that were queued during freeze.""" + if not layoutmanager.get_instance().index_updated: + logging.debug('_thaw_work_cb(): Index is not up-to-date, waiting') + return True + if not self.queue: + logging.info('Fully thawed.') + async_cb() return False self.queue.pop(0)() diff --git a/src/carquinyol/optimizer.py b/src/carquinyol/optimizer.py index 2b6ce29..0be0a99 100644 --- a/src/carquinyol/optimizer.py +++ b/src/carquinyol/optimizer.py @@ -73,6 +73,11 @@ class Optimizer(object): if e.errno != errno.ENOTEMPTY: raise + def async_running(self): + """Check whether there are any asynchronous operations in progress. + """ + return self._enqueue_checksum_id is not None + def _identical_file_already_exists(self, checksum): """Check if we already have files with this checksum. diff --git a/tests/test_freeze.py b/tests/test_freeze.py new file mode 100644 index 0000000..8ebc02e --- /dev/null +++ b/tests/test_freeze.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +"""Test the freeze/thaw feature.""" + +import os +import unittest + +from test_massops import MassOpsTestCase + + +_DBUS_TIMEOUT_MAX= 2147483646//1000 + +class FreezeThawTestCase(MassOpsTestCase): + """Test the freeze/thaw feature.""" + + # TODO: test queuing + + def _test_freeze_thaw(self): + """Issue freeze(), force a migration and run thaw().""" + self._datastore.freeze(timeout=_DBUS_TIMEOUT_MAX) + os.remove(os.environ['HOME']+'/.sugar/default/datastore/version') + self._datastore.thaw(timeout=_DBUS_TIMEOUT_MAX) + + test_a_freeze_thaw = _test_freeze_thaw + test_y_freeze_thaw = _test_freeze_thaw + + +def suite(): + test_suite = unittest.TestLoader().loadTestsFromTestCase(FreezeThawTestCase) + test_suite.__doc__ = FreezeThawTestCase.__doc__ + return test_suite diff --git a/tests/test_massops.py b/tests/test_massops.py index ddc5242..ac524cf 100644 --- a/tests/test_massops.py +++ b/tests/test_massops.py @@ -153,6 +153,11 @@ class MassOpsTestCase(unittest.TestCase): finally: os.remove(filename) + def test_z_remove_all(self): + """Remove all entries from data store.""" + for entry in self._datastore.find({}, ['uid'], byte_arrays=True)[0]: + self._datastore.delete(entry['uid']) + def _filter_properties(self, properties): for key in IGNORE_PROPERTIES: properties.pop(key, None) |