mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-06-21 08:29:41 +00:00
put create() methods in i2p_, tor_provider
Also Provider -> _Provider, improve docs and update tests
This commit is contained in:
@ -22,6 +22,8 @@ from allmydata.util.encodingutil import (get_filesystem_encoding,
|
|||||||
from_utf8_or_none)
|
from_utf8_or_none)
|
||||||
from allmydata.util.abbreviate import parse_abbreviated_size
|
from allmydata.util.abbreviate import parse_abbreviated_size
|
||||||
from allmydata.util.time_format import parse_duration, parse_date
|
from allmydata.util.time_format import parse_duration, parse_date
|
||||||
|
from allmydata.util.i2p_provider import create as create_i2p_provider
|
||||||
|
from allmydata.util.tor_provider import create as create_tor_provider
|
||||||
from allmydata.stats import StatsProvider
|
from allmydata.stats import StatsProvider
|
||||||
from allmydata.history import History
|
from allmydata.history import History
|
||||||
from allmydata.interfaces import IStatsProducer, SDMF_VERSION, MDMF_VERSION
|
from allmydata.interfaces import IStatsProducer, SDMF_VERSION, MDMF_VERSION
|
||||||
@ -210,8 +212,6 @@ def create_client(basedir=u".", _client_factory=None):
|
|||||||
# this can/should be async
|
# this can/should be async
|
||||||
# @defer.inlineCallbacks
|
# @defer.inlineCallbacks
|
||||||
def create_client_from_config(basedir, config):
|
def create_client_from_config(basedir, config):
|
||||||
from twisted.internet import reactor
|
|
||||||
from allmydata.node import create_i2p_provider, create_tor_provider
|
|
||||||
i2p_provider = create_i2p_provider(reactor, basedir, config)
|
i2p_provider = create_i2p_provider(reactor, basedir, config)
|
||||||
tor_provider = create_tor_provider(reactor, basedir, config)
|
tor_provider = create_tor_provider(reactor, basedir, config)
|
||||||
handlers = create_connection_handlers(reactor, basedir, config, i2p_provider, tor_provider)
|
handlers = create_connection_handlers(reactor, basedir, config, i2p_provider, tor_provider)
|
||||||
|
@ -7,6 +7,10 @@ from foolscap.api import Referenceable
|
|||||||
import allmydata
|
import allmydata
|
||||||
from allmydata import node
|
from allmydata import node
|
||||||
from allmydata.util import log, rrefutil
|
from allmydata.util import log, rrefutil
|
||||||
|
from allmydata.util import fileutil
|
||||||
|
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||||
|
from allmydata.util.i2p_provider import create as create_i2p_provider
|
||||||
|
from allmydata.util.tor_provider import create as create_tor_provider
|
||||||
from allmydata.introducer.interfaces import \
|
from allmydata.introducer.interfaces import \
|
||||||
RIIntroducerPublisherAndSubscriberService_v2
|
RIIntroducerPublisherAndSubscriberService_v2
|
||||||
from allmydata.introducer.common import unsign_from_foolscap, \
|
from allmydata.introducer.common import unsign_from_foolscap, \
|
||||||
@ -48,7 +52,6 @@ def create_introducer(basedir=u"."):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# XXX fix up imports etc (also: reactor)
|
# XXX fix up imports etc (also: reactor)
|
||||||
from allmydata.node import create_i2p_provider, create_tor_provider
|
|
||||||
i2p_provider = create_i2p_provider(reactor, basedir, config)
|
i2p_provider = create_i2p_provider(reactor, basedir, config)
|
||||||
tor_provider = create_tor_provider(reactor, basedir, config)
|
tor_provider = create_tor_provider(reactor, basedir, config)
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ from allmydata.util.assertutil import _assert
|
|||||||
from allmydata.util.fileutil import abspath_expanduser_unicode
|
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||||
from allmydata.util.encodingutil import get_filesystem_encoding, quote_output
|
from allmydata.util.encodingutil import get_filesystem_encoding, quote_output
|
||||||
from allmydata.util import configutil
|
from allmydata.util import configutil
|
||||||
from allmydata.util import i2p_provider, tor_provider
|
|
||||||
|
|
||||||
def _common_config_sections():
|
def _common_config_sections():
|
||||||
return {
|
return {
|
||||||
@ -430,18 +429,6 @@ def create_tub_options(config):
|
|||||||
return tub_options
|
return tub_options
|
||||||
|
|
||||||
|
|
||||||
def create_i2p_provider(reactor, basedir, config):
|
|
||||||
provider = i2p_provider.Provider(basedir, config, reactor)
|
|
||||||
provider.check_dest_config()
|
|
||||||
return provider
|
|
||||||
|
|
||||||
|
|
||||||
def create_tor_provider(reactor, basedir, config):
|
|
||||||
provider = tor_provider.Provider(basedir, config, reactor)
|
|
||||||
provider.check_onion_config()
|
|
||||||
return provider
|
|
||||||
|
|
||||||
|
|
||||||
def _make_tcp_handler():
|
def _make_tcp_handler():
|
||||||
# this is always available
|
# this is always available
|
||||||
from foolscap.connections.tcp import default
|
from foolscap.connections.tcp import default
|
||||||
|
@ -193,16 +193,15 @@ class FakeConfig(dict):
|
|||||||
|
|
||||||
class Provider(unittest.TestCase):
|
class Provider(unittest.TestCase):
|
||||||
def test_build(self):
|
def test_build(self):
|
||||||
i2p_provider.Provider(FakeConfig(), "reactor")
|
i2p_provider.create("reactor", FakeConfig())
|
||||||
|
|
||||||
def test_handler_disabled(self):
|
def test_handler_disabled(self):
|
||||||
p = i2p_provider.Provider(FakeConfig(enabled=False),
|
p = i2p_provider.create("reactor", FakeConfig(enabled=False))
|
||||||
"reactor")
|
|
||||||
self.assertEqual(p.get_i2p_handler(), None)
|
self.assertEqual(p.get_i2p_handler(), None)
|
||||||
|
|
||||||
def test_handler_no_i2p(self):
|
def test_handler_no_i2p(self):
|
||||||
with mock_i2p(None):
|
with mock_i2p(None):
|
||||||
p = i2p_provider.Provider(FakeConfig(), "reactor")
|
p = i2p_provider.create("reactor", FakeConfig())
|
||||||
self.assertEqual(p.get_i2p_handler(), None)
|
self.assertEqual(p.get_i2p_handler(), None)
|
||||||
|
|
||||||
def test_handler_sam_endpoint(self):
|
def test_handler_sam_endpoint(self):
|
||||||
@ -213,8 +212,8 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(**{"sam.port": "ep_desc"}),
|
p = i2p_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(**{"sam.port": "ep_desc"}))
|
||||||
with mock.patch("allmydata.util.i2p_provider.clientFromString",
|
with mock.patch("allmydata.util.i2p_provider.clientFromString",
|
||||||
return_value=ep) as cfs:
|
return_value=ep) as cfs:
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
@ -229,8 +228,8 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(launch=True),
|
p = i2p_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(launch=True))
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
i2p.launch.assert_called_with(i2p_configdir=None, i2p_binary=None)
|
i2p.launch.assert_called_with(i2p_configdir=None, i2p_binary=None)
|
||||||
@ -242,9 +241,9 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(launch=True,
|
p = i2p_provider.create(reactor,
|
||||||
**{"i2p.configdir": "configdir"}),
|
FakeConfig(launch=True,
|
||||||
reactor)
|
**{"i2p.configdir": "configdir"}))
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
i2p.launch.assert_called_with(i2p_configdir="configdir", i2p_binary=None)
|
i2p.launch.assert_called_with(i2p_configdir="configdir", i2p_binary=None)
|
||||||
@ -256,11 +255,11 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(launch=True,
|
p = i2p_provider.create(reactor,
|
||||||
**{"i2p.configdir": "configdir",
|
FakeConfig(launch=True,
|
||||||
"i2p.executable": "myi2p",
|
**{"i2p.configdir": "configdir",
|
||||||
}),
|
"i2p.executable": "myi2p",
|
||||||
reactor)
|
}))
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
i2p.launch.assert_called_with(i2p_configdir="configdir", i2p_binary="myi2p")
|
i2p.launch.assert_called_with(i2p_configdir="configdir", i2p_binary="myi2p")
|
||||||
@ -272,8 +271,8 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(**{"i2p.configdir": "configdir"}),
|
p = i2p_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(**{"i2p.configdir": "configdir"}))
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
i2p.local_i2p.assert_called_with("configdir")
|
i2p.local_i2p.assert_called_with("configdir")
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
@ -285,7 +284,7 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(), reactor)
|
p = i2p_provider.create(reactor, FakeConfig())
|
||||||
h = p.get_i2p_handler()
|
h = p.get_i2p_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
i2p.default.assert_called_with(reactor, keyfile=None)
|
i2p.default.assert_called_with(reactor, keyfile=None)
|
||||||
@ -304,14 +303,14 @@ class ProviderListener(unittest.TestCase):
|
|||||||
|
|
||||||
privkeyfile = os.path.join("private", "i2p_dest.privkey")
|
privkeyfile = os.path.join("private", "i2p_dest.privkey")
|
||||||
with mock_i2p(i2p):
|
with mock_i2p(i2p):
|
||||||
p = i2p_provider.Provider(FakeConfig(**{
|
p = i2p_provider.create(reactor,
|
||||||
"i2p.configdir": "configdir",
|
FakeConfig(**{
|
||||||
"sam.port": "good:port",
|
"i2p.configdir": "configdir",
|
||||||
"dest": "true",
|
"sam.port": "good:port",
|
||||||
"dest.port": "3457",
|
"dest": "true",
|
||||||
"dest.private_key_file": privkeyfile,
|
"dest.port": "3457",
|
||||||
}),
|
"dest.private_key_file": privkeyfile,
|
||||||
reactor)
|
}))
|
||||||
endpoint_or_description = p.get_listener()
|
endpoint_or_description = p.get_listener()
|
||||||
self.assertEqual(endpoint_or_description,
|
self.assertEqual(endpoint_or_description,
|
||||||
"i2p:%s:3457:api=SAM:apiEndpoint=good\\:port" % privkeyfile)
|
"i2p:%s:3457:api=SAM:apiEndpoint=good\\:port" % privkeyfile)
|
||||||
@ -321,55 +320,75 @@ class Provider_CheckI2PConfig(unittest.TestCase):
|
|||||||
# default config doesn't start an I2P service, so it should be
|
# default config doesn't start an I2P service, so it should be
|
||||||
# happy both with and without txi2p
|
# happy both with and without txi2p
|
||||||
|
|
||||||
p = i2p_provider.Provider(FakeConfig(), "reactor")
|
p = i2p_provider.create("reactor", FakeConfig())
|
||||||
p.check_dest_config()
|
p.check_dest_config()
|
||||||
|
|
||||||
with mock_txi2p(None):
|
with mock_txi2p(None):
|
||||||
p = i2p_provider.Provider(FakeConfig(), "reactor")
|
p = i2p_provider.create("reactor", FakeConfig())
|
||||||
p.check_dest_config()
|
p.check_dest_config()
|
||||||
|
|
||||||
def test_no_txi2p(self):
|
def test_no_txi2p(self):
|
||||||
with mock_txi2p(None):
|
with mock_txi2p(None):
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True),
|
with self.assertRaises(ValueError) as ctx:
|
||||||
"reactor")
|
i2p_provider.create("reactor", FakeConfig(dest=True))
|
||||||
e = self.assertRaises(ValueError, p.check_dest_config)
|
self.assertEqual(
|
||||||
self.assertEqual(str(e), "Cannot create I2P Destination without txi2p. "
|
str(ctx.exception),
|
||||||
"Please 'pip install tahoe-lafs[i2p]' to fix.")
|
"Cannot create I2P Destination without txi2p. "
|
||||||
|
"Please 'pip install tahoe-lafs[i2p]' to fix."
|
||||||
|
)
|
||||||
|
|
||||||
def test_no_launch_no_control(self):
|
def test_no_launch_no_control(self):
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True), "reactor")
|
with self.assertRaises(ValueError) as ctx:
|
||||||
e = self.assertRaises(ValueError, p.check_dest_config)
|
i2p_provider.create("reactor", FakeConfig(dest=True))
|
||||||
self.assertEqual(str(e), "[i2p] dest = true, but we have neither "
|
self.assertEqual(
|
||||||
"sam.port= nor launch=true nor configdir=")
|
str(ctx.exception),
|
||||||
|
"[i2p] dest = true, but we have neither "
|
||||||
|
"sam.port= nor launch=true nor configdir="
|
||||||
|
)
|
||||||
|
|
||||||
def test_missing_keys(self):
|
def test_missing_keys(self):
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True,
|
with self.assertRaises(ValueError) as ctx:
|
||||||
**{"sam.port": "x",
|
i2p_provider.create("reactor",
|
||||||
}), "reactor")
|
FakeConfig(
|
||||||
e = self.assertRaises(ValueError, p.check_dest_config)
|
dest=True,
|
||||||
self.assertEqual(str(e), "[i2p] dest = true, "
|
**{"sam.port": "x",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
self.assertEqual(str(ctx.exception), "[i2p] dest = true, "
|
||||||
"but dest.port= is missing")
|
"but dest.port= is missing")
|
||||||
|
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True,
|
with self.assertRaises(ValueError) as ctx:
|
||||||
**{"sam.port": "x",
|
i2p_provider.create("reactor",
|
||||||
"dest.port": "y",
|
FakeConfig(dest=True,
|
||||||
}), "reactor")
|
**{"sam.port": "x",
|
||||||
e = self.assertRaises(ValueError, p.check_dest_config)
|
"dest.port": "y",
|
||||||
self.assertEqual(str(e), "[i2p] dest = true, "
|
}))
|
||||||
"but dest.private_key_file= is missing")
|
self.assertEqual(
|
||||||
|
str(ctx.exception),
|
||||||
|
"[i2p] dest = true, "
|
||||||
|
"but dest.private_key_file= is missing"
|
||||||
|
)
|
||||||
|
|
||||||
def test_launch_not_implemented(self):
|
def test_launch_not_implemented(self):
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True, launch=True,
|
with self.assertRaises(NotImplementedError) as ctx:
|
||||||
**{"dest.port": "x",
|
i2p_provider.create("reactor",
|
||||||
"dest.private_key_file": "y",
|
FakeConfig(dest=True, launch=True,
|
||||||
}), "reactor")
|
**{"dest.port": "x",
|
||||||
e = self.assertRaises(NotImplementedError, p.check_dest_config)
|
"dest.private_key_file": "y",
|
||||||
self.assertEqual(str(e), "[i2p] launch is under development.")
|
}))
|
||||||
|
self.assertEqual(
|
||||||
|
str(ctx.exception),
|
||||||
|
"[i2p] launch is under development."
|
||||||
|
)
|
||||||
|
|
||||||
def test_ok(self):
|
def test_ok(self):
|
||||||
p = i2p_provider.Provider(FakeConfig(dest=True,
|
i2p_provider.create(
|
||||||
**{"sam.port": "x",
|
"reactor",
|
||||||
"dest.port": "y",
|
FakeConfig(
|
||||||
"dest.private_key_file": "z",
|
dest=True, **{
|
||||||
}), "reactor")
|
"sam.port": "x",
|
||||||
p.check_dest_config()
|
"dest.port": "y",
|
||||||
|
"dest.private_key_file": "z",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -286,22 +286,20 @@ class EmptyContext(object):
|
|||||||
|
|
||||||
class Provider(unittest.TestCase):
|
class Provider(unittest.TestCase):
|
||||||
def test_build(self):
|
def test_build(self):
|
||||||
tor_provider.Provider(FakeConfig(), "reactor")
|
tor_provider.create("reactor", FakeConfig())
|
||||||
|
|
||||||
def test_handler_disabled(self):
|
def test_handler_disabled(self):
|
||||||
p = tor_provider.Provider(FakeConfig(enabled=False),
|
p = tor_provider.create("reactor", FakeConfig(enabled=False))
|
||||||
"reactor")
|
|
||||||
self.assertEqual(p.get_tor_handler(), None)
|
self.assertEqual(p.get_tor_handler(), None)
|
||||||
|
|
||||||
def test_handler_no_tor(self):
|
def test_handler_no_tor(self):
|
||||||
with mock_tor(None):
|
with mock_tor(None):
|
||||||
p = tor_provider.Provider(FakeConfig(), "reactor")
|
p = tor_provider.create("reactor", FakeConfig())
|
||||||
self.assertEqual(p.get_tor_handler(), None)
|
self.assertEqual(p.get_tor_handler(), None)
|
||||||
|
|
||||||
def test_handler_launch_no_txtorcon(self):
|
def test_handler_launch_no_txtorcon(self):
|
||||||
with mock_txtorcon(None):
|
with mock_txtorcon(None):
|
||||||
p = tor_provider.Provider(FakeConfig(launch=True),
|
p = tor_provider.create("reactor", FakeConfig(launch=True))
|
||||||
"reactor")
|
|
||||||
self.assertEqual(p.get_tor_handler(), None)
|
self.assertEqual(p.get_tor_handler(), None)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@ -314,8 +312,7 @@ class Provider(unittest.TestCase):
|
|||||||
tor.add_context = mock.Mock(return_value=EmptyContext())
|
tor.add_context = mock.Mock(return_value=EmptyContext())
|
||||||
with mock_tor(tor):
|
with mock_tor(tor):
|
||||||
with mock_txtorcon(txtorcon):
|
with mock_txtorcon(txtorcon):
|
||||||
p = tor_provider.Provider(FakeConfig(launch=True),
|
p = tor_provider.create(reactor, FakeConfig(launch=True))
|
||||||
reactor)
|
|
||||||
h = p.get_tor_handler()
|
h = p.get_tor_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
tor.control_endpoint_maker.assert_called_with(p._make_control_endpoint,
|
tor.control_endpoint_maker.assert_called_with(p._make_control_endpoint,
|
||||||
@ -360,8 +357,8 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_tor(tor):
|
with mock_tor(tor):
|
||||||
p = tor_provider.Provider(FakeConfig(**{"socks.port": "ep_desc"}),
|
p = tor_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(**{"socks.port": "ep_desc"}))
|
||||||
with mock.patch("allmydata.util.tor_provider.clientFromString", cfs):
|
with mock.patch("allmydata.util.tor_provider.clientFromString", cfs):
|
||||||
h = p.get_tor_handler()
|
h = p.get_tor_handler()
|
||||||
cfs.assert_called_with(reactor, "ep_desc")
|
cfs.assert_called_with(reactor, "ep_desc")
|
||||||
@ -377,8 +374,8 @@ class Provider(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_tor(tor):
|
with mock_tor(tor):
|
||||||
p = tor_provider.Provider(FakeConfig(**{"control.port": "ep_desc"}),
|
p = tor_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(**{"control.port": "ep_desc"}))
|
||||||
with mock.patch("allmydata.util.tor_provider.clientFromString", cfs):
|
with mock.patch("allmydata.util.tor_provider.clientFromString", cfs):
|
||||||
h = p.get_tor_handler()
|
h = p.get_tor_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
@ -391,7 +388,7 @@ class Provider(unittest.TestCase):
|
|||||||
tor.default_socks = mock.Mock(return_value=handler)
|
tor.default_socks = mock.Mock(return_value=handler)
|
||||||
|
|
||||||
with mock_tor(tor):
|
with mock_tor(tor):
|
||||||
p = tor_provider.Provider(FakeConfig(), "reactor")
|
p = tor_provider.create("reactor", FakeConfig())
|
||||||
h = p.get_tor_handler()
|
h = p.get_tor_handler()
|
||||||
self.assertIs(h, handler)
|
self.assertIs(h, handler)
|
||||||
tor.default_socks.assert_called_with()
|
tor.default_socks.assert_called_with()
|
||||||
@ -408,8 +405,8 @@ class ProviderListener(unittest.TestCase):
|
|||||||
reactor = object()
|
reactor = object()
|
||||||
|
|
||||||
with mock_tor(tor):
|
with mock_tor(tor):
|
||||||
p = tor_provider.Provider(FakeConfig(**{"onion.local_port": "321"}),
|
p = tor_provider.create(reactor,
|
||||||
reactor)
|
FakeConfig(**{"onion.local_port": "321"}))
|
||||||
fake_ep = object()
|
fake_ep = object()
|
||||||
with mock.patch("allmydata.util.tor_provider.TCP4ServerEndpoint",
|
with mock.patch("allmydata.util.tor_provider.TCP4ServerEndpoint",
|
||||||
return_value=fake_ep) as e:
|
return_value=fake_ep) as e:
|
||||||
@ -423,62 +420,78 @@ class Provider_CheckOnionConfig(unittest.TestCase):
|
|||||||
# default config doesn't start an onion service, so it should be
|
# default config doesn't start an onion service, so it should be
|
||||||
# happy both with and without txtorcon
|
# happy both with and without txtorcon
|
||||||
|
|
||||||
p = tor_provider.Provider(FakeConfig(), "reactor")
|
p = tor_provider.create("reactor", FakeConfig())
|
||||||
p.check_onion_config()
|
p.check_onion_config()
|
||||||
|
|
||||||
with mock_txtorcon(None):
|
with mock_txtorcon(None):
|
||||||
p = tor_provider.Provider(FakeConfig(), "reactor")
|
p = tor_provider.create("reactor", FakeConfig())
|
||||||
p.check_onion_config()
|
p.check_onion_config()
|
||||||
|
|
||||||
def test_no_txtorcon(self):
|
def test_no_txtorcon(self):
|
||||||
with mock_txtorcon(None):
|
with mock_txtorcon(None):
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True),
|
with self.assertRaises(ValueError) as ctx:
|
||||||
"reactor")
|
tor_provider.create("reactor", FakeConfig(onion=True))
|
||||||
e = self.assertRaises(ValueError, p.check_onion_config)
|
self.assertEqual(
|
||||||
self.assertEqual(str(e), "Cannot create onion without txtorcon. "
|
str(ctx.exception),
|
||||||
"Please 'pip install tahoe-lafs[tor]' to fix.")
|
"Cannot create onion without txtorcon. "
|
||||||
|
"Please 'pip install tahoe-lafs[tor]' to fix."
|
||||||
|
)
|
||||||
|
|
||||||
def test_no_launch_no_control(self):
|
def test_no_launch_no_control(self):
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True), "reactor")
|
with self.assertRaises(ValueError) as ctx:
|
||||||
e = self.assertRaises(ValueError, p.check_onion_config)
|
tor_provider.create("reactor", FakeConfig(onion=True))
|
||||||
self.assertEqual(str(e), "[tor] onion = true, but we have neither "
|
self.assertEqual(
|
||||||
"launch=true nor control.port=")
|
str(ctx.exception),
|
||||||
|
"[tor] onion = true, but we have neither "
|
||||||
|
"launch=true nor control.port="
|
||||||
|
)
|
||||||
|
|
||||||
def test_missing_keys(self):
|
def test_missing_keys0(self):
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True,
|
with self.assertRaises(ValueError) as ctx:
|
||||||
launch=True), "reactor")
|
tor_provider.create("reactor", FakeConfig(onion=True, launch=True))
|
||||||
e = self.assertRaises(ValueError, p.check_onion_config)
|
self.assertEqual(
|
||||||
self.assertEqual(str(e), "[tor] onion = true, "
|
str(ctx.exception),
|
||||||
"but onion.local_port= is missing")
|
"[tor] onion = true, "
|
||||||
|
"but onion.local_port= is missing"
|
||||||
|
)
|
||||||
|
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True, launch=True,
|
def test_missing_keys1(self):
|
||||||
**{"onion.local_port": "x",
|
with self.assertRaises(ValueError) as ctx:
|
||||||
}), "reactor")
|
tor_provider.create("reactor",
|
||||||
e = self.assertRaises(ValueError, p.check_onion_config)
|
FakeConfig(onion=True, launch=True,
|
||||||
self.assertEqual(str(e), "[tor] onion = true, "
|
**{"onion.local_port": "x",
|
||||||
"but onion.external_port= is missing")
|
}))
|
||||||
|
self.assertEqual(
|
||||||
|
str(ctx.exception),
|
||||||
|
"[tor] onion = true, but onion.external_port= is missing"
|
||||||
|
)
|
||||||
|
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True, launch=True,
|
def test_missing_keys2(self):
|
||||||
**{"onion.local_port": "x",
|
with self.assertRaises(ValueError) as ctx:
|
||||||
"onion.external_port": "y",
|
tor_provider.create("reactor",
|
||||||
}), "reactor")
|
FakeConfig(onion=True, launch=True,
|
||||||
e = self.assertRaises(ValueError, p.check_onion_config)
|
**{"onion.local_port": "x",
|
||||||
self.assertEqual(str(e), "[tor] onion = true, "
|
"onion.external_port": "y",
|
||||||
"but onion.private_key_file= is missing")
|
}))
|
||||||
|
self.assertEqual(
|
||||||
|
str(ctx.exception),
|
||||||
|
"[tor] onion = true, but onion.private_key_file= is missing"
|
||||||
|
)
|
||||||
|
|
||||||
def test_ok(self):
|
def test_ok(self):
|
||||||
p = tor_provider.Provider(FakeConfig(onion=True, launch=True,
|
p = tor_provider.create("reactor",
|
||||||
**{"onion.local_port": "x",
|
FakeConfig(onion=True, launch=True,
|
||||||
"onion.external_port": "y",
|
**{"onion.local_port": "x",
|
||||||
"onion.private_key_file": "z",
|
"onion.external_port": "y",
|
||||||
}), "reactor")
|
"onion.private_key_file": "z",
|
||||||
|
}))
|
||||||
p.check_onion_config()
|
p.check_onion_config()
|
||||||
|
|
||||||
class Provider_Service(unittest.TestCase):
|
class Provider_Service(unittest.TestCase):
|
||||||
def test_no_onion(self):
|
def test_no_onion(self):
|
||||||
reactor = object()
|
reactor = object()
|
||||||
p = tor_provider.Provider(FakeConfig(onion=False), reactor)
|
p = tor_provider.create(reactor, FakeConfig(onion=False))
|
||||||
with mock.patch("allmydata.util.tor_provider.Provider._start_onion") as s:
|
with mock.patch("allmydata.util.tor_provider._Provider._start_onion") as s:
|
||||||
p.startService()
|
p.startService()
|
||||||
self.assertEqual(s.mock_calls, [])
|
self.assertEqual(s.mock_calls, [])
|
||||||
self.assertEqual(p.running, True)
|
self.assertEqual(p.running, True)
|
||||||
@ -502,7 +515,7 @@ class Provider_Service(unittest.TestCase):
|
|||||||
|
|
||||||
txtorcon = mock.Mock()
|
txtorcon = mock.Mock()
|
||||||
with mock_txtorcon(txtorcon):
|
with mock_txtorcon(txtorcon):
|
||||||
p = tor_provider.Provider(cfg, reactor)
|
p = tor_provider.create(reactor, basedir, cfg)
|
||||||
tor_state = mock.Mock()
|
tor_state = mock.Mock()
|
||||||
tor_state.protocol = object()
|
tor_state.protocol = object()
|
||||||
ehs = mock.Mock()
|
ehs = mock.Mock()
|
||||||
@ -543,7 +556,7 @@ class Provider_Service(unittest.TestCase):
|
|||||||
|
|
||||||
txtorcon = mock.Mock()
|
txtorcon = mock.Mock()
|
||||||
with mock_txtorcon(txtorcon):
|
with mock_txtorcon(txtorcon):
|
||||||
p = tor_provider.Provider(cfg, reactor)
|
p = tor_provider.create(reactor, basedir, cfg)
|
||||||
tor_state = mock.Mock()
|
tor_state = mock.Mock()
|
||||||
tor_state.protocol = object()
|
tor_state.protocol = object()
|
||||||
txtorcon.build_tor_connection = mock.Mock(return_value=tor_state)
|
txtorcon.build_tor_connection = mock.Mock(return_value=tor_state)
|
||||||
|
@ -7,6 +7,22 @@ from twisted.internet.endpoints import clientFromString
|
|||||||
from twisted.internet.error import ConnectionRefusedError, ConnectError
|
from twisted.internet.error import ConnectionRefusedError, ConnectError
|
||||||
from twisted.application import service
|
from twisted.application import service
|
||||||
|
|
||||||
|
|
||||||
|
def create(reactor, basedir, config):
|
||||||
|
"""
|
||||||
|
Create a new Provider service (this is an IService so must be
|
||||||
|
hooked up to a parent or otherwise started).
|
||||||
|
|
||||||
|
If foolscap.connections.i2p or txi2p are not installed, then
|
||||||
|
Provider.get_i2p_handler() will return None. If 'tahoe.cfg' wants
|
||||||
|
to start an I2P Destination too, then this `create()` method will
|
||||||
|
throw a nice error (and startService will throw an ugly error).
|
||||||
|
"""
|
||||||
|
provider = _Provider(basedir, config, reactor)
|
||||||
|
provider.check_dest_config()
|
||||||
|
return provider
|
||||||
|
|
||||||
|
|
||||||
def _import_i2p():
|
def _import_i2p():
|
||||||
# this exists to be overridden by unit tests
|
# this exists to be overridden by unit tests
|
||||||
try:
|
try:
|
||||||
@ -118,12 +134,8 @@ def create_config(reactor, cli_config):
|
|||||||
|
|
||||||
returnValue((tahoe_config_i2p, i2p_port, i2p_location))
|
returnValue((tahoe_config_i2p, i2p_port, i2p_location))
|
||||||
|
|
||||||
# we can always create a Provider. If foolscap.connections.i2p or txi2p
|
|
||||||
# are not installed, then get_i2p_handler() will return None. If tahoe.cfg
|
|
||||||
# wants to start an I2P Destination too, then check_dest_config() will throw
|
|
||||||
# a nice error, and startService will throw an ugly error.
|
|
||||||
|
|
||||||
class Provider(service.MultiService):
|
class _Provider(service.MultiService):
|
||||||
def __init__(self, config, reactor):
|
def __init__(self, config, reactor):
|
||||||
service.MultiService.__init__(self)
|
service.MultiService.__init__(self)
|
||||||
self._config = config
|
self._config = config
|
||||||
|
@ -10,6 +10,22 @@ from twisted.application import service
|
|||||||
from .observer import OneShotObserverList
|
from .observer import OneShotObserverList
|
||||||
from .iputil import allocate_tcp_port
|
from .iputil import allocate_tcp_port
|
||||||
|
|
||||||
|
|
||||||
|
def create(reactor, basedir, config):
|
||||||
|
"""
|
||||||
|
Create a new _Provider service (this is an IService so must be
|
||||||
|
hooked up to a parent or otherwise started).
|
||||||
|
|
||||||
|
If foolscap.connections.tor or txtorcon are not installed, then
|
||||||
|
Provider.get_tor_handler() will return None. If tahoe.cfg wants
|
||||||
|
to start an onion service too, then this `create()` method will
|
||||||
|
throw a nice error (and startService will throw an ugly error).
|
||||||
|
"""
|
||||||
|
provider = _Provider(basedir, config, reactor)
|
||||||
|
provider.check_onion_config()
|
||||||
|
return provider
|
||||||
|
|
||||||
|
|
||||||
def _import_tor():
|
def _import_tor():
|
||||||
# this exists to be overridden by unit tests
|
# this exists to be overridden by unit tests
|
||||||
try:
|
try:
|
||||||
@ -192,12 +208,8 @@ def create_config(reactor, cli_config):
|
|||||||
|
|
||||||
returnValue((tahoe_config_tor, tor_port, tor_location))
|
returnValue((tahoe_config_tor, tor_port, tor_location))
|
||||||
|
|
||||||
# we can always create a Provider. If foolscap.connections.tor or txtorcon
|
|
||||||
# are not installed, then get_tor_handler() will return None. If tahoe.cfg
|
|
||||||
# wants to start an onion service too, then check_onion_config() will throw a
|
|
||||||
# nice error, and startService will throw an ugly error.
|
|
||||||
|
|
||||||
class Provider(service.MultiService):
|
class _Provider(service.MultiService):
|
||||||
def __init__(self, config, reactor):
|
def __init__(self, config, reactor):
|
||||||
service.MultiService.__init__(self)
|
service.MultiService.__init__(self)
|
||||||
self._config = config
|
self._config = config
|
||||||
|
Reference in New Issue
Block a user