Что нарушает протоколирование в AsyncWebsocketConsumer?
У меня есть проект Django, который использует Channels для связи через websocket, и я наткнулся на то, что, как мне кажется, может быть ошибкой, но я не уверен, поэтому я надеюсь, что кто-то, кто понимает это лучше, чем я, может помочь объяснить, что здесь происходит:
Сообщение об ошибке теста:
AssertionError: "INFO:websocket.camera_consumer:Doesn't work" not found in ['INFO:websocket.camera_consumer:Works']
Тест, который не удался:
class TestCameraConsumerTests(TransactionTestCase):
async def test_fails(self):
communicator = WebsocketCommunicator(TestConsumer.as_asgi(), '/ws/device')
with self.assertLogs(f'websocket.camera_consumer', level=logging.INFO) as logs:
await communicator.connect(timeout=10)
await communicator.disconnect()
self.assertIn(f"INFO:websocket.camera_consumer:Doesn't work", logs.output)
websocket.camera_consumer.py
:
import logging
from channels.generic.websocket import AsyncWebsocketConsumer
def sync_function():
pass
class TestConsumer(AsyncWebsocketConsumer):
async def connect(self):
await super().connect()
logger = logging.getLogger(__name__)
logger.info("Works")
await sync_to_async(sync_function)()
logger.info("Doesn't work")
Что я узнал за это время:
- Перемещение вызова getLogger за пределы функции
connect
не исправляет ситуацию .
- Перемещение вызова
super
ниже вызоваsync_to_async
исправляет проблему - Удаление функции
sync_to_async
(и превращениеsync_function
в async) также исправляет ситуацию .
- Где-то в процессе вызова функции
sync_to_async
объект обработчика логгеров, который инжектируетassertLogs
, удаляется, поэтому первое сообщение лога попадает в тест, а второе - нет .
- Я попытался проследить за вызовом sync_to_async, но не могу понять, как отслеживать объект логгера внутри цикла async (я все еще относительно новичок в коде async, поэтому не очень хорошо разбираюсь в том, как он работает под капотом).