#1030600 redis breaks python-fakeredis autopkgtest: Connection refused

#1030600#5
Date:
2023-02-05 14:23:11 UTC
From:
To:
Dear maintainer(s),

With a recent upload of redis the autopkgtest of python-fakeredis fails
in testing when that autopkgtest is run with the binary packages of
redis from unstable. It passes when run with only packages from testing.
In tabular form:

                        pass            fail
redis                  from testing    5:7.0.8-2
python-fakeredis       from testing    1.9.0-0.1
all others             from testing    from testing

I copied some of the output at the bottom of this report.

Currently this regression is blocking the migration of redis to testing
[1]. Due to the nature of this issue, I filed this bug report against
both packages. Can you please investigate the situation and reassign the
bug to the right package?

More information about this bug and the reason for filing it can be found on
https://wiki.debian.org/ContinuousIntegration/RegressionEmailInformation

Paul

[1] https://qa.debian.org/excuses.php?package=redis

https://ci.debian.net/data/autopkgtest/testing/amd64/p/python-fakeredis/31066293/log.gz

=================================== FAILURES
===================================
                 lambda: self._connect(), lambda error:
self.disconnect(error)
             )

/usr/lib/python3/dist-packages/redis/connection.py:611: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <redis.retry.Retry object at 0x7f8087f81710>
do = <function Connection.connect.<locals>.<lambda> at 0x7f8088401a80>
fail = <function Connection.connect.<locals>.<lambda> at 0x7f8088402840>

     def call_with_retry(self, do, fail):
         """
         Execute an operation that might fail and returns its result, or
         raise the exception that was thrown depending on the `Backoff`
object.
         `do`: the operation to call. Expects no argument.
         `fail`: the failure handler, expects the last error that was thrown
         """
         self._backoff.reset()
         failures = 0
         while True:
             try:

/usr/lib/python3/dist-packages/redis/retry.py:46: _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
     )

/usr/lib/python3/dist-packages/redis/connection.py:612: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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)
                     # set the socket_timeout now that we're connected
                 sock.settimeout(self.socket_timeout)
                 return sock
                 except OSError as _:
                 err = _
                 if sock is not None:
                     sock.close()
             if err is not None:

/usr/lib/python3/dist-packages/redis/connection.py:677: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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
/usr/lib/python3/dist-packages/redis/connection.py:665:
ConnectionRefusedError

During handling of the above exception, another exception occurred:

self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)

test/test_hypothesis.py:252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
kwargs = {}

     def ping(self, **kwargs) -> ResponseT:
         """
         Ping the Redis server
             For more information see https://redis.io/commands/ping
         """

/usr/lib/python3/dist-packages/redis/commands/core.py:1132: _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
args = ('PING',), options = {}
pool = ConnectionPool<Connection<host=localhost,port=6379,db=0>>

     def execute_command(self, *args, **options):
         """Execute a command and return a parsed response"""
         pool = self.connection_pool
         command_name = args[0]

/usr/lib/python3/dist-packages/redis/client.py:1235: _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ConnectionPool<Connection<host=localhost,port=6379,db=0>>
command_name = 'PING', keys = (), options = {}
connection = Connection<host=localhost,port=6379,db=0>

     def get_connection(self, command_name, *keys, **options):
         "Get a connection from the pool"
         self._checkpid()
         with self._lock:
             try:
                 connection = self._available_connections.pop()
             except IndexError:
                 connection = self.make_connection()
             self._in_use_connections.add(connection)
             try:
             # ensure this connection is connected to Redis

/usr/lib/python3/dist-packages/redis/connection.py:1387: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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")
         except OSError as e:

/usr/lib/python3/dist-packages/redis/connection.py:617: ConnectionError

During handling of the above exception, another exception occurred:

self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f80877f7d90>
data = ConjectureData(VALID, 0 bytes, frozen)

     def test_function(self, data):
         if self.__pending_call_explanation is not None:
             self.debug(self.__pending_call_explanation)
             self.__pending_call_explanation = None
             assert isinstance(data.observer, TreeRecordingObserver)
         self.call_count += 1
             interrupted = False
         try:

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:209:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f80877f7d90>
data = ConjectureData(VALID, 0 bytes, frozen)

     def __stoppable_test_function(self, data):
         """Run ``self._test_function``, but convert a ``StopTest``
exception
         into a normal return and avoid raising Flaky for RecursionErrors.
         """
         depth = stack_depth_of_caller()
         # Because we add to the recursion limit, to be good citizens we
also add
         # a check for unbounded recursion.  The default limit is 1000,
so this can
         # only ever trigger if something really strange is happening
and it's hard
         # to imagine an intentionally-deeply-recursive use of this code.
         assert depth <= 1000, (
             "Hypothesis would usually add %d to the stack depth of %d
here, "
             "but we are already much deeper than expected.  Aborting
now, to "
             "avoid extending the stack limit in an infinite loop..."
             % (self.__recursion_limit, depth)
         )
         try:
             sys.setrecursionlimit(depth + self.__recursion_limit)

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:185:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f80880f8250>
data = ConjectureData(VALID, 0 bytes, frozen)

     def _execute_once_for_engine(self, data):
         """Wrapper around ``execute_once`` that intercepts test failure
         exceptions and single-test control exceptions, and turns them into
         appropriate method calls to `data` instead.
             This allows the engine to assume that any exception other than
         ``StopTest`` must be a fatal error, and should stop the entire
engine.
         """
         try:
             trace = frozenset()
             if (
                 self.failed_normally
                 and not self.failed_due_to_deadline
                 and Phase.shrink in self.settings.phases
                 and Phase.explain in self.settings.phases
                 and sys.gettrace() is None
                 and not PYPY
             ):  # pragma: no cover
                 # This is in fact covered by our *non-coverage* tests,
but due to the
                 # settrace() contention *not* by our coverage tests.
Ah well.
                 tracer = Tracer()
                 try:
                     sys.settrace(tracer.trace)
                     result = self.execute_once(data)
                     if data.status == Status.VALID:

self.explain_traces[None].add(frozenset(tracer.branches))
                 finally:
                     sys.settrace(None)
                     trace = frozenset(tracer.branches)
             else:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f80880f8250>
