more refactor + fix some node tests

This commit is contained in:
meejah 2018-01-28 01:27:25 -07:00
parent 71484b4a12
commit 43d857a0bd
5 changed files with 115 additions and 68 deletions

View File

@ -206,17 +206,21 @@ def create_client(basedir=u".", _client_factory=None):
config = read_config(basedir, u"client.port", _valid_config_sections=_valid_config_sections)
return create_client_from_config(basedir, config)
# this can/should be async
# @defer.inlineCallbacks
def create_client_from_config(basedir, config):
default_connection_handlers, foolscap_connection_handlers = create_connection_handlers(reactor, 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)
tor_provider = create_tor_provider(reactor, basedir, config)
handlers = create_connection_handlers(reactor, basedir, config, i2p_provider, tor_provider)
default_connection_handlers, foolscap_connection_handlers = handlers
tub_options = create_tub_options(config)
i2p_provider = None
tor_provider = None
main_tub, is_listening = create_main_tub(
basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers,
foolscap_connection_handlers, i2p_provider, tor_provider,
)
control_tub = create_control_tub()
return defer.succeed(

View File

@ -47,14 +47,20 @@ def create_introducer(basedir=u"."):
_valid_config_sections=_valid_config_sections,
)
default_connection_handlers, foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config)
# XXX fix up imports etc (also: reactor)
from twisted.internet import reactor
from allmydata.node import create_i2p_provider, create_tor_provider
i2p_provider = create_i2p_provider(reactor, basedir, config)
tor_provider = create_tor_provider(reactor, basedir, config)
default_connection_handlers, foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config, i2p_provider, tor_provider)
tub_options = create_tub_options(config)
i2p_provider = None
tor_provider = None
main_tub, is_listening = create_main_tub(
basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers,
foolscap_connection_handlers, i2p_provider, tor_provider,
)
control_tub = create_control_tub()

View File

@ -459,13 +459,11 @@ def _make_i2p_handler(i2p_provider):
return i2p_provider.get_i2p_handler()
def create_connection_handlers(reactor, config):
def create_connection_handlers(reactor, config, i2p_provider, tor_provider):
"""
:returns: 2-tuple of default_connection_handlers, foolscap_connection_handlers
"""
reveal_ip = config.get_config("node", "reveal-IP-address", True, boolean=True)
i2p_provider = create_i2p_provider(reactor, basedir, config)
tor_provider = create_tor_provider(reactor, basedir, config)
# We store handlers for everything. None means we were unable to
# create that handler, so hints which want it will be ignored.
@ -625,8 +623,10 @@ def _tub_portlocation(config, cfg_tubport, cfg_location):
return tubport, location
def create_main_tub(basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers, handler_overrides={}):
def create_main_tub(basedir, config, tub_options,
default_connection_handlers, foolscap_connection_handlers,
i2p_provider, tor_provider,
handler_overrides={}, cert_filename="node.pem"):
cfg_tubport = config.get_config("node", "tub.port", None)
cfg_location = config.get_config("node", "tub.location", None)
portlocation = _tub_portlocation(config, cfg_tubport, cfg_location)
@ -646,9 +646,9 @@ def create_main_tub(basedir, config, tub_options, default_connection_handlers,
# that will create one, so we don't have to stuff all the
# options into the tub.port string (which would need a lot
# of escaping)
port_or_endpoint = self._i2p_provider.get_listener()
port_or_endpoint = i2p_provider.get_listener()
elif port == "listen:tor":
port_or_endpoint = self._tor_provider.get_listener()
port_or_endpoint = tor_provider.get_listener()
else:
port_or_endpoint = port
tub.listenOn(port_or_endpoint)
@ -708,7 +708,7 @@ class Node(service.MultiService):
# need them? (note: look in client.py also!)
# (client.py DOES use them in init_client_storage_broker, but
# we'll want to pull that out as well...so FIXME later)
self._default_connection_handlers, self._foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config)
## self._default_connection_handlers, self._foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config)
self.tub = main_tub
if self.tub is not None:

View File

