Skip to content
Snippets Groups Projects
Unverified Commit f6682ba9 authored by Erik Montnemery's avatar Erik Montnemery Committed by GitHub
Browse files

Block tests from opening sockets (#55516)

parent a8b7c521
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@ pipdeptree==2.1.0
pylint-strict-informational==0.1
pytest-aiohttp==0.3.0
pytest-cov==2.12.1
pytest-socket==0.4.1
pytest-test-groups==1.0.3
pytest-sugar==0.9.4
pytest-timeout==1.4.2
......
"""Test configuration for auth."""
import pytest
@pytest.fixture
def aiohttp_client(loop, aiohttp_client, socket_enabled):
"""Return aiohttp_client and allow opening sockets."""
return aiohttp_client
......@@ -28,6 +28,12 @@ class MockTransport:
self.sends.append((response, addr))
@pytest.fixture
def aiohttp_client(loop, aiohttp_client, socket_enabled):
"""Return aiohttp_client and allow opening sockets."""
return aiohttp_client
@pytest.fixture
def hue_client(aiohttp_client):
"""Return a hue API client."""
......
......@@ -79,6 +79,12 @@ async def frontend_themes(hass):
)
@pytest.fixture
def aiohttp_client(loop, aiohttp_client, socket_enabled):
"""Return aiohttp_client and allow opening sockets."""
return aiohttp_client
@pytest.fixture
async def mock_http_client(hass, aiohttp_client, frontend):
"""Start the Home Assistant HTTP component."""
......
"""Test configuration for http."""
import pytest
@pytest.fixture
def aiohttp_client(loop, aiohttp_client, socket_enabled):
"""Return aiohttp_client and allow opening sockets."""
return aiohttp_client
"""The tests for the image_processing component."""
from unittest.mock import PropertyMock, patch
import pytest
import homeassistant.components.http as http
import homeassistant.components.image_processing as ip
from homeassistant.const import ATTR_ENTITY_PICTURE
......@@ -11,6 +13,12 @@ from tests.common import assert_setup_component, async_capture_events
from tests.components.image_processing import common
@pytest.fixture
def aiohttp_unused_port(loop, aiohttp_unused_port, socket_enabled):
"""Return aiohttp_unused_port and allow opening sockets."""
return aiohttp_unused_port
def get_url(hass):
"""Return camera url."""
state = hass.states.get("camera.demo_camera")
......
"""Test the motionEye camera."""
import copy
import logging
from typing import Any, cast
from unittest.mock import AsyncMock, Mock
......@@ -48,7 +47,11 @@ from . import (
from tests.common import async_fire_time_changed
_LOGGER = logging.getLogger(__name__)
@pytest.fixture
def aiohttp_server(loop, aiohttp_server, socket_enabled):
"""Return aiohttp_server and allow opening sockets."""
return aiohttp_server
async def test_setup_camera(hass: HomeAssistant) -> None:
......
......@@ -48,6 +48,12 @@ class FakeAuth(AbstractAuth):
return aiohttp.web.json_response()
@pytest.fixture
def aiohttp_client(loop, aiohttp_client, socket_enabled):
"""Return aiohttp_client and allow opening sockets."""
return aiohttp_client
@pytest.fixture
async def auth(aiohttp_client):
"""Fixture for an AbstractAuth."""
......
......@@ -3,6 +3,7 @@ import asyncio
import datetime
import functools
import logging
import socket
import ssl
import threading
from unittest.mock import MagicMock, patch
......@@ -10,6 +11,7 @@ from unittest.mock import MagicMock, patch
from aiohttp.test_utils import make_mocked_request
import multidict
import pytest
import pytest_socket
import requests_mock as _requests_mock
from homeassistant import core as ha, loader, runner, util
......@@ -61,6 +63,70 @@ def pytest_configure(config):
)
def pytest_runtest_setup():
"""Throw if tests attempt to open sockets.
allow_unix_socket is set to True because it's needed by asyncio.
Important: socket_allow_hosts must be called before disable_socket, otherwise all
destinations will be allowed.
"""
pytest_socket.socket_allow_hosts(["127.0.0.1"])
disable_socket(allow_unix_socket=True)
@pytest.fixture
def socket_disabled(pytestconfig):
"""Disable socket.socket for duration of this test function.
This incorporates changes from https://github.com/miketheman/pytest-socket/pull/76
and hardcodes allow_unix_socket to True because it's not passed on the command line.
"""
socket_was_enabled = socket.socket == pytest_socket._true_socket
disable_socket(allow_unix_socket=True)
yield
if socket_was_enabled:
pytest_socket.enable_socket()
@pytest.fixture
def socket_enabled(pytestconfig):
"""Enable socket.socket for duration of this test function.
This incorporates changes from https://github.com/miketheman/pytest-socket/pull/76
and hardcodes allow_unix_socket to True because it's not passed on the command line.
"""
socket_was_disabled = socket.socket != pytest_socket._true_socket
pytest_socket.enable_socket()
yield
if socket_was_disabled:
disable_socket(allow_unix_socket=True)
def disable_socket(allow_unix_socket=False):
"""Disable socket.socket to disable the Internet. useful in testing.
This incorporates changes from https://github.com/miketheman/pytest-socket/pull/75
"""
class GuardedSocket(socket.socket):
"""socket guard to disable socket creation (from pytest-socket)."""
def __new__(cls, *args, **kwargs):
try:
if len(args) > 0:
is_unix_socket = args[0] == socket.AF_UNIX
else:
is_unix_socket = kwargs.get("family") == socket.AF_UNIX
except AttributeError:
# AF_UNIX not supported on Windows https://bugs.python.org/issue33408
is_unix_socket = False
if is_unix_socket and allow_unix_socket:
return super().__new__(cls, *args, **kwargs)
raise pytest_socket.SocketBlockedError()
socket.socket = GuardedSocket
def check_real(func):
"""Force a function to require a keyword _test_real to be passed in."""
......@@ -319,7 +385,7 @@ def local_auth(hass):
@pytest.fixture
def hass_client(hass, aiohttp_client, hass_access_token):
def hass_client(hass, aiohttp_client, hass_access_token, socket_enabled):
"""Return an authenticated HTTP client."""
async def auth_client():
......@@ -332,7 +398,7 @@ def hass_client(hass, aiohttp_client, hass_access_token):
@pytest.fixture
def hass_client_no_auth(hass, aiohttp_client):
def hass_client_no_auth(hass, aiohttp_client, socket_enabled):
"""Return an unauthenticated HTTP client."""
async def client():
......@@ -367,7 +433,7 @@ def current_request_with_host(current_request):
@pytest.fixture
def hass_ws_client(aiohttp_client, hass_access_token, hass):
def hass_ws_client(aiohttp_client, hass_access_token, hass, socket_enabled):
"""Websocket client fixture connected to websocket server."""
async def create_client(hass=hass, access_token=hass_access_token):
......
"""Test test fixture configuration."""
import socket
import pytest
import pytest_socket
def test_sockets_disabled():
"""Test we can't open sockets."""
with pytest.raises(pytest_socket.SocketBlockedError):
socket.socket()
def test_sockets_enabled(socket_enabled):
"""Test we can't connect to an address different from 127.0.0.1."""
mysocket = socket.socket()
with pytest.raises(pytest_socket.SocketConnectBlockedError):
mysocket.connect(("127.0.0.2", 1234))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment