miketheman / pytest-socket

Pytest Plugin to disable socket calls during tests

Home Page:https://pypi.org/project/pytest-socket/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue with sockets when trying to run Home Assistant tests

mrtolkien opened this issue · comments

commented

Hi,

Posting this issue here as it's related to this repo:

Running pytest . on this repo:
https://github.com/mrtolkien/hass-nature-remo

Logs are the following:

./tests/test_api.py::test_get_appliances[pyloop] Failed: [undefined]pytest_socket.SocketConnectBlockedError: A test tried to use socket.socket.connect() with host "15.197.175.142" (allowed: "127.0.0.1").
hass = <homeassistant.core.HomeAssistant object at 0x7f46905c1db0>
socket_enabled = None

    @pytest.mark.enable_socket()
    async def test_get_appliances(hass, socket_enabled):
        api = NatureRemoAPI(
            os.environ[tests.access_token_field],
            async_get_clientsession(hass),
        )
    
>       devices = await api.get_devices()

tests/test_api.py:18: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
custom_components/nature_remo/api/nature_remo_api.py:43: in get_devices
    devices_response = await devices_query
../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/aiohttp/client.py:520: in _request
    conn = await self._connector.connect(
../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/aiohttp/connector.py:535: in connect
    proto = await self._create_connection(req, traces, timeout)
../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/aiohttp/connector.py:892: in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/aiohttp/connector.py:1020: in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/aiohttp/connector.py:969: in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
../../../.pyenv/versions/3.10.1/lib/python3.10/asyncio/base_events.py:1040: in create_connection
    sock = await self._connect_sock(
../../../.pyenv/versions/3.10.1/lib/python3.10/asyncio/base_events.py:954: in _connect_sock
    await self.sock_connect(sock, address)
../../../.pyenv/versions/3.10.1/lib/python3.10/asyncio/selector_events.py:502: in sock_connect
    return await fut
../../../.pyenv/versions/3.10.1/lib/python3.10/asyncio/selector_events.py:507: in _sock_connect
    sock.connect(address)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

inst = <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
args = (('15.197.175.142', 443),), host = '15.197.175.142'

    def guarded_connect(inst, *args):
        host = host_from_connect_args(args)
        if host and host in allowed:
            return _true_connect(inst, *args)
>       raise SocketConnectBlockedError(allowed, host)
E       pytest_socket.SocketConnectBlockedError: A test tried to use socket.socket.connect() with host "15.197.175.142" (allowed: "127.0.0.1").

../../../.cache/pypoetry/virtualenvs/home-assistant-nature-remo-Aj4ZNfxY-py3.10/lib/python3.10/site-packages/pytest_socket.py:154: SocketConnectBlockedError

It seems that by default sockets and hosts are all disabled for the tests there. I have tried adding adopts = --allow-unix-socket --allow-hosts=15.197.175.142 to pytest.ini, and the mark @pytest.mark.enable_socket(), to no avail.

Any clue about what I should change to let pytest use sockets?

Hi @mrtolkien ! Thanks for trying out the library.

Some things that stands out to me are:

You appear to be mixing the pytest marker, fixture, and CLI options/config together - and I don't think I've expressed that level of combination in the test suite yet.

With no modifications to the test module itself, I ran this command:

poetry run pytest --disable-socket --allow-unix-socket --allow-hosts=15.197.175.142 tests/test_api.py 

Avoids the SocketConnectBlockedError. (There are other errors, since I don't have a valid access token, I used null for the purpose of the test.)

If you wanted to constrain the allowable hosts to only that test, here's how you might structure the implementation:

CLI options (or config):

--disable-socket --allow-unix-socket

Decorate the test that should be allowed to call the endpoint:

@pytest.mark.allow_hosts(["15.197.175.142", "3.33.185.105"])
async def test_get_appliances(hass):
    api = NatureRemoAPI(
...

I added the second IP address since that's what returned for the DNS entry:

$ host api.nature.global
api.nature.global has address 3.33.185.105
api.nature.global has address 15.197.175.142

Hope this helps you out!

commented

Thanks a lot for the help!

Passing the arguments directly to pytest did help but I'm indeed facing new errors that used to not be there in the library. I'll likely rewrite my code so it can sidestep this.