mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-02 00:21:15 +00:00
Prepare to move drop_upload.py to magic_folder.py.
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
76a178969d
commit
3170cab0fc
@ -144,7 +144,7 @@ class Client(node.Node, pollmixin.PollMixin):
|
||||
self.init_helper()
|
||||
self.init_ftp_server()
|
||||
self.init_sftp_server()
|
||||
self.init_drop_uploader()
|
||||
self.init_magic_folder()
|
||||
|
||||
# If the node sees an exit_trigger file, it will poll every second to see
|
||||
# whether the file still exists, and what its mtime is. If the file does not
|
||||
@ -472,28 +472,31 @@ class Client(node.Node, pollmixin.PollMixin):
|
||||
sftp_portstr, pubkey_file, privkey_file)
|
||||
s.setServiceParent(self)
|
||||
|
||||
def init_drop_uploader(self):
|
||||
def init_magic_folder(self):
|
||||
#print "init_magic_folder"
|
||||
if self.get_config("drop_upload", "enabled", False, boolean=True):
|
||||
if self.get_config("drop_upload", "upload.dircap", None):
|
||||
raise OldConfigOptionError("The [drop_upload]upload.dircap option is no longer supported; please "
|
||||
"put the cap in a 'private/drop_upload_dircap' file, and delete this option.")
|
||||
raise OldConfigOptionError("The [drop_upload] section must be renamed to [magic_folder].\n"
|
||||
"See docs/frontends/magic-folder.rst for more information.")
|
||||
|
||||
upload_dircap = self.get_or_create_private_config("drop_upload_dircap")
|
||||
local_dir_config = self.get_config("drop_upload", "local.directory").decode("utf-8")
|
||||
if self.get_config("magic_folder", "enabled", False, boolean=True):
|
||||
#print "magic folder enabled"
|
||||
upload_dircap = self.get_private_config("magic_folder_dircap")
|
||||
collective_dircap = self.get_private_config("collective_dircap")
|
||||
|
||||
local_dir_config = self.get_config("magic_folder", "local.directory").decode("utf-8")
|
||||
local_dir = abspath_expanduser_unicode(local_dir_config, base=self.basedir)
|
||||
|
||||
try:
|
||||
from allmydata.frontends import drop_upload
|
||||
dbfile = os.path.join(self.basedir, "private", "magicfolderdb.sqlite")
|
||||
dbfile = abspath_expanduser_unicode(dbfile)
|
||||
s = drop_upload.DropUploader(self, upload_dircap, local_dir, dbfile)
|
||||
s.setServiceParent(self)
|
||||
s.startService()
|
||||
dbfile = os.path.join(self.basedir, "private", "magicfolderdb.sqlite")
|
||||
dbfile = abspath_expanduser_unicode(dbfile)
|
||||
|
||||
# start processing the upload queue when we've connected to enough servers
|
||||
self.connected_enough_d.addCallback(s.ready)
|
||||
except Exception, e:
|
||||
self.log("couldn't start drop-uploader: %r", args=(e,))
|
||||
from allmydata.frontends import magic_folder
|
||||
|
||||
s = magic_folder.MagicFolder(self, upload_dircap, local_dir, dbfile)
|
||||
s.setServiceParent(self)
|
||||
s.startService()
|
||||
|
||||
# start processing the upload queue when we've connected to enough servers
|
||||
self.connected_enough_d.addCallback(s.ready)
|
||||
|
||||
def _check_exit_trigger(self, exit_trigger_file):
|
||||
if os.path.exists(exit_trigger_file):
|
||||
|
@ -15,8 +15,9 @@ from allmydata.immutable.upload import FileName
|
||||
from allmydata import backupdb
|
||||
|
||||
|
||||
class DropUploader(service.MultiService):
|
||||
name = 'drop-upload'
|
||||
|
||||
class MagicFolder(service.MultiService):
|
||||
name = 'magic-folder'
|
||||
|
||||
def __init__(self, client, upload_dircap, local_dir, dbfile, inotify=None,
|
||||
pending_delay=1.0):
|
||||
@ -40,20 +41,20 @@ class DropUploader(service.MultiService):
|
||||
self._inotify = inotify
|
||||
|
||||
if not self._local_path.exists():
|
||||
raise AssertionError("The '[drop_upload] local.directory' parameter was %s "
|
||||
raise AssertionError("The '[magic_folder] local.directory' parameter was %s "
|
||||
"but there is no directory at that location."
|
||||
% quote_local_unicode_path(local_dir))
|
||||
if not self._local_path.isdir():
|
||||
raise AssertionError("The '[drop_upload] local.directory' parameter was %s "
|
||||
raise AssertionError("The '[magic_folder] local.directory' parameter was %s "
|
||||
"but the thing at that location is not a directory."
|
||||
% quote_local_unicode_path(local_dir))
|
||||
|
||||
# TODO: allow a path rather than a cap URI.
|
||||
self._parent = self._client.create_node_from_uri(upload_dircap)
|
||||
if not IDirectoryNode.providedBy(self._parent):
|
||||
raise AssertionError("The URI in 'private/drop_upload_dircap' does not refer to a directory.")
|
||||
raise AssertionError("The URI in 'private/magic_folder_dircap' does not refer to a directory.")
|
||||
if self._parent.is_unknown() or self._parent.is_readonly():
|
||||
raise AssertionError("The URI in 'private/drop_upload_dircap' is not a writecap to a directory.")
|
||||
raise AssertionError("The URI in 'private/magic_folder_dircap' is not a writecap to a directory.")
|
||||
|
||||
self._uploaded_callback = lambda ign: None
|
||||
|
||||
|
@ -4,7 +4,7 @@ from twisted.trial import unittest
|
||||
from twisted.application import service
|
||||
|
||||
import allmydata
|
||||
import allmydata.frontends.drop_upload
|
||||
import allmydata.frontends.magic_folder
|
||||
import allmydata.util.log
|
||||
|
||||
from allmydata.node import Node, OldConfigError, OldConfigOptionError, MissingConfigEntry, UnescapedHashError
|
||||
@ -299,9 +299,9 @@ class Basic(testutil.ReallyEqualMixin, testutil.NonASCIIPathMixin, unittest.Test
|
||||
_check("helper.furl = None", None)
|
||||
_check("helper.furl = pb://blah\n", "pb://blah")
|
||||
|
||||
def test_create_drop_uploader(self):
|
||||
class MockDropUploader(service.MultiService):
|
||||
name = 'drop-upload'
|
||||
def test_create_magic_folder_service(self):
|
||||
class MockMagicFolder(service.MultiService):
|
||||
name = 'magic-folder'
|
||||
|
||||
def __init__(self, client, upload_dircap, local_dir, dbfile, inotify=None,
|
||||
pending_delay=1.0):
|
||||
@ -312,7 +312,7 @@ class Basic(testutil.ReallyEqualMixin, testutil.NonASCIIPathMixin, unittest.Test
|
||||
self.dbfile = dbfile
|
||||
self.inotify = inotify
|
||||
|
||||
self.patch(allmydata.frontends.drop_upload, 'DropUploader', MockDropUploader)
|
||||
self.patch(allmydata.frontends.magic_folder, 'MagicFolder', MockMagicFolder)
|
||||
|
||||
upload_dircap = "URI:DIR2:blah"
|
||||
local_dir_u = self.unicode_or_fallback(u"loc\u0101l_dir", u"local_dir")
|
||||
@ -320,56 +320,56 @@ class Basic(testutil.ReallyEqualMixin, testutil.NonASCIIPathMixin, unittest.Test
|
||||
config = (BASECONFIG +
|
||||
"[storage]\n" +
|
||||
"enabled = false\n" +
|
||||
"[drop_upload]\n" +
|
||||
"[magic_folder]\n" +
|
||||
"enabled = true\n")
|
||||
|
||||
basedir1 = "test_client.Basic.test_create_drop_uploader1"
|
||||
basedir1 = "test_client.Basic.test_create_magic_folder_service1"
|
||||
os.mkdir(basedir1)
|
||||
fileutil.write(os.path.join(basedir1, "tahoe.cfg"),
|
||||
config + "local.directory = " + local_dir_utf8 + "\n")
|
||||
self.failUnlessRaises(MissingConfigEntry, client.Client, basedir1)
|
||||
|
||||
fileutil.write(os.path.join(basedir1, "tahoe.cfg"), config)
|
||||
fileutil.write(os.path.join(basedir1, "private", "drop_upload_dircap"), "URI:DIR2:blah")
|
||||
fileutil.write(os.path.join(basedir1, "private", "magic_folder_dircap"), "URI:DIR2:blah")
|
||||
self.failUnlessRaises(MissingConfigEntry, client.Client, basedir1)
|
||||
|
||||
fileutil.write(os.path.join(basedir1, "tahoe.cfg"),
|
||||
config + "upload.dircap = " + upload_dircap + "\n")
|
||||
config.replace("[magic_folder]\n", "[drop_upload]\n"))
|
||||
self.failUnlessRaises(OldConfigOptionError, client.Client, basedir1)
|
||||
|
||||
fileutil.write(os.path.join(basedir1, "tahoe.cfg"),
|
||||
config + "local.directory = " + local_dir_utf8 + "\n")
|
||||
c1 = client.Client(basedir1)
|
||||
uploader = c1.getServiceNamed('drop-upload')
|
||||
self.failUnless(isinstance(uploader, MockDropUploader), uploader)
|
||||
self.failUnlessReallyEqual(uploader.client, c1)
|
||||
self.failUnlessReallyEqual(uploader.upload_dircap, upload_dircap)
|
||||
self.failUnlessReallyEqual(os.path.basename(uploader.local_dir), local_dir_u)
|
||||
self.failUnless(uploader.inotify is None, uploader.inotify)
|
||||
self.failUnless(uploader.running)
|
||||
magicfolder = c1.getServiceNamed('magic-folder')
|
||||
self.failUnless(isinstance(magicfolder, MockMagicFolder), magicfolder)
|
||||
self.failUnlessReallyEqual(magicfolder.client, c1)
|
||||
self.failUnlessReallyEqual(magicfolder.upload_dircap, upload_dircap)
|
||||
self.failUnlessReallyEqual(os.path.basename(magicfolder.local_dir), local_dir_u)
|
||||
self.failUnless(magicfolder.inotify is None, magicfolder.inotify)
|
||||
self.failUnless(magicfolder.running)
|
||||
|
||||
class Boom(Exception):
|
||||
pass
|
||||
def BoomDropUploader(client, upload_dircap, local_dir_utf8, inotify=None):
|
||||
def BoomMagicFolder(client, upload_dircap, local_dir_utf8, inotify=None):
|
||||
raise Boom()
|
||||
self.patch(allmydata.frontends.magic_folder, 'MagicFolder', BoomMagicFolder)
|
||||
|
||||
logged_messages = []
|
||||
def mock_log(*args, **kwargs):
|
||||
logged_messages.append("%r %r" % (args, kwargs))
|
||||
self.patch(allmydata.util.log, 'msg', mock_log)
|
||||
self.patch(allmydata.frontends.drop_upload, 'DropUploader', BoomDropUploader)
|
||||
|
||||
basedir2 = "test_client.Basic.test_create_drop_uploader2"
|
||||
basedir2 = "test_client.Basic.test_create_magic_folder_service2"
|
||||
os.mkdir(basedir2)
|
||||
os.mkdir(os.path.join(basedir2, "private"))
|
||||
fileutil.write(os.path.join(basedir2, "tahoe.cfg"),
|
||||
BASECONFIG +
|
||||
"[drop_upload]\n" +
|
||||
"[magic_folder]\n" +
|
||||
"enabled = true\n" +
|
||||
"local.directory = " + local_dir_utf8 + "\n")
|
||||
fileutil.write(os.path.join(basedir2, "private", "drop_upload_dircap"), "URI:DIR2:blah")
|
||||
fileutil.write(os.path.join(basedir2, "private", "magic_folder_dircap"), "URI:DIR2:blah")
|
||||
c2 = client.Client(basedir2)
|
||||
self.failUnlessRaises(KeyError, c2.getServiceNamed, 'drop-upload')
|
||||
self.failUnlessRaises(KeyError, c2.getServiceNamed, 'magic-folder')
|
||||
self.failUnless([True for arg in logged_messages if "Boom" in arg],
|
||||
logged_messages)
|
||||
|
||||
|
@ -14,11 +14,11 @@ from allmydata.test.no_network import GridTestMixin
|
||||
from allmydata.test.common_util import ReallyEqualMixin, NonASCIIPathMixin
|
||||
from allmydata.test.common import ShouldFailMixin
|
||||
|
||||
from allmydata.frontends.drop_upload import DropUploader
|
||||
from allmydata.frontends.magic_folder import MagicFolder
|
||||
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||
|
||||
|
||||
class DropUploadTestMixin(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, NonASCIIPathMixin):
|
||||
class MagicFolderTestMixin(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, NonASCIIPathMixin):
|
||||
"""
|
||||
These tests will be run both with a mock notifier, and (on platforms that support it)
|
||||
with the real INotify.
|
||||
@ -122,7 +122,7 @@ class DropUploadTestMixin(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, NonA
|
||||
return d
|
||||
|
||||
|
||||
class MockTest(DropUploadTestMixin, unittest.TestCase):
|
||||
class MockTest(MagicFolderTestMixin, unittest.TestCase):
|
||||
"""This can run on any platform, and even if twisted.internet.inotify can't be imported."""
|
||||
|
||||
def test_errors(self):
|
||||
@ -143,15 +143,15 @@ class MockTest(DropUploadTestMixin, unittest.TestCase):
|
||||
readonly_dircap = n.get_readonly_uri()
|
||||
|
||||
self.shouldFail(AssertionError, 'nonexistent local.directory', 'there is no directory',
|
||||
DropUploader, client, upload_dircap, doesnotexist, inotify=fake_inotify)
|
||||
MagicFolder, client, upload_dircap, doesnotexist, inotify=fake_inotify)
|
||||
self.shouldFail(AssertionError, 'non-directory local.directory', 'is not a directory',
|
||||
DropUploader, client, upload_dircap, not_a_dir, inotify=fake_inotify)
|
||||
MagicFolder, client, upload_dircap, not_a_dir, inotify=fake_inotify)
|
||||
self.shouldFail(AssertionError, 'bad upload.dircap', 'does not refer to a directory',
|
||||
DropUploader, client, 'bad', errors_dir, inotify=fake_inotify)
|
||||
MagicFolder, client, 'bad', errors_dir, inotify=fake_inotify)
|
||||
self.shouldFail(AssertionError, 'non-directory upload.dircap', 'does not refer to a directory',
|
||||
DropUploader, client, 'URI:LIT:foo', errors_dir, inotify=fake_inotify)
|
||||
MagicFolder, client, 'URI:LIT:foo', errors_dir, inotify=fake_inotify)
|
||||
self.shouldFail(AssertionError, 'readonly upload.dircap', 'is not a writecap to a directory',
|
||||
DropUploader, client, readonly_dircap, errors_dir, inotify=fake_inotify)
|
||||
MagicFolder, client, readonly_dircap, errors_dir, inotify=fake_inotify)
|
||||
d.addCallback(_made_upload_dir)
|
||||
return d
|
||||
|
||||
@ -164,7 +164,7 @@ class MockTest(DropUploadTestMixin, unittest.TestCase):
|
||||
self.uploader._notifier.event(path, self.inotify.IN_CLOSE_WRITE)
|
||||
|
||||
|
||||
class RealTest(DropUploadTestMixin, unittest.TestCase):
|
||||
class RealTest(MagicFolderTestMixin, unittest.TestCase):
|
||||
"""This is skipped unless both Twisted and the platform support inotify."""
|
||||
|
||||
def test_drop_upload(self):
|
||||
@ -177,4 +177,4 @@ class RealTest(DropUploadTestMixin, unittest.TestCase):
|
||||
pass
|
||||
|
||||
if sys.platform != "win32" and not runtime.platform.supportsINotify():
|
||||
RealTest.skip = "Drop-upload support can only be tested for-real on an OS that supports inotify or equivalent."
|
||||
RealTest.skip = "Magic Folder support can only be tested for-real on an OS that supports inotify or equivalent."
|
||||
|
Loading…
x
Reference in New Issue
Block a user