coveragepy
coveragepy copied to clipboard
Missing coverage when using the "redis" library
Describe the bug When using asyncio with redis.asyncio (redispy), some lines that are definitely hit remain mysteriously uncovered, even when using a combination of different concurrency settings
To Reproduce
- Python version 3.11.4, with coverage 7.3.0 and redis 5.0.0 (OS is Ubuntu 22.04)
- My .coveragerc file:
[run]
source = .
parallel = True
concurrency =
thread
gevent
multiprocessing
(I've tried various combinations of concurrency, but I most often leave it blank. I suspect it's not even appropriate for my application, though I'm not certain)
My minimal example (coverage_test.py):
import asyncio
import redis.asyncio as redis
async def main():
client = redis.Redis()
result = await client.get('key')
print('running main')
if __name__ == '__main__':
asyncio.run(main())
print('finished main')
I issue the coverage command with a bash script (coverage.sh) as follows:
coverage erase
coverage run coverage_test.py
coverage combine
coverage html
xdg-open htmlcov/index.html
The output of the script is:
running main
finished main
And the coverage of the file looks like this:
I would expect the last print statement (which is executed, according to the output) to be marked green. I see there are some similar issues (most notably https://github.com/nedbat/coveragepy/issues/1082 and https://github.com/nedbat/coveragepy/issues/1598), but as I mentioned I haven't found a concurrency setting that mitigates this.
Is there a way to reproduce this without running a Redis instance? I get a ConnectionError.
Oh wow, that's a solid point. I don't know of a way around it at the moment, but I can look into it. Thanks for the response!
I've tried for a bit to reproduce this issue with asyncio streams (which, drilling down, seems to be where the issue comes up). I haven't been able to do it with just the naive echo client/server that python's documentation lays out. There's something here happening that seems specific to redis-py, and I don't know how to reproduce the issue without a redis instance running :/. I've left an inquiry on their project (basically the same information as here, but with a longer example included, as well) - I'm hoping they have some insights: https://github.com/redis/redis-py/issues/2912
I saw that python released a new version for python 3.11.5. I've tried everything again with this new version. I still see the same behavior in coverage, but I am now seeing an additional traceback from redis as the script closes. I thought it might be related to this line of missing coverage. I'm including it here:
Exception ignored in: <function StreamWriter.del at 0x7fcd228adb20> Traceback (most recent call last): File "/usr/local/lib/python3.11/asyncio/streams.py", line 396, in del self.close() File "/usr/local/lib/python3.11/asyncio/streams.py", line 344, in close return self._transport.close() ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 860, in close self._loop.call_soon(self._call_connection_lost, None) File "/usr/local/lib/python3.11/asyncio/base_events.py", line 761, in call_soon self._check_closed() File "/usr/local/lib/python3.11/asyncio/base_events.py", line 519, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed
Is there a way to reproduce this without running a Redis instance? I get a ConnectionError.
I'm seeing it using fakeredis, which is what I use to test redis code.
I'm seeing it using fakeredis, which is what I use to test redis code.
Any chance you can give us a way to reproduce it?
I'm seeing it using fakeredis, which is what I use to test redis code.
Any chance you can give us a way to reproduce it?
This repo was setup in a hurry so things in pyproject.toml
aren't correct, but it should be good enough to demonstrate:
https://github.com/aw-was-here/redis-cov-test