2007-05-23 22:08:55 +00:00
|
|
|
|
2007-12-17 23:39:54 +00:00
|
|
|
import os, stat, sys, time
|
2015-07-17 21:03:53 +00:00
|
|
|
|
2007-05-23 22:08:55 +00:00
|
|
|
from twisted.trial import unittest
|
2007-05-24 00:55:04 +00:00
|
|
|
from twisted.internet import defer
|
2007-05-23 22:08:55 +00:00
|
|
|
from twisted.python import log
|
|
|
|
|
2009-05-22 00:38:23 +00:00
|
|
|
from foolscap.api import flushEventualQueue
|
2015-07-17 21:03:53 +00:00
|
|
|
import foolscap.logging.log
|
|
|
|
|
2007-05-23 22:08:55 +00:00
|
|
|
from twisted.application import service
|
2012-06-11 00:46:38 +00:00
|
|
|
from allmydata.node import Node, formatTimeTahoeStyle, MissingConfigEntry
|
2016-08-30 01:49:20 +00:00
|
|
|
from allmydata.introducer.server import IntroducerNode
|
|
|
|
from allmydata.client import Client
|
2015-02-09 19:48:06 +00:00
|
|
|
from allmydata.util import fileutil, iputil
|
2015-07-17 21:03:53 +00:00
|
|
|
from allmydata.util.namespace import Namespace
|
2010-02-26 08:14:33 +00:00
|
|
|
import allmydata.test.common_util as testutil
|
2007-05-23 22:08:55 +00:00
|
|
|
|
2015-07-17 21:03:53 +00:00
|
|
|
|
2007-05-23 22:08:55 +00:00
|
|
|
class LoggingMultiService(service.MultiService):
|
2007-11-20 01:23:18 +00:00
|
|
|
def log(self, msg, **kw):
|
2007-05-23 22:08:55 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
class TestNode(Node):
|
|
|
|
CERTFILE='DEFAULT_CERTFILE_BLANK'
|
|
|
|
PORTNUMFILE='DEFAULT_PORTNUMFILE_BLANK'
|
|
|
|
|
2009-02-23 21:43:12 +00:00
|
|
|
class TestCase(testutil.SignalMixin, unittest.TestCase):
|
2007-05-23 22:08:55 +00:00
|
|
|
def setUp(self):
|
2009-02-23 21:43:12 +00:00
|
|
|
testutil.SignalMixin.setUp(self)
|
2007-05-23 22:08:55 +00:00
|
|
|
self.parent = LoggingMultiService()
|
|
|
|
self.parent.startService()
|
|
|
|
def tearDown(self):
|
|
|
|
log.msg("%s.tearDown" % self.__class__.__name__)
|
2009-02-23 21:43:12 +00:00
|
|
|
testutil.SignalMixin.tearDown(self)
|
2007-05-23 22:08:55 +00:00
|
|
|
d = defer.succeed(None)
|
|
|
|
d.addCallback(lambda res: self.parent.stopService())
|
|
|
|
d.addCallback(flushEventualQueue)
|
|
|
|
return d
|
|
|
|
|
2015-02-09 19:48:06 +00:00
|
|
|
def _test_location(self, basedir, expected_addresses, tub_port=None, tub_location=None, local_addresses=None):
|
2007-11-02 00:29:15 +00:00
|
|
|
fileutil.make_dirs(basedir)
|
2008-11-13 01:44:58 +00:00
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write("[node]\n")
|
2015-02-09 19:45:31 +00:00
|
|
|
if tub_port:
|
|
|
|
f.write("tub.port = %d\n" % (tub_port,))
|
|
|
|
if tub_location is not None:
|
|
|
|
f.write("tub.location = %s\n" % (tub_location,))
|
2007-11-02 00:29:15 +00:00
|
|
|
f.close()
|
2007-05-23 22:08:55 +00:00
|
|
|
|
2015-02-09 19:48:06 +00:00
|
|
|
if local_addresses:
|
2016-04-27 01:21:36 +00:00
|
|
|
self.patch(iputil, 'get_local_addresses_sync',
|
|
|
|
lambda: local_addresses)
|
2015-02-09 19:48:06 +00:00
|
|
|
|
2007-11-02 00:29:15 +00:00
|
|
|
n = TestNode(basedir)
|
2007-05-23 22:08:55 +00:00
|
|
|
n.setServiceParent(self.parent)
|
2016-04-27 01:21:36 +00:00
|
|
|
furl = n.tub.registerReference(n)
|
|
|
|
for address in expected_addresses:
|
|
|
|
self.failUnlessIn(address, furl)
|
2007-05-23 22:08:55 +00:00
|
|
|
|
2015-02-09 19:45:31 +00:00
|
|
|
def test_location1(self):
|
|
|
|
return self._test_location(basedir="test_node/test_location1",
|
|
|
|
expected_addresses=["192.0.2.0:1234"],
|
|
|
|
tub_location="192.0.2.0:1234")
|
2008-09-30 06:08:16 +00:00
|
|
|
|
2015-02-09 19:45:31 +00:00
|
|
|
def test_location2(self):
|
|
|
|
return self._test_location(basedir="test_node/test_location2",
|
|
|
|
expected_addresses=["192.0.2.0:1234", "example.org:8091"],
|
|
|
|
tub_location="192.0.2.0:1234,example.org:8091")
|
2008-09-30 06:08:16 +00:00
|
|
|
|
2015-02-09 19:48:06 +00:00
|
|
|
def test_location_not_set(self):
|
|
|
|
"""Checks the autogenerated furl when tub.location is not set."""
|
|
|
|
return self._test_location(basedir="test_node/test_location3",
|
|
|
|
expected_addresses=["127.0.0.1:1234", "192.0.2.0:1234"],
|
|
|
|
tub_port=1234,
|
|
|
|
local_addresses=["127.0.0.1", "192.0.2.0"])
|
|
|
|
|
|
|
|
def test_location_auto_and_explicit(self):
|
|
|
|
"""Checks the autogenerated furl when tub.location contains 'AUTO'."""
|
|
|
|
return self._test_location(basedir="test_node/test_location4",
|
|
|
|
expected_addresses=["127.0.0.1:1234", "192.0.2.0:1234", "example.com:4321"],
|
|
|
|
tub_port=1234,
|
|
|
|
tub_location="AUTO,example.com:4321",
|
|
|
|
local_addresses=["127.0.0.1", "192.0.2.0", "example.com:4321"])
|
2008-09-30 06:08:16 +00:00
|
|
|
|
2011-08-08 18:05:52 +00:00
|
|
|
def test_tahoe_cfg_utf8(self):
|
|
|
|
basedir = "test_node/test_tahoe_cfg_utf8"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write(u"\uFEFF[node]\n".encode('utf-8'))
|
|
|
|
f.write(u"nickname = \u2621\n".encode('utf-8'))
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
n = TestNode(basedir)
|
|
|
|
n.setServiceParent(self.parent)
|
2016-04-27 01:21:36 +00:00
|
|
|
self.failUnlessEqual(n.get_config("node", "nickname").decode('utf-8'),
|
|
|
|
u"\u2621")
|
2011-08-08 18:05:52 +00:00
|
|
|
|
2014-05-05 21:55:50 +00:00
|
|
|
def test_tahoe_cfg_hash_in_name(self):
|
|
|
|
basedir = "test_node/test_cfg_hash_in_name"
|
|
|
|
nickname = "Hash#Bang!" # a clever nickname containing a hash
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write("[node]\n")
|
|
|
|
f.write("nickname = %s\n" % (nickname,))
|
|
|
|
f.close()
|
|
|
|
n = TestNode(basedir)
|
|
|
|
self.failUnless(n.nickname == nickname)
|
|
|
|
|
2012-06-11 00:46:38 +00:00
|
|
|
def test_private_config(self):
|
|
|
|
basedir = "test_node/test_private_config"
|
|
|
|
privdir = os.path.join(basedir, "private")
|
|
|
|
fileutil.make_dirs(privdir)
|
|
|
|
f = open(os.path.join(privdir, 'already'), 'wt')
|
|
|
|
f.write("secret")
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
n = TestNode(basedir)
|
|
|
|
self.failUnlessEqual(n.get_private_config("already"), "secret")
|
|
|
|
self.failUnlessEqual(n.get_private_config("not", "default"), "default")
|
|
|
|
self.failUnlessRaises(MissingConfigEntry, n.get_private_config, "not")
|
|
|
|
value = n.get_or_create_private_config("new", "start")
|
|
|
|
self.failUnlessEqual(value, "start")
|
|
|
|
self.failUnlessEqual(n.get_private_config("new"), "start")
|
|
|
|
counter = []
|
|
|
|
def make_newer():
|
|
|
|
counter.append("called")
|
|
|
|
return "newer"
|
|
|
|
value = n.get_or_create_private_config("newer", make_newer)
|
|
|
|
self.failUnlessEqual(len(counter), 1)
|
|
|
|
self.failUnlessEqual(value, "newer")
|
|
|
|
self.failUnlessEqual(n.get_private_config("newer"), "newer")
|
|
|
|
|
|
|
|
value = n.get_or_create_private_config("newer", make_newer)
|
|
|
|
self.failUnlessEqual(len(counter), 1) # don't call unless necessary
|
|
|
|
self.failUnlessEqual(value, "newer")
|
|
|
|
|
2007-10-31 07:54:42 +00:00
|
|
|
def test_timestamp(self):
|
|
|
|
# this modified logger doesn't seem to get used during the tests,
|
|
|
|
# probably because we don't modify the LogObserver that trial
|
|
|
|
# installs (only the one that twistd installs). So manually exercise
|
|
|
|
# it a little bit.
|
|
|
|
t = formatTimeTahoeStyle("ignored", time.time())
|
|
|
|
self.failUnless("Z" in t)
|
|
|
|
t2 = formatTimeTahoeStyle("ignored", int(time.time()))
|
|
|
|
self.failUnless("Z" in t2)
|
2007-12-17 23:39:54 +00:00
|
|
|
|
|
|
|
def test_secrets_dir(self):
|
|
|
|
basedir = "test_node/test_secrets_dir"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
n = TestNode(basedir)
|
2010-01-14 22:17:19 +00:00
|
|
|
self.failUnless(isinstance(n, TestNode))
|
2007-12-17 23:39:54 +00:00
|
|
|
self.failUnless(os.path.exists(os.path.join(basedir, "private")))
|
|
|
|
|
|
|
|
def test_secrets_dir_protected(self):
|
|
|
|
if "win32" in sys.platform.lower() or "cygwin" in sys.platform.lower():
|
|
|
|
# We don't know how to test that unprivileged users can't read this
|
|
|
|
# thing. (Also we don't know exactly how to set the permissions so
|
|
|
|
# that unprivileged users can't read this thing.)
|
|
|
|
raise unittest.SkipTest("We don't know how to set permissions on Windows.")
|
|
|
|
basedir = "test_node/test_secrets_dir_protected"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
n = TestNode(basedir)
|
2010-01-14 22:17:19 +00:00
|
|
|
self.failUnless(isinstance(n, TestNode))
|
2007-12-17 23:39:54 +00:00
|
|
|
privdir = os.path.join(basedir, "private")
|
|
|
|
st = os.stat(privdir)
|
|
|
|
bits = stat.S_IMODE(st[stat.ST_MODE])
|
|
|
|
self.failUnless(bits & 0001 == 0, bits)
|
2012-04-29 02:28:44 +00:00
|
|
|
|
2015-07-17 21:03:53 +00:00
|
|
|
def test_logdir_is_str(self):
|
2012-04-29 02:28:44 +00:00
|
|
|
basedir = "test_node/test_logdir_is_str"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
|
2015-07-17 21:03:53 +00:00
|
|
|
ns = Namespace()
|
|
|
|
ns.called = False
|
2012-04-29 02:28:44 +00:00
|
|
|
def call_setLogDir(logdir):
|
2015-07-17 21:03:53 +00:00
|
|
|
ns.called = True
|
2012-04-29 02:28:44 +00:00
|
|
|
self.failUnless(isinstance(logdir, str), logdir)
|
2015-07-17 21:03:53 +00:00
|
|
|
self.patch(foolscap.logging.log, 'setLogDir', call_setLogDir)
|
2012-04-29 02:28:44 +00:00
|
|
|
|
|
|
|
TestNode(basedir)
|
2015-07-17 21:03:53 +00:00
|
|
|
self.failUnless(ns.called)
|
2016-08-30 01:49:20 +00:00
|
|
|
|
|
|
|
NO_LISTEN_CONFIG = """
|
|
|
|
[node]
|
|
|
|
tub.port =
|
|
|
|
#tub.location =
|
|
|
|
[client]
|
|
|
|
introducer.furl = empty
|
|
|
|
"""
|
|
|
|
|
|
|
|
class ClientNotListening(unittest.TestCase):
|
|
|
|
def test_port_none(self):
|
|
|
|
basedir = "test_node/test_port_none"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write(NO_LISTEN_CONFIG)
|
|
|
|
f.write("[storage]\n")
|
|
|
|
f.write("enabled = false\n")
|
|
|
|
f.close()
|
|
|
|
n = Client(basedir)
|
|
|
|
self.assertEqual(n.tub.getListeners(), [])
|
|
|
|
|
|
|
|
def test_port_none_location_none(self):
|
|
|
|
basedir = "test_node/test_port_none_location_none"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write(NO_LISTEN_CONFIG)
|
|
|
|
f.write("tub.location =\n")
|
|
|
|
f.write("[storage]\n")
|
|
|
|
f.write("enabled = false\n")
|
|
|
|
f.close()
|
|
|
|
n = Client(basedir)
|
|
|
|
self.assertEqual(n.tub.getListeners(), [])
|
|
|
|
|
|
|
|
def test_port_none_storage(self):
|
|
|
|
basedir = "test_node/test_port_none_storage"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write(NO_LISTEN_CONFIG)
|
|
|
|
f.write("[storage]\n")
|
|
|
|
f.write("enabled = true")
|
|
|
|
f.close()
|
|
|
|
e = self.assertRaises(ValueError, Client, basedir)
|
|
|
|
self.assertIn("storage is enabled, but tub is not listening", str(e))
|
|
|
|
|
|
|
|
def test_port_none_helper(self):
|
|
|
|
basedir = "test_node/test_port_none_helper"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write(NO_LISTEN_CONFIG)
|
|
|
|
f.write("[storage]\n")
|
|
|
|
f.write("enabled = false\n")
|
|
|
|
f.write("[helper]\n")
|
|
|
|
f.write("enabled = true")
|
|
|
|
f.close()
|
|
|
|
e = self.assertRaises(ValueError, Client, basedir)
|
|
|
|
self.assertIn("helper is enabled, but tub is not listening", str(e))
|
|
|
|
|
|
|
|
class IntroducerNotListening(unittest.TestCase):
|
|
|
|
def test_port_none_introducer(self):
|
|
|
|
basedir = "test_node/test_port_none_introducer"
|
|
|
|
fileutil.make_dirs(basedir)
|
|
|
|
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
|
|
|
f.write("[node]\n")
|
|
|
|
f.write("tub.port = \n")
|
|
|
|
f.write("#tub.location = \n")
|
|
|
|
f.close()
|
|
|
|
e = self.assertRaises(ValueError, IntroducerNode, basedir)
|
|
|
|
self.assertIn("we are Introducer, but tub is not listening", str(e))
|