data = ConjectureData(VALID, 0 bytes, frozen), print_example = False
is_final = False, expected_failure = None

     def execute_once(
         self, data, print_example=False, is_final=False,
expected_failure=None
     ):
         """Run the test function once, using ``data`` as input.
             If the test raises an exception, it will propagate through
to the
         caller of this method. Depending on its type, this could represent
         an ordinary test failure, or a fatal error, or a control exception.
             If this method returns normally, the test might have passed, or
         it might have placed ``data`` in an unsuccessful state and then
         swallowed the corresponding control exception.
         """
             self.ever_executed = True
         data.is_find = self.is_find
             text_repr = None
         if self.settings.deadline is None:
             test = self.test
         else:
                 @proxies(self.test)
             def test(*args, **kwargs):
                 self.__test_runtime = None
                 initial_draws = len(data.draw_times)
                 start = time.perf_counter()
                 result = self.test(*args, **kwargs)
                 finish = time.perf_counter()
                 internal_draw_time = sum(data.draw_times[initial_draws:])
                 runtime = datetime.timedelta(
                     seconds=finish - start - internal_draw_time
                 )
                 self.__test_runtime = runtime
                 current_deadline = self.settings.deadline
                 if not is_final:
                     current_deadline = (current_deadline // 4) * 5
                 if runtime >= current_deadline:
                     raise DeadlineExceeded(runtime, self.settings.deadline)
                 return result
             def run(data):
             # Set up dynamic context needed by a single test run.
             with local_settings(self.settings):
                 with deterministic_PRNG():
                     with BuildContext(data, is_final=is_final) as context:
                             # Generate all arguments to the test function.
                         args, kwargs = data.draw(self.search_strategy)
                         if expected_failure is not None:
                             nonlocal text_repr
                             text_repr = repr_call(test, args, kwargs)
                             if print_example or current_verbosity() >=
Verbosity.verbose:
                             output = StringIO()
                                 printer = RepresentationPrinter(output,
context=context)
                             if print_example:
                                 printer.text("Falsifying example:")
                             else:
                                 printer.text("Trying example:")
                                 if self.print_given_args:
                                 printer.text(" ")
                                 printer.repr_call(
                                     test.__name__,
                                     args,
                                     kwargs,
                                     force_split=True,
                                 )
                             report(printer.getvalue())
                         return test(*args, **kwargs)
             # Run the test function once, via the executor hook.
         # In most cases this will delegate straight to `run(data)`.

/usr/lib/python3/dist-packages/hypothesis/core.py:818: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)
function = <function
StateForActualGivenExecution.execute_once.<locals>.run at 0x7f8087473240>

     def default_new_style_executor(data, function):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)

     def run(data):
         # Set up dynamic context needed by a single test run.
         with local_settings(self.settings):
             with deterministic_PRNG():
                 with BuildContext(data, is_final=is_final) as context:
                         # Generate all arguments to the test function.
                     args, kwargs = data.draw(self.search_strategy)
                     if expected_failure is not None:
                         nonlocal text_repr
                         text_repr = repr_call(test, args, kwargs)
                         if print_example or current_verbosity() >=
Verbosity.verbose:
                         output = StringIO()
                             printer = RepresentationPrinter(output,
context=context)
                         if print_example:
                             printer.text("Falsifying example:")
                         else:
                             printer.text("Trying example:")
                             if self.print_given_args:
                             printer.text(" ")
                             printer.repr_call(
                                 test.__name__,
                                 args,
                                 kwargs,
                                 force_split=True,
                             )
                         report(printer.getvalue())

/usr/lib/python3/dist-packages/hypothesis/core.py:814: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
factory = <class 'test_hypothesis.BaseTest.test.<locals>.Machine'>
data = data(...)

     @settings
     @given(st.data())
     def run_state_machine(factory, data):
         cd = data.conjecture_data

/usr/lib/python3/dist-packages/hypothesis/stateful.py:110: _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)
             self.real.ping()
         except redis.ConnectionError:

test/test_hypothesis.py:254: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
reason = 'redis is not running'

     @_with_exception(Skipped)
     def skip(
         reason: str = "", *, allow_module_level: bool = False, msg:
Optional[str] = None
     ) -> NoReturn:
         """Skip an executing test with the given message.
             This function should be called only during testing (setup,
call or teardown) or
         during collection by using the ``allow_module_level`` flag.
This function can
         be called in doctests as well.
             :param reason:
             The message to show the user as reason for the skip.
             :param allow_module_level:
             Allows this function to be called at module level, skipping
the rest
             of the module. Defaults to False.
             :param msg:
             Same as ``reason``, but deprecated. Will be removed in a
future version, use ``reason`` instead.
             .. note::
             It is better to use the :ref:`pytest.mark.skipif ref`
marker when
             possible to declare a test to be skipped under certain
conditions
             like mismatching platforms or dependencies.
             Similarly, use the ``# doctest: +SKIP`` directive (see
:py:data:`doctest.SKIP`)
             to skip a doctest statically.
         """
         __tracebackhide__ = True
         reason = _resolve_msg_to_reason("skip", reason, msg)
/usr/lib/python3/dist-packages/_pytest/outcomes.py:175: Skipped

During handling of the above exception, another exception occurred:

self = <test_hypothesis.TestString object at 0x7f80877a1310>

     @pytest.mark.slow
     def test(self):
         class Machine(CommonMachine):
             create_command_strategy = self.create_command_strategy
             command_strategy = self.command_strategy
             # hypothesis.settings.register_profile("debug",
max_examples=10, verbosity=hypothesis.Verbosity.debug)
         # hypothesis.settings.load_profile("debug")

test/test_hypothesis.py:354: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/hypothesis/stateful.py:222: in
run_state_machine_as_test
     run_state_machine(state_machine_factory)
/usr/lib/python3/dist-packages/hypothesis/stateful.py:107: in
run_state_machine
     @given(st.data())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
     def inconsistent_generation():
             "Inconsistent data generation! Data generation behaved
differently "
             "between different runs. Is your data generation depending
on external "
             "state?"
         )
E       hypothesis.errors.Flaky: Inconsistent data generation! Data
generation behaved differently between different runs. Is your data
generation depending on external state?

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/datatree.py:29:
Flaky

                 lambda: self._connect(), lambda error:
self.disconnect(error)
             )

/usr/lib/python3/dist-packages/redis/connection.py:611: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <redis.retry.Retry object at 0x7f80880c17d0>
do = <function Connection.connect.<locals>.<lambda> at 0x7f8087980fe0>
fail = <function Connection.connect.<locals>.<lambda> at 0x7f80880cf920>

     def call_with_retry(self, do, fail):
         """
         Execute an operation that might fail and returns its result, or
         raise the exception that was thrown depending on the `Backoff`
object.
         `do`: the operation to call. Expects no argument.
         `fail`: the failure handler, expects the last error that was thrown
         """
         self._backoff.reset()
         failures = 0
         while True:
             try:

