diff --git a/.github/workflows/test-library.yml b/.github/workflows/test-library.yml index 6c4c781d44..e849773a9e 100644 --- a/.github/workflows/test-library.yml +++ b/.github/workflows/test-library.yml @@ -67,6 +67,7 @@ jobs: sdist-artifact-name: ${{ steps.artifact-name.outputs.sdist }} wheel-artifact-name: ${{ steps.artifact-name.outputs.wheel }} container-version: v${{ steps.container.outputs.version }} + container-platforms: ${{ steps.container.outputs.platforms }} steps: - name: Switch to using Python 3.9 by default uses: actions/setup-python@v2 @@ -204,7 +205,9 @@ jobs: && github.event.inputs.release-version || steps.scm-version.outputs.dist-version }}' | tr + .); - echo "::set-output name=version::$VER" + PLATFORMS="linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x"; + echo "::set-output name=version::$VER"; + echo "::set-output name=platforms::$PLATFORMS" build: name: 👷 dists ${{ needs.pre-setup.outputs.git-tag }} @@ -727,19 +730,36 @@ jobs: --local-executor && ./tests/integration/test_integration.sh 8899 - name: Push to GHCR run: >- - PLATFORMS=linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x; REGISTRY_URL="ghcr.io/abhinavsingh/proxy.py"; CONTAINER_TAG=$REGISTRY_URL:${{ needs.pre-setup.outputs.container-version }}; + docker buildx build + --push + --platform ${{ + needs.pre-setup.outputs.container-platforms + }} + --build-arg PROXYPY_PKG_PATH='dist/${{ + needs.pre-setup.outputs.wheel-artifact-name + }}' + -t $CONTAINER_TAG . + - name: Tag latest on GHCR + if: >- + github.event_name == 'push' && + github.ref == format( + 'refs/heads/{0}', github.event.repository.default_branch + ) + run: >- + REGISTRY_URL="ghcr.io/abhinavsingh/proxy.py"; LATEST_TAG=$REGISTRY_URL:latest; docker buildx build --push - --platform $PLATFORMS + --platform ${{ + needs.pre-setup.outputs.container-platforms + }} --build-arg PROXYPY_PKG_PATH='dist/${{ needs.pre-setup.outputs.wheel-artifact-name }}' - -t $CONTAINER_TAG -t $LATEST_TAG . - name: Login to DockerHub uses: docker/login-action@v1 @@ -748,14 +768,15 @@ jobs: password: ${{ secrets.DOCKER_ACCESS_TOKEN }} - name: Push to DockerHub run: >- - PLATFORMS=linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x; REGISTRY_URL="abhinavsingh/proxy.py"; CONTAINER_TAG=$REGISTRY_URL:${{ needs.pre-setup.outputs.container-version }}; docker buildx build --push - --platform $PLATFORMS + --platform ${{ + needs.pre-setup.outputs.container-platforms + }} --build-arg PROXYPY_PKG_PATH='dist/${{ needs.pre-setup.outputs.wheel-artifact-name }}' @@ -839,35 +860,6 @@ jobs: password: ${{ secrets.TESTPYPI_API_TOKEN }} repository_url: https://test.pypi.org/legacy/ - # publish-docker: - # name: Publish 🐳 📦 ${{ needs.pre-setup.outputs.git-tag }} to Docker Hub - # needs: - # - check - # - pre-setup # transitive, for accessing settings - # if: >- - # fromJSON(needs.pre-setup.outputs.release-requested) - # runs-on: Ubuntu-latest - - # environment: - # name: release-docker - # url: >- - # https://test.pypi.org/project/proxy.py/${{ - # needs.pre-setup.outputs.dist-version - # }} - - # steps: - # - name: Download all the dists - # uses: actions/download-artifact@v2 - # with: - # name: python-package-distributions - # path: dist/ - # - name: >- - # Publish 🐳 📦 ${{ needs.pre-setup.outputs.git-tag }} to Docker Hub - # uses: pypa/gh-action-pypi-publish@release/v1 - # with: - # password: ${{ secrets.TESTPYPI_API_TOKEN }} - # repository_url: https://test.pypi.org/legacy/ - post-release-repo-update: name: >- Publish post-release Git tag diff --git a/benchmark/requirements.txt b/benchmark/requirements.txt index a10b94f066..3da05de1a1 100644 --- a/benchmark/requirements.txt +++ b/benchmark/requirements.txt @@ -1,5 +1,5 @@ aiohttp==3.8.1 -blacksheep==1.2.1 +blacksheep==1.2.2 starlette==0.17.1 tornado==6.1 uvicorn==0.16.0 diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 7f6fa7dc5c..e99aef9c12 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -14,7 +14,7 @@ "@types/js-cookie": "^3.0.1", "@typescript-eslint/eslint-plugin": "^2.34.0", "@typescript-eslint/parser": "^2.34.0", - "chrome-devtools-frontend": "^1.0.949424", + "chrome-devtools-frontend": "^1.0.952865", "eslint": "^6.8.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-import": "^2.25.3", @@ -24,7 +24,7 @@ "http-server": "^14.0.0", "jasmine": "^3.10.0", "jasmine-ts": "^0.3.0", - "jquery": "^3.5.1", + "jquery": "^3.6.0", "js-cookie": "^3.0.1", "jsdom": "^15.2.1", "ncp": "^2.0.0", @@ -728,9 +728,9 @@ } }, "node_modules/chrome-devtools-frontend": { - "version": "1.0.949424", - "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.949424.tgz", - "integrity": "sha512-v4A+tyfJia6yOonl0I1M3lXYIV9J6idJ49+dT2TK7Z9SmlNd1ZPCcXDi3sBWBkpxdHJfpzl1We8HhUTh2VX5FA==", + "version": "1.0.952865", + "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.952865.tgz", + "integrity": "sha512-ewbHzHGo1UlK1WGokSzbavc65f/alJG3h+HEdgu0VohN9n3pc9AlfH26OZdzQEhWte2a3NWWmJksjR/Opcm+gQ==", "dev": true }, "node_modules/cli-cursor": { @@ -3278,9 +3278,9 @@ } }, "node_modules/jquery": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", - "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", "dev": true }, "node_modules/js-cookie": { @@ -5969,9 +5969,9 @@ "dev": true }, "chrome-devtools-frontend": { - "version": "1.0.949424", - "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.949424.tgz", - "integrity": "sha512-v4A+tyfJia6yOonl0I1M3lXYIV9J6idJ49+dT2TK7Z9SmlNd1ZPCcXDi3sBWBkpxdHJfpzl1We8HhUTh2VX5FA==", + "version": "1.0.952865", + "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.952865.tgz", + "integrity": "sha512-ewbHzHGo1UlK1WGokSzbavc65f/alJG3h+HEdgu0VohN9n3pc9AlfH26OZdzQEhWte2a3NWWmJksjR/Opcm+gQ==", "dev": true }, "cli-cursor": { @@ -7928,9 +7928,9 @@ } }, "jquery": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", - "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", "dev": true }, "js-cookie": { diff --git a/dashboard/package.json b/dashboard/package.json index bef79b2016..02744dacd2 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -30,7 +30,7 @@ "@types/js-cookie": "^3.0.1", "@typescript-eslint/eslint-plugin": "^2.34.0", "@typescript-eslint/parser": "^2.34.0", - "chrome-devtools-frontend": "^1.0.949424", + "chrome-devtools-frontend": "^1.0.952865", "eslint": "^6.8.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-import": "^2.25.3", @@ -40,7 +40,7 @@ "http-server": "^14.0.0", "jasmine": "^3.10.0", "jasmine-ts": "^0.3.0", - "jquery": "^3.5.1", + "jquery": "^3.6.0", "js-cookie": "^3.0.1", "jsdom": "^15.2.1", "ncp": "^2.0.0", diff --git a/helper/benchmark.sh b/helper/benchmark.sh index ca0cc43c7d..b03651d310 100755 --- a/helper/benchmark.sh +++ b/helper/benchmark.sh @@ -64,8 +64,6 @@ run_benchmark POST_RUN_OPEN_FILES=$(./helper/monitor_open_files.sh) -echo $output - echo "Open files diff:" diff <( echo "$PRE_RUN_OPEN_FILES" ) <( echo "$POST_RUN_OPEN_FILES" ) diff --git a/proxy/common/backports.py b/proxy/common/backports.py index 9aec16df4c..c2533fe020 100644 --- a/proxy/common/backports.py +++ b/proxy/common/backports.py @@ -55,6 +55,7 @@ def randint(self): backports getter Arndt + del """ def __init__(self, ttl: float = 0): diff --git a/proxy/common/flag.py b/proxy/common/flag.py index 2e3f4a9536..3c7f88b855 100644 --- a/proxy/common/flag.py +++ b/proxy/common/flag.py @@ -22,7 +22,7 @@ from ._compat import IS_WINDOWS # noqa: WPS436 from .plugins import Plugins from .types import IpAddress -from .utils import bytes_, is_py2, set_open_file_limit +from .utils import bytes_, is_py2, is_threadless, set_open_file_limit from .constants import COMMA, DEFAULT_DATA_DIRECTORY_PATH, DEFAULT_NUM_ACCEPTORS, DEFAULT_NUM_WORKERS from .constants import DEFAULT_DEVTOOLS_WS_PATH, DEFAULT_DISABLE_HEADERS, PY2_DEPRECATION_MESSAGE from .constants import PLUGIN_DASHBOARD, PLUGIN_DEVTOOLS_PROTOCOL, DEFAULT_MIN_COMPRESSION_LIMIT @@ -186,7 +186,7 @@ def initialize( for p in FlagParser.get_default_plugins(args) ] requested_plugins = Plugins.resolve_plugin_flag( - args.plugins, opts.get('plugins', None), + args.plugins, opts.get('plugins'), ) plugins = Plugins.load( default_plugins + auth_plugins + requested_plugins, @@ -340,14 +340,6 @@ def initialize( ), ) args.timeout = cast(int, opts.get('timeout', args.timeout)) - args.threadless = cast(bool, opts.get('threadless', args.threadless)) - args.threaded = cast(bool, opts.get('threaded', args.threaded)) - args.pid_file = cast( - Optional[str], opts.get( - 'pid_file', - args.pid_file, - ), - ) args.local_executor = cast( bool, opts.get( @@ -355,6 +347,22 @@ def initialize( args.local_executor, ), ) + args.threaded = cast(bool, opts.get('threaded', args.threaded)) + # Pre-evaluate threadless values based upon environment and config + # + # --threadless is now default mode of execution + # but we still have exceptions based upon OS config. + # Make sure executors are not started if is_threadless + # evaluates to False. + args.threadless = cast(bool, opts.get('threadless', args.threadless)) + args.threadless = is_threadless(args.threadless, args.threaded) + + args.pid_file = cast( + Optional[str], opts.get( + 'pid_file', + args.pid_file, + ), + ) args.proxy_py_data_dir = DEFAULT_DATA_DIRECTORY_PATH os.makedirs(args.proxy_py_data_dir, exist_ok=True) diff --git a/proxy/common/pki.py b/proxy/common/pki.py index 2a4395e904..93aab09e46 100644 --- a/proxy/common/pki.py +++ b/proxy/common/pki.py @@ -298,16 +298,16 @@ def run_openssl_command(command: List[str], timeout: int) -> bool: ', '.join(available_actions), ) sys.exit(1) - if args.action in ('gen_private_key', 'gen_public_key'): - if args.private_key_path is None: - logger.error('--private-key-path is required for ' + args.action) - sys.exit(1) - if args.action == 'gen_public_key': - if args.public_key_path is None: - logger.error( - '--public-key-file is required for private key generation', - ) - sys.exit(1) + if args.action in ('gen_private_key', 'gen_public_key') and \ + args.private_key_path is None: + logger.error('--private-key-path is required for ' + args.action) + sys.exit(1) + if args.action == 'gen_public_key' and \ + args.public_key_path is None: + logger.error( + '--public-key-file is required for private key generation', + ) + sys.exit(1) # Execute if args.action == 'gen_private_key': diff --git a/proxy/common/plugins.py b/proxy/common/plugins.py index b2236145a2..ff1704b8c3 100644 --- a/proxy/common/plugins.py +++ b/proxy/common/plugins.py @@ -74,12 +74,18 @@ def load( mro = list(inspect.getmro(klass)) mro.reverse() iterator = iter(mro) - while next(iterator) is not abc.ABC: - pass - base_klass = next(iterator) - if klass not in p[bytes_(base_klass.__name__)]: - p[bytes_(base_klass.__name__)].append(klass) - logger.info('Loaded plugin %s.%s', module_name, klass.__name__) + try: + while next(iterator) is not abc.ABC: + pass + base_klass = next(iterator) + if klass not in p[bytes_(base_klass.__name__)]: + p[bytes_(base_klass.__name__)].append(klass) + logger.info('Loaded plugin %s.%s', module_name, klass.__name__) + except StopIteration: + logger.warn( + '%s is NOT a valid plugin', + text_(plugin_), + ) return p @staticmethod diff --git a/proxy/common/utils.py b/proxy/common/utils.py index f76c2faaa6..54a2cb4162 100644 --- a/proxy/common/utils.py +++ b/proxy/common/utils.py @@ -99,7 +99,7 @@ def build_http_response( headers = {} has_content_length = False has_transfer_encoding = False - for k in headers: + for k, _ in headers.items(): if k.lower() == b'content-length': has_content_length = True if k.lower() == b'transfer-encoding': @@ -124,8 +124,8 @@ def build_http_pkt( """Build and returns a HTTP request or response packet.""" pkt = WHITESPACE.join(line) + CRLF if headers is not None: - for k in headers: - pkt += build_http_header(k, headers[k]) + CRLF + for k, v in headers.items(): + pkt += build_http_header(k, v) + CRLF pkt += CRLF if body: pkt += body diff --git a/proxy/core/acceptor/acceptor.py b/proxy/core/acceptor/acceptor.py index efaa9adc31..c600f00766 100644 --- a/proxy/core/acceptor/acceptor.py +++ b/proxy/core/acceptor/acceptor.py @@ -26,7 +26,6 @@ from typing import List, Optional, Tuple from ...common.flag import flags -from ...common.utils import is_threadless from ...common.logger import Logger from ...common.backports import NonBlockingQueue from ...common.constants import DEFAULT_LOCAL_EXECUTOR @@ -113,17 +112,17 @@ def accept( ) -> List[Tuple[socket.socket, Optional[Tuple[str, int]]]]: works = [] for _, mask in events: - if mask & selectors.EVENT_READ: - if self.sock is not None: - try: - conn, addr = self.sock.accept() - logging.debug( - 'Accepting new work#{0}'.format(conn.fileno()), - ) - works.append((conn, addr or None)) - except BlockingIOError: - # logger.info('blocking io error') - pass + if mask & selectors.EVENT_READ and \ + self.sock is not None: + try: + conn, addr = self.sock.accept() + logging.debug( + 'Accepting new work#{0}'.format(conn.fileno()), + ) + works.append((conn, addr or None)) + except BlockingIOError: + # logger.info('blocking io error') + pass return works def run_once(self) -> None: @@ -207,7 +206,7 @@ def _stop_local(self) -> None: def _work(self, conn: socket.socket, addr: Optional[Tuple[str, int]]) -> None: self._total = self._total or 0 - if is_threadless(self.flags.threadless, self.flags.threaded): + if self.flags.threadless: # Index of worker to which this work should be dispatched # Use round-robin strategy by default. # diff --git a/proxy/core/acceptor/executors.py b/proxy/core/acceptor/executors.py index b2c29a733b..e4e165b97b 100644 --- a/proxy/core/acceptor/executors.py +++ b/proxy/core/acceptor/executors.py @@ -26,7 +26,6 @@ from ..event import EventQueue, eventNames from ...common.flag import flags -from ...common.utils import is_threadless from ...common.constants import DEFAULT_NUM_WORKERS, DEFAULT_THREADLESS logger = logging.getLogger(__name__) @@ -150,7 +149,7 @@ def start_threaded_work( def setup(self) -> None: """Setup threadless processes.""" - if is_threadless(self.flags.threadless, self.flags.threaded): + if self.flags.threadless: for index in range(self.flags.num_workers): self._start_worker(index) logger.info( @@ -161,7 +160,7 @@ def setup(self) -> None: def shutdown(self) -> None: """Shutdown threadless processes.""" - if is_threadless(self.flags.threadless, self.flags.threaded): + if self.flags.threadless: self._shutdown_workers() logger.info( 'Stopped {0} threadless workers'.format( diff --git a/proxy/core/base/tcp_server.py b/proxy/core/base/tcp_server.py index ce1d476116..236d5b764e 100644 --- a/proxy/core/base/tcp_server.py +++ b/proxy/core/base/tcp_server.py @@ -99,10 +99,10 @@ async def handle_writables(self, writables: Writables) -> bool: 'Flushing buffer to client {0}'.format(self.work.address), ) self.work.flush() - if self.must_flush_before_shutdown is True: - if not self.work.has_buffer(): - teardown = True - self.must_flush_before_shutdown = False + if self.must_flush_before_shutdown is True and \ + not self.work.has_buffer(): + teardown = True + self.must_flush_before_shutdown = False return teardown async def handle_readables(self, readables: Readables) -> bool: diff --git a/proxy/http/handler.py b/proxy/http/handler.py index d8f28e035d..4a03aa5915 100644 --- a/proxy/http/handler.py +++ b/proxy/http/handler.py @@ -23,7 +23,7 @@ from .exception import HttpProtocolException from ..common.types import Readables, Writables -from ..common.utils import wrap_socket, is_threadless +from ..common.utils import wrap_socket from ..core.base import BaseTcpServerHandler from ..core.connection import TcpClientConnection from ..common.flag import flags @@ -76,7 +76,7 @@ def __init__(self, *args: Any, **kwargs: Any): enable_proxy_protocol=self.flags.enable_proxy_protocol, ) self.selector: Optional[selectors.DefaultSelector] = None - if not is_threadless(self.flags.threadless, self.flags.threaded): + if not self.flags.threadless: self.selector = selectors.DefaultSelector() self.plugins: Dict[str, HttpProtocolHandlerPlugin] = {} diff --git a/proxy/http/proxy/server.py b/proxy/http/proxy/server.py index 9b805a2813..0a54c4d5f7 100644 --- a/proxy/http/proxy/server.py +++ b/proxy/http/proxy/server.py @@ -87,7 +87,7 @@ '--ca-cert-dir', type=str, default=DEFAULT_CA_CERT_DIR, - help='Default: ~/.proxy.py. Directory to store dynamically generated certificates. ' + help='Default: ~/.proxy/certificates. Directory to store dynamically generated certificates. ' 'Also see --ca-key-file, --ca-cert-file and --ca-signing-key-file', ) @@ -730,7 +730,7 @@ def gen_ca_signed_certificate( ca_key_path = self.flags.ca_key_file ca_key_password = '' ca_crt_path = self.flags.ca_cert_file - serial = self.uid + serial = '%d%d' % (time.time(), os.getpid()) # Sign generated CSR if not os.path.isfile(cert_file_path): diff --git a/proxy/http/websocket/frame.py b/proxy/http/websocket/frame.py index 97387e59ef..e17490591f 100644 --- a/proxy/http/websocket/frame.py +++ b/proxy/http/websocket/frame.py @@ -16,9 +16,9 @@ Websocket """ import io -import hashlib import base64 import struct +import hashlib import secrets import logging diff --git a/proxy/proxy.py b/proxy/proxy.py index 4142691a16..c35e9e0b4a 100644 --- a/proxy/proxy.py +++ b/proxy/proxy.py @@ -171,8 +171,9 @@ def setup(self) -> None: event_queue = self.event_manager.queue \ if self.event_manager is not None \ else None - # Setup remote executors - if not self.flags.local_executor: + # Setup remote executors only if + # --local-executor mode isn't enabled. + if self.remote_executors_enabled: self.executors = ThreadlessPool( flags=self.flags, event_queue=event_queue, @@ -193,7 +194,7 @@ def setup(self) -> None: def shutdown(self) -> None: assert self.acceptors self.acceptors.shutdown() - if not self.flags.local_executor: + if self.remote_executors_enabled: assert self.executors self.executors.shutdown() if self.flags.enable_events: @@ -214,14 +215,18 @@ def _delete_pid_file(self) -> None: if self.flags.pid_file and os.path.exists(self.flags.pid_file): os.remove(self.flags.pid_file) + @property + def remote_executors_enabled(self) -> bool: + return self.flags.threadless and not self.flags.local_executor + def main(**opts: Any) -> None: - try: - with Proxy(sys.argv[1:], **opts): - while True: + with Proxy(sys.argv[1:], **opts): + while True: + try: time.sleep(1) - except KeyboardInterrupt: - pass + except KeyboardInterrupt: + break def entry_point() -> None: diff --git a/proxy/testing/test_case.py b/proxy/testing/test_case.py index f0a869aa7d..f6d75ce0de 100644 --- a/proxy/testing/test_case.py +++ b/proxy/testing/test_case.py @@ -23,6 +23,7 @@ class TestCase(unittest.TestCase): """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', @@ -37,16 +38,10 @@ 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.INPUT_ARGS.append('--hostname') - cls.INPUT_ARGS.append('0.0.0.0') - cls.INPUT_ARGS.append('--port') - cls.INPUT_ARGS.append('0') - 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) diff --git a/requirements-testing.txt b/requirements-testing.txt index 1e4a531ca0..d65ce96771 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -8,7 +8,7 @@ pytest-xdist == 2.5.0 pytest-mock==3.6.1 pytest-asyncio==0.16.0 autopep8==1.6.0 -mypy==0.910 +mypy==0.920 py-spy==0.3.11 codecov==2.1.12 tox==3.24.4 diff --git a/tests/test_main.py b/tests/test_main.py index 5927823fbb..e39cbb3100 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -15,6 +15,7 @@ from unittest import mock from proxy.proxy import main, entry_point +from proxy.common.constants import _env_threadless_compliant # noqa: WPS450 from proxy.common.utils import bytes_ from proxy.common.constants import DEFAULT_ENABLE_DASHBOARD, DEFAULT_LOCAL_EXECUTOR, DEFAULT_LOG_LEVEL, DEFAULT_LOG_FILE @@ -244,8 +245,9 @@ def test_enable_dashboard( mock_event_manager.assert_called_once() mock_event_manager.return_value.setup.assert_called_once() mock_event_manager.return_value.shutdown.assert_called_once() - mock_executor_pool.assert_called_once() - mock_executor_pool.return_value.setup.assert_called_once() + if _env_threadless_compliant(): + mock_executor_pool.assert_called_once() + mock_executor_pool.return_value.setup.assert_called_once() mock_acceptor_pool.assert_called_once() mock_acceptor_pool.return_value.setup.assert_called_once() mock_listener.return_value.setup.assert_called_once() @@ -283,8 +285,9 @@ def test_enable_devtools( mock_parse_args.assert_called_once() # Currently --enable-devtools flag alone doesn't enable eventing core mock_event_manager.assert_not_called() - mock_executor_pool.assert_called_once() - mock_executor_pool.return_value.setup.assert_called_once() + if _env_threadless_compliant(): + mock_executor_pool.assert_called_once() + mock_executor_pool.return_value.setup.assert_called_once() mock_acceptor_pool.assert_called_once() mock_acceptor_pool.return_value.setup.assert_called_once() mock_listener.return_value.setup.assert_called_once()