Open kneufeld opened 4 years ago
I am getting the same error when trying to use the aiohttp test_client to consume a single message from a mocked websocket.
I notice pytest-asyncio
in the original issue. Does everything work if pytest-asyncio
is uninstalled?
Uninstalling pytest-asyncio made no difference for me.
I am essentially doing this (distilled to bare essentials):
# Mocked websocket server handler added to mock server via 'create_app()'
async def mock_websocket(request: web.Request) -> WebSocketResponse:
ws = web.WebSocketResponse()
await ws.prepare(request)
try:
await ws.send_json(SOME_JSON)
return ws
finally:
if not ws.closed:
await ws.close()
async def test_subscribe_to_thing(test_client):
try:
test_session = await test_client(create_app)
my_client: MyClient = await _get_my_client(test_session)
async for result in my_client.subscribe_to_thing():
if result:
logger.debug(result)
assert True
return
except ClientResponseError as e:
raise pytest.fail(str(e))
MyClient.subscribe_to_thing()
has this section which errors when it triggers the __aexit__
and closes out the test_client session:
async with self.session as session: # This raises the RuntimeError on `__aexit__`
async with session.ws_connect(url, headers={}, timeout=5.0) as ws:
async for msg in ws:
content = json.loads(msg.data)
yield content
And I get the same error as OP:
RuntimeError: Site <aiohttp.web_runner.SockSite object at 0x...> is not registered in runner <aiohttp.web_runner.AppRunner object at 0x...>
I am working around this issue for now by catching the RuntimeError in my source code with a comment that this is to catch a pytest bug...
Ah! I'm a dummy. I've changed the code from:
async with self.session as session: # This raises the RuntimeError on `__aexit__`
async with session.ws_connect(url, headers={}, timeout=5.0) as ws:
async for msg in ws:
content = json.loads(msg.data)
yield content
to:
async with self.session.ws_connect(url, headers={}, timeout=5.0) as ws:
async for msg in ws:
content = json.loads(msg.data)
yield content
I was using a context manager for the cached session instance when I should not be - I want the ClientSession to hang around
I'm not clear what's surprising about the original issue. You've created a ClientSession inside a generator function and then not executed the generator to completion in order for the ClientSession to close and clean up. I would expect something to mess up there..
🐞 Describe the bug
If your test finishes before exhausting any async generators then the test appears to try and deregister twice, causing an error. Or something.
This is using
pytest
andaiohttp_client
fixture.python 3.7.7
(on osx)pytest
versions:5.3.5
and5.4.1
pytest-asyncio-0.10.0
pytest-aiohttp-0.3.0
aiohttp-3.6.2
💡 To Reproduce
The following is a distilled version of my code that I found the problem in. Search for
TOGGLE
near the end of the file for various ways to "fix" the problem. All the fixes are essentially the same.💡 Expected behaviour
Tests should pass and exit cleanly. Note the
1 passed, 1 error
even though there is only one test.📋 Logs/tracebacks
📋 Your version of the Python
📋 Your version of the aiohttp/yarl/multidict distributions
📋 Additional context
client
I think