From f07af09e3de6f38a2637a094fc58d8b69a49eff4 Mon Sep 17 00:00:00 2001 From: meejah Date: Mon, 2 Nov 2015 13:25:50 -0700 Subject: [PATCH] Add a unit-test and correct the code for "already deleted" If a Downloader decides that it needs to delete a file, but that file is already gone locally, the exeption is caugt and a log message produced. --- src/allmydata/frontends/magic_folder.py | 3 +- src/allmydata/test/test_magic_folder.py | 74 ++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/allmydata/frontends/magic_folder.py b/src/allmydata/frontends/magic_folder.py index 93463e7a..42b639c7 100644 --- a/src/allmydata/frontends/magic_folder.py +++ b/src/allmydata/frontends/magic_folder.py @@ -505,8 +505,7 @@ class WriteFileMixin(object): self._log('renaming deleted file to backup: %s' % (abspath_u,)) try: fileutil.rename_no_overwrite(abspath_u, abspath_u + u'.backup') - except IOError: - # XXX is this the correct error? + except OSError: self._log("Already gone: '%s'" % (abspath_u,)) return abspath_u diff --git a/src/allmydata/test/test_magic_folder.py b/src/allmydata/test/test_magic_folder.py index 59eb1cff..8f6c12b3 100644 --- a/src/allmydata/test/test_magic_folder.py +++ b/src/allmydata/test/test_magic_folder.py @@ -317,7 +317,6 @@ class MagicFolderTestMixin(MagicFolderCLITestMixin, ShouldFailMixin, ReallyEqual finally: yield self.cleanup(None) - @defer.inlineCallbacks def test_alice_delete_bob_restore(self): alice_clock = task.Clock() @@ -406,6 +405,79 @@ class MagicFolderTestMixin(MagicFolderCLITestMixin, ShouldFailMixin, ReallyEqual bob_clock.advance(0) yield d1 + @defer.inlineCallbacks + def test_alice_sees_bobs_delete_with_error(self): + # alice creates a file, bob deletes it -- and we also arrange + # for Alice's file to have "gone missing" as well. + alice_clock = task.Clock() + bob_clock = task.Clock() + yield self.setup_alice_and_bob(alice_clock, bob_clock) + alice_dir = self.alice_magicfolder.uploader._local_path_u + bob_dir = self.bob_magicfolder.uploader._local_path_u + alice_fname = os.path.join(alice_dir, 'blam') + bob_fname = os.path.join(bob_dir, 'blam') + + try: + # alice creates a file, bob downloads it + alice_proc = self.alice_magicfolder.uploader.set_hook('processed') + bob_proc = self.bob_magicfolder.downloader.set_hook('processed') + + fileutil.write(alice_fname, 'contents0\n') + self.notify(to_filepath(alice_fname), self.inotify.IN_CLOSE_WRITE, magic=self.alice_magicfolder) + + alice_clock.advance(0) + yield alice_proc # alice uploads + + bob_clock.advance(0) + yield bob_proc # bob downloads + + # check the state + yield self._check_version_in_dmd(self.alice_magicfolder, u"blam", 1) + yield self._check_version_in_local_db(self.alice_magicfolder, u"blam", 0) + yield self._check_version_in_dmd(self.bob_magicfolder, u"blam", 1) + yield self._check_version_in_local_db(self.bob_magicfolder, u"blam", 0) + yield self.failUnlessReallyEqual( + self._get_count('downloader.objects_failed', client=self.bob_magicfolder._client), + 0 + ) + yield self.failUnlessReallyEqual( + self._get_count('downloader.objects_downloaded', client=self.bob_magicfolder._client), + 1 + ) + + print("BOB DELETE") + # now bob deletes it (bob should upload, alice download) + bob_proc = self.bob_magicfolder.uploader.set_hook('processed') + alice_proc = self.alice_magicfolder.downloader.set_hook('processed') + os.unlink(bob_fname) + self.notify(to_filepath(bob_fname), self.inotify.IN_DELETE, magic=self.bob_magicfolder) + # just after notifying bob, we also delete alice's, + # covering the 'except' flow in _rename_deleted_file() + os.unlink(alice_fname) + + bob_clock.advance(0) + yield bob_proc + alice_clock.advance(0) + yield alice_proc + + # check versions + node, metadata = yield self.alice_magicfolder.downloader._get_collective_latest_file(u'blam') + self.assertTrue(metadata['deleted']) + yield self._check_version_in_dmd(self.bob_magicfolder, u"blam", 1) + yield self._check_version_in_local_db(self.bob_magicfolder, u"blam", 1) + yield self._check_version_in_dmd(self.alice_magicfolder, u"blam", 1) + yield self._check_version_in_local_db(self.alice_magicfolder, u"blam", 1) + + finally: + # cleanup + d0 = self.alice_magicfolder.finish() + alice_clock.advance(0) + yield d0 + + d1 = self.bob_magicfolder.finish() + bob_clock.advance(0) + yield d1 + @defer.inlineCallbacks def test_alice_create_bob_update(self): alice_clock = task.Clock() -- 2.45.2