tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mock.py (7040B)


      1 # Copyright 2011, Google Inc.
      2 # All rights reserved.
      3 #
      4 # Redistribution and use in source and binary forms, with or without
      5 # modification, are permitted provided that the following conditions are
      6 # met:
      7 #
      8 #     * Redistributions of source code must retain the above copyright
      9 # notice, this list of conditions and the following disclaimer.
     10 #     * Redistributions in binary form must reproduce the above
     11 # copyright notice, this list of conditions and the following disclaimer
     12 # in the documentation and/or other materials provided with the
     13 # distribution.
     14 #     * Neither the name of Google Inc. nor the names of its
     15 # contributors may be used to endorse or promote products derived from
     16 # this software without specific prior written permission.
     17 #
     18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 """Mocks for testing.
     30 """
     31 
     32 from __future__ import absolute_import
     33 
     34 import six
     35 import six.moves.queue
     36 from six.moves import range
     37 
     38 from pywebsocket3 import common, util
     39 from pywebsocket3.stream import Stream, StreamOptions
     40 
     41 
     42 class _MockConnBase(object):
     43    """Base class of mocks for mod_python.apache.mp_conn.
     44 
     45    This enables tests to check what is written to a (mock) mp_conn.
     46    """
     47    def __init__(self):
     48        self._write_data = []
     49        self.remote_addr = b'fake_address'
     50 
     51    def write(self, data):
     52        """Override mod_python.apache.mp_conn.write.
     53 
     54        data should be bytes when touching this method manually.
     55        """
     56 
     57        self._write_data.append(data)
     58 
     59    def written_data(self):
     60        """Get bytes written to this mock."""
     61 
     62        return b''.join(self._write_data)
     63 
     64 
     65 class MockConn(_MockConnBase):
     66    """Mock for mod_python.apache.mp_conn.
     67 
     68    This enables tests to specify what should be read from a (mock) mp_conn as
     69    well as to check what is written to it.
     70    """
     71    def __init__(self, read_data):
     72        """Constructs an instance.
     73 
     74        Args:
     75            read_data: bytes that should be returned when read* methods are
     76            called.
     77        """
     78 
     79        _MockConnBase.__init__(self)
     80        self._read_data = read_data
     81        self._read_pos = 0
     82 
     83    def readline(self):
     84        """Override mod_python.apache.mp_conn.readline."""
     85 
     86        if self._read_pos >= len(self._read_data):
     87            return b''
     88        end_index = self._read_data.find(b'\n', self._read_pos) + 1
     89        if not end_index:
     90            end_index = len(self._read_data)
     91        return self._read_up_to(end_index)
     92 
     93    def read(self, length):
     94        """Override mod_python.apache.mp_conn.read."""
     95 
     96        if self._read_pos >= len(self._read_data):
     97            return b''
     98        end_index = min(len(self._read_data), self._read_pos + length)
     99        return self._read_up_to(end_index)
    100 
    101    def _read_up_to(self, end_index):
    102        line = self._read_data[self._read_pos:end_index]
    103        self._read_pos = end_index
    104        return line
    105 
    106 
    107 class MockBlockingConn(_MockConnBase):
    108    """Blocking mock for mod_python.apache.mp_conn.
    109 
    110    This enables tests to specify what should be read from a (mock) mp_conn as
    111    well as to check what is written to it.
    112    Callers of read* methods will block if there is no bytes available.
    113    """
    114    def __init__(self):
    115        _MockConnBase.__init__(self)
    116        self._queue = six.moves.queue.Queue()
    117 
    118    def readline(self):
    119        """Override mod_python.apache.mp_conn.readline."""
    120        line = bytearray()
    121        while True:
    122            c = self._queue.get()
    123            line.append(c)
    124            if c == ord(b'\n'):
    125                return bytes(line)
    126 
    127    def read(self, length):
    128        """Override mod_python.apache.mp_conn.read."""
    129 
    130        data = bytearray()
    131        for unused in range(length):
    132            data.append(self._queue.get())
    133 
    134        return bytes(data)
    135 
    136    def put_bytes(self, bytes):
    137        """Put bytes to be read from this mock.
    138 
    139        Args:
    140            bytes: bytes to be read.
    141        """
    142 
    143        for byte in six.iterbytes(bytes):
    144            self._queue.put(byte)
    145 
    146 
    147 class MockTable(dict):
    148    """Mock table.
    149 
    150    This mimics mod_python mp_table. Note that only the methods used by
    151    tests are overridden.
    152    """
    153    def __init__(self, copy_from={}):
    154        if isinstance(copy_from, dict):
    155            copy_from = list(copy_from.items())
    156        for key, value in copy_from:
    157            self.__setitem__(key, value)
    158 
    159    def __getitem__(self, key):
    160        return super(MockTable, self).__getitem__(key.lower())
    161 
    162    def __setitem__(self, key, value):
    163        super(MockTable, self).__setitem__(key.lower(), value)
    164 
    165    def get(self, key, def_value=None):
    166        return super(MockTable, self).get(key.lower(), def_value)
    167 
    168 
    169 class MockRequest(object):
    170    """Mock request.
    171 
    172    This mimics mod_python request.
    173    """
    174    def __init__(self,
    175                 uri=None,
    176                 headers_in={},
    177                 connection=None,
    178                 method='GET',
    179                 protocol='HTTP/1.1',
    180                 is_https=False):
    181        """Construct an instance.
    182 
    183        Arguments:
    184            uri: URI of the request.
    185            headers_in: Request headers.
    186            connection: Connection used for the request.
    187            method: request method.
    188            is_https: Whether this request is over SSL.
    189 
    190        See the document of mod_python Request for details.
    191        """
    192        self.uri = uri
    193        self.unparsed_uri = uri
    194        self.connection = connection
    195        self.method = method
    196        self.protocol = protocol
    197        self.headers_in = MockTable(headers_in)
    198        # self.is_https_ needs to be accessible from tests.  To avoid name
    199        # conflict with self.is_https(), it is named as such.
    200        self.is_https_ = is_https
    201        self.ws_stream = Stream(self, StreamOptions())
    202        self.ws_close_code = None
    203        self.ws_close_reason = None
    204        self.ws_version = common.VERSION_HYBI_LATEST
    205        self.ws_deflate = False
    206 
    207    def is_https(self):
    208        """Return whether this request is over SSL."""
    209        return self.is_https_
    210 
    211 
    212 class MockDispatcher(object):
    213    """Mock for dispatch.Dispatcher."""
    214    def __init__(self):
    215        self.do_extra_handshake_called = False
    216 
    217    def do_extra_handshake(self, conn_context):
    218        self.do_extra_handshake_called = True
    219 
    220    def transfer_data(self, conn_context):
    221        pass
    222 
    223 
    224 # vi:sts=4 sw=4 et