def test_sentry_integration(client, monkeypatch, caplog, mocker):
    """
    Tests the sentry integration
    """
    from sentry_sdk.scope import Scope
    from django_guid.integrations import SentryIntegration
    from django_guid.config import settings as guid_settings

    monkeypatch.setattr(guid_settings, 'INTEGRATIONS', [SentryIntegration()])
    mock_scope = mocker.patch.object(Scope, 'set_tag')

    client.get('/api', **{'HTTP_Correlation-ID': '97c304252fd14b25b72d6aee31565842'})
    expected = [
        (None, 'Correlation-ID found in the header: 97c304252fd14b25b72d6aee31565842'),
        (None, '97c304252fd14b25b72d6aee31565842 is a valid GUID'),
        ('97c304252fd14b25b72d6aee31565842', 'Running integration: `SentryIntegration`'),
        ('97c304252fd14b25b72d6aee31565842', 'Setting Sentry transaction_id to 97c304252fd14b25b72d6aee31565842'),
        ('97c304252fd14b25b72d6aee31565842', 'This is a DRF view log, and should have a GUID.'),
        ('97c304252fd14b25b72d6aee31565842', 'Some warning in a function'),
        ('97c304252fd14b25b72d6aee31565842', 'Running tear down for integration: `SentryIntegration`'),
        ('97c304252fd14b25b72d6aee31565842', 'Received signal `request_finished`'),
        ('97c304252fd14b25b72d6aee31565842', 'Deleting 97c304252fd14b25b72d6aee31565842 from _guid'),
    ]
    mock_scope.assert_called_with('transaction_id', '97c304252fd14b25b72d6aee31565842')
    assert [(x.correlation_id, x.message) for x in caplog.records] == expected
예제 #2
0
def test_non_callable_methods(monkeypatch, subtests):
    """
    Tests that an exception is raised when any of the integration base methods are non-callable.
    """
    from django_guid.integrations import SentryIntegration
    from django.conf import settings
    from django_guid.config import Settings

    mock_integration = SentryIntegration()

    to_test = [
        {
            'function_name': 'cleanup',
            'error': 'Integration method `cleanup` needs to be made callable for `SentryIntegration`.',
        },
        {
            'function_name': 'run',
            'error': 'Integration method `run` needs to be made callable for `SentryIntegration`.',
        },
        {
            'function_name': 'setup',
            'error': 'Integration method `setup` needs to be made callable for `SentryIntegration`.',
        },
    ]

    for test in to_test:
        setattr(mock_integration, test.get('function_name'), 'test')
        monkeypatch.setattr(settings, 'DJANGO_GUID', {'INTEGRATIONS': [mock_integration]})
        with subtests.test(msg=f'Testing function {test.get("function_name")}'):
            with pytest.raises(ImproperlyConfigured, match=test.get('error')):
                Settings()
예제 #3
0
def test_missing_identifier(monkeypatch):
    """
    Tests that an exception is raised when identifier is missing.
    """
    from django_guid.integrations import SentryIntegration

    monkeypatch.setattr(SentryIntegration, 'identifier', None)
    with pytest.raises(ImproperlyConfigured, match='`identifier` cannot be None'):
        SentryIntegration()
예제 #4
0
def test_missing_run_method(monkeypatch, client):
    """
    Tests that an exception is raised when the run method has not been defined.
    """
    from django_guid.config import settings as guid_settings
    from django_guid.integrations import SentryIntegration

    monkeypatch.delattr(SentryIntegration, 'run')
    monkeypatch.setattr(guid_settings, 'INTEGRATIONS', [SentryIntegration()])
    with pytest.raises(ImproperlyConfigured, match='The integration `SentryIntegration` is missing a `run` method'):
        client.get('/api')
