Merge branch '2826-async-dispatch'
This commit is contained in:
commit
ecc2080372
|
@ -1,6 +1,4 @@
|
|||
|
||||
import os, sys
|
||||
|
||||
import os
|
||||
from allmydata.scripts.common import BasedirOptions, NoDefaultBasedirOptions
|
||||
from allmydata.scripts.default_nodedir import _default_nodedir
|
||||
from allmydata.util.assertutil import precondition
|
||||
|
@ -129,7 +127,9 @@ def write_client_config(c, config):
|
|||
c.write("enabled = false\n")
|
||||
c.write("\n")
|
||||
|
||||
def create_node(config, out=sys.stdout, err=sys.stderr):
|
||||
def create_node(config):
|
||||
out = config.stdout
|
||||
err = config.stderr
|
||||
basedir = config['basedir']
|
||||
# This should always be called with an absolute Unicode basedir.
|
||||
precondition(isinstance(basedir, unicode), basedir)
|
||||
|
@ -162,12 +162,14 @@ def create_node(config, out=sys.stdout, err=sys.stderr):
|
|||
print >>out, " Please set [node]nickname= in tahoe.cfg"
|
||||
return 0
|
||||
|
||||
def create_client(config, out=sys.stdout, err=sys.stderr):
|
||||
def create_client(config):
|
||||
config['no-storage'] = True
|
||||
return create_node(config, out=out, err=err)
|
||||
return create_node(config)
|
||||
|
||||
|
||||
def create_introducer(config, out=sys.stdout, err=sys.stderr):
|
||||
def create_introducer(config):
|
||||
out = config.stdout
|
||||
err = config.stderr
|
||||
basedir = config['basedir']
|
||||
# This should always be called with an absolute Unicode basedir.
|
||||
precondition(isinstance(basedir, unicode), basedir)
|
||||
|
|
|
@ -3,6 +3,7 @@ import os, sys
|
|||
from cStringIO import StringIO
|
||||
|
||||
from twisted.python import usage
|
||||
from twisted.internet import defer, task, threads
|
||||
|
||||
from allmydata.scripts.common import get_default_nodedir
|
||||
from allmydata.scripts import debug, create_node, startstop_node, cli, \
|
||||
|
@ -89,32 +90,17 @@ create_dispatch = {}
|
|||
for module in (create_node, stats_gatherer):
|
||||
create_dispatch.update(module.dispatch)
|
||||
|
||||
def runner(argv,
|
||||
run_by_human=True,
|
||||
stdin=None, stdout=None, stderr=None,
|
||||
install_node_control=True, additional_commands=None):
|
||||
|
||||
assert sys.version_info < (3,), ur"Tahoe-LAFS does not run under Python 3. Please use Python 2.7.x."
|
||||
|
||||
stdin = stdin or sys.stdin
|
||||
stdout = stdout or sys.stdout
|
||||
stderr = stderr or sys.stderr
|
||||
|
||||
def parse_options(argv, config=None):
|
||||
if not config:
|
||||
config = Options()
|
||||
if install_node_control:
|
||||
config.subCommands.extend(startstop_node.subCommands)
|
||||
|
||||
ac_dispatch = {}
|
||||
if additional_commands:
|
||||
for ac in additional_commands:
|
||||
config.subCommands.extend(ac.subCommands)
|
||||
ac_dispatch.update(ac.dispatch)
|
||||
config.parseOptions(argv) # may raise usage.error
|
||||
return config
|
||||
|
||||
def parse_or_exit_with_explanation(argv, stdout=sys.stdout):
|
||||
config = Options()
|
||||
try:
|
||||
config.parseOptions(argv)
|
||||
parse_options(argv, config=config)
|
||||
except usage.error, e:
|
||||
if not run_by_human:
|
||||
raise
|
||||
c = config
|
||||
while hasattr(c, 'subOptions'):
|
||||
c = c.subOptions
|
||||
|
@ -124,51 +110,68 @@ def runner(argv,
|
|||
except Exception:
|
||||
msg = repr(e)
|
||||
print >>stdout, "%s: %s\n" % (sys.argv[0], quote_output(msg, quotemarks=False))
|
||||
return 1
|
||||
sys.exit(1)
|
||||
return config
|
||||
|
||||
def dispatch(config,
|
||||
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
|
||||
command = config.subCommand
|
||||
so = config.subOptions
|
||||
|
||||
if config['quiet']:
|
||||
stdout = StringIO()
|
||||
|
||||
so.stdout = stdout
|
||||
so.stderr = stderr
|
||||
so.stdin = stdin
|
||||
|
||||
if command in create_dispatch:
|
||||
rc = create_dispatch[command](so, stdout, stderr)
|
||||
f = create_dispatch[command]
|
||||
elif command in startstop_node.dispatch:
|
||||
rc = startstop_node.dispatch[command](so, stdout, stderr)
|
||||
f = startstop_node.dispatch[command]
|
||||
elif command in debug.dispatch:
|
||||
rc = debug.dispatch[command](so)
|
||||
f = debug.dispatch[command]
|
||||
elif command in admin.dispatch:
|
||||
rc = admin.dispatch[command](so)
|
||||
f = admin.dispatch[command]
|
||||
elif command in cli.dispatch:
|
||||
rc = cli.dispatch[command](so)
|
||||
# these are blocking, and must be run in a thread
|
||||
f0 = cli.dispatch[command]
|
||||
f = lambda so: threads.deferToThread(f0, so)
|
||||
elif command in magic_folder_cli.dispatch:
|
||||
rc = magic_folder_cli.dispatch[command](so)
|
||||
elif command in ac_dispatch:
|
||||
rc = ac_dispatch[command](so, stdout, stderr)
|
||||
# same
|
||||
f0 = magic_folder_cli.dispatch[command]
|
||||
f = lambda so: threads.deferToThread(f0, so)
|
||||
else:
|
||||
raise usage.UsageError()
|
||||
|
||||
return rc
|
||||
d = defer.maybeDeferred(f, so)
|
||||
# the calling convention for CLI dispatch functions is that they either:
|
||||
# 1: succeed and return rc=0
|
||||
# 2: print explanation to stderr and return rc!=0
|
||||
# 3: raise an exception that should just be printed normally
|
||||
# 4: return a Deferred that does 1 or 2 or 3
|
||||
def _raise_sys_exit(rc):
|
||||
sys.exit(rc)
|
||||
d.addCallback(_raise_sys_exit)
|
||||
return d
|
||||
|
||||
def run():
|
||||
assert sys.version_info < (3,), ur"Tahoe-LAFS does not run under Python 3. Please use Python 2.7.x."
|
||||
|
||||
def run(install_node_control=True):
|
||||
try:
|
||||
if sys.platform == "win32":
|
||||
from allmydata.windows.fixups import initialize
|
||||
initialize()
|
||||
|
||||
rc = runner(sys.argv[1:], install_node_control=install_node_control)
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
rc = 1
|
||||
|
||||
sys.exit(rc)
|
||||
d = defer.maybeDeferred(parse_or_exit_with_explanation, sys.argv[1:])
|
||||
d.addCallback(dispatch)
|
||||
def _show_exception(f):
|
||||
# when task.react() notices a non-SystemExit exception, it does
|
||||
# log.err() with the failure and then exits with rc=1. We want this
|
||||
# to actually print the exception to stderr, like it would do if we
|
||||
# weren't using react().
|
||||
if f.check(SystemExit):
|
||||
return f # dispatch function handled it
|
||||
f.printTraceback(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
d.addErrback(_show_exception)
|
||||
task.react(lambda _reactor: d) # doesn't return: calls sys.exit(rc)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
|
|
@ -99,7 +99,9 @@ def identify_node_type(basedir):
|
|||
return t
|
||||
return None
|
||||
|
||||
def start(config, out=sys.stdout, err=sys.stderr):
|
||||
def start(config):
|
||||
out = config.stdout
|
||||
err = config.stderr
|
||||
basedir = config['basedir']
|
||||
quoted_basedir = quote_local_unicode_path(basedir)
|
||||
print >>out, "STARTING", quoted_basedir
|
||||
|
@ -169,7 +171,9 @@ def start(config, out=sys.stdout, err=sys.stderr):
|
|||
# we should only reach here if --nodaemon or equivalent was used
|
||||
return 0
|
||||
|
||||
def stop(config, out=sys.stdout, err=sys.stderr):
|
||||
def stop(config):
|
||||
out = config.stdout
|
||||
err = config.stderr
|
||||
basedir = config['basedir']
|
||||
quoted_basedir = quote_local_unicode_path(basedir)
|
||||
print >>out, "STOPPING", quoted_basedir
|
||||
|
@ -227,23 +231,24 @@ def stop(config, out=sys.stdout, err=sys.stderr):
|
|||
# we define rc=1 to mean "I think something is still running, sorry"
|
||||
return 1
|
||||
|
||||
def restart(config, stdout, stderr):
|
||||
rc = stop(config, stdout, stderr)
|
||||
def restart(config):
|
||||
stderr = config.stderr
|
||||
rc = stop(config)
|
||||
if rc == 2:
|
||||
print >>stderr, "ignoring couldn't-stop"
|
||||
rc = 0
|
||||
if rc:
|
||||
print >>stderr, "not restarting"
|
||||
return rc
|
||||
return start(config, stdout, stderr)
|
||||
return start(config)
|
||||
|
||||
def run(config, stdout, stderr):
|
||||
def run(config):
|
||||
config.twistd_args = config.twistd_args + ("--nodaemon",)
|
||||
# Previously we would do the equivalent of adding ("--logfile",
|
||||
# "tahoesvc.log"), but that redirects stdout/stderr which is often
|
||||
# unhelpful, and the user can add that option explicitly if they want.
|
||||
|
||||
return start(config, stdout, stderr)
|
||||
return start(config)
|
||||
|
||||
|
||||
subCommands = [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, sys
|
||||
import os
|
||||
from twisted.python import usage
|
||||
from allmydata.scripts.common import NoDefaultBasedirOptions
|
||||
from allmydata.scripts.create_node import write_tac
|
||||
|
@ -56,7 +56,8 @@ class CreateStatsGathererOptions(NoDefaultBasedirOptions):
|
|||
"""
|
||||
|
||||
|
||||
def create_stats_gatherer(config, out=sys.stdout, err=sys.stderr):
|
||||
def create_stats_gatherer(config):
|
||||
err = config.stderr
|
||||
basedir = config['basedir']
|
||||
# This should always be called with an absolute Unicode basedir.
|
||||
precondition(isinstance(basedir, unicode), basedir)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
from ...util.encodingutil import unicode_to_argv
|
||||
from ...scripts import runner
|
||||
from ..common_util import ReallyEqualMixin, run_cli
|
||||
|
||||
def parse_options(basedir, command, args):
|
||||
o = runner.Options()
|
||||
o.parseOptions(["--node-directory", basedir, command] + args)
|
||||
while hasattr(o, "subOptions"):
|
||||
o = o.subOptions
|
||||
return o
|
||||
|
||||
class CLITestMixin(ReallyEqualMixin):
|
||||
def do_cli(self, verb, *args, **kwargs):
|
||||
# client_num is used to execute client CLI commands on a specific
|
||||
# client.
|
||||
client_num = kwargs.get("client_num", 0)
|
||||
client_dir = unicode_to_argv(self.get_clientdir(i=client_num))
|
||||
nodeargs = [ "--node-directory", client_dir ]
|
||||
return run_cli(verb, nodeargs=nodeargs, *args, **kwargs)
|
|
@ -14,7 +14,7 @@ from allmydata.util.namespace import Namespace
|
|||
from allmydata.scripts import cli, backupdb
|
||||
from ..common_util import StallMixin
|
||||
from ..no_network import GridTestMixin
|
||||
from .test_cli import CLITestMixin, parse_options
|
||||
from .common import CLITestMixin, parse_options
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from allmydata.mutable.publish import MutableData
|
|||
from allmydata.immutable import upload
|
||||
from allmydata.scripts import debug
|
||||
from ..no_network import GridTestMixin
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import urllib, sys
|
|||
|
||||
from twisted.trial import unittest
|
||||
from twisted.python.monkey import MonkeyPatcher
|
||||
from twisted.internet import task
|
||||
|
||||
import allmydata
|
||||
from allmydata.util import fileutil, hashutil, base32, keyutil
|
||||
|
@ -29,57 +30,16 @@ from allmydata.scripts.common import DEFAULT_ALIAS, get_aliases, get_alias, \
|
|||
DefaultAliasMarker
|
||||
|
||||
from allmydata.scripts import cli, debug, runner
|
||||
from ..common_util import ReallyEqualMixin
|
||||
from ..common_util import (ReallyEqualMixin, skip_if_cannot_represent_filename,
|
||||
run_cli)
|
||||
from ..no_network import GridTestMixin
|
||||
from twisted.internet import threads # CLI tests use deferToThread
|
||||
from .common import CLITestMixin, parse_options
|
||||
from twisted.python import usage
|
||||
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.util.encodingutil import listdir_unicode, unicode_platform, \
|
||||
get_io_encoding, get_filesystem_encoding, unicode_to_argv
|
||||
from allmydata.util.encodingutil import listdir_unicode, get_io_encoding
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
def parse_options(basedir, command, args):
|
||||
o = runner.Options()
|
||||
o.parseOptions(["--node-directory", basedir, command] + args)
|
||||
while hasattr(o, "subOptions"):
|
||||
o = o.subOptions
|
||||
return o
|
||||
|
||||
class CLITestMixin(ReallyEqualMixin):
|
||||
def do_cli(self, verb, *args, **kwargs):
|
||||
precondition(not [True for arg in args if not isinstance(arg, str)],
|
||||
"arguments to do_cli must be strs -- convert using unicode_to_argv", args=args)
|
||||
|
||||
# client_num is used to execute client CLI commands on a specific client.
|
||||
client_num = kwargs.get("client_num", 0)
|
||||
|
||||
nodeargs = [
|
||||
"--node-directory", unicode_to_argv(self.get_clientdir(i=client_num)),
|
||||
]
|
||||
argv = nodeargs + [verb] + list(args)
|
||||
stdin = kwargs.get("stdin", "")
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
d = threads.deferToThread(runner.runner, argv, run_by_human=False,
|
||||
stdin=StringIO(stdin),
|
||||
stdout=stdout, stderr=stderr)
|
||||
def _done(rc):
|
||||
return rc, stdout.getvalue(), stderr.getvalue()
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def skip_if_cannot_represent_filename(self, u):
|
||||
precondition(isinstance(u, unicode))
|
||||
|
||||
enc = get_filesystem_encoding()
|
||||
if not unicode_platform():
|
||||
try:
|
||||
u.encode(enc)
|
||||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
|
||||
|
||||
|
||||
class CLI(CLITestMixin, unittest.TestCase):
|
||||
def _dump_cap(self, *args):
|
||||
config = debug.DumpCapOptions()
|
||||
|
@ -534,7 +494,7 @@ class CLI(CLITestMixin, unittest.TestCase):
|
|||
filenames = [u'L\u00F4zane', u'Bern', u'Gen\u00E8ve'] # must be NFC
|
||||
|
||||
for name in filenames:
|
||||
self.skip_if_cannot_represent_filename(name)
|
||||
skip_if_cannot_represent_filename(name)
|
||||
|
||||
basedir = "cli/common/listdir_unicode_good"
|
||||
fileutil.make_dirs(basedir)
|
||||
|
@ -552,10 +512,9 @@ class CLI(CLITestMixin, unittest.TestCase):
|
|||
exc = Exception("canary")
|
||||
ns = Namespace()
|
||||
|
||||
ns.runner_called = False
|
||||
def call_runner(args, install_node_control=True):
|
||||
ns.runner_called = True
|
||||
self.failUnlessEqual(install_node_control, True)
|
||||
ns.parse_called = False
|
||||
def call_parse_or_exit(args):
|
||||
ns.parse_called = True
|
||||
raise exc
|
||||
|
||||
ns.sys_exit_called = False
|
||||
|
@ -563,13 +522,23 @@ class CLI(CLITestMixin, unittest.TestCase):
|
|||
ns.sys_exit_called = True
|
||||
self.failUnlessEqual(exitcode, 1)
|
||||
|
||||
patcher = MonkeyPatcher((runner, 'runner', call_runner),
|
||||
def fake_react(f):
|
||||
d = f("reactor")
|
||||
# normally this Deferred would be errbacked with SystemExit, but
|
||||
# since we mocked out sys.exit, it will be fired with None. So
|
||||
# it's safe to drop it on the floor.
|
||||
del d
|
||||
|
||||
patcher = MonkeyPatcher((runner, 'parse_or_exit_with_explanation',
|
||||
call_parse_or_exit),
|
||||
(sys, 'argv', ["tahoe"]),
|
||||
(sys, 'exit', call_sys_exit),
|
||||
(sys, 'stderr', stderr))
|
||||
(sys, 'stderr', stderr),
|
||||
(task, 'react', fake_react),
|
||||
)
|
||||
patcher.runWithPatches(runner.run)
|
||||
|
||||
self.failUnless(ns.runner_called)
|
||||
self.failUnless(ns.parse_called)
|
||||
self.failUnless(ns.sys_exit_called)
|
||||
self.failUnlessIn(str(exc), stderr.getvalue())
|
||||
|
||||
|
@ -747,21 +716,9 @@ class Ln(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||
|
||||
|
||||
class Admin(unittest.TestCase):
|
||||
def do_cli(self, *args, **kwargs):
|
||||
argv = list(args)
|
||||
stdin = kwargs.get("stdin", "")
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
d = threads.deferToThread(runner.runner, argv, run_by_human=False,
|
||||
stdin=StringIO(stdin),
|
||||
stdout=stdout, stderr=stderr)
|
||||
def _done(res):
|
||||
return stdout.getvalue(), stderr.getvalue()
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def test_generate_keypair(self):
|
||||
d = self.do_cli("admin", "generate-keypair")
|
||||
def _done( (stdout, stderr) ):
|
||||
d = run_cli("admin", "generate-keypair")
|
||||
def _done( (rc, stdout, stderr) ):
|
||||
lines = [line.strip() for line in stdout.splitlines()]
|
||||
privkey_bits = lines[0].split()
|
||||
pubkey_bits = lines[1].split()
|
||||
|
@ -780,8 +737,8 @@ class Admin(unittest.TestCase):
|
|||
|
||||
def test_derive_pubkey(self):
|
||||
priv1,pub1 = keyutil.make_keypair()
|
||||
d = self.do_cli("admin", "derive-pubkey", priv1)
|
||||
def _done( (stdout, stderr) ):
|
||||
d = run_cli("admin", "derive-pubkey", priv1)
|
||||
def _done( (rc, stdout, stderr) ):
|
||||
lines = stdout.split("\n")
|
||||
privkey_line = lines[0].strip()
|
||||
pubkey_line = lines[1].strip()
|
||||
|
|
|
@ -9,7 +9,8 @@ from allmydata.util.encodingutil import (quote_output, get_io_encoding,
|
|||
unicode_to_output, to_str)
|
||||
from allmydata.util.assertutil import _assert
|
||||
from ..no_network import GridTestMixin
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
from ..common_util import skip_if_cannot_represent_filename
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
@ -30,7 +31,7 @@ class Cp(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII command argument could not be encoded on this platform.")
|
||||
|
||||
self.skip_if_cannot_represent_filename(fn1)
|
||||
skip_if_cannot_represent_filename(fn1)
|
||||
|
||||
self.set_up_grid(oneshare=True)
|
||||
|
||||
|
@ -198,7 +199,7 @@ class Cp(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII command argument could not be encoded on this platform.")
|
||||
|
||||
self.skip_if_cannot_represent_filename(fn1)
|
||||
skip_if_cannot_represent_filename(fn1)
|
||||
|
||||
self.set_up_grid(oneshare=True)
|
||||
|
||||
|
|
|
@ -1,54 +1,53 @@
|
|||
import os
|
||||
from StringIO import StringIO
|
||||
from twisted.trial import unittest
|
||||
from allmydata.scripts import runner
|
||||
from twisted.internet import defer
|
||||
from allmydata.util import configutil
|
||||
from ..common_util import run_cli
|
||||
|
||||
class Config(unittest.TestCase):
|
||||
def do_cli(self, *args):
|
||||
argv = list(args)
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
rc = runner.runner(argv, run_by_human=False,
|
||||
stdout=stdout, stderr=stderr)
|
||||
return rc, stdout.getvalue(), stderr.getvalue()
|
||||
|
||||
def read_config(self, basedir):
|
||||
tahoe_cfg = os.path.join(basedir, "tahoe.cfg")
|
||||
config = configutil.get_config(tahoe_cfg)
|
||||
return config
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-client", basedir)
|
||||
rc, out, err = yield run_cli("create-client", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_hide_ip(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-client", "--hide-ip", basedir)
|
||||
rc, out, err = yield run_cli("create-client", "--hide-ip", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-node", basedir)
|
||||
rc, out, err = yield run_cli("create-node", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_hide_ip(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-node", "--hide-ip", basedir)
|
||||
rc, out, err = yield run_cli("create-node", "--hide-ip", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_introducer(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-introducer", basedir)
|
||||
rc, out, err = yield run_cli("create-introducer", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_introducer_hide_ip(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = self.do_cli("create-introducer", "--hide-ip", basedir)
|
||||
rc, out, err = yield run_cli("create-introducer", "--hide-ip", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False)
|
||||
|
|
|
@ -6,7 +6,7 @@ from allmydata.scripts.common import get_aliases
|
|||
from allmydata.scripts import cli, runner
|
||||
from ..no_network import GridTestMixin
|
||||
from allmydata.util.encodingutil import quote_output, get_io_encoding
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from allmydata.interfaces import MDMF_VERSION, SDMF_VERSION
|
|||
from allmydata.mutable.publish import MutableData
|
||||
from ..no_network import GridTestMixin
|
||||
from allmydata.util.encodingutil import quote_output, get_io_encoding
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from allmydata.util.assertutil import precondition
|
|||
from allmydata.util import fileutil
|
||||
from allmydata.scripts.common import get_aliases
|
||||
from ..no_network import GridTestMixin
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
from allmydata.scripts import magic_folder_cli
|
||||
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||
from allmydata.util.encodingutil import unicode_to_argv
|
||||
|
|
|
@ -3,7 +3,7 @@ from twisted.trial import unittest
|
|||
from allmydata.util import fileutil
|
||||
from ..no_network import GridTestMixin
|
||||
from allmydata.scripts import tahoe_mv
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ from allmydata.util import fileutil
|
|||
from allmydata.scripts.common import get_aliases
|
||||
from allmydata.scripts import cli
|
||||
from ..no_network import GridTestMixin
|
||||
from ..common_util import skip_if_cannot_represent_filename
|
||||
from allmydata.util.encodingutil import get_io_encoding, unicode_to_argv
|
||||
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||
from .test_cli import CLITestMixin
|
||||
from .common import CLITestMixin
|
||||
|
||||
timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s
|
||||
|
||||
|
@ -427,7 +428,7 @@ class Put(GridTestMixin, CLITestMixin, unittest.TestCase):
|
|||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII command argument could not be encoded on this platform.")
|
||||
|
||||
self.skip_if_cannot_represent_filename(u"\u00E0 trier.txt")
|
||||
skip_if_cannot_represent_filename(u"\u00E0 trier.txt")
|
||||
|
||||
self.basedir = "cli/Put/immutable_from_file_unicode"
|
||||
self.set_up_grid(oneshare=True)
|
||||
|
|
|
@ -1,12 +1,50 @@
|
|||
import os, signal, sys, time
|
||||
from random import randrange
|
||||
from cStringIO import StringIO
|
||||
|
||||
from twisted.internet import reactor, defer
|
||||
from twisted.python import failure
|
||||
from twisted.trial import unittest
|
||||
|
||||
from allmydata.util import fileutil, log
|
||||
from ..util.assertutil import precondition
|
||||
from allmydata.util.encodingutil import unicode_platform, get_filesystem_encoding
|
||||
from ..scripts import runner
|
||||
|
||||
def skip_if_cannot_represent_filename(u):
|
||||
precondition(isinstance(u, unicode))
|
||||
|
||||
enc = get_filesystem_encoding()
|
||||
if not unicode_platform():
|
||||
try:
|
||||
u.encode(enc)
|
||||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
|
||||
|
||||
def run_cli(verb, *args, **kwargs):
|
||||
precondition(not [True for arg in args if not isinstance(arg, str)],
|
||||
"arguments to do_cli must be strs -- convert using unicode_to_argv", args=args)
|
||||
nodeargs = kwargs.get("nodeargs", [])
|
||||
argv = nodeargs + [verb] + list(args)
|
||||
stdin = kwargs.get("stdin", "")
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
d = defer.succeed(argv)
|
||||
d.addCallback(runner.parse_or_exit_with_explanation, stdout=stdout)
|
||||
d.addCallback(runner.dispatch,
|
||||
stdin=StringIO(stdin),
|
||||
stdout=stdout, stderr=stderr)
|
||||
def _done(rc):
|
||||
return 0, stdout.getvalue(), stderr.getvalue()
|
||||
def _err(f):
|
||||
f.trap(SystemExit)
|
||||
return f.value.code, stdout.getvalue(), stderr.getvalue()
|
||||
d.addCallbacks(_done, _err)
|
||||
return d
|
||||
|
||||
def parse_cli(*argv):
|
||||
# This parses the CLI options (synchronously), and returns the Options
|
||||
# argument, or throws usage.UsageError if something went wrong.
|
||||
return runner.parse_options(argv)
|
||||
|
||||
class DevNullDictionary(dict):
|
||||
def __setitem__(self, key, value):
|
||||
|
|
|
@ -4,9 +4,9 @@ from StringIO import StringIO
|
|||
from twisted.trial import unittest
|
||||
|
||||
from allmydata.util import fileutil
|
||||
from allmydata.util.encodingutil import listdir_unicode, get_filesystem_encoding, unicode_platform
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.util.encodingutil import listdir_unicode
|
||||
from allmydata.scripts import backupdb
|
||||
from .common_util import skip_if_cannot_represent_filename
|
||||
|
||||
class BackupDB(unittest.TestCase):
|
||||
def create(self, dbfile):
|
||||
|
@ -15,16 +15,6 @@ class BackupDB(unittest.TestCase):
|
|||
self.failUnless(bdb, "unable to create backupdb from %r" % (dbfile,))
|
||||
return bdb
|
||||
|
||||
def skip_if_cannot_represent_filename(self, u):
|
||||
precondition(isinstance(u, unicode))
|
||||
|
||||
enc = get_filesystem_encoding()
|
||||
if not unicode_platform():
|
||||
try:
|
||||
u.encode(enc)
|
||||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
|
||||
|
||||
def test_basic(self):
|
||||
self.basedir = basedir = os.path.join("backupdb", "create")
|
||||
fileutil.make_dirs(basedir)
|
||||
|
@ -222,8 +212,8 @@ class BackupDB(unittest.TestCase):
|
|||
self.failIf(r.was_created())
|
||||
|
||||
def test_unicode(self):
|
||||
self.skip_if_cannot_represent_filename(u"f\u00f6\u00f6.txt")
|
||||
self.skip_if_cannot_represent_filename(u"b\u00e5r.txt")
|
||||
skip_if_cannot_represent_filename(u"f\u00f6\u00f6.txt")
|
||||
skip_if_cannot_represent_filename(u"b\u00e5r.txt")
|
||||
|
||||
self.basedir = basedir = os.path.join("backupdb", "unicode")
|
||||
fileutil.make_dirs(basedir)
|
||||
|
|
|
@ -4,12 +4,11 @@ from twisted.trial import unittest
|
|||
|
||||
from allmydata.util import configutil
|
||||
from allmydata.test.no_network import GridTestMixin
|
||||
from .cli.test_cli import CLITestMixin
|
||||
from ..scripts import create_node
|
||||
from .. import client
|
||||
|
||||
|
||||
class ConfigUtilTests(CLITestMixin, GridTestMixin, unittest.TestCase):
|
||||
class ConfigUtilTests(GridTestMixin, unittest.TestCase):
|
||||
|
||||
def test_config_utils(self):
|
||||
self.basedir = "cli/ConfigUtilTests/test-config-utils"
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
|
||||
import os, simplejson, urllib
|
||||
from cStringIO import StringIO
|
||||
from twisted.trial import unittest
|
||||
from twisted.internet import defer
|
||||
from twisted.internet import threads # CLI tests use deferToThread
|
||||
from allmydata.immutable import upload
|
||||
from allmydata.mutable.common import UnrecoverableFileError
|
||||
from allmydata.mutable.publish import MutableData
|
||||
from allmydata.util import idlib
|
||||
from allmydata.util import base32
|
||||
from allmydata.scripts import runner
|
||||
from allmydata.interfaces import ICheckResults, ICheckAndRepairResults, \
|
||||
IDeepCheckResults, IDeepCheckAndRepairResults
|
||||
from allmydata.monitor import Monitor, OperationCancelledError
|
||||
|
@ -18,19 +15,13 @@ from twisted.web.client import getPage
|
|||
|
||||
from allmydata.test.common import ErrorMixin, _corrupt_mutable_share_data, \
|
||||
ShouldFailMixin
|
||||
from allmydata.test.common_util import StallMixin
|
||||
from .common_util import StallMixin, run_cli
|
||||
from allmydata.test.no_network import GridTestMixin
|
||||
from .cli.common import CLITestMixin
|
||||
|
||||
timeout = 2400 # One of these took 1046.091s on Zandr's ARM box.
|
||||
|
||||
class MutableChecker(GridTestMixin, unittest.TestCase, ErrorMixin):
|
||||
def _run_cli(self, argv):
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
# this can only do synchronous operations
|
||||
assert argv[0] == "debug"
|
||||
runner.runner(argv, run_by_human=False, stdout=stdout, stderr=stderr)
|
||||
return stdout.getvalue()
|
||||
|
||||
def test_good(self):
|
||||
self.basedir = "deepcheck/MutableChecker/good"
|
||||
self.set_up_grid()
|
||||
|
@ -130,7 +121,8 @@ class MutableChecker(GridTestMixin, unittest.TestCase, ErrorMixin):
|
|||
return d
|
||||
|
||||
|
||||
class DeepCheckBase(GridTestMixin, ErrorMixin, StallMixin, ShouldFailMixin):
|
||||
class DeepCheckBase(GridTestMixin, ErrorMixin, StallMixin, ShouldFailMixin,
|
||||
CLITestMixin):
|
||||
|
||||
def web_json(self, n, **kwargs):
|
||||
kwargs["output"] = "json"
|
||||
|
@ -727,17 +719,6 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
|
||||
return d
|
||||
|
||||
def _run_cli(self, argv, stdin=""):
|
||||
#print "CLI:", argv
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
d = threads.deferToThread(runner.runner, argv, run_by_human=False,
|
||||
stdin=StringIO(stdin),
|
||||
stdout=stdout, stderr=stderr)
|
||||
def _done(res):
|
||||
return stdout.getvalue(), stderr.getvalue()
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def do_test_cli_good(self, ignored):
|
||||
d = defer.succeed(None)
|
||||
d.addCallback(lambda ign: self.do_cli_manifest_stream1())
|
||||
|
@ -757,11 +738,8 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
self.failUnless(base32.b2a(self.large.get_storage_index()) in lines)
|
||||
|
||||
def do_cli_manifest_stream1(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"manifest",
|
||||
self.root_uri])
|
||||
def _check((out,err)):
|
||||
d = self.do_cli("manifest", self.root_uri)
|
||||
def _check((rc,out,err)):
|
||||
self.failUnlessEqual(err, "")
|
||||
lines = [l for l in out.split("\n") if l]
|
||||
self.failUnlessEqual(len(lines), 8)
|
||||
|
@ -785,12 +763,8 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
return d
|
||||
|
||||
def do_cli_manifest_stream2(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"manifest",
|
||||
"--raw",
|
||||
self.root_uri])
|
||||
def _check((out,err)):
|
||||
d = self.do_cli("manifest", "--raw", self.root_uri)
|
||||
def _check((rc,out,err)):
|
||||
self.failUnlessEqual(err, "")
|
||||
# this should be the same as the POST t=stream-manifest output
|
||||
self._check_streamed_manifest(out)
|
||||
|
@ -798,24 +772,16 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
return d
|
||||
|
||||
def do_cli_manifest_stream3(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"manifest",
|
||||
"--storage-index",
|
||||
self.root_uri])
|
||||
def _check((out,err)):
|
||||
d = self.do_cli("manifest", "--storage-index", self.root_uri)
|
||||
def _check((rc,out,err)):
|
||||
self.failUnlessEqual(err, "")
|
||||
self._check_manifest_storage_index(out)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def do_cli_manifest_stream4(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"manifest",
|
||||
"--verify-cap",
|
||||
self.root_uri])
|
||||
def _check((out,err)):
|
||||
d = self.do_cli("manifest", "--verify-cap", self.root_uri)
|
||||
def _check((rc,out,err)):
|
||||
self.failUnlessEqual(err, "")
|
||||
lines = [l for l in out.split("\n") if l]
|
||||
self.failUnlessEqual(len(lines), 3)
|
||||
|
@ -826,12 +792,8 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
return d
|
||||
|
||||
def do_cli_manifest_stream5(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"manifest",
|
||||
"--repair-cap",
|
||||
self.root_uri])
|
||||
def _check((out,err)):
|
||||
d = self.do_cli("manifest", "--repair-cap", self.root_uri)
|
||||
def _check((rc,out,err)):
|
||||
self.failUnlessEqual(err, "")
|
||||
lines = [l for l in out.split("\n") if l]
|
||||
self.failUnlessEqual(len(lines), 3)
|
||||
|
@ -842,11 +804,8 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
return d
|
||||
|
||||
def do_cli_stats1(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"stats",
|
||||
self.root_uri])
|
||||
def _check3((out,err)):
|
||||
d = self.do_cli("stats", self.root_uri)
|
||||
def _check3((rc,out,err)):
|
||||
lines = [l.strip() for l in out.split("\n") if l]
|
||||
self.failUnless("count-immutable-files: 1" in lines)
|
||||
self.failUnless("count-mutable-files: 1" in lines)
|
||||
|
@ -862,12 +821,8 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
|
|||
return d
|
||||
|
||||
def do_cli_stats2(self):
|
||||
basedir = self.get_clientdir(0)
|
||||
d = self._run_cli(["--node-directory", basedir,
|
||||
"stats",
|
||||
"--raw",
|
||||
self.root_uri])
|
||||
def _check4((out,err)):
|
||||
d = self.do_cli("stats", "--raw", self.root_uri)
|
||||
def _check4((rc,out,err)):
|
||||
data = simplejson.loads(out)
|
||||
self.failUnlessEqual(data["count-immutable-files"], 1)
|
||||
self.failUnlessEqual(data["count-immutable-files"], 1)
|
||||
|
@ -983,20 +938,14 @@ class DeepCheckWebBad(DeepCheckBase, unittest.TestCase):
|
|||
|
||||
return d
|
||||
|
||||
def _run_cli(self, argv):
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
# this can only do synchronous operations
|
||||
assert argv[0] == "debug"
|
||||
runner.runner(argv, run_by_human=False, stdout=stdout, stderr=stderr)
|
||||
return stdout.getvalue()
|
||||
|
||||
def _delete_some_shares(self, node):
|
||||
self.delete_shares_numbered(node.get_uri(), [0,1])
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _corrupt_some_shares(self, node):
|
||||
for (shnum, serverid, sharefile) in self.find_uri_shares(node.get_uri()):
|
||||
if shnum in (0,1):
|
||||
self._run_cli(["debug", "corrupt-share", sharefile])
|
||||
yield run_cli("debug", "corrupt-share", sharefile)
|
||||
|
||||
def _delete_most_shares(self, node):
|
||||
self.delete_shares_numbered(node.get_uri(), range(1,10))
|
||||
|
|
|
@ -71,7 +71,7 @@ from allmydata.util.encodingutil import argv_to_unicode, unicode_to_url, \
|
|||
get_io_encoding, get_filesystem_encoding, to_str, from_utf8_or_none, _reload, \
|
||||
to_filepath, extend_filepath, unicode_from_filepath, unicode_segments_from
|
||||
from allmydata.dirnode import normalize
|
||||
|
||||
from .common_util import skip_if_cannot_represent_filename
|
||||
from twisted.python import usage
|
||||
|
||||
|
||||
|
@ -265,16 +265,8 @@ class StdlibUnicode(unittest.TestCase):
|
|||
"""This mainly tests that some of the stdlib functions support Unicode paths, but also that
|
||||
listdir_unicode works for valid filenames."""
|
||||
|
||||
def skip_if_cannot_represent_filename(self, u):
|
||||
enc = get_filesystem_encoding()
|
||||
if not unicode_platform():
|
||||
try:
|
||||
u.encode(enc)
|
||||
except UnicodeEncodeError:
|
||||
raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
|
||||
|
||||
def test_mkdir_open_exists_abspath_listdir_expanduser(self):
|
||||
self.skip_if_cannot_represent_filename(lumiere_nfc)
|
||||
skip_if_cannot_represent_filename(lumiere_nfc)
|
||||
|
||||
try:
|
||||
os.mkdir(lumiere_nfc)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import os.path, re, sys, subprocess
|
||||
from cStringIO import StringIO
|
||||
|
||||
from twisted.trial import unittest
|
||||
|
||||
|
@ -10,11 +9,11 @@ from twisted.internet.defer import inlineCallbacks, returnValue
|
|||
from allmydata.util import fileutil, pollmixin
|
||||
from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output, \
|
||||
get_filesystem_encoding
|
||||
from allmydata.scripts import runner
|
||||
from allmydata.client import Client
|
||||
from allmydata.test import common_util
|
||||
import allmydata
|
||||
from allmydata import __appname__
|
||||
from .common_util import parse_cli, run_cli
|
||||
|
||||
|
||||
timeout = 240
|
||||
|
@ -180,11 +179,7 @@ class CreateNode(unittest.TestCase):
|
|||
fileutil.make_dirs(basedir)
|
||||
return basedir
|
||||
|
||||
def run_tahoe(self, argv):
|
||||
out,err = StringIO(), StringIO()
|
||||
rc = runner.runner(argv, stdout=out, stderr=err)
|
||||
return rc, out.getvalue(), err.getvalue()
|
||||
|
||||
@inlineCallbacks
|
||||
def do_create(self, kind, *args):
|
||||
basedir = self.workdir("test_" + kind)
|
||||
command = "create-" + kind
|
||||
|
@ -193,7 +188,7 @@ class CreateNode(unittest.TestCase):
|
|||
|
||||
n1 = os.path.join(basedir, command + "-n1")
|
||||
argv = ["--quiet", command, "--basedir", n1] + list(args)
|
||||
rc, out, err = self.run_tahoe(argv)
|
||||
rc, out, err = yield run_cli(*argv)
|
||||
self.failUnlessEqual(err, "")
|
||||
self.failUnlessEqual(out, "")
|
||||
self.failUnlessEqual(rc, 0)
|
||||
|
@ -213,7 +208,7 @@ class CreateNode(unittest.TestCase):
|
|||
self.failUnless("\nreserved_space = 1G\n" in content)
|
||||
|
||||
# creating the node a second time should be rejected
|
||||
rc, out, err = self.run_tahoe(argv)
|
||||
rc, out, err = yield run_cli(*argv)
|
||||
self.failIfEqual(rc, 0, str((out, err, rc)))
|
||||
self.failUnlessEqual(out, "")
|
||||
self.failUnless("is not empty." in err)
|
||||
|
@ -226,7 +221,7 @@ class CreateNode(unittest.TestCase):
|
|||
# test that the non --basedir form works too
|
||||
n2 = os.path.join(basedir, command + "-n2")
|
||||
argv = ["--quiet", command] + list(args) + [n2]
|
||||
rc, out, err = self.run_tahoe(argv)
|
||||
rc, out, err = yield run_cli(*argv)
|
||||
self.failUnlessEqual(err, "")
|
||||
self.failUnlessEqual(out, "")
|
||||
self.failUnlessEqual(rc, 0)
|
||||
|
@ -236,7 +231,7 @@ class CreateNode(unittest.TestCase):
|
|||
# test the --node-directory form
|
||||
n3 = os.path.join(basedir, command + "-n3")
|
||||
argv = ["--quiet", "--node-directory", n3, command] + list(args)
|
||||
rc, out, err = self.run_tahoe(argv)
|
||||
rc, out, err = yield run_cli(*argv)
|
||||
self.failUnlessEqual(err, "")
|
||||
self.failUnlessEqual(out, "")
|
||||
self.failUnlessEqual(rc, 0)
|
||||
|
@ -247,7 +242,7 @@ class CreateNode(unittest.TestCase):
|
|||
# test that the output (without --quiet) includes the base directory
|
||||
n4 = os.path.join(basedir, command + "-n4")
|
||||
argv = [command] + list(args) + [n4]
|
||||
rc, out, err = self.run_tahoe(argv)
|
||||
rc, out, err = yield run_cli(*argv)
|
||||
self.failUnlessEqual(err, "")
|
||||
self.failUnlessIn(" created in ", out)
|
||||
self.failUnlessIn(n4, out)
|
||||
|
@ -257,18 +252,14 @@ class CreateNode(unittest.TestCase):
|
|||
self.failUnless(os.path.exists(os.path.join(n4, tac)))
|
||||
|
||||
# make sure it rejects too many arguments
|
||||
argv = [command, "basedir", "extraarg"]
|
||||
self.failUnlessRaises(usage.UsageError,
|
||||
runner.runner, argv,
|
||||
run_by_human=False)
|
||||
self.failUnlessRaises(usage.UsageError, parse_cli,
|
||||
command, "basedir", "extraarg")
|
||||
|
||||
# when creating a non-client, there is no default for the basedir
|
||||
if not is_client:
|
||||
argv = [command]
|
||||
self.failUnlessRaises(usage.UsageError,
|
||||
runner.runner, argv,
|
||||
run_by_human=False)
|
||||
|
||||
self.failUnlessRaises(usage.UsageError, parse_cli,
|
||||
command)
|
||||
|
||||
def test_node(self):
|
||||
self.do_create("node")
|
||||
|
@ -285,49 +276,42 @@ class CreateNode(unittest.TestCase):
|
|||
|
||||
def test_subcommands(self):
|
||||
# no arguments should trigger a command listing, via UsageError
|
||||
self.failUnlessRaises(usage.UsageError,
|
||||
runner.runner,
|
||||
[],
|
||||
run_by_human=False)
|
||||
self.failUnlessRaises(usage.UsageError, parse_cli,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_stats_gatherer_good_args(self):
|
||||
rc = runner.runner(["create-stats-gatherer", "--hostname=foo",
|
||||
self.mktemp()])
|
||||
rc,out,err = yield run_cli("create-stats-gatherer", "--hostname=foo",
|
||||
self.mktemp())
|
||||
self.assertEqual(rc, 0)
|
||||
rc = runner.runner(["create-stats-gatherer", "--location=tcp:foo:1234",
|
||||
"--port=tcp:1234", self.mktemp()])
|
||||
rc,out,err = yield run_cli("create-stats-gatherer",
|
||||
"--location=tcp:foo:1234",
|
||||
"--port=tcp:1234", self.mktemp())
|
||||
self.assertEqual(rc, 0)
|
||||
|
||||
|
||||
def test_stats_gatherer_bad_args(self):
|
||||
def _test(args):
|
||||
argv = args.split()
|
||||
self.assertRaises(usage.UsageError, parse_cli, *argv)
|
||||
|
||||
# missing hostname/location/port
|
||||
argv = "create-stats-gatherer D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer D")
|
||||
|
||||
# missing port
|
||||
argv = "create-stats-gatherer --location=foo D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer --location=foo D")
|
||||
|
||||
# missing location
|
||||
argv = "create-stats-gatherer --port=foo D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer --port=foo D")
|
||||
|
||||
# can't provide both
|
||||
argv = "create-stats-gatherer --hostname=foo --port=foo D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer --hostname=foo --port=foo D")
|
||||
|
||||
# can't provide both
|
||||
argv = "create-stats-gatherer --hostname=foo --location=foo D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer --hostname=foo --location=foo D")
|
||||
|
||||
# can't provide all three
|
||||
argv = "create-stats-gatherer --hostname=foo --location=foo --port=foo D"
|
||||
self.assertRaises(usage.UsageError, runner.runner, argv.split(),
|
||||
run_by_human=False)
|
||||
_test("create-stats-gatherer --hostname=foo --location=foo --port=foo D")
|
||||
|
||||
class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
|
||||
RunBinTahoeMixin):
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
import os, re, sys, time, simplejson
|
||||
from cStringIO import StringIO
|
||||
|
||||
from twisted.trial import unittest
|
||||
from twisted.internet import defer
|
||||
from twisted.internet import threads # CLI tests use deferToThread
|
||||
from twisted.application import service
|
||||
|
||||
import allmydata
|
||||
|
@ -20,7 +18,6 @@ from allmydata.util import log, base32
|
|||
from allmydata.util.encodingutil import quote_output, unicode_to_argv
|
||||
from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||
from allmydata.util.consumer import MemoryConsumer, download_to_data
|
||||
from allmydata.scripts import runner
|
||||
from allmydata.stats import StatsGathererService
|
||||
from allmydata.interfaces import IDirectoryNode, IFileNode, \
|
||||
NoSuchChildError, NoSharesError
|
||||
|
@ -39,6 +36,7 @@ from .common import TEST_RSA_KEY_SIZE
|
|||
# TODO: move this to common or common_util
|
||||
from allmydata.test.test_runner import RunBinTahoeMixin
|
||||
from . import common_util as testutil
|
||||
from .common_util import run_cli
|
||||
|
||||
LARGE_DATA = """
|
||||
This is some data to publish to the remote grid.., which needs to be large
|
||||
|
@ -1064,6 +1062,7 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
return d1
|
||||
d.addCallback(_create_mutable)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _test_debug(res):
|
||||
# find a share. It is important to run this while there is only
|
||||
# one slot in the grid.
|
||||
|
@ -1073,11 +1072,8 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
% filename)
|
||||
log.msg(" for clients[%d]" % client_num)
|
||||
|
||||
out,err = StringIO(), StringIO()
|
||||
rc = runner.runner(["debug", "dump-share", "--offsets",
|
||||
filename],
|
||||
stdout=out, stderr=err)
|
||||
output = out.getvalue()
|
||||
rc,output,err = yield run_cli("debug", "dump-share", "--offsets",
|
||||
filename)
|
||||
self.failUnlessEqual(rc, 0)
|
||||
try:
|
||||
self.failUnless("Mutable slot found:\n" in output)
|
||||
|
@ -1862,6 +1858,7 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
|
||||
return d
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _test_runner(self, res):
|
||||
# exercise some of the diagnostic tools in runner.py
|
||||
|
||||
|
@ -1887,11 +1884,8 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
% self.basedir)
|
||||
log.msg("test_system.SystemTest._test_runner using %r" % filename)
|
||||
|
||||
out,err = StringIO(), StringIO()
|
||||
rc = runner.runner(["debug", "dump-share", "--offsets",
|
||||
unicode_to_argv(filename)],
|
||||
stdout=out, stderr=err)
|
||||
output = out.getvalue()
|
||||
rc,output,err = yield run_cli("debug", "dump-share", "--offsets",
|
||||
unicode_to_argv(filename))
|
||||
self.failUnlessEqual(rc, 0)
|
||||
|
||||
# we only upload a single file, so we can assert some things about
|
||||
|
@ -1917,23 +1911,18 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
sharedir, shnum = os.path.split(filename)
|
||||
storagedir, storage_index_s = os.path.split(sharedir)
|
||||
storage_index_s = str(storage_index_s)
|
||||
out,err = StringIO(), StringIO()
|
||||
nodedirs = [self.getdir("client%d" % i) for i in range(self.numclients)]
|
||||
cmd = ["debug", "find-shares", storage_index_s] + nodedirs
|
||||
rc = runner.runner(cmd, stdout=out, stderr=err)
|
||||
rc,out,err = yield run_cli("debug", "find-shares", storage_index_s,
|
||||
*nodedirs)
|
||||
self.failUnlessEqual(rc, 0)
|
||||
out.seek(0)
|
||||
sharefiles = [sfn.strip() for sfn in out.readlines()]
|
||||
sharefiles = [sfn.strip() for sfn in out.splitlines()]
|
||||
self.failUnlessEqual(len(sharefiles), 10)
|
||||
|
||||
# also exercise the 'catalog-shares' tool
|
||||
out,err = StringIO(), StringIO()
|
||||
nodedirs = [self.getdir("client%d" % i) for i in range(self.numclients)]
|
||||
cmd = ["debug", "catalog-shares"] + nodedirs
|
||||
rc = runner.runner(cmd, stdout=out, stderr=err)
|
||||
rc,out,err = yield run_cli("debug", "catalog-shares", *nodedirs)
|
||||
self.failUnlessEqual(rc, 0)
|
||||
out.seek(0)
|
||||
descriptions = [sfn.strip() for sfn in out.readlines()]
|
||||
descriptions = [sfn.strip() for sfn in out.splitlines()]
|
||||
self.failUnlessEqual(len(descriptions), 30)
|
||||
matching = [line
|
||||
for line in descriptions
|
||||
|
@ -1981,10 +1970,10 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
f.write(private_uri)
|
||||
f.close()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def run(ignored, verb, *args, **kwargs):
|
||||
stdin = kwargs.get("stdin", "")
|
||||
newargs = nodeargs + [verb] + list(args)
|
||||
return self._run_cli(newargs, stdin=stdin)
|
||||
rc,out,err = yield run_cli(verb, *args, nodeargs=nodeargs, **kwargs)
|
||||
defer.returnValue((out,err))
|
||||
|
||||
def _check_ls((out,err), expected_children, unexpected_children=[]):
|
||||
self.failUnlessEqual(err, "")
|
||||
|
@ -2345,17 +2334,6 @@ class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase):
|
|||
d.addCallback(_check_ls)
|
||||
return d
|
||||
|
||||
def _run_cli(self, argv, stdin=""):
|
||||
#print "CLI:", argv
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
d = threads.deferToThread(runner.runner, argv, run_by_human=False,
|
||||
stdin=StringIO(stdin),
|
||||
stdout=stdout, stderr=stderr)
|
||||
def _done(res):
|
||||
return stdout.getvalue(), stderr.getvalue()
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def _test_checker(self, res):
|
||||
ut = upload.Data("too big to be literal" * 200, convergence=None)
|
||||
d = self._personal_node.add_file(u"big file", ut)
|
||||
|
|
Loading…
Reference in New Issue