/usr/lib/python3/dist-packages/redis/retry.py:46: _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
     )

/usr/lib/python3/dist-packages/redis/connection.py:612: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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)
                     # set the socket_timeout now that we're connected
                 sock.settimeout(self.socket_timeout)
                 return sock
                 except OSError as _:
                 err = _
                 if sock is not None:
                     sock.close()
             if err is not None:

/usr/lib/python3/dist-packages/redis/connection.py:677: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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
/usr/lib/python3/dist-packages/redis/connection.py:665:
ConnectionRefusedError

During handling of the above exception, another exception occurred:

self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)

test/test_hypothesis.py:252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
kwargs = {}

     def ping(self, **kwargs) -> ResponseT:
         """
         Ping the Redis server
             For more information see https://redis.io/commands/ping
         """

/usr/lib/python3/dist-packages/redis/commands/core.py:1132: _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
args = ('PING',), options = {}
pool = ConnectionPool<Connection<host=localhost,port=6379,db=0>>

     def execute_command(self, *args, **options):
         """Execute a command and return a parsed response"""
         pool = self.connection_pool
         command_name = args[0]

/usr/lib/python3/dist-packages/redis/client.py:1235: _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ConnectionPool<Connection<host=localhost,port=6379,db=0>>
command_name = 'PING', keys = (), options = {}
connection = Connection<host=localhost,port=6379,db=0>

     def get_connection(self, command_name, *keys, **options):
         "Get a connection from the pool"
         self._checkpid()
         with self._lock:
             try:
                 connection = self._available_connections.pop()
             except IndexError:
                 connection = self.make_connection()
             self._in_use_connections.add(connection)
             try:
             # ensure this connection is connected to Redis

/usr/lib/python3/dist-packages/redis/connection.py:1387: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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")
         except OSError as e:

/usr/lib/python3/dist-packages/redis/connection.py:617: ConnectionError

During handling of the above exception, another exception occurred:

self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f8088928110>
data = ConjectureData(VALID, 0 bytes, frozen)

     def test_function(self, data):
         if self.__pending_call_explanation is not None:
             self.debug(self.__pending_call_explanation)
             self.__pending_call_explanation = None
             assert isinstance(data.observer, TreeRecordingObserver)
         self.call_count += 1
             interrupted = False
         try:

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:209:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f8088928110>
data = ConjectureData(VALID, 0 bytes, frozen)

     def __stoppable_test_function(self, data):
         """Run ``self._test_function``, but convert a ``StopTest``
exception
         into a normal return and avoid raising Flaky for RecursionErrors.
         """
         depth = stack_depth_of_caller()
         # Because we add to the recursion limit, to be good citizens we
also add
         # a check for unbounded recursion.  The default limit is 1000,
so this can
         # only ever trigger if something really strange is happening
and it's hard
         # to imagine an intentionally-deeply-recursive use of this code.
         assert depth <= 1000, (
             "Hypothesis would usually add %d to the stack depth of %d
here, "
             "but we are already much deeper than expected.  Aborting
now, to "
             "avoid extending the stack limit in an infinite loop..."
             % (self.__recursion_limit, depth)
         )
         try:
             sys.setrecursionlimit(depth + self.__recursion_limit)

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:185:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f8087d21b10>
data = ConjectureData(VALID, 0 bytes, frozen)

     def _execute_once_for_engine(self, data):
         """Wrapper around ``execute_once`` that intercepts test failure
         exceptions and single-test control exceptions, and turns them into
         appropriate method calls to `data` instead.
             This allows the engine to assume that any exception other than
         ``StopTest`` must be a fatal error, and should stop the entire
engine.
         """
         try:
             trace = frozenset()
             if (
                 self.failed_normally
                 and not self.failed_due_to_deadline
                 and Phase.shrink in self.settings.phases
                 and Phase.explain in self.settings.phases
                 and sys.gettrace() is None
                 and not PYPY
             ):  # pragma: no cover
                 # This is in fact covered by our *non-coverage* tests,
but due to the
                 # settrace() contention *not* by our coverage tests.
Ah well.
                 tracer = Tracer()
                 try:
                     sys.settrace(tracer.trace)
                     result = self.execute_once(data)
                     if data.status == Status.VALID:

self.explain_traces[None].add(frozenset(tracer.branches))
                 finally:
                     sys.settrace(None)
                     trace = frozenset(tracer.branches)
             else:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f8087d21b10>
data = ConjectureData(VALID, 0 bytes, frozen), print_example = False
is_final = False, expected_failure = None

     def execute_once(
         self, data, print_example=False, is_final=False,
expected_failure=None
     ):
         """Run the test function once, using ``data`` as input.
             If the test raises an exception, it will propagate through
to the
         caller of this method. Depending on its type, this could represent
         an ordinary test failure, or a fatal error, or a control exception.
             If this method returns normally, the test might have passed, or
         it might have placed ``data`` in an unsuccessful state and then
         swallowed the corresponding control exception.
         """
             self.ever_executed = True
         data.is_find = self.is_find
             text_repr = None
         if self.settings.deadline is None:
             test = self.test
         else:
                 @proxies(self.test)
             def test(*args, **kwargs):
                 self.__test_runtime = None
                 initial_draws = len(data.draw_times)
                 start = time.perf_counter()
                 result = self.test(*args, **kwargs)
                 finish = time.perf_counter()
                 internal_draw_time = sum(data.draw_times[initial_draws:])
                 runtime = datetime.timedelta(
                     seconds=finish - start - internal_draw_time
                 )
                 self.__test_runtime = runtime
                 current_deadline = self.settings.deadline
                 if not is_final:
                     current_deadline = (current_deadline // 4) * 5
                 if runtime >= current_deadline:
                     raise DeadlineExceeded(runtime, self.settings.deadline)
                 return result
             def run(data):
             # Set up dynamic context needed by a single test run.
             with local_settings(self.settings):
                 with deterministic_PRNG():
                     with BuildContext(data, is_final=is_final) as context:
                             # Generate all arguments to the test function.
                         args, kwargs = data.draw(self.search_strategy)
                         if expected_failure is not None:
                             nonlocal text_repr
                             text_repr = repr_call(test, args, kwargs)
                             if print_example or current_verbosity() >=
Verbosity.verbose:
                             output = StringIO()
                                 printer = RepresentationPrinter(output,
context=context)
                             if print_example:
                                 printer.text("Falsifying example:")
                             else:
                                 printer.text("Trying example:")
                                 if self.print_given_args:
                                 printer.text(" ")
                                 printer.repr_call(
                                     test.__name__,
                                     args,
                                     kwargs,
                                     force_split=True,
                                 )
                             report(printer.getvalue())
                         return test(*args, **kwargs)
             # Run the test function once, via the executor hook.
         # In most cases this will delegate straight to `run(data)`.

/usr/lib/python3/dist-packages/hypothesis/core.py:818: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)
function = <function
StateForActualGivenExecution.execute_once.<locals>.run at 0x7f80889f7740>

     def default_new_style_executor(data, function):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)

     def run(data):
         # Set up dynamic context needed by a single test run.
         with local_settings(self.settings):
             with deterministic_PRNG():
                 with BuildContext(data, is_final=is_final) as context:
                         # Generate all arguments to the test function.
                     args, kwargs = data.draw(self.search_strategy)
                     if expected_failure is not None:
                         nonlocal text_repr
                         text_repr = repr_call(test, args, kwargs)
                         if print_example or current_verbosity() >=
