12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# Copyright 2011, Google Inc. 22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# All rights reserved. 32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# 42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# Redistribution and use in source and binary forms, with or without 52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# modification, are permitted provided that the following conditions are 62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# met: 72da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# 82da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# * Redistributions of source code must retain the above copyright 92da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# notice, this list of conditions and the following disclaimer. 102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# * Redistributions in binary form must reproduce the above 112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# copyright notice, this list of conditions and the following disclaimer 122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# in the documentation and/or other materials provided with the 132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# distribution. 142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# * Neither the name of Google Inc. nor the names of its 152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# contributors may be used to endorse or promote products derived from 162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# this software without specific prior written permission. 172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# 182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis"""Mocks for testing. 322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis""" 332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennisimport Queue 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennisimport threading 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 382da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket import common 392da489cd246702bee5938545b18a6f710ed214bcJamie Gennisfrom mod_pywebsocket.stream import StreamHixie75 402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 422da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass _MockConnBase(object): 432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Base class of mocks for mod_python.apache.mp_conn. 442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis This enables tests to check what is written to a (mock) mp_conn. 462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self): 492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._write_data = [] 502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.remote_addr = 'fake_address' 512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def write(self, data): 532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Override mod_python.apache.mp_conn.write.""" 542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._write_data.append(data) 562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def written_data(self): 582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Get bytes written to this mock.""" 592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return ''.join(self._write_data) 612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 632da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass MockConn(_MockConnBase): 642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Mock for mod_python.apache.mp_conn. 652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis This enables tests to specify what should be read from a (mock) mp_conn as 672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis well as to check what is written to it. 682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self, read_data): 712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Constructs an instance. 722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Args: 742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis read_data: bytes that should be returned when read* methods are 752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis called. 762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis _MockConnBase.__init__(self) 792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._read_data = read_data 802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._read_pos = 0 812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def readline(self): 832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Override mod_python.apache.mp_conn.readline.""" 842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if self._read_pos >= len(self._read_data): 862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return '' 872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis end_index = self._read_data.find('\n', self._read_pos) + 1 882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if not end_index: 892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis end_index = len(self._read_data) 902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return self._read_up_to(end_index) 912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def read(self, length): 932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Override mod_python.apache.mp_conn.read.""" 942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if self._read_pos >= len(self._read_data): 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return '' 972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis end_index = min(len(self._read_data), self._read_pos + length) 982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return self._read_up_to(end_index) 992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def _read_up_to(self, end_index): 1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis line = self._read_data[self._read_pos:end_index] 1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._read_pos = end_index 1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return line 1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass MockBlockingConn(_MockConnBase): 1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Blocking mock for mod_python.apache.mp_conn. 1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis This enables tests to specify what should be read from a (mock) mp_conn as 1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis well as to check what is written to it. 1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Callers of read* methods will block if there is no bytes available. 1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self): 1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis _MockConnBase.__init__(self) 1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._queue = Queue.Queue() 1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def readline(self): 1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Override mod_python.apache.mp_conn.readline.""" 1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis line = '' 1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while True: 1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis c = self._queue.get() 1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis line += c 1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if c == '\n': 1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return line 1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def read(self, length): 1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Override mod_python.apache.mp_conn.read.""" 1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis data = '' 1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for unused in range(length): 1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis data += self._queue.get() 1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return data 1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def put_bytes(self, bytes): 1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Put bytes to be read from this mock. 1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Args: 1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis bytes: bytes to be read. 1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for byte in bytes: 1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self._queue.put(byte) 1442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1462da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass MockTable(dict): 1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Mock table. 1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis This mimics mod_python mp_table. Note that only the methods used by 1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tests are overridden. 1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self, copy_from={}): 1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if isinstance(copy_from, dict): 1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis copy_from = copy_from.items() 1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for key, value in copy_from: 1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.__setitem__(key, value) 1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __getitem__(self, key): 1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return super(MockTable, self).__getitem__(key.lower()) 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __setitem__(self, key, value): 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis super(MockTable, self).__setitem__(key.lower(), value) 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def get(self, key, def_value=None): 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return super(MockTable, self).get(key.lower(), def_value) 1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass MockRequest(object): 1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Mock request. 1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis This mimics mod_python request. 1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self, uri=None, headers_in={}, connection=None, method='GET', 1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis is_https=False): 1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Construct an instance. 1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Arguments: 1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis uri: URI of the request. 1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis headers_in: Request headers. 1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis connection: Connection used for the request. 1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis method: request method. 1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis is_https: Whether this request is over SSL. 1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis See the document of mod_python Request for details. 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """ 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.uri = uri 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.connection = connection 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.method = method 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.headers_in = MockTable(headers_in) 1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis # self.is_https_ needs to be accessible from tests. To avoid name 1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis # conflict with self.is_https(), it is named as such. 1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.is_https_ = is_https 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.ws_stream = StreamHixie75(self, True) 1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.ws_close_code = None 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.ws_close_reason = None 1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.ws_version = common.VERSION_HYBI00 1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.ws_deflate = False 2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.drain_received_data_called = False 2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def is_https(self): 2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Return whether this request is over SSL.""" 2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return self.is_https_ 2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def _drain_received_data(self): 2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.drain_received_data_called = True 2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennisclass MockDispatcher(object): 2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis """Mock for dispatch.Dispatcher.""" 2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def __init__(self): 2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.do_extra_handshake_called = False 2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def do_extra_handshake(self, conn_context): 2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis self.do_extra_handshake_called = True 2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis def transfer_data(self, conn_context): 2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis pass 2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis# vi:sts=4 sw=4 et 225