diff --git a/swift/common/db_replicator.py b/swift/common/db_replicator.py index 9d3cb2dcfc..6f73f8470b 100644 --- a/swift/common/db_replicator.py +++ b/swift/common/db_replicator.py @@ -423,8 +423,16 @@ class Replicator(Daemon): self.logger.timing_since('timing', start_time) def delete_db(self, object_file): + hash_dir = os.path.dirname(object_file) + suf_dir = os.path.dirname(hash_dir) with lock_parent_directory(object_file): - shutil.rmtree(os.path.dirname(object_file), True) + shutil.rmtree(hash_dir, True) + try: + os.rmdir(suf_dir) + except OSError, err: + if err.errno not in (errno.ENOENT, errno.ENOTEMPTY): + self.logger.exception( + _('ERROR while trying to clean up %s') % suf_dir) self.stats['remove'] += 1 device_name = self.extract_device(object_file) self.logger.increment('removes.' + device_name) diff --git a/test/unit/common/test_db_replicator.py b/test/unit/common/test_db_replicator.py index 0f0d58270c..33b4cc47aa 100644 --- a/test/unit/common/test_db_replicator.py +++ b/test/unit/common/test_db_replicator.py @@ -18,6 +18,7 @@ from contextlib import contextmanager import os import logging import errno +from shutil import rmtree from tempfile import mkdtemp, NamedTemporaryFile from swift.common import db_replicator @@ -332,20 +333,52 @@ class TestDBReplicator(unittest.TestCase): replicator.logger = FakeLogger() temp_dir = mkdtemp() - temp_file = NamedTemporaryFile(dir=temp_dir, delete=False) + try: + temp_suf_dir = os.path.join(temp_dir, '16e') + os.mkdir(temp_suf_dir) + temp_hash_dir = os.path.join(temp_suf_dir, + '166e33924a08ede4204871468c11e16e') + os.mkdir(temp_hash_dir) + temp_file = NamedTemporaryFile(dir=temp_hash_dir, delete=False) + temp_hash_dir2 = os.path.join(temp_suf_dir, + '266e33924a08ede4204871468c11e16e') + os.mkdir(temp_hash_dir2) + temp_file2 = NamedTemporaryFile(dir=temp_hash_dir2, delete=False) - # sanity-checks - self.assertTrue(os.path.exists(temp_dir)) - self.assertTrue(os.path.exists(temp_file.name)) - self.assertEqual(0, replicator.stats['remove']) + # sanity-checks + self.assertTrue(os.path.exists(temp_dir)) + self.assertTrue(os.path.exists(temp_suf_dir)) + self.assertTrue(os.path.exists(temp_hash_dir)) + self.assertTrue(os.path.exists(temp_file.name)) + self.assertTrue(os.path.exists(temp_hash_dir2)) + self.assertTrue(os.path.exists(temp_file2.name)) + self.assertEqual(0, replicator.stats['remove']) - replicator.delete_db(temp_file.name) + replicator.delete_db(temp_file.name) - self.assertFalse(os.path.exists(temp_dir)) - self.assertFalse(os.path.exists(temp_file.name)) - self.assertEqual([(('removes.some_device',), {})], - replicator.logger.log_dict['increment']) - self.assertEqual(1, replicator.stats['remove']) + self.assertTrue(os.path.exists(temp_dir)) + self.assertTrue(os.path.exists(temp_suf_dir)) + self.assertFalse(os.path.exists(temp_hash_dir)) + self.assertFalse(os.path.exists(temp_file.name)) + self.assertTrue(os.path.exists(temp_hash_dir2)) + self.assertTrue(os.path.exists(temp_file2.name)) + self.assertEqual([(('removes.some_device',), {})], + replicator.logger.log_dict['increment']) + self.assertEqual(1, replicator.stats['remove']) + + replicator.delete_db(temp_file2.name) + + self.assertTrue(os.path.exists(temp_dir)) + self.assertFalse(os.path.exists(temp_suf_dir)) + self.assertFalse(os.path.exists(temp_hash_dir)) + self.assertFalse(os.path.exists(temp_file.name)) + self.assertFalse(os.path.exists(temp_hash_dir2)) + self.assertFalse(os.path.exists(temp_file2.name)) + self.assertEqual([(('removes.some_device',), {})] * 2, + replicator.logger.log_dict['increment']) + self.assertEqual(2, replicator.stats['remove']) + finally: + rmtree(temp_dir) def test_extract_device(self): replicator = TestReplicator({'devices': '/some/root'})