Verbosity.verbose:
                         output = StringIO()
                             printer = RepresentationPrinter(output,
context=context)
                         if print_example:
                             printer.text("Falsifying example:")
                         else:
                             printer.text("Trying example:")
                             if self.print_given_args:
                             printer.text(" ")
                             printer.repr_call(
                                 test.__name__,
                                 args,
                                 kwargs,
                                 force_split=True,
                             )
                         report(printer.getvalue())

/usr/lib/python3/dist-packages/hypothesis/core.py:814: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
factory = <class 'test_hypothesis.BaseTest.test.<locals>.Machine'>
data = data(...)

     @settings
     @given(st.data())
     def run_state_machine(factory, data):
         cd = data.conjecture_data

/usr/lib/python3/dist-packages/hypothesis/stateful.py:110: _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)
             self.real.ping()
         except redis.ConnectionError:

test/test_hypothesis.py:254: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
reason = 'redis is not running'

     @_with_exception(Skipped)
     def skip(
         reason: str = "", *, allow_module_level: bool = False, msg:
Optional[str] = None
     ) -> NoReturn:
         """Skip an executing test with the given message.
             This function should be called only during testing (setup,
call or teardown) or
         during collection by using the ``allow_module_level`` flag.
This function can
         be called in doctests as well.
             :param reason:
             The message to show the user as reason for the skip.
             :param allow_module_level:
             Allows this function to be called at module level, skipping
the rest
             of the module. Defaults to False.
             :param msg:
             Same as ``reason``, but deprecated. Will be removed in a
future version, use ``reason`` instead.
             .. note::
             It is better to use the :ref:`pytest.mark.skipif ref`
marker when
             possible to declare a test to be skipped under certain
conditions
             like mismatching platforms or dependencies.
             Similarly, use the ``# doctest: +SKIP`` directive (see
:py:data:`doctest.SKIP`)
             to skip a doctest statically.
         """
         __tracebackhide__ = True
         reason = _resolve_msg_to_reason("skip", reason, msg)
/usr/lib/python3/dist-packages/_pytest/outcomes.py:175: Skipped

During handling of the above exception, another exception occurred:

self = <test_hypothesis.TestTransaction object at 0x7f80877a24d0>

     @pytest.mark.slow
     def test(self):
         class Machine(CommonMachine):
             create_command_strategy = self.create_command_strategy
             command_strategy = self.command_strategy
             # hypothesis.settings.register_profile("debug",
max_examples=10, verbosity=hypothesis.Verbosity.debug)
         # hypothesis.settings.load_profile("debug")

test/test_hypothesis.py:354: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/hypothesis/stateful.py:222: in
run_state_machine_as_test
     run_state_machine(state_machine_factory)
/usr/lib/python3/dist-packages/hypothesis/stateful.py:107: in
run_state_machine
     @given(st.data())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
     def inconsistent_generation():
             "Inconsistent data generation! Data generation behaved
differently "
             "between different runs. Is your data generation depending
on external "
             "state?"
         )
E       hypothesis.errors.Flaky: Inconsistent data generation! Data
generation behaved differently between different runs. Is your data
generation depending on external state?

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/datatree.py:29:
Flaky

                 lambda: self._connect(), lambda error:
self.disconnect(error)
             )

/usr/lib/python3/dist-packages/redis/connection.py:611: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <redis.retry.Retry object at 0x7f8088905850>
do = <function Connection.connect.<locals>.<lambda> at 0x7f80875ba660>
fail = <function Connection.connect.<locals>.<lambda> at 0x7f80875b9120>

     def call_with_retry(self, do, fail):
         """
         Execute an operation that might fail and returns its result, or
         raise the exception that was thrown depending on the `Backoff`
object.
         `do`: the operation to call. Expects no argument.
         `fail`: the failure handler, expects the last error that was thrown
         """
         self._backoff.reset()
         failures = 0
         while True:
             try:

/usr/lib/python3/dist-packages/redis/retry.py:46: _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
     )

/usr/lib/python3/dist-packages/redis/connection.py:612: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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)
                     # set the socket_timeout now that we're connected
                 sock.settimeout(self.socket_timeout)
                 return sock
                 except OSError as _:
                 err = _
                 if sock is not None:
                     sock.close()
             if err is not None:

/usr/lib/python3/dist-packages/redis/connection.py:677: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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
/usr/lib/python3/dist-packages/redis/connection.py:665:
ConnectionRefusedError

During handling of the above exception, another exception occurred:

self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)

test/test_hypothesis.py:252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
kwargs = {}

     def ping(self, **kwargs) -> ResponseT:
         """
         Ping the Redis server
             For more information see https://redis.io/commands/ping
         """

/usr/lib/python3/dist-packages/redis/commands/core.py:1132: _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
args = ('PING',), options = {}
pool = ConnectionPool<Connection<host=localhost,port=6379,db=0>>

     def execute_command(self, *args, **options):
         """Execute a command and return a parsed response"""
         pool = self.connection_pool
         command_name = args[0]

