Make devel/test.py less repetitive.

This commit is contained in:
Emil Mikulic 2011-01-18 00:51:56 +11:00
parent 594e65d474
commit da24c211d7

View File

@ -2,6 +2,7 @@
import unittest
import socket
import signal
import re
class Conn:
def __init__(self):
@ -10,11 +11,19 @@ class Conn:
self.s.connect(("0.0.0.0", self.port))
# connect throws socket.error on connection refused
def get(self, req):
def get(self, url, http_ver=None, endl="\n",
req_hdrs={"User-Agent": "test.py"}):
req = "GET "+url
if http_ver is not None:
req += " HTTP/"+http_ver
req += "\n"
for k,v in req_hdrs.items():
req += k+": "+v+endl
req += endl # end of request
self.s.send(req)
ret = ""
while True:
signal.alarm(1)
signal.alarm(1) # don't wait forever
r = self.s.recv(65536)
signal.alarm(0)
if r == "":
@ -23,6 +32,20 @@ class Conn:
ret += r
return ret
def parse(resp):
"""
Parse response into status line, headers and body.
"""
pos = resp.index("\r\n\r\n") # throws exception on failure
head = resp[:pos]
body = resp[pos+4:]
status,head = head.split("\r\n", 1)
hdrs = {}
for line in head.split("\r\n"):
k, v = line.split(": ", 1)
hdrs[k] = v
return (status, hdrs, body)
class TestCases(unittest.TestCase):
def assertContains(self, body, *strings):
for s in strings:
@ -43,41 +66,78 @@ class TestCases(unittest.TestCase):
"You requested an invalid URI: %s\n"%path,
'Generated by darkhttpd')
# FIXME: failing
#def testIndex_HTTP_0_9(self):
# body = Conn().get("GET /\n\n")
# self.assertIsIndex(body)
def nerf(s):
return re.sub("[^a-zA-Z0-9]", "_", s)
def testIndex_HTTP_1_0(self):
body = Conn().get("GET / HTTP/1.0\n\n")
self.assertIsIndex(body, "/")
def makeCase(name, url, hdr_checker=None, body_checker=None,
req_hdrs={"User-Agent": "test.py"},
http_ver=None, endl="\n"):
def do_test(self):
resp = Conn().get(url, http_ver, endl, req_hdrs)
if http_ver is None:
status = ""
hdrs = {}
body = resp
else:
status, hdrs, body = parse(resp)
def testUpDirValid(self):
body = Conn().get("GET /dir/../ HTTP/1.0\n\n")
self.assertIsIndex(body, "/dir/../")
if hdr_checker is not None and http_ver is not None:
hdr_checker(self, hdrs)
def testExtraneousSlashes(self):
body = Conn().get("GET //dir///..//// HTTP/1.0\n\n")
self.assertIsIndex(body, "//dir///..////")
if body_checker is not None:
body_checker(self, body)
def testWithoutTrailingSlash(self):
body = Conn().get("GET /dir/.. HTTP/1.0\n\n")
self.assertIsIndex(body, "/dir/..")
# FIXME: check status
if http_ver is not None:
prefix = "HTTP/1.1 " # should 1.0 stay 1.0?
self.assertTrue(status.startswith(prefix),
msg="%s at start of %s"%(repr(prefix), repr(status)))
def testWithoutLeadingSlashFails(self):
body = Conn().get("GET dir/../ HTTP/1.0\n\n")
self.assertIsInvalid(body, "dir/../")
v = http_ver
if v is None:
v = "0.9"
test_name = "_".join([
"test",
nerf(name),
nerf("HTTP"+v),
{"\n":"LF", "\r\n":"CRLF"}[endl],
])
setattr(TestCases, test_name, do_test)
def testUpDirInvalid(self):
body = Conn().get("GET /../ HTTP/1.0\n\n")
self.assertIsInvalid(body, "/../")
def makeCases(name, url, hdr_checker=None, body_checker=None,
req_hdrs={"User-Agent": "test.py"}):
# FIXME: 0.9 is broken
#for http_ver in [None, "1.0", "1.1"]:
for http_ver in ["1.0", "1.1"]:
for endl in ["\n", "\r\n"]:
makeCase(name, url, hdr_checker, body_checker,
req_hdrs, http_ver, endl)
def testUpDirInvalidFancy(self):
body = Conn().get("GET /dir/../../ HTTP/1.0\n\n")
self.assertIsInvalid(body, "/dir/../../")
makeCases("index", "/", None,
lambda self,body: self.assertIsIndex(body, "/"))
makeCases("up dir", "/dir/../", None,
lambda self,body: self.assertIsIndex(body, "/dir/../"))
makeCases("extra slashes", "//dir///..////", None,
lambda self,body: self.assertIsIndex(body, "//dir///..////"))
makeCases("no trailing slash", "/dir/..", None,
lambda self,body: self.assertIsIndex(body, "/dir/.."))
makeCases("no leading slash", "dir/../", None,
lambda self,body: self.assertIsInvalid(body, "dir/../"))
makeCases("invalid up dir", "/../", None,
lambda self,body: self.assertIsInvalid(body, "/../"))
makeCases("fancy invalid up dir", "/./dir/./../../", None,
lambda self,body: self.assertIsInvalid(body, "/./dir/./../../"))
if __name__ == '__main__':
unittest.main()
#print Conn().get("GET /xyz/../ HTTP/1.0")
#x = Conn().get("/xyz/../", "1.0")
#y = parse(x)
#print repr(y)
# vim:set ts=4 sw=4 et: