proxy.py/proxy/testing/test_case.py

87 lines
2.6 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""
proxy.py
~~~~~~~~
Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
Network monitoring, controls & Application development, testing, debugging.
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
import contextlib
import time
import unittest
from typing import Optional, List, Generator, Any
from ..proxy import Proxy
from ..common.constants import DEFAULT_TIMEOUT
from ..common.utils import new_socket_connection
from ..plugin import CacheResponsesPlugin
class TestCase(unittest.TestCase):
2021-11-16 23:34:29 +00:00
"""Base TestCase class that automatically setup and tear down proxy.py."""
DEFAULT_PROXY_PY_STARTUP_FLAGS = [
'--hostname', '127.0.0.1',
'--port', '0',
'--num-workers', '1',
'--num-acceptors', '1',
'--threadless',
]
PROXY: Optional[Proxy] = None
INPUT_ARGS: Optional[List[str]] = None
@classmethod
def setUpClass(cls) -> None:
cls.INPUT_ARGS = getattr(cls, 'PROXY_PY_STARTUP_FLAGS') \
if hasattr(cls, 'PROXY_PY_STARTUP_FLAGS') \
else cls.DEFAULT_PROXY_PY_STARTUP_FLAGS
cls.PROXY = Proxy(cls.INPUT_ARGS)
cls.PROXY.flags.plugins[b'HttpProxyBasePlugin'].append(
CacheResponsesPlugin,
)
cls.PROXY.__enter__()
assert cls.PROXY.acceptors
cls.wait_for_server(cls.PROXY.flags.port)
@staticmethod
def wait_for_server(
proxy_port: int,
wait_for_seconds: float = DEFAULT_TIMEOUT,
) -> None:
"""Wait for proxy.py server to come up."""
start_time = time.time()
while True:
try:
new_socket_connection(
('localhost', proxy_port),
).close()
break
except ConnectionRefusedError:
time.sleep(0.1)
if time.time() - start_time > wait_for_seconds:
raise TimeoutError(
'Timed out while waiting for proxy.py to start...',
)
@classmethod
def tearDownClass(cls) -> None:
assert cls.PROXY
cls.PROXY.__exit__(None, None, None)
cls.PROXY = None
cls.INPUT_ARGS = None
@contextlib.contextmanager
def vcr(self) -> Generator[None, None, None]:
try:
CacheResponsesPlugin.ENABLED.set()
yield
finally:
CacheResponsesPlugin.ENABLED.clear()
def run(self, result: Optional[unittest.TestResult] = None) -> Any:
super().run(result)