/usr/lib/python3/dist-packages/redis/client.py:1235: _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ConnectionPool<Connection<host=localhost,port=6379,db=0>>
command_name = 'PING', keys = (), options = {}
connection = Connection<host=localhost,port=6379,db=0>

     def get_connection(self, command_name, *keys, **options):
         "Get a connection from the pool"
         self._checkpid()
         with self._lock:
             try:
                 connection = self._available_connections.pop()
             except IndexError:
                 connection = self.make_connection()
             self._in_use_connections.add(connection)
             try:
             # ensure this connection is connected to Redis

/usr/lib/python3/dist-packages/redis/connection.py:1387: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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")
         except OSError as e:

/usr/lib/python3/dist-packages/redis/connection.py:617: ConnectionError

During handling of the above exception, another exception occurred:

self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f8088998550>
data = ConjectureData(VALID, 0 bytes, frozen)

     def test_function(self, data):
         if self.__pending_call_explanation is not None:
             self.debug(self.__pending_call_explanation)
             self.__pending_call_explanation = None
             assert isinstance(data.observer, TreeRecordingObserver)
         self.call_count += 1
             interrupted = False
         try:

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:209:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f8088998550>
data = ConjectureData(VALID, 0 bytes, frozen)

     def __stoppable_test_function(self, data):
         """Run ``self._test_function``, but convert a ``StopTest``
exception
         into a normal return and avoid raising Flaky for RecursionErrors.
         """
         depth = stack_depth_of_caller()
         # Because we add to the recursion limit, to be good citizens we
also add
         # a check for unbounded recursion.  The default limit is 1000,
so this can
         # only ever trigger if something really strange is happening
and it's hard
         # to imagine an intentionally-deeply-recursive use of this code.
         assert depth <= 1000, (
             "Hypothesis would usually add %d to the stack depth of %d
here, "
             "but we are already much deeper than expected.  Aborting
now, to "
             "avoid extending the stack limit in an infinite loop..."
             % (self.__recursion_limit, depth)
         )
         try:
             sys.setrecursionlimit(depth + self.__recursion_limit)

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:185:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f808899b3d0>
data = ConjectureData(VALID, 0 bytes, frozen)

     def _execute_once_for_engine(self, data):
         """Wrapper around ``execute_once`` that intercepts test failure
         exceptions and single-test control exceptions, and turns them into
         appropriate method calls to `data` instead.
             This allows the engine to assume that any exception other than
         ``StopTest`` must be a fatal error, and should stop the entire
engine.
         """
         try:
             trace = frozenset()
             if (
                 self.failed_normally
                 and not self.failed_due_to_deadline
                 and Phase.shrink in self.settings.phases
                 and Phase.explain in self.settings.phases
                 and sys.gettrace() is None
                 and not PYPY
             ):  # pragma: no cover
                 # This is in fact covered by our *non-coverage* tests,
but due to the
                 # settrace() contention *not* by our coverage tests.
Ah well.
                 tracer = Tracer()
                 try:
                     sys.settrace(tracer.trace)
                     result = self.execute_once(data)
                     if data.status == Status.VALID:

self.explain_traces[None].add(frozenset(tracer.branches))
                 finally:
                     sys.settrace(None)
                     trace = frozenset(tracer.branches)
             else:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f808899b3d0>
data = ConjectureData(VALID, 0 bytes, frozen), print_example = False
is_final = False, expected_failure = None

     def execute_once(
         self, data, print_example=False, is_final=False,
expected_failure=None
     ):
         """Run the test function once, using ``data`` as input.
             If the test raises an exception, it will propagate through
to the
         caller of this method. Depending on its type, this could represent
         an ordinary test failure, or a fatal error, or a control exception.
             If this method returns normally, the test might have passed, or
         it might have placed ``data`` in an unsuccessful state and then
         swallowed the corresponding control exception.
         """
             self.ever_executed = True
         data.is_find = self.is_find
             text_repr = None
         if self.settings.deadline is None:
             test = self.test
         else:
                 @proxies(self.test)
             def test(*args, **kwargs):
                 self.__test_runtime = None
                 initial_draws = len(data.draw_times)
                 start = time.perf_counter()
                 result = self.test(*args, **kwargs)
                 finish = time.perf_counter()
                 internal_draw_time = sum(data.draw_times[initial_draws:])
                 runtime = datetime.timedelta(
                     seconds=finish - start - internal_draw_time
                 )
                 self.__test_runtime = runtime
                 current_deadline = self.settings.deadline
                 if not is_final:
                     current_deadline = (current_deadline // 4) * 5
                 if runtime >= current_deadline:
                     raise DeadlineExceeded(runtime, self.settings.deadline)
                 return result
             def run(data):
             # Set up dynamic context needed by a single test run.
             with local_settings(self.settings):
                 with deterministic_PRNG():
                     with BuildContext(data, is_final=is_final) as context:
                             # Generate all arguments to the test function.
                         args, kwargs = data.draw(self.search_strategy)
                         if expected_failure is not None:
                             nonlocal text_repr
                             text_repr = repr_call(test, args, kwargs)
                             if print_example or current_verbosity() >=
Verbosity.verbose:
                             output = StringIO()
                                 printer = RepresentationPrinter(output,
context=context)
                             if print_example:
                                 printer.text("Falsifying example:")
                             else:
                                 printer.text("Trying example:")
                                 if self.print_given_args:
                                 printer.text(" ")
                                 printer.repr_call(
                                     test.__name__,
                                     args,
                                     kwargs,
                                     force_split=True,
                                 )
                             report(printer.getvalue())
                         return test(*args, **kwargs)
             # Run the test function once, via the executor hook.
         # In most cases this will delegate straight to `run(data)`.

/usr/lib/python3/dist-packages/hypothesis/core.py:818: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)
function = <function
StateForActualGivenExecution.execute_once.<locals>.run at 0x7f80875b9940>

     def default_new_style_executor(data, function):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)

     def run(data):
         # Set up dynamic context needed by a single test run.
         with local_settings(self.settings):
             with deterministic_PRNG():
                 with BuildContext(data, is_final=is_final) as context:
                         # Generate all arguments to the test function.
                     args, kwargs = data.draw(self.search_strategy)
                     if expected_failure is not None:
                         nonlocal text_repr
                         text_repr = repr_call(test, args, kwargs)
                         if print_example or current_verbosity() >=
