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