@ -3,6 +3,7 @@ import os
from twisted.python.filepath import FilePath
from twisted.trial import unittest
from twisted.internet import defer
from allmydata.util import yamlutil
from allmydata.client import create_client
from allmydata.scripts.create_node import write_node_config
@ -33,35 +34,38 @@ class MultiIntroTests(unittest.TestCase):
self.yaml_path = FilePath(os.path.join(self.basedir, "private",
"introducers.yaml"))
@defer.inlineCallbacks
def test_introducer_count(self):
""" Ensure that the Client creates same number of introducer clients
as found in "basedir/private/introducers" config file. """
connections = {'introducers':
{
u'intro1':{ 'furl': 'furl1' },
u'intro2':{ 'furl': 'furl4' }
},
connections = {
'introducers': {
u'intro1':{ 'furl': 'furl1' },
u'intro2':{ 'furl': 'furl4' },
},
}
self.yaml_path.setContent(yamlutil.safe_dump(connections))
# get a client and count of introducer_clients
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
ic_count = len(myclient.introducer_clients)
# assertions
self.failUnlessEqual(ic_count, 3)
@defer.inlineCallbacks
def test_introducer_count_commented(self):
""" Ensure that the Client creates same number of introducer clients
as found in "basedir/private/introducers" config file when there is one
commented."""
self.yaml_path.setContent(INTRODUCERS_CFG_FURLS_COMMENTED)
# get a client and count of introducer_clients
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
ic_count = len(myclient.introducer_clients)
# assertions
self.failUnlessEqual(ic_count, 2)
@defer.inlineCallbacks
def test_read_introducer_furl_from_tahoecfg(self):
""" Ensure that the Client reads the introducer.furl config item from
the tahoe.cfg file. """
@ -78,19 +82,26 @@ class MultiIntroTests(unittest.TestCase):
c.close()
# get a client and first introducer_furl
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
tahoe_cfg_furl = myclient.introducer_furls[0]
# assertions
self.failUnlessEqual(fake_furl, tahoe_cfg_furl)
@defer.inlineCallbacks
def test_reject_default_in_yaml(self):
connections = {'introducers': {
u'default': { 'furl': 'furl1' },
}}
self.yaml_path.setContent(yamlutil.safe_dump(connections))
e = self.assertRaises(ValueError, create_client, self.basedir)
self.assertEquals(str(e), "'default' introducer furl cannot be specified in introducers.yaml; please fix impossible configuration.")
with self.assertRaises(ValueError) as ctx:
yield create_client(self.basedir)
self.assertEquals(
str(ctx.exception),
"'default' introducer furl cannot be specified in introducers.yaml; please "
"fix impossible configuration.",
)
SIMPLE_YAML = """
introducers:
@ -124,30 +135,38 @@ class NoDefault(unittest.TestCase):
self.yaml_path = FilePath(os.path.join(self.basedir, "private",
"introducers.yaml"))
@defer.inlineCallbacks
def test_ok(self):
connections = {'introducers': {
u'one': { 'furl': 'furl1' },
}}
self.yaml_path.setContent(yamlutil.safe_dump(connections))
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
tahoe_cfg_furl = myclient.introducer_furls[0]
self.assertEquals(tahoe_cfg_furl, 'furl1')
@defer.inlineCallbacks
def test_real_yaml(self):
self.yaml_path.setContent(SIMPLE_YAML)
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
tahoe_cfg_furl = myclient.introducer_furls[0]
self.assertEquals(tahoe_cfg_furl, 'furl1')
@defer.inlineCallbacks
def test_invalid_equals_yaml(self):
self.yaml_path.setContent(EQUALS_YAML)
e = self.assertRaises(TypeError, create_client, self.basedir)
self.assertEquals(str(e), "string indices must be integers")
with self.assertRaises(TypeError) as ctx:
yield create_client(self.basedir)
self.assertEquals(
str(ctx.exception),
"string indices must be integers",
)
@defer.inlineCallbacks
def test_introducerless(self):
connections = {'introducers': {} }
self.yaml_path.setContent(yamlutil.safe_dump(connections))
myclient = create_client(self.basedir)
myclient = yield create_client(self.basedir)
self.assertEquals(len(myclient.introducer_furls), 0)
if __name__ == "__main__":

View File

@ -16,6 +16,10 @@ import foolscap.logging.log
from twisted.application import service
from allmydata.node import Node, formatTimeTahoeStyle, MissingConfigEntry, read_config, config_from_string, create_node_dir
from allmydata.node import create_tub
from allmydata.node import create_tub_options
from allmydata.node import create_main_tub
from allmydata.node import create_connection_handlers
from allmydata.introducer.server import create_introducer
from allmydata import client
@ -30,15 +34,26 @@ class LoggingMultiService(service.MultiService):
def log(self, msg, **kw):
pass
class TestNode(Node):
CERTFILE='DEFAULT_CERTFILE_BLANK'
def __init__(self, basedir):
config = read_config(
basedir,
'DEFAULT_PORTNUMFILE_BLANK',
)
Node.__init__(self, config)
def testing_tub(config_data=''):
from twisted.internet import reactor
from allmydata.node import create_i2p_provider, create_tor_provider
config = config_from_string(config_data, 'DEFAULT_PORTNUMFILE_BLANK')
basedir = 'dummy_basedir'
fileutil.make_dirs(os.path.join(basedir, 'private'))
i2p_provider = create_i2p_provider(reactor, basedir, config)
tor_provider = create_tor_provider(reactor, basedir, config)
handlers = create_connection_handlers(reactor, basedir, config, i2p_provider, tor_provider)
default_connection_handlers, foolscap_connection_handlers = handlers
tub_options = create_tub_options(config)
main_tub, is_listening = create_main_tub(
basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers, i2p_provider, tor_provider,
cert_filename='DEFAULT_CERTFILE_BLANK'
)
return main_tub
class TestCase(testutil.SignalMixin, unittest.TestCase):
@ -63,17 +78,21 @@ class TestCase(testutil.SignalMixin, unittest.TestCase):
with open(os.path.join(basedir, 'tahoe.cfg'), 'wt') as f:
f.write("[node]\n")
if tub_port:
f.write("tub.port = %d\n" % (tub_port,))
f.write("tub.port = {}\n".format(tub_port))
if tub_location is not None:
f.write("tub.location = %s\n" % (tub_location,))
f.write("tub.location = {}\n".format(tub_location))
if local_addresses:
self.patch(iputil, 'get_local_addresses_sync',
lambda: local_addresses)
n = TestNode(basedir)
n.setServiceParent(self.parent)
furl = n.tub.registerReference(n)
tub = testing_tub(config_data)
tub.setServiceParent(self.parent)
class Foo(object):
pass
furl = tub.registerReference(Foo())
for address in expected_addresses:
self.failUnlessIn(address, furl)
@ -505,10 +524,10 @@ class FakeTub:
def setServiceParent(self, parent): pass
class Listeners(unittest.TestCase):
def test_multiple_ports(self):
basedir = self.mktemp()
create_node_dir(basedir, "testing")
port1 = iputil.allocate_tcp_port()
port2 = iputil.allocate_tcp_port()
port = ("tcp:%d:interface=127.0.0.1,tcp:%d:interface=127.0.0.1" %
@ -521,20 +540,16 @@ class Listeners(unittest.TestCase):
# we're doing a lot of calling-into-setup-methods here, it might be
# better to just create a real Node instance, I'm not sure.
config = client.read_config(
basedir,
"client.port",
)
n = Node(config)
n.check_privacy()
n.services = []
n.create_i2p_provider()
n.create_tor_provider()
n.init_connections()
n.set_tub_options()
config = read_config(basedir, "client.port")
i2p_provider = mock.Mock()
tor_provider = mock.Mock()
dfh, fch = create_connection_handlers(None, basedir, config, i2p_provider, tor_provider)
tub_options = create_tub_options(config)
t = FakeTub()
with mock.patch("allmydata.node.Tub", return_value=t):
n.create_main_tub()
create_main_tub(basedir, config, tub_options, dfh, fch, i2p_provider, tor_provider)
self.assertEqual(t.listening_ports,
["tcp:%d:interface=127.0.0.1" % port1,
"tcp:%d:interface=127.0.0.1" % port2])
@ -563,22 +578,25 @@ class Listeners(unittest.TestCase):
i2p_mock = mock.patch('allmydata.node.i2p_provider', new=i2p_x)
tor_ep = object()
tor_prov = tor_provider.Provider(config, mock.Mock())
tor_prov.get_listener = mock.Mock(return_value=tor_ep)
tor_x = mock.Mock()
tor_x.Provider = lambda c, r: tor_prov
tor_mock = mock.patch('allmydata.node.tor_provider', new=tor_x)
tub_mock = mock.patch("allmydata.node.Tub", return_value=FakeTub())
with i2p_mock, tor_mock, tub_mock:
n = Node(config)
tor_provider.get_listener = mock.Mock(return_value=tor_ep)
tub_options = create_tub_options(config)
t = FakeTub()
dfh, fch = create_connection_handlers(None, basedir, config, i2p_provider, tor_provider)
with mock.patch("allmydata.node.Tub", return_value=t):
create_main_tub(basedir, config, tub_options, dfh, fch, i2p_provider, tor_provider)
self.assertEqual(i2p_provider.get_listener.mock_calls, [mock.call()])
self.assertEqual(tor_provider.get_listener.mock_calls, [mock.call()])
self.assertEqual(t.listening_ports, [i2p_ep, tor_ep])
self.assertEqual(n._i2p_provider.get_listener.mock_calls, [mock.call()])
self.assertEqual(n._tor_provider.get_listener.mock_calls, [mock.call()])
self.assertIn(i2p_ep, n.tub.listening_ports)
self.assertIn(tor_ep, n.tub.listening_ports)
class ClientNotListening(unittest.TestCase):
@defer.inlineCallbacks
def test_disabled(self):
basedir = "test_node/test_disabled"
create_node_dir(basedir, "testing")
@ -587,7 +605,7 @@ class ClientNotListening(unittest.TestCase):
f.write(NOLISTEN)
f.write(DISABLE_STORAGE)
f.close()
n = client.create_client(basedir)
n = yield client.create_client(basedir)
self.assertEqual(n.tub.getListeners(), [])
def test_disabled_but_storage(self):