Verbosity.verbose:
                         output = StringIO()
                             printer = RepresentationPrinter(output,
context=context)
                         if print_example:
                             printer.text("Falsifying example:")
                         else:
                             printer.text("Trying example:")
                             if self.print_given_args:
                             printer.text(" ")
                             printer.repr_call(
                                 test.__name__,
                                 args,
                                 kwargs,
                                 force_split=True,
                             )
                         report(printer.getvalue())

/usr/lib/python3/dist-packages/hypothesis/core.py:814: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
factory = <class 'test_hypothesis.BaseTest.test.<locals>.Machine'>
data = data(...)

     @settings
     @given(st.data())
     def run_state_machine(factory, data):
         cd = data.conjecture_data

/usr/lib/python3/dist-packages/hypothesis/stateful.py:110: _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)
             self.real.ping()
         except redis.ConnectionError:

test/test_hypothesis.py:254: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
reason = 'redis is not running'

     @_with_exception(Skipped)
     def skip(
         reason: str = "", *, allow_module_level: bool = False, msg:
Optional[str] = None
     ) -> NoReturn:
         """Skip an executing test with the given message.
             This function should be called only during testing (setup,
call or teardown) or
         during collection by using the ``allow_module_level`` flag.
This function can
         be called in doctests as well.
             :param reason:
             The message to show the user as reason for the skip.
             :param allow_module_level:
             Allows this function to be called at module level, skipping
the rest
             of the module. Defaults to False.
             :param msg:
             Same as ``reason``, but deprecated. Will be removed in a
future version, use ``reason`` instead.
             .. note::
             It is better to use the :ref:`pytest.mark.skipif ref`
marker when
             possible to declare a test to be skipped under certain
conditions
             like mismatching platforms or dependencies.
             Similarly, use the ``# doctest: +SKIP`` directive (see
:py:data:`doctest.SKIP`)
             to skip a doctest statically.
         """
         __tracebackhide__ = True
         reason = _resolve_msg_to_reason("skip", reason, msg)
/usr/lib/python3/dist-packages/_pytest/outcomes.py:175: Skipped

During handling of the above exception, another exception occurred:

self = <test_hypothesis.TestServer object at 0x7f80877a22d0>

     @pytest.mark.slow
     def test(self):
         class Machine(CommonMachine):
             create_command_strategy = self.create_command_strategy
             command_strategy = self.command_strategy
             # hypothesis.settings.register_profile("debug",
max_examples=10, verbosity=hypothesis.Verbosity.debug)
         # hypothesis.settings.load_profile("debug")

test/test_hypothesis.py:354: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/hypothesis/stateful.py:222: in
run_state_machine_as_test
     run_state_machine(state_machine_factory)
/usr/lib/python3/dist-packages/hypothesis/stateful.py:107: in
run_state_machine
     @given(st.data())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
     def inconsistent_generation():
             "Inconsistent data generation! Data generation behaved
differently "
             "between different runs. Is your data generation depending
on external "
             "state?"
         )
E       hypothesis.errors.Flaky: Inconsistent data generation! Data
generation behaved differently between different runs. Is your data
generation depending on external state?

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/datatree.py:29:
Flaky

                 lambda: self._connect(), lambda error:
self.disconnect(error)
             )

/usr/lib/python3/dist-packages/redis/connection.py:611: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <redis.retry.Retry object at 0x7f8088011d90>
do = <function Connection.connect.<locals>.<lambda> at 0x7f80889f6520>
fail = <function Connection.connect.<locals>.<lambda> at 0x7f80889f7ec0>

     def call_with_retry(self, do, fail):
         """
         Execute an operation that might fail and returns its result, or
         raise the exception that was thrown depending on the `Backoff`
object.
         `do`: the operation to call. Expects no argument.
         `fail`: the failure handler, expects the last error that was thrown
         """
         self._backoff.reset()
         failures = 0
         while True:
             try:

/usr/lib/python3/dist-packages/redis/retry.py:46: _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
     )

/usr/lib/python3/dist-packages/redis/connection.py:612: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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)
                     # set the socket_timeout now that we're connected
                 sock.settimeout(self.socket_timeout)
                 return sock
                 except OSError as _:
                 err = _
                 if sock is not None:
                     sock.close()
             if err is not None:

/usr/lib/python3/dist-packages/redis/connection.py:677: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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
/usr/lib/python3/dist-packages/redis/connection.py:665:
ConnectionRefusedError

During handling of the above exception, another exception occurred:

self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)

test/test_hypothesis.py:252: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
kwargs = {}

     def ping(self, **kwargs) -> ResponseT:
         """
         Ping the Redis server
             For more information see https://redis.io/commands/ping
         """

/usr/lib/python3/dist-packages/redis/commands/core.py:1132: _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
args = ('PING',), options = {}
pool = ConnectionPool<Connection<host=localhost,port=6379,db=0>>

     def execute_command(self, *args, **options):
         """Execute a command and return a parsed response"""
         pool = self.connection_pool
         command_name = args[0]

/usr/lib/python3/dist-packages/redis/client.py:1235: _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ConnectionPool<Connection<host=localhost,port=6379,db=0>>
command_name = 'PING', keys = (), options = {}
connection = Connection<host=localhost,port=6379,db=0>

     def get_connection(self, command_name, *keys, **options):
         "Get a connection from the pool"
         self._checkpid()
         with self._lock:
             try:
                 connection = self._available_connections.pop()
             except IndexError:
                 connection = self.make_connection()
             self._in_use_connections.add(connection)
             try:
             # ensure this connection is connected to Redis

/usr/lib/python3/dist-packages/redis/connection.py:1387: _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Connection<host=localhost,port=6379,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")
         except OSError as e:

/usr/lib/python3/dist-packages/redis/connection.py:617: ConnectionError

During handling of the above exception, another exception occurred:

self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f80880d0b50>
data = ConjectureData(VALID, 0 bytes, frozen)

     def test_function(self, data):
         if self.__pending_call_explanation is not None:
             self.debug(self.__pending_call_explanation)
             self.__pending_call_explanation = None
             assert isinstance(data.observer, TreeRecordingObserver)
         self.call_count += 1
             interrupted = False
         try:

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:209:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.internal.conjecture.engine.ConjectureRunner object at
0x7f80880d0b50>
data = ConjectureData(VALID, 0 bytes, frozen)

     def __stoppable_test_function(self, data):
         """Run ``self._test_function``, but convert a ``StopTest``
exception
         into a normal return and avoid raising Flaky for RecursionErrors.
         """
         depth = stack_depth_of_caller()
         # Because we add to the recursion limit, to be good citizens we
