mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Block tests from opening sockets (#55516)
This commit is contained in:
parent
a8b7c521f6
commit
f6682ba99d
@ -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
|
||||
|
8
tests/components/auth/conftest.py
Normal file
8
tests/components/auth/conftest.py
Normal file
@ -0,0 +1,8 @@
|
||||
"""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."""
|
||||
|
8
tests/components/http/conftest.py
Normal file
8
tests/components/http/conftest.py
Normal file
@ -0,0 +1,8 @@
|
||||
"""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
|
@ -1,6 +1,8 @@
|
||||
"""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")
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""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):
|
||||
|
18
tests/test_test_fixtures.py
Normal file
18
tests/test_test_fixtures.py
Normal file
@ -0,0 +1,18 @@
|
||||
"""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))
|
Loading…
x
Reference in New Issue
Block a user