mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-22 10:20:59 +00:00
runner.py: improve test coverage further: implement --quiet with StringIOs
This commit is contained in:
parent
de24d3cd94
commit
912fc5a77e
@ -1,6 +1,7 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
|
||||||
import os, subprocess, sys, signal, time
|
import os, subprocess, sys, signal, time
|
||||||
|
from cStringIO import StringIO
|
||||||
from twisted.python import usage
|
from twisted.python import usage
|
||||||
|
|
||||||
from twisted.python.procutils import which
|
from twisted.python.procutils import which
|
||||||
@ -104,17 +105,11 @@ class CreateClientOptions(NoDefaultBasedirMixin, usage.Options):
|
|||||||
optParameters = [
|
optParameters = [
|
||||||
["basedir", "C", None, "which directory to create the client in"],
|
["basedir", "C", None, "which directory to create the client in"],
|
||||||
]
|
]
|
||||||
optFlags = [
|
|
||||||
["quiet", "q", "operate silently"],
|
|
||||||
]
|
|
||||||
|
|
||||||
class CreateIntroducerOptions(NoDefaultBasedirMixin, usage.Options):
|
class CreateIntroducerOptions(NoDefaultBasedirMixin, usage.Options):
|
||||||
optParameters = [
|
optParameters = [
|
||||||
["basedir", "C", None, "which directory to create the introducer in"],
|
["basedir", "C", None, "which directory to create the introducer in"],
|
||||||
]
|
]
|
||||||
optFlags = [
|
|
||||||
["quiet", "q", "operate silently"],
|
|
||||||
]
|
|
||||||
|
|
||||||
class DumpOptions(usage.Options):
|
class DumpOptions(usage.Options):
|
||||||
optParameters = [
|
optParameters = [
|
||||||
@ -180,6 +175,10 @@ c.setServiceParent(application)
|
|||||||
class Options(usage.Options):
|
class Options(usage.Options):
|
||||||
synopsis = "Usage: allmydata <command> [command options]"
|
synopsis = "Usage: allmydata <command> [command options]"
|
||||||
|
|
||||||
|
optFlags = [
|
||||||
|
["quiet", "q", "operate silently"],
|
||||||
|
]
|
||||||
|
|
||||||
subCommands = [
|
subCommands = [
|
||||||
["create-client", None, CreateClientOptions, "Create a client node."],
|
["create-client", None, CreateClientOptions, "Create a client node."],
|
||||||
["create-introducer", None, CreateIntroducerOptions, "Create a introducer node."],
|
["create-introducer", None, CreateIntroducerOptions, "Create a introducer node."],
|
||||||
@ -198,7 +197,7 @@ class Options(usage.Options):
|
|||||||
if not hasattr(self, 'subOptions'):
|
if not hasattr(self, 'subOptions'):
|
||||||
raise usage.UsageError("must specify a command")
|
raise usage.UsageError("must specify a command")
|
||||||
|
|
||||||
def runner(argv, run_by_human=True):
|
def runner(argv, run_by_human=True, stdout=sys.stdout, stderr=sys.stderr):
|
||||||
config = Options()
|
config = Options()
|
||||||
try:
|
try:
|
||||||
config.parseOptions(argv)
|
config.parseOptions(argv)
|
||||||
@ -214,45 +213,48 @@ def runner(argv, run_by_human=True):
|
|||||||
command = config.subCommand
|
command = config.subCommand
|
||||||
so = config.subOptions
|
so = config.subOptions
|
||||||
|
|
||||||
|
if config['quiet']:
|
||||||
|
stdout = StringIO()
|
||||||
|
|
||||||
rc = 0
|
rc = 0
|
||||||
if command == "create-client":
|
if command == "create-client":
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = create_client(basedir, so) or rc
|
rc = create_client(basedir, so, stdout, stderr) or rc
|
||||||
elif command == "create-introducer":
|
elif command == "create-introducer":
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = create_introducer(basedir, so) or rc
|
rc = create_introducer(basedir, so, stdout, stderr) or rc
|
||||||
elif command == "start":
|
elif command == "start":
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = start(basedir, so) or rc
|
rc = start(basedir, so, stdout, stderr) or rc
|
||||||
elif command == "stop":
|
elif command == "stop":
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = stop(basedir, so) or rc
|
rc = stop(basedir, so, stdout, stderr) or rc
|
||||||
elif command == "restart":
|
elif command == "restart":
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = stop(basedir, so) or rc
|
rc = stop(basedir, so, stdout, stderr) or rc
|
||||||
if rc:
|
if rc:
|
||||||
print "not restarting"
|
print >>stderr, "not restarting"
|
||||||
return rc
|
return rc
|
||||||
for basedir in so.basedirs:
|
for basedir in so.basedirs:
|
||||||
rc = start(basedir, so) or rc
|
rc = start(basedir, so, stdout, stderr) or rc
|
||||||
elif command == "dump-uri-extension":
|
elif command == "dump-uri-extension":
|
||||||
rc = dump_uri_extension(so)
|
rc = dump_uri_extension(so, stdout, stderr)
|
||||||
elif command == "dump-root-dirnode":
|
elif command == "dump-root-dirnode":
|
||||||
rc = dump_root_dirnode(so.basedirs[0], so)
|
rc = dump_root_dirnode(so.basedirs[0], so, stdout, stderr)
|
||||||
elif command == "dump-dirnode":
|
elif command == "dump-dirnode":
|
||||||
rc = dump_directory_node(so.basedirs[0], so)
|
rc = dump_directory_node(so.basedirs[0], so, stdout, stderr)
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
rc = runner(sys.argv[1:])
|
rc = runner(sys.argv[1:])
|
||||||
sys.exit(rc)
|
sys.exit(rc)
|
||||||
|
|
||||||
def create_client(basedir, config):
|
def create_client(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
if os.path.exists(basedir):
|
if os.path.exists(basedir):
|
||||||
if os.listdir(basedir):
|
if os.listdir(basedir):
|
||||||
print "The base directory already exists: %s" % basedir
|
print >>err, "The base directory already exists: %s" % basedir
|
||||||
print "To avoid clobbering anything, I am going to quit now"
|
print >>err, "To avoid clobbering anything, I am going to quit now"
|
||||||
print "Please use a different directory, or delete this one"
|
print >>err, "Please use a different directory, or delete this one"
|
||||||
return -1
|
return -1
|
||||||
# we're willing to use an empty directory
|
# we're willing to use an empty directory
|
||||||
else:
|
else:
|
||||||
@ -260,16 +262,15 @@ def create_client(basedir, config):
|
|||||||
f = open(os.path.join(basedir, "client.tac"), "w")
|
f = open(os.path.join(basedir, "client.tac"), "w")
|
||||||
f.write(client_tac)
|
f.write(client_tac)
|
||||||
f.close()
|
f.close()
|
||||||
if not config['quiet']:
|
print >>out, "client created in %s" % basedir
|
||||||
print "client created in %s" % basedir
|
print >>out, " please copy introducer.furl and vdrive.furl into the directory"
|
||||||
print " please copy introducer.furl and vdrive.furl into the directory"
|
|
||||||
|
|
||||||
def create_introducer(basedir, config):
|
def create_introducer(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
if os.path.exists(basedir):
|
if os.path.exists(basedir):
|
||||||
if os.listdir(basedir):
|
if os.listdir(basedir):
|
||||||
print "The base directory already exists: %s" % basedir
|
print >>err, "The base directory already exists: %s" % basedir
|
||||||
print "To avoid clobbering anything, I am going to quit now"
|
print >>err, "To avoid clobbering anything, I am going to quit now"
|
||||||
print "Please use a different directory, or delete this one"
|
print >>err, "Please use a different directory, or delete this one"
|
||||||
return -1
|
return -1
|
||||||
# we're willing to use an empty directory
|
# we're willing to use an empty directory
|
||||||
else:
|
else:
|
||||||
@ -277,11 +278,10 @@ def create_introducer(basedir, config):
|
|||||||
f = open(os.path.join(basedir, "introducer.tac"), "w")
|
f = open(os.path.join(basedir, "introducer.tac"), "w")
|
||||||
f.write(introducer_tac)
|
f.write(introducer_tac)
|
||||||
f.close()
|
f.close()
|
||||||
if not config['quiet']:
|
print >>out, "introducer created in %s" % basedir
|
||||||
print "introducer created in %s" % basedir
|
|
||||||
|
|
||||||
def start(basedir, config):
|
def start(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
print "STARTING", basedir
|
print >>out, "STARTING", basedir
|
||||||
if os.path.exists(os.path.join(basedir, "client.tac")):
|
if os.path.exists(os.path.join(basedir, "client.tac")):
|
||||||
tac = "client.tac"
|
tac = "client.tac"
|
||||||
type = "client"
|
type = "client"
|
||||||
@ -289,23 +289,23 @@ def start(basedir, config):
|
|||||||
tac = "introducer.tac"
|
tac = "introducer.tac"
|
||||||
type = "introducer"
|
type = "introducer"
|
||||||
else:
|
else:
|
||||||
print "%s does not look like a node directory" % basedir
|
print >>err, "%s does not look like a node directory" % basedir
|
||||||
if not os.path.isdir(basedir):
|
if not os.path.isdir(basedir):
|
||||||
print " in fact, it doesn't look like a directory at all!"
|
print >>err, " in fact, it doesn't look like a directory at all!"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
rc = subprocess.call(["python", twistd, "-y", tac,], cwd=basedir)
|
rc = subprocess.call(["python", twistd, "-y", tac,], cwd=basedir)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
print "%s node probably started" % type
|
print >>out, "%s node probably started" % type
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
print "%s node probably not started" % type
|
print >>err, "%s node probably not started" % type
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def stop(basedir, config):
|
def stop(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
print "STOPPING", basedir
|
print >>out, "STOPPING", basedir
|
||||||
pidfile = os.path.join(basedir, "twistd.pid")
|
pidfile = os.path.join(basedir, "twistd.pid")
|
||||||
if not os.path.exists(pidfile):
|
if not os.path.exists(pidfile):
|
||||||
print "%s does not look like a running node directory (no twistd.pid)" % basedir
|
print >>err, "%s does not look like a running node directory (no twistd.pid)" % basedir
|
||||||
return 1
|
return 1
|
||||||
pid = open(pidfile, "r").read()
|
pid = open(pidfile, "r").read()
|
||||||
pid = int(pid)
|
pid = int(pid)
|
||||||
@ -318,14 +318,14 @@ def stop(basedir, config):
|
|||||||
try:
|
try:
|
||||||
os.kill(pid, 0)
|
os.kill(pid, 0)
|
||||||
except OSError:
|
except OSError:
|
||||||
print "process %d is dead" % pid
|
print >>out, "process %d is dead" % pid
|
||||||
return
|
return
|
||||||
timer += 1
|
timer += 1
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
print "never saw process go away"
|
print >>err, "never saw process go away"
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def dump_uri_extension(config, output=sys.stdout):
|
def dump_uri_extension(config, out=sys.stdout, err=sys.stderr):
|
||||||
from allmydata import uri
|
from allmydata import uri
|
||||||
|
|
||||||
filename = config['filename']
|
filename = config['filename']
|
||||||
@ -338,26 +338,26 @@ def dump_uri_extension(config, output=sys.stdout):
|
|||||||
"share_root_hash")
|
"share_root_hash")
|
||||||
for k in keys1:
|
for k in keys1:
|
||||||
if k in unpacked:
|
if k in unpacked:
|
||||||
print >>output, "%19s: %s" % (k, unpacked[k])
|
print >>out, "%19s: %s" % (k, unpacked[k])
|
||||||
print >>output
|
print >>out
|
||||||
for k in keys2:
|
for k in keys2:
|
||||||
if k in unpacked:
|
if k in unpacked:
|
||||||
print >>output, "%19s: %s" % (k, unpacked[k])
|
print >>out, "%19s: %s" % (k, unpacked[k])
|
||||||
print >>output
|
print >>out
|
||||||
for k in keys3:
|
for k in keys3:
|
||||||
if k in unpacked:
|
if k in unpacked:
|
||||||
print >>output, "%19s: %s" % (k, unpacked[k])
|
print >>out, "%19s: %s" % (k, unpacked[k])
|
||||||
|
|
||||||
leftover = set(unpacked.keys()) - set(keys1 + keys2 + keys3)
|
leftover = set(unpacked.keys()) - set(keys1 + keys2 + keys3)
|
||||||
if leftover:
|
if leftover:
|
||||||
print >>output
|
print >>out
|
||||||
for k in sorted(leftover):
|
for k in sorted(leftover):
|
||||||
print >>output, "%s: %s" % (k, unpacked[k])
|
print >>out, "%s: %s" % (k, unpacked[k])
|
||||||
|
|
||||||
print >>output
|
print >>out
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def dump_root_dirnode(basedir, config, output=sys.stdout):
|
def dump_root_dirnode(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
from allmydata import uri
|
from allmydata import uri
|
||||||
|
|
||||||
root_dirnode_file = os.path.join(basedir, "vdrive", "root")
|
root_dirnode_file = os.path.join(basedir, "vdrive", "root")
|
||||||
@ -365,14 +365,14 @@ def dump_root_dirnode(basedir, config, output=sys.stdout):
|
|||||||
f = open(root_dirnode_file, "rb")
|
f = open(root_dirnode_file, "rb")
|
||||||
key = f.read()
|
key = f.read()
|
||||||
rooturi = uri.pack_dirnode_uri("fakeFURL", key)
|
rooturi = uri.pack_dirnode_uri("fakeFURL", key)
|
||||||
print >>output, rooturi
|
print >>out, rooturi
|
||||||
return 0
|
return 0
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
print >>output, "unable to read root dirnode file from %s" % \
|
print >>out, "unable to read root dirnode file from %s" % \
|
||||||
root_dirnode_file
|
root_dirnode_file
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def dump_directory_node(basedir, config, f=sys.stdout):
|
def dump_directory_node(basedir, config, out=sys.stdout, err=sys.stderr):
|
||||||
from allmydata import filetable, vdrive, uri
|
from allmydata import filetable, vdrive, uri
|
||||||
from allmydata.util import hashutil, idlib
|
from allmydata.util import hashutil, idlib
|
||||||
dir_uri = config['uri']
|
dir_uri = config['uri']
|
||||||
@ -386,43 +386,43 @@ def dump_directory_node(basedir, config, f=sys.stdout):
|
|||||||
|
|
||||||
filename = os.path.join(basedir, "vdrive", idlib.b2a(index))
|
filename = os.path.join(basedir, "vdrive", idlib.b2a(index))
|
||||||
|
|
||||||
print >>f
|
print >>out
|
||||||
print >>f, "dirnode uri: %s" % dir_uri
|
print >>out, "dirnode uri: %s" % dir_uri
|
||||||
print >>f, "filename : %s" % filename
|
print >>out, "filename : %s" % filename
|
||||||
print >>f, "index : %s" % idlib.b2a(index)
|
print >>out, "index : %s" % idlib.b2a(index)
|
||||||
if wk:
|
if wk:
|
||||||
print >>f, "writekey : %s" % idlib.b2a(wk)
|
print >>out, "writekey : %s" % idlib.b2a(wk)
|
||||||
print >>f, "write_enabler: %s" % idlib.b2a(we)
|
print >>out, "write_enabler: %s" % idlib.b2a(we)
|
||||||
else:
|
else:
|
||||||
print >>f, "writekey : None"
|
print >>out, "writekey : None"
|
||||||
print >>f, "write_enabler: None"
|
print >>out, "write_enabler: None"
|
||||||
print >>f, "readkey : %s" % idlib.b2a(rk)
|
print >>out, "readkey : %s" % idlib.b2a(rk)
|
||||||
|
|
||||||
print >>f
|
print >>out
|
||||||
|
|
||||||
vds = filetable.VirtualDriveServer(os.path.join(basedir, "vdrive"), False)
|
vds = filetable.VirtualDriveServer(os.path.join(basedir, "vdrive"), False)
|
||||||
data = vds._read_from_file(index)
|
data = vds._read_from_file(index)
|
||||||
if we:
|
if we:
|
||||||
if we != data[0]:
|
if we != data[0]:
|
||||||
print >>f, "ERROR: write_enabler does not match"
|
print >>out, "ERROR: write_enabler does not match"
|
||||||
|
|
||||||
for (H_key, E_key, E_write, E_read) in data[1]:
|
for (H_key, E_key, E_write, E_read) in data[1]:
|
||||||
if verbose:
|
if verbose:
|
||||||
print >>f, " H_key %s" % idlib.b2a(H_key)
|
print >>out, " H_key %s" % idlib.b2a(H_key)
|
||||||
print >>f, " E_key %s" % idlib.b2a(E_key)
|
print >>out, " E_key %s" % idlib.b2a(E_key)
|
||||||
print >>f, " E_write %s" % idlib.b2a(E_write)
|
print >>out, " E_write %s" % idlib.b2a(E_write)
|
||||||
print >>f, " E_read %s" % idlib.b2a(E_read)
|
print >>out, " E_read %s" % idlib.b2a(E_read)
|
||||||
key = vdrive.decrypt(rk, E_key)
|
key = vdrive.decrypt(rk, E_key)
|
||||||
print >>f, " key %s" % key
|
print >>out, " key %s" % key
|
||||||
if hashutil.dir_name_hash(rk, key) != H_key:
|
if hashutil.dir_name_hash(rk, key) != H_key:
|
||||||
print >>f, " ERROR: H_key does not match"
|
print >>out, " ERROR: H_key does not match"
|
||||||
if wk and E_write:
|
if wk and E_write:
|
||||||
if len(E_write) < 14:
|
if len(E_write) < 14:
|
||||||
print >>f, " ERROR: write data is short:", idlib.b2a(E_write)
|
print >>out, " ERROR: write data is short:", idlib.b2a(E_write)
|
||||||
write = vdrive.decrypt(wk, E_write)
|
write = vdrive.decrypt(wk, E_write)
|
||||||
print >>f, " write: %s" % write
|
print >>out, " write: %s" % write
|
||||||
read = vdrive.decrypt(rk, E_read)
|
read = vdrive.decrypt(rk, E_read)
|
||||||
print >>f, " read: %s" % read
|
print >>out, " read: %s" % read
|
||||||
print >>f
|
print >>out
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -16,13 +16,24 @@ class CreateNode(unittest.TestCase):
|
|||||||
def test_client(self):
|
def test_client(self):
|
||||||
basedir = self.workdir("test_client")
|
basedir = self.workdir("test_client")
|
||||||
c1 = os.path.join(basedir, "c1")
|
c1 = os.path.join(basedir, "c1")
|
||||||
argv = ["create-client", "--basedir", c1, "--quiet"]
|
argv = ["--quiet", "create-client", "--basedir", c1]
|
||||||
runner.runner(argv)
|
out,err = StringIO(), StringIO()
|
||||||
|
rc = runner.runner(argv, stdout=out, stderr=err)
|
||||||
|
self.failUnlessEqual(err.getvalue(), "")
|
||||||
|
self.failUnlessEqual(out.getvalue(), "")
|
||||||
|
self.failUnlessEqual(rc, 0)
|
||||||
self.failUnless(os.path.exists(c1))
|
self.failUnless(os.path.exists(c1))
|
||||||
self.failUnless(os.path.exists(os.path.join(c1, "client.tac")))
|
self.failUnless(os.path.exists(os.path.join(c1, "client.tac")))
|
||||||
|
|
||||||
|
# creating the client a second time should throw an exception
|
||||||
|
out,err = StringIO(), StringIO()
|
||||||
|
rc = runner.runner(argv, stdout=out, stderr=err)
|
||||||
|
self.failIfEqual(rc, 0)
|
||||||
|
self.failUnlessEqual(out.getvalue(), "")
|
||||||
|
self.failUnless("The base directory already exists" in err.getvalue())
|
||||||
|
|
||||||
c2 = os.path.join(basedir, "c2")
|
c2 = os.path.join(basedir, "c2")
|
||||||
argv = ["create-client", "--quiet", c2]
|
argv = ["--quiet", "create-client", c2]
|
||||||
runner.runner(argv)
|
runner.runner(argv)
|
||||||
self.failUnless(os.path.exists(c2))
|
self.failUnless(os.path.exists(c2))
|
||||||
self.failUnless(os.path.exists(os.path.join(c2, "client.tac")))
|
self.failUnless(os.path.exists(os.path.join(c2, "client.tac")))
|
||||||
@ -40,13 +51,24 @@ class CreateNode(unittest.TestCase):
|
|||||||
def test_introducer(self):
|
def test_introducer(self):
|
||||||
basedir = self.workdir("test_introducer")
|
basedir = self.workdir("test_introducer")
|
||||||
c1 = os.path.join(basedir, "c1")
|
c1 = os.path.join(basedir, "c1")
|
||||||
argv = ["create-introducer", "--basedir", c1, "--quiet"]
|
argv = ["--quiet", "create-introducer", "--basedir", c1]
|
||||||
runner.runner(argv)
|
out,err = StringIO(), StringIO()
|
||||||
|
rc = runner.runner(argv, stdout=out, stderr=err)
|
||||||
|
self.failUnlessEqual(err.getvalue(), "")
|
||||||
|
self.failUnlessEqual(out.getvalue(), "")
|
||||||
|
self.failUnlessEqual(rc, 0)
|
||||||
self.failUnless(os.path.exists(c1))
|
self.failUnless(os.path.exists(c1))
|
||||||
self.failUnless(os.path.exists(os.path.join(c1, "introducer.tac")))
|
self.failUnless(os.path.exists(os.path.join(c1, "introducer.tac")))
|
||||||
|
|
||||||
|
# creating the introducer a second time should throw an exception
|
||||||
|
out,err = StringIO(), StringIO()
|
||||||
|
rc = runner.runner(argv, stdout=out, stderr=err)
|
||||||
|
self.failIfEqual(rc, 0)
|
||||||
|
self.failUnlessEqual(out.getvalue(), "")
|
||||||
|
self.failUnless("The base directory already exists" in err.getvalue())
|
||||||
|
|
||||||
c2 = os.path.join(basedir, "c2")
|
c2 = os.path.join(basedir, "c2")
|
||||||
argv = ["create-introducer", "--quiet", c2]
|
argv = ["--quiet", "create-introducer", c2]
|
||||||
runner.runner(argv)
|
runner.runner(argv)
|
||||||
self.failUnless(os.path.exists(c2))
|
self.failUnless(os.path.exists(c2))
|
||||||
self.failUnless(os.path.exists(os.path.join(c2, "introducer.tac")))
|
self.failUnless(os.path.exists(os.path.join(c2, "introducer.tac")))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user