def test_sentry_validation(client, monkeypatch):
    """
    Tests that the package handles multiple header values by defaulting to one and logging a warning.
    """
    import sys
    from django_guid.integrations import SentryIntegration
    from django_guid.config import Settings
    from django.conf import settings

    # Mock away the sentry_sdk dependency
    sys.modules['sentry_sdk'] = None

    monkeypatch.setattr(settings, 'DJANGO_GUID', {'INTEGRATIONS': [SentryIntegration()]})
    with pytest.raises(
        ImproperlyConfigured,
        match='The package `sentry-sdk` is required for extending your tracing IDs to Sentry. '
        'Please run `pip install sentry-sdk` if you wish to include this integration.',
    ):
        Settings()
예제 #6
0
 def validate(self) -> None:
     if not isinstance(self.use_django_logging, bool):
         raise ImproperlyConfigured(
             'The CeleryIntegration use_django_logging setting must be a boolean.'
         )
     if not isinstance(self.log_parent, bool):
         raise ImproperlyConfigured(
             'The CeleryIntegration log_parent setting must be a boolean.')
     if type(self.uuid_length
             ) is not int or not 1 <= self.uuid_length <= 32:
         raise ImproperlyConfigured(
             'The CeleryIntegration uuid_length setting must be an integer.'
         )
     if not isinstance(self.sentry_integration, bool):
         raise ImproperlyConfigured(
             'The CeleryIntegration sentry_integration setting must be a boolean.'
         )
     if self.sentry_integration:
         SentryIntegration().setup()
def test_missing_run_method(monkeypatch, client):
    """
    Tests that an exception is raised when the run method has not been defined.
    """
    from django_guid.integrations import SentryIntegration

    monkeypatch.delattr(SentryIntegration, 'run')
    mocked_settings = deepcopy(django_settings.DJANGO_GUID)
    mocked_settings['INTEGRATIONS'] = [SentryIntegration()]

    with override_settings(DJANGO_GUID=mocked_settings):
        settings = Settings()
        monkeypatch.setattr('django_guid.middleware.settings', settings)
        with pytest.raises(
                ImproperlyConfigured,
                match=
                'The integration `SentryIntegration` is missing a `run` method'
        ):
            client.get('/api')
import sys

from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings

import pytest
from sentry_sdk.scope import Scope

from django_guid.config import Settings
from django_guid.integrations import SentryIntegration

mocked_settings = {
    'GUID_HEADER_NAME': 'Correlation-ID',
    'VALIDATE_GUID': True,
    'INTEGRATIONS': [SentryIntegration()],
    'IGNORE_URLS': ['no-guid'],
}


def test_sentry_integration(client, caplog, mocker, monkeypatch):
    """
    Tests the sentry integration
    """
    mock_scope = mocker.patch.object(Scope, 'set_tag')
    with override_settings(DJANGO_GUID=mocked_settings):
        settings = Settings()
        monkeypatch.setattr('django_guid.middleware.settings', settings)
        client.get(
            '/api',
            **{'HTTP_Correlation-ID': '97c304252fd14b25b72d6aee31565842'})
        expected = [
예제 #9
0
    },
]

# fmt: off

# OBS: No setting in Django GUID is required. These are example settings.
DJANGO_GUID = {
    'GUID_HEADER_NAME': 'Correlation-ID',
    'VALIDATE_GUID': True,
    'INTEGRATIONS': [
        CeleryIntegration(
            use_django_logging=True,
            log_parent=True,
            uuid_length=10
        ),
        SentryIntegration()
    ],
    'IGNORE_URLS': ['no-guid'],
}

# Set up logging for the project
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'correlation_id': {'()': 'django_guid.log_filters.CorrelationId'},  # <-- Add correlation ID
        'celery_tracing': {'()': 'django_guid.integrations.celery.log_filters.CeleryTracing'},  # <-- Add celery IDs
    },
    'formatters': {
        # Basic log format without django-guid filters
        'basic_format': {'format': '%(levelname)s %(asctime)s %(name)s - %(message)s'},