1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
# -*- coding: utf-8 -*-
# thumbor imaging service
# https://github.com/thumbor/thumbor/wiki
# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 globo.com thumbor@googlegroups.com
from preggy import expect
from sentry_sdk import Hub
from sentry_sdk.transport import Transport
from tests.base import TestCase
from thumbor import __version__
from thumbor.config import Config
from thumbor.context import ServerParameters
from thumbor.server import get_importer
class MockTransport(Transport):
"""
Transport that stores events in memory instead of sending them to Sentry.
"""
def __init__(self, options=None):
super().__init__(options=options)
self.captured_events = []
def capture_event(self, event):
self.captured_events.append(event)
class FakeRequest:
def __init__(self):
self.headers = {
"header1": "value1",
"Cookie": "cookie1=value; cookie2=value2;",
}
self.url = "test/"
self.method = "GET"
self.arguments = []
self.body = "body"
self.query = "a=1&b=2"
self.remote_ip = "127.0.0.1"
def full_url(self):
return f"http://test/{self.url}"
class FakeHandler:
def __init__(self):
self.request = FakeRequest()
class InvalidSentryTestCase(TestCase):
def get_importer(self):
return get_importer(self.config)
def test_when_missing_dsn(self):
self.config = Config(
SECURITY_KEY="ACME-SEC",
USE_CUSTOM_ERROR_HANDLING=True,
ERROR_HANDLER_MODULE="thumbor.error_handlers.sentry",
)
with expect.error_to_happen(RuntimeError):
self.get_importer()
def test_when_invalid_path(self):
self.config = Config(
SECURITY_KEY="ACME-SEC",
USE_CUSTOM_ERROR_HANDLING=True,
SENTRY_DSN_URL="https://key@sentry.io/12345",
ERROR_HANDLER_MODULE="thumbor.error_handlers.invalid",
)
with expect.error_to_happen(ImportError):
self.get_importer()
class SentryTestCase(TestCase):
def setUp(self):
super().setUp()
self.app = self.get_app()
self.transport_mock = MockTransport()
Hub.current.client.transport = self.transport_mock
self.http_handler = FakeHandler()
def get_server(self):
server = ServerParameters(
8889, "localhost", "thumbor.conf", None, "info", None
)
server.security_key = "ACME-SEC"
return server
def get_config(self):
return Config(
SECURITY_KEY="ACME-SEC",
SENTRY_DSN_URL="https://key@sentry.io/12345",
USE_CUSTOM_ERROR_HANDLING=True,
ERROR_HANDLER_MODULE="thumbor.error_handlers.sentry",
SENTRY_ENVIRONMENT="env",
)
def get_importer(self):
return get_importer(self.config)
def test_when_error_occurs_should_have_called_client(self):
self.importer.error_handler.handle_error(
self.context, self.http_handler, RuntimeError("Test")
)
expect(self.transport_mock.captured_events).not_to_be_empty()
expect(self.transport_mock.captured_events).to_length(1)
event = self.transport_mock.captured_events[0]
expect(event["exception"]["values"][0]["type"]).to_equal(
"RuntimeError"
)
expect(event["environment"]).to_equal("env")
expect(event).to_include("extra")
expect(event).to_include("request")
request, extra = event["request"], event["extra"]
expect(extra).to_include("thumbor-version")
expect(extra["thumbor-version"]).to_equal(__version__)
expect(extra).to_include("thumbor-loader")
expect(extra["thumbor-loader"]).to_equal(self.config.LOADER)
expect(extra).to_include("thumbor-storage")
expect(extra["thumbor-storage"]).to_equal(self.config.STORAGE)
expect(request).to_include("headers")
expect(request["headers"]).to_length(2)
expect(request["headers"]).to_include("Cookie")
expect(request["headers"]["Cookie"]).to_equal("[Filtered]")
expect(request["headers"]["header1"]).to_equal("value1")
expect(request["query_string"]).to_equal("a=1&b=2")
expect(event["modules"]).not_to_be_empty()
|