also add
         # a check for unbounded recursion.  The default limit is 1000,
so this can
         # only ever trigger if something really strange is happening
and it's hard
         # to imagine an intentionally-deeply-recursive use of this code.
         assert depth <= 1000, (
             "Hypothesis would usually add %d to the stack depth of %d
here, "
             "but we are already much deeper than expected.  Aborting
now, to "
             "avoid extending the stack limit in an infinite loop..."
             % (self.__recursion_limit, depth)
         )
         try:
             sys.setrecursionlimit(depth + self.__recursion_limit)

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/engine.py:185:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f80880d1110>
data = ConjectureData(VALID, 0 bytes, frozen)

     def _execute_once_for_engine(self, data):
         """Wrapper around ``execute_once`` that intercepts test failure
         exceptions and single-test control exceptions, and turns them into
         appropriate method calls to `data` instead.
             This allows the engine to assume that any exception other than
         ``StopTest`` must be a fatal error, and should stop the entire
engine.
         """
         try:
             trace = frozenset()
             if (
                 self.failed_normally
                 and not self.failed_due_to_deadline
                 and Phase.shrink in self.settings.phases
                 and Phase.explain in self.settings.phases
                 and sys.gettrace() is None
                 and not PYPY
             ):  # pragma: no cover
                 # This is in fact covered by our *non-coverage* tests,
but due to the
                 # settrace() contention *not* by our coverage tests.
Ah well.
                 tracer = Tracer()
                 try:
                     sys.settrace(tracer.trace)
                     result = self.execute_once(data)
                     if data.status == Status.VALID:

self.explain_traces[None].add(frozenset(tracer.branches))
                 finally:
                     sys.settrace(None)
                     trace = frozenset(tracer.branches)
             else:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <hypothesis.core.StateForActualGivenExecution object at
0x7f80880d1110>
data = ConjectureData(VALID, 0 bytes, frozen), print_example = False
is_final = False, expected_failure = None

     def execute_once(
         self, data, print_example=False, is_final=False,
expected_failure=None
     ):
         """Run the test function once, using ``data`` as input.
             If the test raises an exception, it will propagate through
to the
         caller of this method. Depending on its type, this could represent
         an ordinary test failure, or a fatal error, or a control exception.
             If this method returns normally, the test might have passed, or
         it might have placed ``data`` in an unsuccessful state and then
         swallowed the corresponding control exception.
         """
             self.ever_executed = True
         data.is_find = self.is_find
             text_repr = None
         if self.settings.deadline is None:
             test = self.test
         else:
                 @proxies(self.test)
             def test(*args, **kwargs):
                 self.__test_runtime = None
                 initial_draws = len(data.draw_times)
                 start = time.perf_counter()
                 result = self.test(*args, **kwargs)
                 finish = time.perf_counter()
                 internal_draw_time = sum(data.draw_times[initial_draws:])
                 runtime = datetime.timedelta(
                     seconds=finish - start - internal_draw_time
                 )
                 self.__test_runtime = runtime
                 current_deadline = self.settings.deadline
                 if not is_final:
                     current_deadline = (current_deadline // 4) * 5
                 if runtime >= current_deadline:
                     raise DeadlineExceeded(runtime, self.settings.deadline)
                 return result
             def run(data):
             # Set up dynamic context needed by a single test run.
             with local_settings(self.settings):
                 with deterministic_PRNG():
                     with BuildContext(data, is_final=is_final) as context:
                             # Generate all arguments to the test function.
                         args, kwargs = data.draw(self.search_strategy)
                         if expected_failure is not None:
                             nonlocal text_repr
                             text_repr = repr_call(test, args, kwargs)
                             if print_example or current_verbosity() >=
Verbosity.verbose:
                             output = StringIO()
                                 printer = RepresentationPrinter(output,
context=context)
                             if print_example:
                                 printer.text("Falsifying example:")
                             else:
                                 printer.text("Trying example:")
                                 if self.print_given_args:
                                 printer.text(" ")
                                 printer.repr_call(
                                     test.__name__,
                                     args,
                                     kwargs,
                                     force_split=True,
                                 )
                             report(printer.getvalue())
                         return test(*args, **kwargs)
             # Run the test function once, via the executor hook.
         # In most cases this will delegate straight to `run(data)`.

/usr/lib/python3/dist-packages/hypothesis/core.py:818: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)
function = <function
StateForActualGivenExecution.execute_once.<locals>.run at 0x7f80889f6e80>

     def default_new_style_executor(data, function):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = ConjectureData(VALID, 0 bytes, frozen)

     def run(data):
         # Set up dynamic context needed by a single test run.
         with local_settings(self.settings):
             with deterministic_PRNG():
                 with BuildContext(data, is_final=is_final) as context:
                         # Generate all arguments to the test function.
                     args, kwargs = data.draw(self.search_strategy)
                     if expected_failure is not None:
                         nonlocal text_repr
                         text_repr = repr_call(test, args, kwargs)
                         if print_example or current_verbosity() >=
Verbosity.verbose:
                         output = StringIO()
                             printer = RepresentationPrinter(output,
context=context)
                         if print_example:
                             printer.text("Falsifying example:")
                         else:
                             printer.text("Trying example:")
                             if self.print_given_args:
                             printer.text(" ")
                             printer.repr_call(
                                 test.__name__,
                                 args,
                                 kwargs,
                                 force_split=True,
                             )
                         report(printer.getvalue())

/usr/lib/python3/dist-packages/hypothesis/core.py:814: _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
factory = <class 'test_hypothesis.BaseTest.test.<locals>.Machine'>
data = data(...)

     @settings
     @given(st.data())
     def run_state_machine(factory, data):
         cd = data.conjecture_data

/usr/lib/python3/dist-packages/hypothesis/stateful.py:110: _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Machine({})

     def __init__(self):
         super().__init__()
         try:
             self.real = redis.StrictRedis('localhost', port=6379)
             self.real.ping()
         except redis.ConnectionError:

