diff --git a/tooz/drivers/file.py b/tooz/drivers/file.py index c1fc12d..ef89a28 100644 --- a/tooz/drivers/file.py +++ b/tooz/drivers/file.py @@ -449,6 +449,11 @@ class FileDriver(coordination._RunWatchersMixin, else: if len(entries) > 1: raise coordination.GroupNotEmpty(group_id) + elif len(entries) == 1 and entries != ['.metadata']: + raise coordination.ToozError( + "Unexpected path '%s' found in" + " group directory '%s' (expected to only find" + " a '.metadata' path)" % (entries[0], group_dir)) else: try: shutil.rmtree(group_dir) diff --git a/tooz/tests/drivers/test_file.py b/tooz/tests/drivers/test_file.py index c95eb66..f392f18 100644 --- a/tooz/tests/drivers/test_file.py +++ b/tooz/tests/drivers/test_file.py @@ -15,6 +15,9 @@ # License for the specific language governing permissions and limitations # under the License. +import os + +import fixtures import mock from testtools import testcase @@ -32,6 +35,26 @@ class TestFileDriver(testcase.TestCase): coord = coordination.get_coordinator(url, self._FAKE_MEMBER_ID) self.assertEqual(file_path, coord._dir) + def test_leftover_file(self): + fixture = self.useFixture(fixtures.TempDir()) + + file_path = fixture.path + url = 'file://%s' % file_path + + coord = coordination.get_coordinator(url, self._FAKE_MEMBER_ID) + coord.start() + self.addCleanup(coord.stop) + + coord.create_group(b"my_group").get() + safe_group_id = coord._make_filesystem_safe(b"my_group") + with open(os.path.join(file_path, 'groups', + safe_group_id, "junk.txt"), "wb"): + pass + os.unlink(os.path.join(file_path, 'groups', + safe_group_id, '.metadata')) + self.assertRaises(coordination.ToozError, + coord.delete_group(b"my_group").get) + @mock.patch('os.path.normpath', lambda x: x.replace('/', '\\')) @mock.patch('sys.platform', 'win32') def test_base_dir_win32(self):