schireson / pytest-mock-resources

Pytest Fixtures that let you actually test against external resource (Postgres, Mongo, Redshift...) dependent code.
https://pytest-mock-resources.readthedocs.io/en/latest/quickstart.html
MIT License
179 stars 19 forks source link

Redis Container dont start after update Docker for Desktop on windows. #200

Closed nische closed 9 months ago

nische commented 9 months ago

Hi Guys,

I have the Problem that my create_redis_fixture dont start the Docker container after updated Docker Desktop to v4.25.2 on Windows. My Project worked before the update without Problems.

I can actual run containers with "python-on-whales" from my python shell.

I use python 3.10.11 with pytest-mock-resource v2.9.2 on windows with a venv.

 pip list
Package               Version   Editable project location
--------------------- --------- ----------------------------------------------
annotated-types       0.5.0
astroid               2.15.6
async-timeout         4.0.3
autopep8              2.0.4
certifi               2023.7.22
chardet               5.2.0
charset-normalizer    3.2.0
click                 8.1.7
colorama              0.4.6
commonmark            0.9.1
coverage              7.3.1
dacite                1.8.1
dill                  0.3.7
EPCPyYes              2.0.5
exceptiongroup        1.1.3
filelock              3.12.3
greenlet              2.0.2
httmock               1.4.0
idna                  3.4
iniconfig             2.0.0
isort                 5.12.0
Jinja2                3.1.2
lazy-object-proxy     1.9.0
litequeue             0.7
lxml                  4.9.3
MarkupSafe            2.1.3
mccabe                0.7.0
packaging             23.1
pip                   23.2.1
platformdirs          3.10.0
pluggy                1.3.0
pycodestyle           2.11.0
pydantic              2.3.0
pydantic_core         2.6.3
pylint                2.17.5
PyMuPDF               1.23.6
PyMuPDFb              1.23.6
PyPDF2                3.0.1
pytest                7.4.2
pytest-cov            4.1.0
pytest-env            1.0.1
pytest-mock           3.11.1
pytest-mock-resources 2.9.2
python-on-whales      0.64.3
redis                 5.0.0
requests              2.31.0
requests-mock         1.11.0
setuptools            65.5.0
six                   1.16.0
SQLAlchemy            2.0.22
tomli                 2.0.1
tomlkit               0.12.1
tqdm                  4.66.1
typer                 0.9.0
typing_extensions     4.7.1
urllib3               2.0.4
wrapt                 1.15.0
xmltodict             0.13.0

Did anybody know this problem?

BR,

NiSche

DanCardin commented 9 months ago

Is pytest-mock-resources timing out or hanging? or what does "dont start" mean.

I know in the past i've needed to docker pull redis:5.0.7 ahead of running the tests due to slow network speed. if you dont have the image in question ahead of time it will pull it and potentially introduce longer startup time than we allow for in our timeouts.

nische commented 9 months ago

Thanks for your answer

The Image is already on my system. The package throws the exeption below. And if i watch docker desktop gui the container dont start (and it did before the update). The exception says redis cant connect but i belief the problem is that the container is not started.

self = Connection<host=host.docker.internal,port=6380,db=0>
    def connect(self):
        "Connects to the Redis server if not already connected"
        if self._sock:
            return
        try:
>           sock = self.retry.call_with_retry(
                lambda: self._connect(), lambda error: self.disconnect(error)
            )
.venv\lib\site-packages\redis\connection.py:259: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv\lib\site-packages\redis\retry.py:51: in call_with_retry
    raise error
.venv\lib\site-packages\redis\retry.py:46: in call_with_retry
    return do()
.venv\lib\site-packages\redis\connection.py:260: in <lambda>
    lambda: self._connect(), lambda error: self.disconnect(error)
.venv\lib\site-packages\redis\connection.py:617: in _connect
    raise err
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=host.docker.internal,port=6380,db=0>
    def _connect(self):
        "Create a TCP socket connection"
        # we want to mimic what socket.create_connection does to support
        # ipv4/ipv6, but we want to set options prior to calling
        # socket.connect()
        err = None
        for res in socket.getaddrinfo(
            self.host, self.port, self.socket_type, socket.SOCK_STREAM
        ):
            family, socktype, proto, canonname, socket_address = res
            sock = None
            try:
                sock = socket.socket(family, socktype, proto)
                # TCP_NODELAY
                sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

                # TCP_KEEPALIVE
                if self.socket_keepalive:
                    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
                    for k, v in self.socket_keepalive_options.items():
                        sock.setsockopt(socket.IPPROTO_TCP, k, v)

                # set the socket_connect_timeout before we connect
                sock.settimeout(self.socket_connect_timeout)

                # connect
>               sock.connect(socket_address)
E               TimeoutError: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
.venv\lib\site-packages\redis\connection.py:605: TimeoutError
During handling of the above exception, another exception occurred:
pytestconfig = <_pytest.config.Config object at 0x0000022026CC5CC0>
pmr_redis_config = RedisConfig(image='redis:6.0', host='host.docker.internal', port=6380, ci_port=6379)
    @pytest.fixture(scope="session")
    def pmr_redis_container(pytestconfig, pmr_redis_config):
>       yield from get_container(pytestconfig, pmr_redis_config)
.venv\lib\site-packages\pytest_mock_resources\fixture\redis.py:23: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv\lib\site-packages\pytest_mock_resources\container\base.py:106: in get_container
    container = wait_for_container(
.venv\lib\site-packages\pytest_mock_resources\container\base.py:145: in wait_for_container
    retry(check_fn, retries=1, interval=interval, on_exc=ContainerCheckFailed)
.venv\lib\site-packages\pytest_mock_resources\container\base.py:66: in retry
    result = func(*args, **kwargs)
.venv\lib\site-packages\pytest_mock_resources\container\redis.py:35: in check_fn
    client.ping()
.venv\lib\site-packages\redis\commands\core.py:1216: in ping
    return self.execute_command("PING", **kwargs)
.venv\lib\site-packages\redis\client.py:505: in execute_command
    conn = self.connection or pool.get_connection(command_name, **options)
.venv\lib\site-packages\redis\connection.py:1073: in get_connection
    connection.connect()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=host.docker.internal,port=6380,db=0>
    def connect(self):
        "Connects to the Redis server if not already connected"
        if self._sock:
            return
        try:
            sock = self.retry.call_with_retry(
                lambda: self._connect(), lambda error: self.disconnect(error)
            )
        except socket.timeout:
>           raise TimeoutError("Timeout connecting to server")
E           redis.exceptions.TimeoutError: Timeout connecting to server
.venv\lib\site-packages\redis\connection.py:263: TimeoutError
DanCardin commented 9 months ago

Perhaps a docker system prune -a? If it's failing to spin up the container at the docker level, it's beyond the scope of what PMR can affect the outcome of. Particularly if it was a Docker Desktop upgrade, that pretty much guarantees it's unrelated to the inner workings of this library.

nische commented 9 months ago

pruning the system doesnt fix it. And i have the same error on the new notebook of my colleague.

Did you have any idee?

DanCardin commented 9 months ago

The only other thing I can think of is that the host correct for your docker setup. If you can import python_on_whales or docker-py, construct a client yourself, and create a container yourself, then it's almost certainly that you need to explicitly export the PYTEST_MOCK_RESOURCES_HOST env var to a different value.

If that doesnt work, then the problem is definitely outside PMR itself.

nische commented 9 months ago

That's what I do last week. I use pytest-docker and create the Redis service with this as a fixture. 👍

I wish you a Merry Christmas and a happy new year.

Br, Nische