浏览代码

add more tests for httphandler

Chris McDonough 11 年之前
父节点
当前提交
771ad4f633
共有 2 个文件被更改,包括 196 次插入4 次删除
  1. 11 4
      supervisor/http_client.py
  2. 185 0
      supervisor/tests/test_http_client.py

+ 11 - 4
supervisor/http_client.py

@@ -36,8 +36,15 @@ class Listener(object):
         pass
 
 class HTTPHandler(asynchat.async_chat):
-    def __init__(self, listener, username='', password=None):
-        asynchat.async_chat.__init__(self)
+    def __init__(
+        self,
+        listener,
+        username='',
+        password=None,
+        conn=None,
+        map=None
+        ):
+        asynchat.async_chat.__init__(self, conn, map)
         self.listener = listener
         self.user_agent = 'Supervisor HTTP Client'
         self.buffer = ''
@@ -82,7 +89,7 @@ class HTTPHandler(asynchat.async_chat):
             self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.connect(socketname)
 
-    def close (self):
+    def close(self):
         self.listener.close(self.url)
         self.connected = 0
         self.del_channel()
@@ -93,7 +100,7 @@ class HTTPHandler(asynchat.async_chat):
         self.push('%s: %s' % (name, value))
         self.push(CRLF)
 
-    def handle_error (self):
+    def handle_error(self):
         if self.error_handled:
             return
         if 1 or self.connected:

+ 185 - 0
supervisor/tests/test_http_client.py

@@ -1,3 +1,4 @@
+import socket
 import sys
 import unittest
 
@@ -58,3 +59,187 @@ class ListenerTests(unittest.TestCase):
     def test_close(self):
         inst = self._makeOne()
         self.assertEqual(inst.close(None), None)
+
+class HTTPHandlerTests(unittest.TestCase):
+    def _getTargetClass(self):
+        from supervisor.http_client import HTTPHandler
+        return HTTPHandler
+
+    def _makeOne(self, listener=None, username='', password=None):
+        if listener is None:
+            listener = self._makeListener()
+        socket_map = {}
+        return self._getTargetClass()(
+            listener,
+            username,
+            password,
+            map=socket_map,
+            )
+
+    def _makeListener(self):
+        listener = DummyListener()
+        return listener
+
+    def test_get_url_not_None(self):
+        inst = self._makeOne()
+        inst.url = 'abc'
+        self.assertRaises(AssertionError, inst.get, 'abc')
+
+    def test_get_bad_scheme(self):
+        inst = self._makeOne()
+        self.assertRaises(
+            NotImplementedError,
+            inst.get,
+            'nothttp://localhost',
+            '/abc'
+            )
+        
+    def test_get_implied_port_80(self):
+        inst = self._makeOne()
+        sockets = []
+        connects = []
+        inst.create_socket = lambda *arg: sockets.append(arg)
+        inst.connect = lambda tup: connects.append(tup)
+        inst.get('http://localhost', '/abc/def')
+        self.assertEqual(inst.port, 80)
+        self.assertEqual(sockets, [(socket.AF_INET, socket.SOCK_STREAM)])
+        self.assertEqual(connects, [('localhost', 80)])
+
+    def test_get_explicit_port(self):
+        inst = self._makeOne()
+        sockets = []
+        connects = []
+        inst.create_socket = lambda *arg: sockets.append(arg)
+        inst.connect = lambda tup: connects.append(tup)
+        inst.get('http://localhost:8080', '/abc/def')
+        self.assertEqual(inst.port, 8080)
+        self.assertEqual(sockets, [(socket.AF_INET, socket.SOCK_STREAM)])
+        self.assertEqual(connects, [('localhost', 8080)])
+
+    def test_get_explicit_unix_domain_socket(self):
+        inst = self._makeOne()
+        sockets = []
+        connects = []
+        inst.create_socket = lambda *arg: sockets.append(arg)
+        inst.connect = lambda tup: connects.append(tup)
+        inst.get('unix:///a/b/c', '')
+        self.assertEqual(sockets, [(socket.AF_UNIX, socket.SOCK_STREAM)])
+        self.assertEqual(connects, ['/a/b/c'])
+
+    def test_close(self):
+        inst = self._makeOne()
+        dels = []
+        inst.del_channel = lambda: dels.append(True)
+        inst.socket = DummySocket()
+        inst.close()
+        self.assertEqual(inst.listener.closed, None)
+        self.assertEqual(inst.connected, 0)
+        self.assertEqual(dels, [True])
+        self.assertTrue(inst.socket.closed)
+        self.assertEqual(inst.url, 'CLOSED')
+
+    def test_header(self):
+        from supervisor.http_client import CRLF
+        inst = self._makeOne()
+        pushes = []
+        inst.push = lambda val: pushes.append(val)
+        inst.header('name', 'val')
+        self.assertEqual(pushes, ['name: val', CRLF])
+
+    def test_handle_error_already_handled(self):
+        inst = self._makeOne()
+        inst.error_handled = True
+        self.assertEqual(inst.handle_error(), None)
+        
+    def test_handle_error(self):
+        inst = self._makeOne()
+        closed = []
+        inst.close = lambda: closed.append(True)
+        inst.url = 'foo'
+        self.assertEqual(inst.handle_error(), None)
+        self.assertEqual(inst.listener.error_url, 'foo')
+        self.assertEqual(
+            inst.listener.error_msg,
+            'Cannot connect, error: None (None)',
+            )
+        self.assertEqual(closed, [True])
+        self.assertTrue(inst.error_handled)
+
+    def test_handle_connect_no_password(self):
+        inst = self._makeOne()
+        pushed = []
+        inst.push = lambda val: pushed.append(val)
+        inst.path = '/'
+        inst.host = 'localhost'
+        inst.handle_connect()
+        self.assertTrue(inst.connected)
+        self.assertEqual(
+            pushed,
+            ['GET / HTTP/1.1',
+             '\r\n',
+             'Host: localhost',
+             '\r\n',
+             'Accept-Encoding: chunked',
+             '\r\n',
+             'Accept: */*',
+             '\r\n',
+             'User-agent: Supervisor HTTP Client',
+             '\r\n',
+             '\r\n',
+             '\r\n']
+            )
+
+    def test_handle_connect_with_password(self):
+        inst = self._makeOne()
+        pushed = []
+        inst.push = lambda val: pushed.append(val)
+        inst.path = '/'
+        inst.host = 'localhost'
+        inst.password = 'password'
+        inst.username = 'username'
+        inst.handle_connect()
+        self.assertTrue(inst.connected)
+        self.assertEqual(
+            pushed,
+             ['GET / HTTP/1.1',
+              '\r\n',
+              'Host: localhost',
+              '\r\n',
+              'Accept-Encoding: chunked',
+              '\r\n',
+              'Accept: */*',
+              '\r\n',
+              'User-agent: Supervisor HTTP Client',
+              '\r\n',
+              'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=',
+              '\r\n',
+              '\r\n',
+              '\r\n'],
+            )
+
+    def test_feed(self):
+        inst = self._makeOne()
+        inst.feed('data')
+        self.assertEqual(inst.listener.fed_data, ['data'])
+        
+class DummyListener(object):
+    closed = None
+    error_url = None
+    error_msg = None
+    def __init__(self):
+        self.fed_data = []
+        
+    def close(self, url):
+        self.closed = url
+
+    def error(self, url, msg):
+        self.error_url = url
+        self.error_msg = msg
+
+    def feed(self, url, data):
+        self.fed_data.append(data)
+
+class DummySocket(object):
+    closed = False
+    def close(self):
+        self.closed = True