123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- # Copyright © 2023 Ingram Micro Inc. All rights reserved.
- from unittest.mock import MagicMock
- import pytest
- from dj_cqrs._validation import validate_settings
- def test_full_configuration():
- def f(*a, **kw):
- pass
- settings = MagicMock(
- CQRS={
- 'queue': 'start',
- 'transport': 'dj_cqrs.transport.rabbit_mq.RabbitMQTransport',
- 'host': 'host',
- 'port': 1234,
- 'user': 'user',
- 'password': 'pswd',
- 'master': {
- 'CQRS_AUTO_UPDATE_FIELDS': True,
- 'CQRS_MESSAGE_TTL': 10,
- 'correlation_function': f,
- 'meta_function': f,
- },
- 'replica': {
- 'CQRS_MAX_RETRIES': 5,
- 'CQRS_RETRY_DELAY': 4,
- 'delay_queue_max_size': 2,
- },
- },
- )
- validate_settings(settings)
- def test_configuration_does_not_exist():
- with pytest.raises(AssertionError) as e:
- validate_settings({})
- assert str(e.value) == 'CQRS configuration must be set in Django project settings.'
- @pytest.mark.parametrize('value', ([], 'settings'))
- def test_configuration_has_wrong_type(value):
- with pytest.raises(AssertionError) as e:
- validate_settings(MagicMock(CQRS=value))
- assert str(e.value) == 'CQRS configuration must be dict.'
- def test_transport_is_not_set():
- with pytest.raises(AssertionError) as e:
- validate_settings(MagicMock(CQRS={}))
- assert str(e.value) == 'CQRS transport is not set.'
- def test_transport_is_not_importable():
- with pytest.raises(ImportError):
- validate_settings(MagicMock(CQRS={'transport': 'abc'}))
- def test_transport_has_wrong_inheritance():
- with pytest.raises(AssertionError) as e:
- validate_settings(MagicMock(CQRS={'transport': 'dj_cqrs.dataclasses.TransportPayload'}))
- assert str(e.value) == (
- 'CQRS transport must be inherited from `dj_cqrs.transport.BaseTransport`.'
- )
- @pytest.fixture
- def cqrs_settings():
- return MagicMock(
- CQRS={
- 'transport': 'dj_cqrs.transport.mock.TransportMock',
- 'queue': 'replica',
- },
- )
- def test_master_configuration_not_set(cqrs_settings):
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master'] == {
- 'CQRS_AUTO_UPDATE_FIELDS': False,
- 'CQRS_MESSAGE_TTL': 86400,
- 'correlation_function': None,
- 'meta_function': None,
- }
- @pytest.mark.parametrize('value', ([], 'settings', None))
- def test_master_configuration_has_wrong_type(cqrs_settings, value):
- cqrs_settings.CQRS['master'] = value
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master configuration must be dict.'
- def test_master_configuration_is_empty(cqrs_settings):
- cqrs_settings.CQRS['master'] = {}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master'] == {
- 'CQRS_AUTO_UPDATE_FIELDS': False,
- 'CQRS_MESSAGE_TTL': 86400,
- 'correlation_function': None,
- 'meta_function': None,
- }
- @pytest.mark.parametrize('value', (None, 'true', 1))
- def test_master_auto_update_fields_has_wrong_type(cqrs_settings, value):
- cqrs_settings.CQRS['master'] = {'CQRS_AUTO_UPDATE_FIELDS': value}
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master CQRS_AUTO_UPDATE_FIELDS must be bool.'
- def test_master_message_ttl_is_none(cqrs_settings):
- cqrs_settings.CQRS['master'] = {
- 'CQRS_AUTO_UPDATE_FIELDS': True,
- 'CQRS_MESSAGE_TTL': None,
- }
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master'] == {
- 'CQRS_AUTO_UPDATE_FIELDS': True,
- 'CQRS_MESSAGE_TTL': None,
- 'correlation_function': None,
- 'meta_function': None,
- }
- @pytest.mark.parametrize('value', ({}, 1.23, -2, 0))
- def test_master_message_ttl_has_wrong_type_or_invalid_value(value, cqrs_settings, caplog):
- cqrs_settings.CQRS['master'] = {'CQRS_MESSAGE_TTL': value}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master'] == {
- 'CQRS_AUTO_UPDATE_FIELDS': False,
- 'CQRS_MESSAGE_TTL': 86400,
- 'correlation_function': None,
- 'meta_function': None,
- }
- assert caplog.record_tuples
- def test_master_correlation_func_is_not_callable(cqrs_settings):
- cqrs_settings.CQRS['master'] = {'correlation_function': 'x'}
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master correlation_function must be callable.'
- def test_master_correlation_func_is_callable(cqrs_settings):
- cqrs_settings.CQRS['master'] = {'correlation_function': lambda: 1}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master']['correlation_function']() == 1
- def test_master_meta_func_is_func_from_string(cqrs_settings):
- cqrs_settings.CQRS['master'] = {'meta_function': 'tests.utils.db_error'}
- validate_settings(cqrs_settings)
- assert callable(cqrs_settings.CQRS['master']['meta_function'])
- def test_master_meta_func_is_func(cqrs_settings):
- cqrs_settings.CQRS['master'] = {'meta_function': lambda **kw: 1}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['master']['meta_function']() == 1
- def test_master_meta_func_is_non_importable_from_string(cqrs_settings):
- cqrs_settings.CQRS['master'] = {'meta_function': 'random.stuff'}
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master meta_function import error.'
- @pytest.mark.parametrize('f', ('dj_cqrs.dataclasses.TransportPayload', 5))
- def test_master_meta_func_is_not_func(cqrs_settings, f):
- cqrs_settings.CQRS['master'] = {'meta_function': f}
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master meta_function must be function.'
- @pytest.mark.parametrize('f', ('dj_cqrs.utils.get_message_expiration_dt', lambda: 1))
- def test_master_meta_func_must_support_kwargs(cqrs_settings, f):
- cqrs_settings.CQRS['master'] = {'meta_function': f}
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS master meta_function must support **kwargs.'
- def test_replica_configuration_not_set(cqrs_settings):
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica'] == {
- 'CQRS_MAX_RETRIES': 30,
- 'CQRS_RETRY_DELAY': 2,
- 'delay_queue_max_size': 1000,
- }
- @pytest.mark.parametrize('value', ([], 'settings', None))
- def test_replica_configuration_has_wrong_type(cqrs_settings, value):
- cqrs_settings.CQRS['replica'] = value
- with pytest.raises(AssertionError) as e:
- validate_settings(cqrs_settings)
- assert str(e.value) == 'CQRS replica configuration must be dict.'
- def test_replica_configuration_is_empty(cqrs_settings):
- cqrs_settings.CQRS['replica'] = {}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica'] == {
- 'CQRS_MAX_RETRIES': 30,
- 'CQRS_RETRY_DELAY': 2,
- 'delay_queue_max_size': 1000,
- }
- def test_replica_max_retries_is_none(cqrs_settings):
- cqrs_settings.CQRS['replica'] = {'CQRS_MAX_RETRIES': None}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica']['CQRS_MAX_RETRIES'] is None
- @pytest.mark.parametrize('value', ({}, 1.23, -2))
- def test_replica_max_retries_has_wrong_type_or_invalid_value(value, cqrs_settings, caplog):
- cqrs_settings.CQRS['replica'] = {
- 'CQRS_MAX_RETRIES': value,
- 'CQRS_RETRY_DELAY': 10,
- 'delay_queue_max_size': value,
- }
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica'] == {
- 'CQRS_MAX_RETRIES': 30,
- 'CQRS_RETRY_DELAY': 10,
- 'delay_queue_max_size': 1000,
- }
- assert caplog.record_tuples
- def test_replica_retry_delay_is_none(cqrs_settings):
- cqrs_settings.CQRS['replica'] = {'CQRS_RETRY_DELAY': None}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica']['CQRS_RETRY_DELAY'] == 2
- @pytest.mark.parametrize('value', ({}, 1.23, -2))
- def test_replica_retry_delay_has_wrong_type_or_invalid_value(value, cqrs_settings, caplog):
- cqrs_settings.CQRS['replica'] = {
- 'CQRS_MAX_RETRIES': 0,
- 'CQRS_RETRY_DELAY': value,
- 'delay_queue_max_size': 1,
- }
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica'] == {
- 'CQRS_MAX_RETRIES': 0,
- 'CQRS_RETRY_DELAY': 2,
- 'delay_queue_max_size': 1,
- }
- assert caplog.record_tuples
- def test_replica_delay_queue_max_size_is_none(cqrs_settings):
- cqrs_settings.CQRS['replica'] = {'delay_queue_max_size': None}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica']['delay_queue_max_size'] is None
- @pytest.mark.parametrize('value', ({}, 1.23, -2))
- def test_replica_delay_queue_max_size_has_wrong_type_or_invalid_value(value, cqrs_settings, caplog):
- cqrs_settings.CQRS['replica'] = {
- 'CQRS_RETRY_DELAY': 0,
- 'delay_queue_max_size': value,
- }
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica'] == {
- 'CQRS_MAX_RETRIES': 30,
- 'CQRS_RETRY_DELAY': 0,
- 'delay_queue_max_size': 1000,
- }
- assert caplog.record_tuples
- def test_replica_delay_queue_max_size_deprecated_parameter(cqrs_settings):
- cqrs_settings.CQRS['replica'] = {'delay_queue_max_size': 200}
- validate_settings(cqrs_settings)
- assert cqrs_settings.CQRS['replica']['delay_queue_max_size'] == 200
|