aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/cmdline.py47
-rw-r--r--libpathod/pathoc.py2
-rw-r--r--libpathod/pathod.py2
-rw-r--r--libpathod/utils.py4
-rw-r--r--test/test_cmdline.py56
-rw-r--r--test/tutils.py2
6 files changed, 88 insertions, 25 deletions
diff --git a/libpathod/cmdline.py b/libpathod/cmdline.py
index 7a82a429..6a10d951 100644
--- a/libpathod/cmdline.py
+++ b/libpathod/cmdline.py
@@ -8,17 +8,17 @@ from . import pathoc, pathod, version, utils, language
from netlib import http_uastrings
-def go_pathoc():
+def args_pathoc(argv, stdout=sys.stdout, stderr=sys.stderr):
preparser = argparse.ArgumentParser(add_help=False)
preparser.add_argument(
"--show-uas", dest="showua", action="store_true", default=False,
help="Print user agent shortcuts and exit."
)
- pa = preparser.parse_known_args()[0]
+ pa = preparser.parse_known_args(argv)[0]
if pa.showua:
- print "User agent strings:"
+ print >> stdout, "User agent strings:"
for i in http_uastrings.UASTRINGS:
- print " ", i[1], i[0]
+ print >> stdout, " ", i[1], i[0]
sys.exit(0)
parser = argparse.ArgumentParser(
@@ -145,7 +145,7 @@ def go_pathoc():
help="Output in hexdump format"
)
- args = parser.parse_args()
+ args = parser.parse_args(argv[1:])
args.port = None
if ":" in args.host:
@@ -153,7 +153,7 @@ def go_pathoc():
try:
p = int(p)
except ValueError:
- parser.error("Invalid port in host spec: %s" % args.host)
+ return parser.error("Invalid port in host spec: %s" % args.host)
args.host = h
args.port = p
@@ -163,16 +163,16 @@ def go_pathoc():
try:
args.ignorecodes = [int(i) for i in args.ignorecodes.split(",") if i]
except ValueError:
- parser.error("Invalid return code specification: %s"%args.ignorecodes)
+ return parser.error("Invalid return code specification: %s"%args.ignorecodes)
if args.connect_to:
parts = args.connect_to.split(":")
if len(parts) != 2:
- parser.error("Invalid CONNECT specification: %s"%args.connect_to)
+ return parser.error("Invalid CONNECT specification: %s"%args.connect_to)
try:
parts[1] = int(parts[1])
except ValueError:
- parser.error("Invalid CONNECT specification: %s"%args.connect_to)
+ return parser.error("Invalid CONNECT specification: %s"%args.connect_to)
args.connect_to = parts
else:
args.connect_to = None
@@ -185,14 +185,19 @@ def go_pathoc():
try:
reqs.extend(language.parse_requests(r))
except language.ParseException, v:
- print >> sys.stderr, "Error parsing request spec: %s"%v.msg
- print >> sys.stderr, v.marked()
+ print >> stderr, "Error parsing request spec: %s"%v.msg
+ print >> stderr, v.marked()
sys.exit(1)
args.requests = reqs
+ return args
+
+
+def go_pathoc(): # pragma: nocover
+ args = args_pathoc(sys.argv)
pathoc.main(args)
-def go_pathod():
+def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr):
parser = argparse.ArgumentParser(
description='A pathological HTTP/S daemon.'
)
@@ -333,7 +338,7 @@ def go_pathod():
"-x", dest="hexdump", action="store_true", default=False,
help="Log request/response in hexdump format"
)
- args = parser.parse_args()
+ args = parser.parse_args(argv[1:])
certs = []
for i in args.ssl_certs:
@@ -342,7 +347,7 @@ def go_pathod():
parts = ["*", parts[0]]
parts[1] = os.path.expanduser(parts[1])
if not os.path.exists(parts[1]):
- parser.error("Certificate file does not exist: %s"%parts[1])
+ return parser.error("Certificate file does not exist: %s"%parts[1])
certs.append(parts)
args.ssl_certs = certs
@@ -350,7 +355,7 @@ def go_pathod():
for i in args.anchors:
parts = utils.parse_anchor_spec(i)
if not parts:
- parser.error("Invalid anchor specification: %s"%i)
+ return parser.error("Invalid anchor specification: %s"%i)
alst.append(parts)
args.anchors = alst
@@ -359,7 +364,7 @@ def go_pathod():
try:
sizelimit = utils.parse_size(args.sizelimit)
except ValueError, v:
- parser.error(v)
+ return parser.error(v)
args.sizelimit = sizelimit
anchors = []
@@ -371,15 +376,19 @@ def go_pathod():
try:
req = language.parse_response(spec)
except language.ParseException, v:
- print >> sys.stderr, "Error parsing anchor spec: %s"%v.msg
- print >> sys.stderr, v.marked()
+ print >> stderr, "Error parsing anchor spec: %s"%v.msg
+ print >> stderr, v.marked()
sys.exit(1)
try:
arex = re.compile(patt)
except re.error:
- print >> sys.stderr, "Invalid regex in anchor: %s" % patt
+ print >> stderr, "Invalid regex in anchor: %s" % patt
sys.exit(1)
anchors.append((arex, req))
args.anchors = anchors
+ return args
+
+def go_pathod(): # pragma: nocover
+ args = args_pathod(sys.argv)
pathod.main(args)
diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py
index d6b2c7a2..6c4a99ec 100644
--- a/libpathod/pathoc.py
+++ b/libpathod/pathoc.py
@@ -223,7 +223,7 @@ class Pathoc(tcp.TCPClient):
return True
-def main(args):
+def main(args): # pragma: nocover
memo = set([])
trycount = 0
try:
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index 173773cf..1506e743 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -384,7 +384,7 @@ class Pathod(tcp.TCPServer):
return self.log
-def main(args):
+def main(args): # pragma: nocover
ssloptions = SSLOptions(
cn = args.cn,
confdir = args.confdir,
diff --git a/libpathod/utils.py b/libpathod/utils.py
index d4160a23..39e61eac 100644
--- a/libpathod/utils.py
+++ b/libpathod/utils.py
@@ -112,7 +112,7 @@ class Data:
data = Data(__name__)
-def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
+def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # pragma: nocover
try:
pid = os.fork()
if pid > 0:
@@ -136,5 +136,3 @@ def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
-
-
diff --git a/test/test_cmdline.py b/test/test_cmdline.py
new file mode 100644
index 00000000..d1c79d77
--- /dev/null
+++ b/test/test_cmdline.py
@@ -0,0 +1,56 @@
+from libpathod import cmdline
+import tutils
+import cStringIO
+import mock
+
+
+def test_pathod():
+ assert cmdline.args_pathod(["pathod"])
+
+
+@mock.patch("argparse.ArgumentParser.error")
+def test_pathoc(perror):
+ assert cmdline.args_pathoc(["pathoc", "foo.com", "get:/"])
+ s = cStringIO.StringIO()
+ tutils.raises(SystemExit, cmdline.args_pathoc, ["pathoc", "--show-uas"], s, s)
+
+ a = cmdline.args_pathoc(["pathoc", "foo.com:8888", "get:/"])
+ assert a.port == 8888
+
+ a = cmdline.args_pathoc(["pathoc", "foo.com:xxx", "get:/"])
+ assert perror.called
+ perror.reset_mock()
+
+ a = cmdline.args_pathoc(["pathoc", "-I", "10, 20", "foo.com:8888", "get:/"])
+ assert a.ignorecodes == [10, 20]
+
+ a = cmdline.args_pathoc(["pathoc", "-I", "xx, 20", "foo.com:8888", "get:/"])
+ assert perror.called
+ perror.reset_mock()
+
+ a = cmdline.args_pathoc(["pathoc", "-c", "foo:10", "foo.com:8888", "get:/"])
+ assert a.connect_to == ["foo", 10]
+
+ a = cmdline.args_pathoc(["pathoc", "-c", "foo", "foo.com:8888", "get:/"])
+ assert perror.called
+ perror.reset_mock()
+
+ a = cmdline.args_pathoc(["pathoc", "-c", "foo:bar", "foo.com:8888", "get:/"])
+ assert perror.called
+ perror.reset_mock()
+
+ a = cmdline.args_pathoc(
+ [
+ "pathoc",
+ "foo.com:8888",
+ tutils.test_data.path("data/request")
+ ]
+ )
+ assert len(a.requests) == 1
+
+ tutils.raises(
+ SystemExit,
+ cmdline.args_pathoc,
+ ["pathoc", "foo.com", "invalid"],
+ s, s
+ )
diff --git a/test/tutils.py b/test/tutils.py
index 5876e5e6..c1e55a61 100644
--- a/test/tutils.py
+++ b/test/tutils.py
@@ -104,7 +104,7 @@ def raises(exc, obj, *args, **kwargs):
"""
try:
apply(obj, args, kwargs)
- except Exception, v:
+ except (Exception, SystemExit), v:
if isinstance(exc, basestring):
if exc.lower() in str(v).lower():
return