test/test_hypothesis.py:254: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
reason = 'redis is not running'

     @_with_exception(Skipped)
     def skip(
         reason: str = "", *, allow_module_level: bool = False, msg:
Optional[str] = None
     ) -> NoReturn:
         """Skip an executing test with the given message.
             This function should be called only during testing (setup,
call or teardown) or
         during collection by using the ``allow_module_level`` flag.
This function can
         be called in doctests as well.
             :param reason:
             The message to show the user as reason for the skip.
             :param allow_module_level:
             Allows this function to be called at module level, skipping
the rest
             of the module. Defaults to False.
             :param msg:
             Same as ``reason``, but deprecated. Will be removed in a
future version, use ``reason`` instead.
             .. note::
             It is better to use the :ref:`pytest.mark.skipif ref`
marker when
             possible to declare a test to be skipped under certain
conditions
             like mismatching platforms or dependencies.
             Similarly, use the ``# doctest: +SKIP`` directive (see
:py:data:`doctest.SKIP`)
             to skip a doctest statically.
         """
         __tracebackhide__ = True
         reason = _resolve_msg_to_reason("skip", reason, msg)
/usr/lib/python3/dist-packages/_pytest/outcomes.py:175: Skipped

During handling of the above exception, another exception occurred:

self = <test_hypothesis.TestJoint object at 0x7f80877a0590>

     @pytest.mark.slow
     def test(self):
         class Machine(CommonMachine):
             create_command_strategy = self.create_command_strategy
             command_strategy = self.command_strategy
             # hypothesis.settings.register_profile("debug",
max_examples=10, verbosity=hypothesis.Verbosity.debug)
         # hypothesis.settings.load_profile("debug")

test/test_hypothesis.py:354: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/hypothesis/stateful.py:222: in
run_state_machine_as_test
     run_state_machine(state_machine_factory)
/usr/lib/python3/dist-packages/hypothesis/stateful.py:107: in
run_state_machine
     @given(st.data())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _
     def inconsistent_generation():
             "Inconsistent data generation! Data generation behaved
differently "
             "between different runs. Is your data generation depending
on external "
             "state?"
         )
E       hypothesis.errors.Flaky: Inconsistent data generation! Data
generation behaved differently between different runs. Is your data
generation depending on external state?

/usr/lib/python3/dist-packages/hypothesis/internal/conjecture/datatree.py:29:
Flaky
=============================== warnings summary
===============================
test/test_fakeredis6.py::test_hmset_empty_raises_error[StrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1551:
DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.
     r.hmset('foo', {})

test/test_fakeredis6.py::test_hmset_empty_raises_error[FakeStrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1551:
DeprecationWarning: FakeStrictRedis.hmset() is deprecated. Use
FakeStrictRedis.hset() instead.
     r.hmset('foo', {})

test/test_fakeredis6.py::test_hmset[StrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1556:
DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.
     assert r.hmset('foo', {'k2': 'v2', 'k3': 'v3'}) is True

test/test_fakeredis6.py::test_hmset[FakeStrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1556:
DeprecationWarning: FakeStrictRedis.hmset() is deprecated. Use
FakeStrictRedis.hset() instead.
     assert r.hmset('foo', {'k2': 'v2', 'k3': 'v3'}) is True

test/test_fakeredis6.py::test_hmset_wrong_type[StrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1562:
DeprecationWarning: Redis.hmset() is deprecated. Use Redis.hset() instead.
     r.hmset('foo', {'key': 'value'})

test/test_fakeredis6.py::test_hmset_wrong_type[FakeStrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:1562:
DeprecationWarning: FakeStrictRedis.hmset() is deprecated. Use
FakeStrictRedis.hset() instead.
     r.hmset('foo', {'key': 'value'})

test/test_fakeredis6.py::TestFakeStrictRedisConnectionErrors::test_hmset[FakeStrictRedis]

/tmp/autopkgtest-lxc.69r6mpxc/downtmp/build.0Ds/src/test/test_fakeredis6.py:4443:
DeprecationWarning: FakeStrictRedis.hmset() is deprecated. Use
FakeStrictRedis.hset() instead.
     r.hmset('name', {'key': 1})

#1030600#14
Date:
2023-02-06 18:46:52 UTC
From:
To:
Paul Gevers wrote:

Just had a stab at this. Unfortunately, I tried updating the
python-fakeredis package to the latest upstream version (hey, it worked
before!), but I believe I get the same errors.

Some thoughts:

* I wonder if this is a compatibility issue with python3-redis; a few
  issues on upstream's Github project seem to suggest the two projects
  are more interconnected that one might initially believe.

* Here are the release notes for Redis, showing the difference between
  7.0.7 in testing and 7.0.8 in unstable:
https://raw.githubusercontent.com/redis/redis/7.0/00-RELEASENOTES


Regards,

#1030600#19
Date:
2023-02-22 00:02:21 UTC
From:
To:
Control: tags -1 ftbfs
Control: affects -1 src:beaker

beaker has a FTBFS that looks similar, without fakeredis installed:
https://buildd.debian.org/status/logs.php?pkg=beaker&ver=1.12.1-1

cu
Adrian

#1030600#30
Date:
2023-03-20 11:52:42 UTC
From:
To:
Adrian Bunk wrote:
[…]

Putting aside the question of the beaker FTBFS for a second, this
issue (ie. #1030600, ie. preventing redis from migrating…) is, as I
now believe, caused by the python-fakeredis testsuite being flaky.

I can reproduce this fairly easily:

  $ PYTHONPATH=. python3.11 -Wd -m pytest -v test/test_hypothesis.py::TestString::test
  […]
  test/test_hypothesis.py::TestString::test PASSED
  ======== 1 passed in 6.20s =========

  $ PYTHONPATH=. python3.11 -Wd -m pytest -v test/test_hypothesis.py::TestString::test
  […]
  test/test_hypothesis.py::TestString::test PASSED
  ======== 1 passed in 6.20s =========

  $ PYTHONPATH=. python3.11 -Wd -m pytest -v test/test_hypothesis.py::TestString::test
  […]
  test/test_hypothesis.py::TestString::test FAILED
  […]

In fact, Hypothesis is actually detecting this flakiness:

  E       hypothesis.errors.Flaky: Inconsistent data generation! Data
          generation behaved differently between different runs. Is
          your data generation depending on external state?

There might be other issues with redis (eg. the beaker FTBFS perhaps),
but given that the fakeredis testsuite is currently nondeterministic,
it's difficult to have something solid to reason from. :)

(For the avoidance of doubt, I don't maintain python-fakeredis.)


Best wishes,

#1030600#35
Date:
2023-03-28 19:57:44 UTC
From:
To:
reassign 1030600 src:redis 5:7.0.8-2
affects 1030600 src:python-fakeredis
fixed 1030600 5:7.0.10-1
done 1030600
thanks

Apparently redis reverted or fixed the issue.

Paul