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 unittest
import socket import socket
import signal import signal
import re
class Conn: class Conn:
def __init__(self): def __init__(self):
@ -10,11 +11,19 @@ class Conn:
self.s.connect(("0.0.0.0", self.port)) self.s.connect(("0.0.0.0", self.port))
# connect throws socket.error on connection refused # 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) self.s.send(req)
ret = "" ret = ""
while True: while True:
signal.alarm(1) signal.alarm(1) # don't wait forever
r = self.s.recv(65536) r = self.s.recv(65536)
signal.alarm(0) signal.alarm(0)
if r == "": if r == "":
@ -23,6 +32,20 @@ class Conn:
ret += r ret += r
return ret 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): class TestCases(unittest.TestCase):
def assertContains(self, body, *strings): def assertContains(self, body, *strings):
for s in strings: for s in strings:
@ -43,41 +66,78 @@ class TestCases(unittest.TestCase):
"You requested an invalid URI: %s\n"%path, "You requested an invalid URI: %s\n"%path,
'Generated by darkhttpd') 'Generated by darkhttpd')
# FIXME: failing def nerf(s):
#def testIndex_HTTP_0_9(self): return re.sub("[^a-zA-Z0-9]", "_", s)
# body = Conn().get("GET /\n\n")
# self.assertIsIndex(body)
def testIndex_HTTP_1_0(self): def makeCase(name, url, hdr_checker=None, body_checker=None,
body = Conn().get("GET / HTTP/1.0\n\n") req_hdrs={"User-Agent": "test.py"},
self.assertIsIndex(body, "/") 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): if hdr_checker is not None and http_ver is not None:
body = Conn().get("GET /dir/../ HTTP/1.0\n\n") hdr_checker(self, hdrs)
self.assertIsIndex(body, "/dir/../")
def testExtraneousSlashes(self): if body_checker is not None:
body = Conn().get("GET //dir///..//// HTTP/1.0\n\n") body_checker(self, body)
self.assertIsIndex(body, "//dir///..////")
def testWithoutTrailingSlash(self): # FIXME: check status
body = Conn().get("GET /dir/.. HTTP/1.0\n\n") if http_ver is not None:
self.assertIsIndex(body, "/dir/..") 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): v = http_ver
body = Conn().get("GET dir/../ HTTP/1.0\n\n") if v is None:
self.assertIsInvalid(body, "dir/../") 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): def makeCases(name, url, hdr_checker=None, body_checker=None,
body = Conn().get("GET /../ HTTP/1.0\n\n") req_hdrs={"User-Agent": "test.py"}):
self.assertIsInvalid(body, "/../") # 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): makeCases("index", "/", None,
body = Conn().get("GET /dir/../../ HTTP/1.0\n\n") lambda self,body: self.assertIsIndex(body, "/"))
self.assertIsInvalid(body, "/dir/../../")
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__': if __name__ == '__main__':
unittest.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: # vim:set ts=4 sw=4 et: