From da24c211d7bdac4808c11cb950bc3511d5522293 Mon Sep 17 00:00:00 2001 From: Emil Mikulic Date: Tue, 18 Jan 2011 00:51:56 +1100 Subject: [PATCH] Make devel/test.py less repetitive. --- devel/test.py | 116 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 28 deletions(-) diff --git a/devel/test.py b/devel/test.py index 6a282d6..cb36822 100755 --- a/devel/test.py +++ b/devel/test.py @@ -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: