tor-browser

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

conftest.py (8104B)


      1 import sys
      2 from io import StringIO
      3 from random import randint, seed
      4 from unittest.mock import patch
      5 
      6 import mozdevice
      7 import pytest
      8 
      9 # set up required module-level variables/objects
     10 seed(1488590)
     11 
     12 
     13 def random_tcp_port():
     14    """Returns a pseudo-random integer generated from a seed.
     15 
     16    :returns: int: pseudo-randomly generated integer
     17    """
     18    return randint(8000, 12000)
     19 
     20 
     21 @pytest.fixture(autouse=True)
     22 def mock_command_output(monkeypatch):
     23    """Monkeypatches the ADBDevice.command_output() method call.
     24 
     25    Instead of calling the concrete method implemented in adb.py::ADBDevice,
     26    this method simply returns a string representation of the command that was
     27    received.
     28 
     29    As an exception, if the command begins with "forward tcp:0 ", this method
     30    returns a mock port number.
     31 
     32    :param object monkeypatch: pytest provided fixture for mocking.
     33    """
     34 
     35    def command_output_wrapper(object, cmd, timeout):
     36        """Actual monkeypatch implementation of the command_output method call.
     37 
     38        :param object object: placeholder object representing ADBDevice
     39        :param str cmd: command to be executed
     40        :param timeout: unused parameter to represent timeout threshold
     41        :returns: string - string representation of command to be executed
     42                  int - mock port number (only used when cmd begins with "forward tcp:0 ")
     43        """
     44 
     45        if cmd[0] == "forward" and cmd[1] == "tcp:0":
     46            return 7777
     47 
     48        print(str(cmd))
     49        return str(cmd)
     50 
     51    monkeypatch.setattr(mozdevice.ADBDevice, "command_output", command_output_wrapper)
     52 
     53 
     54 @pytest.fixture(autouse=True)
     55 def mock_shell_output(monkeypatch):
     56    """Monkeypatches the ADBDevice.shell_output() method call.
     57 
     58    Instead of returning the output of an adb call, this method will
     59    return appropriate string output. Content of the string output is
     60    in line with the calling method's expectations.
     61 
     62    :param object monkeypatch: pytest provided fixture for mocking.
     63    """
     64 
     65    def shell_output_wrapper(
     66        object, cmd, env=None, cwd=None, timeout=None, enable_run_as=False, attempts=3
     67    ):
     68        """Actual monkeypatch implementation of the shell_output method call.
     69 
     70        :param object object: placeholder object representing ADBDevice
     71        :param str cmd: command to be executed
     72        :param env: contains the environment variable
     73        :type env: dict or None
     74        :param cwd: The directory from which to execute.
     75        :type cwd: str or None
     76        :param timeout: unused parameter tp represent timeout threshold
     77        :param enable_run_as: bool determining if run_as <app> is to be used
     78        :returns: string - string representation of a simulated call to adb
     79        """
     80        if "pm list package error" in cmd:
     81            return "Error: Could not access the Package Manager"
     82        elif "pm list package none" in cmd:
     83            return ""
     84        elif "pm list package" in cmd:
     85            apps = ["org.mozilla.fennec", "org.mozilla.geckoview_example"]
     86            return ("package:{}\n" * len(apps)).format(*apps)
     87        else:
     88            print(str(cmd))
     89            return str(cmd)
     90 
     91    monkeypatch.setattr(mozdevice.ADBDevice, "shell_output", shell_output_wrapper)
     92 
     93 
     94 @pytest.fixture(autouse=True)
     95 def mock_is_path_internal_storage(monkeypatch):
     96    """Monkeypatches the ADBDevice.is_path_internal_storage() method call.
     97 
     98    Instead of returning the outcome of whether the path provided is
     99    internal storage or external, this will always return True.
    100 
    101    :param object monkeypatch: pytest provided fixture for mocking.
    102    """
    103 
    104    def is_path_internal_storage_wrapper(object, path, timeout=None):
    105        """Actual monkeypatch implementation of the is_path_internal_storage() call.
    106 
    107        :param str path: The path to test.
    108        :param timeout: The maximum time in
    109            seconds for any spawned adb process to complete before
    110            throwing an ADBTimeoutError.  This timeout is per adb call. The
    111            total time spent may exceed this value. If it is not
    112            specified, the value set in the ADBDevice constructor is used.
    113        :returns: boolean
    114 
    115        :raises: * ADBTimeoutError
    116                 * ADBError
    117        """
    118        if "internal_storage" in path:
    119            return True
    120        return False
    121 
    122    monkeypatch.setattr(
    123        mozdevice.ADBDevice,
    124        "is_path_internal_storage",
    125        is_path_internal_storage_wrapper,
    126    )
    127 
    128 
    129 @pytest.fixture(autouse=True)
    130 def mock_enable_run_as_for_path(monkeypatch):
    131    """Monkeypatches the ADBDevice.enable_run_as_for_path(path) method.
    132 
    133    Always return True
    134 
    135    :param object monkeypatch: pytest provided fixture for mocking.
    136    """
    137 
    138    def enable_run_as_for_path_wrapper(object, path):
    139        """Actual monkeypatch implementation of the enable_run_as_for_path() call.
    140 
    141        :param str path: The path to test.
    142        :returns: boolean
    143        """
    144        return True
    145 
    146    monkeypatch.setattr(
    147        mozdevice.ADBDevice, "enable_run_as_for_path", enable_run_as_for_path_wrapper
    148    )
    149 
    150 
    151 @pytest.fixture(autouse=True)
    152 def mock_shell_bool(monkeypatch):
    153    """Monkeypatches the ADBDevice.shell_bool() method call.
    154 
    155    Instead of returning the output of an adb call, this method will
    156    return appropriate string output. Content of the string output is
    157    in line with the calling method's expectations.
    158 
    159    :param object monkeypatch: pytest provided fixture for mocking.
    160    """
    161 
    162    def shell_bool_wrapper(
    163        object, cmd, env=None, cwd=None, timeout=None, enable_run_as=False
    164    ):
    165        """Actual monkeypatch implementation of the shell_bool method call.
    166 
    167        :param object object: placeholder object representing ADBDevice
    168        :param str cmd: command to be executed
    169        :param env: contains the environment variable
    170        :type env: dict or None
    171        :param cwd: The directory from which to execute.
    172        :type cwd: str or None
    173        :param timeout: unused parameter tp represent timeout threshold
    174        :param enable_run_as: bool determining if run_as <app> is to be used
    175        :returns: string - string representation of a simulated call to adb
    176        """
    177        print(cmd)
    178        return str(cmd)
    179 
    180    monkeypatch.setattr(mozdevice.ADBDevice, "shell_bool", shell_bool_wrapper)
    181 
    182 
    183 @pytest.fixture(autouse=True)
    184 def mock_adb_object():
    185    """Patches the __init__ method call when instantiating ADBDevice.
    186 
    187    ADBDevice normally requires instantiated objects in order to execute
    188    its commands.
    189 
    190    With a pytest-mock patch, we are able to mock the initialization of
    191    the ADBDevice object. By yielding the instantiated mock object,
    192    unit tests can be run that call methods that require an instantiated
    193    object.
    194 
    195    :yields: ADBDevice - mock instance of ADBDevice object
    196    """
    197    with patch.object(mozdevice.ADBDevice, "__init__", lambda self: None):
    198        yield mozdevice.ADBDevice()
    199 
    200 
    201 @pytest.fixture
    202 def redirect_stdout_and_assert():
    203    """Redirects the stdout pipe temporarily to a StringIO stream.
    204 
    205    This is useful to assert on methods that do not return
    206    a value, such as most ADBDevice methods.
    207 
    208    The original stdout pipe is preserved throughout the process.
    209 
    210    :returns: _wrapper method
    211    """
    212 
    213    def _wrapper(func, **kwargs):
    214        """Implements the stdout sleight-of-hand.
    215 
    216        After preserving the original sys.stdout, it is switched
    217        to use cStringIO.StringIO.
    218 
    219        Method with no return value is called, and the stdout
    220        pipe is switched back to the original sys.stdout.
    221 
    222        The expected outcome is received as part of the kwargs.
    223        This is asserted against a sanitized output from the method
    224        under test.
    225 
    226        :param object func: method under test
    227        :param dict kwargs: dictionary of function parameters
    228        """
    229        original_stdout = sys.stdout
    230        sys.stdout = testing_stdout = StringIO()
    231        expected_text = kwargs.pop("text")
    232        func(**kwargs)
    233        sys.stdout = original_stdout
    234        assert expected_text in testing_stdout.getvalue().rstrip()
    235 
    236    return _wrapper