downloaded_d = self.magicfolder.downloader.set_hook('processed', ignore_count=1)
uploaded_d = self.magicfolder.uploader.set_hook('processed', ignore_count=1)
self.mkdir_nonascii(small_tree_dir)
- fileutil.write(abspath_expanduser_unicode(u"what", base=small_tree_dir), "say when")
+ what_path = abspath_expanduser_unicode(u"what", base=small_tree_dir)
+ fileutil.write(what_path, "say when")
os.rename(small_tree_dir, new_small_tree_dir)
self.notify(to_filepath(new_small_tree_dir), self.inotify.IN_MOVED_TO)
print "_check_moved_tree_is_watched"
downloaded_d = self.magicfolder.downloader.set_hook('processed', ignore_count=1)
uploaded_d = self.magicfolder.uploader.set_hook('processed')
- fileutil.write(abspath_expanduser_unicode(u"another", base=new_small_tree_dir), "file")
- self.notify(to_filepath(abspath_expanduser_unicode(u"another", base=new_small_tree_dir)), self.inotify.IN_CLOSE_WRITE)
+ another_path = abspath_expanduser_unicode(u"another", base=new_small_tree_dir)
+ fileutil.write(another_path, "file")
+ self.notify(to_filepath(another_path), self.inotify.IN_CLOSE_WRITE)
return DeferredListShouldSucceed([downloaded_d, uploaded_d])
d.addCallback(_check_moved_tree_is_watched)
up_proc = self.magicfolder.uploader.set_hook('processed')
# down_proc = self.magicfolder.downloader.set_hook('processed')
path = os.path.join(self.local_dir, u'foo')
- with open(path, 'w') as f:
- f.write('foo\n')
+ fileutil.write(path, 'foo\n')
self.notify(to_filepath(path), self.inotify.IN_CLOSE_WRITE)
yield up_proc
self.assertTrue(os.path.exists(path))
up_proc = self.magicfolder.uploader.set_hook('processed')
# down_proc = self.magicfolder.downloader.set_hook('processed')
path = os.path.join(self.local_dir, u'foo')
- with open(path, 'w') as f:
- f.write('foo\n')
+ fileutil.write(path, 'foo\n')
self.notify(to_filepath(path), self.inotify.IN_CLOSE_WRITE)
yield up_proc
self.assertTrue(os.path.exists(path))
# restore the file, with different contents
up_proc = self.magicfolder.uploader.set_hook('processed')
path = os.path.join(self.local_dir, u'foo')
- with open(path, 'w') as f:
- f.write('bar\n')
+ fileutil.write(path, 'bar\n')
self.notify(to_filepath(path), self.inotify.IN_CLOSE_WRITE)
yield up_proc
alice_proc = self.alice_magicfolder.uploader.set_hook('processed')
bob_proc = self.bob_magicfolder.downloader.set_hook('processed')
- with open(alice_fname, 'wb') as f:
- f.write('contents0\n')
+ 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)
# now alice restores it (alice should upload, bob download)
alice_proc = self.alice_magicfolder.uploader.set_hook('processed')
bob_proc = self.bob_magicfolder.downloader.set_hook('processed')
- with open(alice_fname, 'wb') as f:
- f.write('new contents\n')
+ fileutil.write(alice_fname, 'new contents\n')
self.notify(to_filepath(alice_fname), self.inotify.IN_CLOSE_WRITE, magic=self.alice_magicfolder)
alice_clock.advance(0)
alice_proc = self.alice_magicfolder.uploader.set_hook('processed')
bob_proc = self.bob_magicfolder.downloader.set_hook('processed')
- with open(alice_fname, 'wb') as f:
- f.write('contents0\n')
+ 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)
# now bob updates it (bob should upload, alice download)
bob_proc = self.bob_magicfolder.uploader.set_hook('processed')
alice_proc = self.alice_magicfolder.downloader.set_hook('processed')
- with open(bob_fname, 'wb') as f:
- f.write('bob wuz here\n')
+ fileutil.write(bob_fname, 'bob wuz here\n')
self.notify(to_filepath(bob_fname), self.inotify.IN_CLOSE_WRITE, magic=self.bob_magicfolder)
bob_clock.advance(0)
alice_proc = self.alice_magicfolder.uploader.set_hook('processed')
bob_proc = self.bob_magicfolder.downloader.set_hook('processed')
- with open(alice_fname, 'wb') as f:
- f.write('contents0\n')
+ 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)
# now alice restores the file (with new contents)
alice_proc = self.alice_magicfolder.uploader.set_hook('processed')
bob_proc = self.bob_magicfolder.downloader.set_hook('processed')
- with open(alice_fname, 'wb') as f:
- f.write('alice wuz here\n')
+ fileutil.write(alice_fname, 'alice wuz here\n')
self.notify(to_filepath(alice_fname), self.inotify.IN_CLOSE_WRITE, magic=self.alice_magicfolder)
alice_clock.advance(0)
f.close()
if temporary and sys.platform == "win32":
os.unlink(path_u)
- self.notify(path, self.inotify.IN_DELETE)
+ self.notify(path, self.inotify.IN_DELETE, flush=False)
event_mask = self.inotify.IN_CLOSE_WRITE
- fileutil.flush_volume(path_u)
self.notify(path, event_mask)
encoded_name_u = magicpath.path2magic(name_u)
path = os.path.join(magicfolder.uploader._local_path_u, relpath_u)
self.assertTrue(not os.path.exists(path))
+ def _check_uploader_count(self, name, expected, magic=None):
+ self.failUnlessReallyEqual(self._get_count('uploader.'+name, client=(magic or self.alice_magicfolder)._client),
+ expected)
+
+ def _check_downloader_count(self, name, expected, magic=None):
+ self.failUnlessReallyEqual(self._get_count('downloader.'+name, client=(magic or self.bob_magicfolder)._client),
+ expected)
+
def test_alice_bob(self):
alice_clock = task.Clock()
bob_clock = task.Clock()
d = self.setup_alice_and_bob(alice_clock, bob_clock)
- def _check_uploader_count(ign, name, expected, alice=True):
- if alice:
- self.failUnlessReallyEqual(self._get_count('uploader.'+name, client=self.alice_magicfolder._client),
- expected)
- else:
- self.failUnlessReallyEqual(self._get_count('uploader.'+name, client=self.bob_magicfolder._client),
- expected)
-
- def _check_downloader_count(ign, name, expected, alice=True):
- if alice:
- self.failUnlessReallyEqual(self._get_count('downloader.'+name, client=self.bob_magicfolder._client),
- expected)
- else:
- self.failUnlessReallyEqual(self._get_count('downloader.'+name, client=self.alice_magicfolder._client),
- expected)
-
def _wait_for_Alice(ign, downloaded_d):
print "Now waiting for Alice to download\n"
alice_clock.advance(0)
d.addCallback(lambda ign: self._check_version_in_dmd(self.alice_magicfolder, u"file1", 0))
d.addCallback(lambda ign: self._check_version_in_local_db(self.alice_magicfolder, u"file1", 0))
- d.addCallback(_check_uploader_count, 'objects_failed', 0)
- d.addCallback(_check_uploader_count, 'objects_succeeded', 1)
- d.addCallback(_check_uploader_count, 'files_uploaded', 1)
- d.addCallback(_check_uploader_count, 'objects_queued', 0)
- d.addCallback(_check_uploader_count, 'directories_created', 0)
- d.addCallback(_check_uploader_count, 'objects_conflicted', 0)
- d.addCallback(_check_uploader_count, 'objects_conflicted', 0, alice=False)
+ d.addCallback(lambda ign: self._check_uploader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 1))
+ d.addCallback(lambda ign: self._check_uploader_count('files_uploaded', 1))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_queued', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('directories_created', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_conflicted', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_conflicted', 0, magic=self.bob_magicfolder))
d.addCallback(lambda ign: self._check_version_in_local_db(self.bob_magicfolder, u"file1", 0))
- d.addCallback(_check_downloader_count, 'objects_failed', 0)
- d.addCallback(_check_downloader_count, 'objects_downloaded', 1)
+ d.addCallback(lambda ign: self._check_downloader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 1))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 0, magic=self.bob_magicfolder))
def Alice_to_delete_file():
print "Alice deletes the file!\n"
def notify_bob_moved(ign):
d0 = self.bob_magicfolder.uploader.set_hook('processed')
p = abspath_expanduser_unicode(u"file1", base=self.bob_magicfolder.uploader._local_path_u)
- self.notify(to_filepath(p), self.inotify.IN_MOVED_FROM, magic=self.bob_magicfolder)
+ self.notify(to_filepath(p), self.inotify.IN_MOVED_FROM, magic=self.bob_magicfolder, flush=False)
self.notify(to_filepath(p + u'.backup'), self.inotify.IN_MOVED_TO, magic=self.bob_magicfolder)
bob_clock.advance(0)
return d0
d.addCallback(lambda ign: self._check_version_in_dmd(self.alice_magicfolder, u"file1", 1))
d.addCallback(lambda ign: self._check_version_in_local_db(self.alice_magicfolder, u"file1", 1))
- d.addCallback(_check_uploader_count, 'objects_failed', 0)
- d.addCallback(_check_uploader_count, 'objects_succeeded', 2)
- d.addCallback(lambda ign: self.failUnlessReallyEqual(self._get_count('uploader.objects_not_uploaded',
- client=self.bob_magicfolder._client), 1))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 2))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_not_uploaded', 1, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 1, magic=self.bob_magicfolder))
d.addCallback(lambda ign: self._check_version_in_local_db(self.bob_magicfolder, u"file1", 1))
d.addCallback(lambda ign: self._check_version_in_dmd(self.bob_magicfolder, u"file1", 1))
d.addCallback(lambda ign: self._check_file_gone(self.bob_magicfolder, u"file1"))
- d.addCallback(_check_downloader_count, 'objects_failed', 0)
- d.addCallback(_check_downloader_count, 'objects_downloaded', 2)
+ d.addCallback(lambda ign: self._check_downloader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 2))
def Alice_to_rewrite_file():
print "Alice rewrites file\n"
d.addCallback(lambda ign: self._check_version_in_dmd(self.alice_magicfolder, u"file1", 2))
d.addCallback(lambda ign: self._check_version_in_local_db(self.alice_magicfolder, u"file1", 2))
- d.addCallback(_check_uploader_count, 'objects_failed', 0)
- d.addCallback(_check_uploader_count, 'objects_succeeded', 3)
- d.addCallback(_check_uploader_count, 'files_uploaded', 3)
- d.addCallback(_check_uploader_count, 'objects_queued', 0)
- d.addCallback(_check_uploader_count, 'directories_created', 0)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0, alice=False)
+ d.addCallback(lambda ign: self._check_uploader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 3))
+ d.addCallback(lambda ign: self._check_uploader_count('files_uploaded', 3))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_queued', 0))
+ d.addCallback(lambda ign: self._check_uploader_count('directories_created', 0))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0, magic=self.alice_magicfolder))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0))
d.addCallback(lambda ign: self._check_version_in_dmd(self.bob_magicfolder, u"file1", 2))
d.addCallback(lambda ign: self._check_version_in_local_db(self.bob_magicfolder, u"file1", 2))
- d.addCallback(_check_downloader_count, 'objects_failed', 0)
- d.addCallback(_check_downloader_count, 'objects_downloaded', 3)
+ d.addCallback(lambda ign: self._check_downloader_count('objects_failed', 0))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 3))
path_u = u"/tmp/magic_folder_test"
encoded_path_u = magicpath.path2magic(u"/tmp/magic_folder_test")
d.addCallback(lambda ign: self.failIf(os.path.exists(path_u)))
d.addCallback(lambda ign: self._check_version_in_local_db(self.bob_magicfolder, encoded_path_u, None))
- d.addCallback(lambda ign: _check_downloader_count(None, 'objects_excluded', self.objects_excluded+1))
- d.addCallback(_check_downloader_count, 'objects_downloaded', 3)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0, alice=False)
-
+ d.addCallback(lambda ign: self._check_downloader_count('objects_excluded', self.objects_excluded+1))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 3))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0, magic=self.alice_magicfolder))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0))
- # XXX
def Bob_to_rewrite_file():
print "Bob rewrites file\n"
self.file_path = abspath_expanduser_unicode(u"file1", base=self.bob_magicfolder.uploader._local_path_u)
d.addCallback(lambda ign: self._check_version_in_dmd(self.bob_magicfolder, u"file1", 3))
d.addCallback(lambda ign: self._check_version_in_local_db(self.bob_magicfolder, u"file1", 3))
- d.addCallback(_check_uploader_count, 'objects_failed', 0, alice=False)
- d.addCallback(_check_uploader_count, 'objects_succeeded', 1, alice=False)
- d.addCallback(_check_uploader_count, 'files_uploaded', 1, alice=False)
- d.addCallback(_check_uploader_count, 'objects_queued', 0, alice=False)
- d.addCallback(_check_uploader_count, 'directories_created', 0, alice=False)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0)
+ d.addCallback(lambda ign: self._check_uploader_count('objects_failed', 0, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_succeeded', 2, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_uploader_count('files_uploaded', 1, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_uploader_count('objects_queued', 0, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_uploader_count('directories_created', 0, magic=self.bob_magicfolder))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0))
d.addCallback(lambda ign: self._check_version_in_dmd(self.alice_magicfolder, u"file1", 3))
d.addCallback(lambda ign: self._check_version_in_local_db(self.alice_magicfolder, u"file1", 3))
- d.addCallback(_check_downloader_count, 'objects_failed', 0, alice=False)
- d.addCallback(_check_downloader_count, 'objects_downloaded', 1, alice=False)
- d.addCallback(_check_downloader_count, 'objects_conflicted', 0, alice=False)
+ d.addCallback(lambda ign: self._check_downloader_count('objects_failed', 0, magic=self.alice_magicfolder))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 1, magic=self.alice_magicfolder))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 0, magic=self.alice_magicfolder))
+
+ def Alice_conflicts_with_Bob():
+ print "Alice conflicts with Bob\n"
+ downloaded_d = self.bob_magicfolder.downloader.set_hook('processed')
+ uploadable = Data("do not follow the white rabbit", self.alice_magicfolder._client.convergence)
+ alice_dmd = self.alice_magicfolder.uploader._upload_dirnode
+ d2 = alice_dmd.add_file(u"file1", uploadable,
+ metadata={"version": 5,
+ "last_downloaded_uri" : "URI:LIT:" },
+ overwrite=True)
+ print "Waiting for Alice to upload\n"
+ d2.addCallback(lambda ign: bob_clock.advance(6))
+ d2.addCallback(lambda ign: downloaded_d)
+ d2.addCallback(lambda ign: self.failUnless(alice_dmd.has_child(encoded_path_u)))
+ return d2
+
+ d.addCallback(lambda ign: Alice_conflicts_with_Bob())
+ # XXX fix the code so that it doesn't increment objects_excluded each turn
+ #d.addCallback(lambda ign: self._check_downloader_count('objects_excluded', 1))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_downloaded', 4))
+ d.addCallback(lambda ign: self._check_downloader_count('objects_conflicted', 1))
def _cleanup(ign, magicfolder, clock):
if magicfolder is not None:
self.inotify = fake_inotify
self.patch(magic_folder, 'get_inotify_module', lambda: self.inotify)
- def notify(self, path, mask, magic=None):
+ def notify(self, path, mask, magic=None, flush=True):
if magic is None:
magic = self.magicfolder
magic.uploader._notifier.event(path, mask)
+ # no flush for the mock test.
def test_errors(self):
self.set_up_grid()
self.shouldFail(AssertionError, 'readonly upload.dircap', 'is not a writecap to a directory',
MagicFolder, client, readonly_dircap, '', errors_dir, magicfolderdb,)
self.shouldFail(AssertionError, 'collective dircap',
- "The URI in 'private/collective_dircap' is not a readonly cap to a directory.",
+ "The URI in '%s' is not a readonly cap to a directory." % os.path.join('private', 'collective_dircap'),
MagicFolder, client, upload_dircap, upload_dircap, errors_dir, magicfolderdb)
def _not_implemented():
MagicFolderTestMixin.setUp(self)
self.inotify = magic_folder.get_inotify_module()
- def notify(self, path, mask, **kw):
+ def notify(self, path, mask, magic=None, flush=True):
# Writing to the filesystem causes the notification.
- pass
+ # However, flushing filesystem buffers may be necessary on Windows.
+ if flush:
+ fileutil.flush_volume(path)
try:
magic_folder.get_inotify_module()