more tests work

This commit is contained in:
meejah 2018-01-27 21:40:43 -07:00
parent 329ef1256a
commit d1a83e9be0
4 changed files with 184 additions and 139 deletions

View File

@ -177,26 +177,7 @@ def read_config(basedir, portnumfile, generated_files=[]):
) )
#@defer.inlineCallbacks # @defer.inlineCallbacks
def create_client(basedir=u"."
node.create_node_dir(basedir, CLIENT_README)
config = read_config(basedir, u"client.port")
if _client_factory is None:
_client_factory = _Client
#defer.returnValue(
return _client_factory(
config,
=======
PRIV_README="""
This directory contains files which contain private data for the Tahoe node,
such as private keys. On Unix-like systems, the permissions on this directory
are set to disallow users other than its owner from reading the contents of
the files. See the 'configuration.rst' documentation file for details."""
@defer.inlineCallbacks
def create_client(basedir=u".", _client_factory=None): def create_client(basedir=u".", _client_factory=None):
""" """
Creates a new client instance (a subclass of Node). Creates a new client instance (a subclass of Node).
@ -221,11 +202,16 @@ def create_client(basedir=u".", _client_factory=None):
if _client_factory is None: if _client_factory is None:
_client_factory = _Client _client_factory = _Client
# pre-requisites
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) default_connection_handlers, foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config)
tub_options = create_tub_options(config) tub_options = create_tub_options(config)
yield
i2p_provider = None i2p_provider = None
tor_provider = None tor_provider = None
reveal_ip = True # XXX FIXME reveal_ip = True # XXX FIXME
@ -234,7 +220,7 @@ def create_client(basedir=u".", _client_factory=None):
foolscap_connection_handlers, reveal_ip=reveal_ip, foolscap_connection_handlers, reveal_ip=reveal_ip,
) )
control_tub = create_control_tub() control_tub = create_control_tub()
defer.returnValue( return defer.succeed(
_Client( _Client(
config, config,
main_tub, main_tub,

View File

@ -443,12 +443,12 @@ def _make_tcp_handler():
# XXX shouldn't need this # XXX shouldn't need this
def _make_tor_handler(tor_provider): def _make_tor_handler(tor_provider):
tor_provider.get_tor_handler() return tor_provider.get_tor_handler()
# XXX shouldn't need this # XXX shouldn't need this
def _make_i2p_handler(i2p_provider): def _make_i2p_handler(i2p_provider):
i2p_provider.get_i2p_handler() return i2p_provider.get_i2p_handler()
def create_connection_handlers(reactor, basedir, config): def create_connection_handlers(reactor, basedir, config):
@ -539,10 +539,11 @@ def _convert_tub_port(s):
return s return s
def _tub_portlocation(config, cfg_tubport, cfg_location, reveal_ip=True): def _tub_portlocation(config, cfg_tubport, cfg_location):
# return None, or tuple of (port, location) # return None, or tuple of (port, location)
tubport_disabled = False tubport_disabled = False
reveal_ip = config.get_config("node", "reveal-IP-address", True, boolean=True)
if cfg_tubport is not None: if cfg_tubport is not None:
cfg_tubport = cfg_tubport.strip() cfg_tubport = cfg_tubport.strip()
if cfg_tubport == "": if cfg_tubport == "":
@ -617,14 +618,15 @@ def _tub_portlocation(config, cfg_tubport, cfg_location, reveal_ip=True):
def create_main_tub(basedir, config, tub_options, default_connection_handlers, def create_main_tub(basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers, handler_overrides={}, reveal_ip=True): foolscap_connection_handlers, handler_overrides={}):
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)
certfile = os.path.join(basedir, "private", "node.pem") # FIXME "node.pem" was the CERTFILE option/thing certfile = os.path.join(basedir, "private", "node.pem") # FIXME "node.pem" was the CERTFILE option/thing
tub = create_tub(tub_options, default_connection_handlers, foolscap_connection_handlers, tub = create_tub(tub_options, default_connection_handlers, foolscap_connection_handlers,
handler_overrides=handler_overrides, certFile=certfile) handler_overrides=handler_overrides, certFile=certfile)
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, reveal_ip)
if portlocation: if portlocation:
tubport, location = portlocation tubport, location = portlocation
for port in tubport.split(","): for port in tubport.split(","):

View File

@ -306,6 +306,7 @@ class Basic(testutil.ReallyEqualMixin, testutil.NonASCIIPathMixin, unittest.Test
c = yield client.create_client(basedir) # just make sure it can be instantiated c = yield client.create_client(basedir) # just make sure it can be instantiated
del c del c
@defer.inlineCallbacks
def test_ftp_auth_no_accountfile_or_url(self): def test_ftp_auth_no_accountfile_or_url(self):
basedir = u"client.Basic.test_ftp_auth_no_accountfile_or_url" basedir = u"client.Basic.test_ftp_auth_no_accountfile_or_url"
os.mkdir(basedir) os.mkdir(basedir)

View File

@ -4,17 +4,18 @@ from twisted.trial import unittest
from twisted.internet import reactor, endpoints, defer from twisted.internet import reactor, endpoints, defer
from twisted.internet.interfaces import IStreamClientEndpoint from twisted.internet.interfaces import IStreamClientEndpoint
from foolscap.connections import tcp from foolscap.connections import tcp
from ..node import Node, PrivacyError from ..node import Node, PrivacyError, config_from_string
from ..node import create_connection_handlers, create_i2p_provider
from ..node import create_main_tub
from ..client import create_client_from_config
from ..util import connection_status from ..util import connection_status
class FakeNode(Node): class FakeNode(Node):
def __init__(self, config_str): def __init__(self, config_str):
from allmydata.node import config_from_string
self.config = config_from_string(config_str, "fake.port", "no-basedir") self.config = config_from_string(config_str, "fake.port", "no-basedir")
self._reveal_ip = True self._reveal_ip = True
self.services = [] self.services = []
self.create_i2p_provider()
self.create_tor_provider()
BASECONFIG = ("[client]\n" BASECONFIG = ("[client]\n"
"introducer.furl = \n" "introducer.furl = \n"
@ -138,180 +139,235 @@ class Tor(unittest.TestCase):
self.assertIdentical(h, h1) self.assertIdentical(h, h1)
class I2P(unittest.TestCase): class I2P(unittest.TestCase):
def test_disabled(self): def test_disabled(self):
n = FakeNode(BASECONFIG+"[i2p]\nenabled = false\n") config = config_from_string(
h = n._make_i2p_handler() BASECONFIG + "[i2p]\nenabled = false\n",
"fake.port",
)
i2p_provider = create_i2p_provider(None, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
self.assertEqual(h, None) self.assertEqual(h, None)
def test_unimportable(self): def test_unimportable(self):
config = config_from_string(
BASECONFIG,
"fake.port",
)
with mock.patch("allmydata.util.i2p_provider._import_i2p", with mock.patch("allmydata.util.i2p_provider._import_i2p",
return_value=None): return_value=None):
n = FakeNode(BASECONFIG) i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = n._make_i2p_handler() h = i2p_provider.get_i2p_handler()
self.assertEqual(h, None) self.assertEqual(h, None)
def test_default(self): def test_default(self):
n = FakeNode(BASECONFIG) config = config_from_string(BASECONFIG, "fake.port")
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.default", with mock.patch("foolscap.connections.i2p.default",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
self.assertEqual(f.mock_calls, [mock.call(reactor, keyfile=None)]) h = i2p_provider.get_i2p_handler()
self.assertIdentical(h, h1) self.assertEqual(f.mock_calls, [mock.call(reactor, keyfile=None)])
self.assertIdentical(h, h1)
def test_samport(self): def test_samport(self):
n = FakeNode(BASECONFIG+"[i2p]\nsam.port = tcp:localhost:1234\n") config = config_from_string(
BASECONFIG + "[i2p]\nsam.port = tcp:localhost:1234\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.sam_endpoint", with mock.patch("foolscap.connections.i2p.sam_endpoint",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
self.assertEqual(len(f.mock_calls), 1) h = i2p_provider.get_i2p_handler()
ep = f.mock_calls[0][1][0]
self.assertIsInstance(ep, endpoints.TCP4ClientEndpoint) self.assertEqual(len(f.mock_calls), 1)
self.assertIdentical(h, h1) ep = f.mock_calls[0][1][0]
self.assertIsInstance(ep, endpoints.TCP4ClientEndpoint)
self.assertIdentical(h, h1)
def test_samport_and_launch(self): def test_samport_and_launch(self):
n = FakeNode(BASECONFIG+"[i2p]\n" + config = config_from_string(
"sam.port = tcp:localhost:1234\n" BASECONFIG + "[i2p]\n" +
+"launch = true\n") "sam.port = tcp:localhost:1234\n" + "launch = true\n",
e = self.assertRaises(ValueError, n._make_i2p_handler) "fake.port",
self.assertIn("must not set both sam.port and launch", str(e)) )
with self.assertRaises(ValueError) as ctx:
i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
self.assertIn(
"must not set both sam.port and launch",
str(ctx.exception)
)
def test_launch(self): def test_launch(self):
n = FakeNode(BASECONFIG+"[i2p]\nlaunch = true\n") config = config_from_string(
BASECONFIG + "[i2p]\nlaunch = true\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.launch", with mock.patch("foolscap.connections.i2p.launch",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
exp = mock.call(i2p_configdir=None, i2p_binary=None) exp = mock.call(i2p_configdir=None, i2p_binary=None)
self.assertEqual(f.mock_calls, [exp]) self.assertEqual(f.mock_calls, [exp])
self.assertIdentical(h, h1) self.assertIdentical(h, h1)
def test_launch_executable(self): def test_launch_executable(self):
n = FakeNode(BASECONFIG+"[i2p]\nlaunch = true\n" + config = config_from_string(
"i2p.executable = i2p\n") BASECONFIG + "[i2p]\nlaunch = true\n" + "i2p.executable = i2p\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.launch", with mock.patch("foolscap.connections.i2p.launch",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
exp = mock.call(i2p_configdir=None, i2p_binary="i2p") exp = mock.call(i2p_configdir=None, i2p_binary="i2p")
self.assertEqual(f.mock_calls, [exp]) self.assertEqual(f.mock_calls, [exp])
self.assertIdentical(h, h1) self.assertIdentical(h, h1)
def test_launch_configdir(self): def test_launch_configdir(self):
n = FakeNode(BASECONFIG+"[i2p]\nlaunch = true\n" + config = config_from_string(
"i2p.configdir = cfg\n") BASECONFIG + "[i2p]\nlaunch = true\n" + "i2p.configdir = cfg\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.launch", with mock.patch("foolscap.connections.i2p.launch",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
exp = mock.call(i2p_configdir="cfg", i2p_binary=None) exp = mock.call(i2p_configdir="cfg", i2p_binary=None)
self.assertEqual(f.mock_calls, [exp]) self.assertEqual(f.mock_calls, [exp])
self.assertIdentical(h, h1) self.assertIdentical(h, h1)
def test_launch_configdir_and_executable(self): def test_launch_configdir_and_executable(self):
n = FakeNode(BASECONFIG+"[i2p]\nlaunch = true\n" + config = config_from_string(
"i2p.executable = i2p\n" + BASECONFIG + "[i2p]\nlaunch = true\n" +
"i2p.configdir = cfg\n") "i2p.executable = i2p\n" + "i2p.configdir = cfg\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.launch", with mock.patch("foolscap.connections.i2p.launch",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(reactor, 'BASEDIR', config)
h = i2p_provider.get_i2p_handler()
exp = mock.call(i2p_configdir="cfg", i2p_binary="i2p") exp = mock.call(i2p_configdir="cfg", i2p_binary="i2p")
self.assertEqual(f.mock_calls, [exp]) self.assertEqual(f.mock_calls, [exp])
self.assertIdentical(h, h1) self.assertIdentical(h, h1)
def test_configdir(self): def test_configdir(self):
n = FakeNode(BASECONFIG+"[i2p]\ni2p.configdir = cfg\n") config = config_from_string(
BASECONFIG + "[i2p]\ni2p.configdir = cfg\n",
"fake.port",
)
h1 = mock.Mock() h1 = mock.Mock()
with mock.patch("foolscap.connections.i2p.local_i2p", with mock.patch("foolscap.connections.i2p.local_i2p",
return_value=h1) as f: return_value=h1) as f:
h = n._make_i2p_handler() i2p_provider = create_i2p_provider(None, 'BASEDIR', config)
self.assertEqual(f.mock_calls, [mock.call("cfg")]) h = i2p_provider.get_i2p_handler()
self.assertIdentical(h, h1)
self.assertEqual(f.mock_calls, [mock.call("cfg")])
self.assertIdentical(h, h1)
class Connections(unittest.TestCase): class Connections(unittest.TestCase):
def setUp(self):
self.basedir = 'BASEDIR'
self.config = config_from_string(BASECONFIG, "fake.port")
def test_default(self): def test_default(self):
n = FakeNode(BASECONFIG) default_connection_handlers, _ = create_connection_handlers(None, self.basedir, self.config)
n.init_connections() self.assertEqual(default_connection_handlers["tcp"], "tcp")
self.assertEqual(n._default_connection_handlers["tcp"], "tcp") self.assertEqual(default_connection_handlers["tor"], "tor")
self.assertEqual(n._default_connection_handlers["tor"], "tor") self.assertEqual(default_connection_handlers["i2p"], "i2p")
self.assertEqual(n._default_connection_handlers["i2p"], "i2p")
n.set_tub_options()
n._create_tub()
def test_tor(self): def test_tor(self):
n = FakeNode(BASECONFIG+"[connections]\ntcp = tor\n") config = config_from_string(
n.init_connections() BASECONFIG + "[connections]\ntcp = tor\n",
self.assertEqual(n._default_connection_handlers["tcp"], "tor") "fake.port",
self.assertEqual(n._default_connection_handlers["tor"], "tor") )
self.assertEqual(n._default_connection_handlers["i2p"], "i2p") default_connection_handlers, _ = create_connection_handlers(None, self.basedir, config)
self.assertEqual(default_connection_handlers["tcp"], "tor")
self.assertEqual(default_connection_handlers["tor"], "tor")
self.assertEqual(default_connection_handlers["i2p"], "i2p")
def test_tor_unimportable(self): def test_tor_unimportable(self):
with mock.patch("allmydata.util.tor_provider._import_tor", with mock.patch("allmydata.util.tor_provider._import_tor",
return_value=None): return_value=None):
n = FakeNode(BASECONFIG+"[connections]\ntcp = tor\n") self.config = config_from_string(
e = self.assertRaises(ValueError, n.init_connections) BASECONFIG + "[connections]\ntcp = tor\n",
self.assertEqual(str(e), "fake.port",
"'tahoe.cfg [connections] tcp='" )
" uses unavailable/unimportable handler type 'tor'." with self.assertRaises(ValueError) as ctx:
" Please pip install tahoe-lafs[tor] to fix.") default_connection_handlers, _ = create_connection_handlers(None, self.basedir, self.config)
self.assertEqual(
str(ctx.exception),
"'tahoe.cfg [connections] tcp='"
" uses unavailable/unimportable handler type 'tor'."
" Please pip install tahoe-lafs[tor] to fix.",
)
def test_unknown(self): def test_unknown(self):
n = FakeNode(BASECONFIG+"[connections]\ntcp = unknown\n") config = config_from_string(
e = self.assertRaises(ValueError, n.init_connections) BASECONFIG + "[connections]\ntcp = unknown\n",
self.assertIn("'tahoe.cfg [connections] tcp='", str(e)) "fake.port",
self.assertIn("uses unknown handler type 'unknown'", str(e)) )
with self.assertRaises(ValueError) as ctx:
create_connection_handlers(None, self.basedir, config)
self.assertIn("'tahoe.cfg [connections] tcp='", str(ctx.exception))
self.assertIn("uses unknown handler type 'unknown'", str(ctx.exception))
def test_tcp_disabled(self): def test_tcp_disabled(self):
n = FakeNode(BASECONFIG+"[connections]\ntcp = disabled\n") config = config_from_string(
n.init_connections() BASECONFIG + "[connections]\ntcp = disabled\n",
self.assertEqual(n._default_connection_handlers["tcp"], None) "fake.port",
self.assertEqual(n._default_connection_handlers["tor"], "tor") )
self.assertEqual(n._default_connection_handlers["i2p"], "i2p") default_connection_handlers, _ = create_connection_handlers(None, self.basedir, config)
n.set_tub_options() self.assertEqual(default_connection_handlers["tcp"], None)
n._create_tub() self.assertEqual(default_connection_handlers["tor"], "tor")
self.assertEqual(default_connection_handlers["i2p"], "i2p")
class Privacy(unittest.TestCase): class Privacy(unittest.TestCase):
def test_flag(self):
n = FakeNode(BASECONFIG)
n.check_privacy()
self.assertTrue(n._reveal_ip)
n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = true\n")
n.check_privacy()
self.assertTrue(n._reveal_ip)
n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n")
n.check_privacy()
self.assertFalse(n._reveal_ip)
n = FakeNode(BASECONFIG+"[node]\nreveal-ip-address = false\n")
n.check_privacy()
self.assertFalse(n._reveal_ip)
def test_connections(self): def test_connections(self):
n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n") config = config_from_string(
n.check_privacy() BASECONFIG + "[node]\nreveal-IP-address = false\n",
e = self.assertRaises(PrivacyError, n.init_connections) "fake.port",
self.assertEqual(str(e), )
"tcp = tcp, must be set to 'tor' or 'disabled'")
with self.assertRaises(PrivacyError) as ctx:
create_connection_handlers(None, 'BASEDIR', config)
self.assertEqual(
str(ctx.exception),
"tcp = tcp, must be set to 'tor' or 'disabled'",
)
def test_connections_tcp_disabled(self): def test_connections_tcp_disabled(self):
n = FakeNode(BASECONFIG+ config = config_from_string(
"[connections]\ntcp = disabled\n"+ BASECONFIG + "[connections]\ntcp = disabled\n" +
"[node]\nreveal-IP-address = false\n") "[node]\nreveal-IP-address = false\n",
n.check_privacy() "fake.port",
n.init_connections() # passes privacy check )
self.assertEqual(n._default_connection_handlers["tcp"], None) default_connection_handlers, _ = create_connection_handlers(None, 'BASEDIR', config)
self.assertEqual(default_connection_handlers["tcp"], None)
def test_tub_location_auto(self): def test_tub_location_auto(self):
n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n") config = config_from_string(
n._portnumfile = "missing" BASECONFIG + "[node]\nreveal-IP-address = false\n",
n.check_privacy() "fake.port",
e = self.assertRaises(PrivacyError, n.get_tub_portlocation, None, None) )
self.assertEqual(str(e), "tub.location uses AUTO")
with self.assertRaises(PrivacyError) as ctx:
create_main_tub('basedir', config, {}, {}, {})
self.assertEqual(
str(ctx.exception),
"tub.location uses AUTO",
)
return
n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n") n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n")
n._portnumfile = "missing" n._portnumfile = "missing"
n.check_privacy() n.check_privacy()