|
2 | 2 | from unittest.mock import Mock |
3 | 3 |
|
4 | 4 | import pytest |
5 | | -from aiokafka.structs import ConsumerRecord |
6 | 5 | from kafka.admin import KafkaAdminClient, NewTopic |
7 | 6 | from taskiq import BrokerMessage |
8 | 7 |
|
9 | 8 | from taskiq_aio_kafka.broker import AioKafkaBroker |
10 | | -from taskiq_aio_kafka.constants import TASK_STREAM_LABEL |
11 | | -from taskiq_aio_kafka.subscriber import StreamMessage |
12 | 9 | from taskiq_aio_kafka.topic import Topic |
13 | 10 |
|
14 | 11 |
|
@@ -43,53 +40,13 @@ async def stop(self) -> None: |
43 | 40 | """Stop consumer.""" |
44 | 41 |
|
45 | 42 |
|
46 | | -class _ConsumerMock: |
47 | | - """Kafka consumer mock.""" |
48 | | - |
49 | | - def __init__(self, messages: list[ConsumerRecord[None, bytes]]) -> None: |
50 | | - self._messages = iter(messages) |
51 | | - |
52 | | - def __aiter__(self) -> "_ConsumerMock": |
53 | | - return self |
54 | | - |
55 | | - async def __anext__(self) -> ConsumerRecord[None, bytes]: |
56 | | - """Return next message.""" |
57 | | - try: |
58 | | - return next(self._messages) |
59 | | - except StopIteration as exc: |
60 | | - raise StopAsyncIteration from exc |
61 | | - |
62 | | - |
63 | 43 | def get_admin_client_mock() -> KafkaAdminClient: |
64 | 44 | """Get kafka admin client mock.""" |
65 | 45 | admin_client = Mock(spec=KafkaAdminClient) |
66 | 46 | admin_client.list_topics.return_value = [] |
67 | 47 | return admin_client |
68 | 48 |
|
69 | 49 |
|
70 | | -def build_consumer_record(topic: str, value: bytes) -> ConsumerRecord[None, bytes]: |
71 | | - """Build Kafka consumer record.""" |
72 | | - return ConsumerRecord( |
73 | | - topic=topic, |
74 | | - partition=0, |
75 | | - offset=0, |
76 | | - timestamp=0, |
77 | | - timestamp_type=0, |
78 | | - key=None, |
79 | | - value=value, |
80 | | - checksum=None, |
81 | | - serialized_key_size=0, |
82 | | - serialized_value_size=len(value), |
83 | | - headers=[], |
84 | | - ) |
85 | | - |
86 | | - |
87 | | -async def get_first_task(broker: AioKafkaBroker) -> bytes: # type: ignore[return] |
88 | | - """Get first message from the topic.""" |
89 | | - async for message in broker.listen(): |
90 | | - return message |
91 | | - |
92 | | - |
93 | 50 | async def test_task_topic_is_used_for_kick() -> None: |
94 | 51 | """Test that task is sent to its declared topic.""" |
95 | 52 | broker = AioKafkaBroker( |
@@ -295,140 +252,3 @@ def create_consumer( |
295 | 252 | await broker.shutdown() |
296 | 253 |
|
297 | 254 | assert consumer_topics == ("default-topic", "extra-topic") |
298 | | - |
299 | | - |
300 | | -async def test_subscribe_wraps_raw_topic_message() -> None: |
301 | | - """Test that raw Kafka messages are wrapped as taskiq messages.""" |
302 | | - broker = AioKafkaBroker( |
303 | | - bootstrap_servers="localhost", |
304 | | - kafka_topic="default-topic", |
305 | | - kafka_admin_client=get_admin_client_mock(), |
306 | | - ) |
307 | | - |
308 | | - @broker.task |
309 | | - async def test_task(message: str) -> None: |
310 | | - assert message |
311 | | - |
312 | | - broker.subscribe( |
313 | | - "stream-topic", |
314 | | - test_task, |
315 | | - decoder=lambda message: message.decode(), |
316 | | - ) |
317 | | - broker._aiokafka_consumer = _ConsumerMock( |
318 | | - [build_consumer_record("stream-topic", b"raw-message")], |
319 | | - ) |
320 | | - broker._is_consumer_started = True |
321 | | - |
322 | | - received_message = await get_first_task(broker) |
323 | | - taskiq_message = broker.formatter.loads(received_message) |
324 | | - |
325 | | - assert taskiq_message.task_name == test_task.task_name |
326 | | - assert taskiq_message.args == ["raw-message"] |
327 | | - assert taskiq_message.kwargs == {} |
328 | | - assert taskiq_message.labels[TASK_STREAM_LABEL] == "stream-topic" |
329 | | - |
330 | | - |
331 | | -async def test_subscribe_accepts_topic_object_and_custom_labels() -> None: |
332 | | - """Test that stream subscriptions can use Topic objects.""" |
333 | | - broker = AioKafkaBroker( |
334 | | - bootstrap_servers="localhost", |
335 | | - kafka_topic="default-topic", |
336 | | - kafka_admin_client=get_admin_client_mock(), |
337 | | - ) |
338 | | - stream_topic = Topic("stream-topic") |
339 | | - |
340 | | - @broker.task |
341 | | - async def test_task(message: bytes) -> None: |
342 | | - assert message |
343 | | - |
344 | | - broker.subscribe(stream_topic, test_task, source="external") |
345 | | - broker._aiokafka_consumer = _ConsumerMock( |
346 | | - [build_consumer_record(stream_topic.name, b"raw-message")], |
347 | | - ) |
348 | | - broker._is_consumer_started = True |
349 | | - |
350 | | - received_message = await get_first_task(broker) |
351 | | - taskiq_message = broker.formatter.loads(received_message) |
352 | | - |
353 | | - assert taskiq_message.task_name == test_task.task_name |
354 | | - assert taskiq_message.args == ["raw-message"] |
355 | | - assert taskiq_message.labels == { |
356 | | - TASK_STREAM_LABEL: stream_topic.name, |
357 | | - "source": "external", |
358 | | - } |
359 | | - |
360 | | - |
361 | | -async def test_subscribe_decoder_can_return_task_args_and_kwargs() -> None: |
362 | | - """Test that stream messages can be mapped to task args and kwargs.""" |
363 | | - broker = AioKafkaBroker( |
364 | | - bootstrap_servers="localhost", |
365 | | - kafka_topic="default-topic", |
366 | | - kafka_admin_client=get_admin_client_mock(), |
367 | | - ) |
368 | | - |
369 | | - @broker.task |
370 | | - async def test_task(user_id: int, email: str, active: bool) -> None: |
371 | | - assert user_id |
372 | | - assert email |
373 | | - assert active |
374 | | - |
375 | | - def decode_message(message: bytes) -> StreamMessage: |
376 | | - user_id, email, active = message.decode().split(":") |
377 | | - return StreamMessage( |
378 | | - args=(int(user_id),), |
379 | | - kwargs={ |
380 | | - "email": email, |
381 | | - "active": active == "true", |
382 | | - }, |
383 | | - ) |
384 | | - |
385 | | - broker.subscribe("stream-topic", test_task, decoder=decode_message) |
386 | | - broker._aiokafka_consumer = _ConsumerMock( |
387 | | - [build_consumer_record("stream-topic", b"1:user@example.com:true")], |
388 | | - ) |
389 | | - broker._is_consumer_started = True |
390 | | - |
391 | | - received_message = await get_first_task(broker) |
392 | | - taskiq_message = broker.formatter.loads(received_message) |
393 | | - |
394 | | - assert taskiq_message.task_name == test_task.task_name |
395 | | - assert taskiq_message.args == [1] |
396 | | - assert taskiq_message.kwargs == { |
397 | | - "email": "user@example.com", |
398 | | - "active": True, |
399 | | - } |
400 | | - |
401 | | - |
402 | | -def test_subscribe_adds_topic_to_broker_topics() -> None: |
403 | | - """Test that subscribed topic is included in listened topics.""" |
404 | | - broker = AioKafkaBroker( |
405 | | - bootstrap_servers="localhost", |
406 | | - kafka_topic="default-topic", |
407 | | - kafka_admin_client=get_admin_client_mock(), |
408 | | - ) |
409 | | - |
410 | | - @broker.task |
411 | | - async def test_task(message: bytes) -> None: |
412 | | - assert message |
413 | | - |
414 | | - broker.subscribe("stream-topic", test_task) |
415 | | - |
416 | | - assert set(broker._kafka_topics) == {"default-topic", "stream-topic"} |
417 | | - |
418 | | - |
419 | | -def test_subscribe_rejects_duplicate_topics() -> None: |
420 | | - """Test that stream topic cannot be subscribed twice.""" |
421 | | - broker = AioKafkaBroker( |
422 | | - bootstrap_servers="localhost", |
423 | | - kafka_topic="default-topic", |
424 | | - kafka_admin_client=get_admin_client_mock(), |
425 | | - ) |
426 | | - |
427 | | - @broker.task |
428 | | - async def test_task(message: bytes) -> None: |
429 | | - assert message |
430 | | - |
431 | | - broker.subscribe("stream-topic", test_task) |
432 | | - |
433 | | - with pytest.raises(ValueError, match="already subscribed"): |
434 | | - broker.subscribe("stream-topic", test_task) |
0 commit comments