summaryrefslogtreecommitdiff
path: root/tests/contrib/sanic/tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/contrib/sanic/tests.py')
-rw-r--r--tests/contrib/sanic/tests.py240
1 files changed, 240 insertions, 0 deletions
diff --git a/tests/contrib/sanic/tests.py b/tests/contrib/sanic/tests.py
new file mode 100644
index 0000000..52ef598
--- /dev/null
+++ b/tests/contrib/sanic/tests.py
@@ -0,0 +1,240 @@
+import json
+import logging
+import pytest
+import sys
+
+from exam import before, fixture
+from mock import patch, Mock
+
+from raven.contrib.sanic import Sentry, logging_configured
+from raven.handlers.logging import SentryHandler
+from raven.utils.testutils import InMemoryClient, TestCase
+
+
+if sys.version_info >= (3, 5):
+ from sanic import Sanic, response
+
+# When using test_client, Sanic will run the server at 127.0.0.1:42101.
+# For ease of reading, let's establish that as a constant.
+BASE_URL = '127.0.0.1:42101'
+
+def create_app(ignore_exceptions=None, debug=False, **config):
+ import os
+ app = Sanic(__name__)
+ for key, value in config.items():
+ app.config[key] = value
+
+ app.debug = debug
+
+ if ignore_exceptions:
+ app.config['RAVEN_IGNORE_EXCEPTIONS'] = ignore_exceptions
+
+ @app.route('/an-error/', methods=['GET', 'POST'])
+ def an_error(request):
+ raise ValueError('hello world')
+
+ @app.route('/log-an-error/', methods=['GET'])
+ def log_an_error(request):
+ logger = logging.getLogger('random-logger')
+ logger.error('Log an error')
+ return response.text('Hello')
+
+ @app.route('/capture/', methods=['GET', 'POST'])
+ def capture_exception(request):
+ try:
+ raise ValueError('Boom')
+ except Exception:
+ request.app.extensions['sentry'].captureException()
+ return response.text('Hello')
+
+ @app.route('/message/', methods=['GET', 'POST'])
+ def capture_message(request):
+ request.app.extensions['sentry'].captureMessage('Interesting')
+ return response.text('World')
+
+ return app
+
+@pytest.mark.skipif(sys.version_info < (3,5), reason="Requires Python 3.5+.")
+class BaseTest(TestCase):
+ @fixture
+ def app(self):
+ return create_app()
+
+ @fixture
+ def client(self):
+ return self.app.test_client
+
+ @before
+ def bind_sentry(self):
+ self.raven = InMemoryClient()
+ self.middleware = Sentry(self.app, client=self.raven)
+
+ def make_client_and_raven(self, logging=False, *args, **kwargs):
+ app = create_app(*args, **kwargs)
+ raven = InMemoryClient()
+ Sentry(app, logging=logging, client=raven)
+ return app.test_client, raven, app
+
+@pytest.mark.skipif(sys.version_info < (3,5), reason="Requires Python 3.5+.")
+class SanicTest(BaseTest):
+ def test_does_add_to_extensions(self):
+ self.assertIn('sentry', self.app.extensions)
+ self.assertEquals(self.app.extensions['sentry'], self.middleware)
+
+ def test_error_handler(self):
+ request, response = self.client.get('/an-error/')
+ self.assertEquals(response.status, 500)
+ self.assertEquals(len(self.raven.events), 1)
+
+ event = self.raven.events.pop(0)
+
+ assert 'exception' in event
+ exc = event['exception']['values'][-1]
+ self.assertEquals(exc['type'], 'ValueError')
+ self.assertEquals(exc['value'], 'hello world')
+ self.assertEquals(event['level'], logging.ERROR)
+ self.assertEquals(event['message'], 'ValueError: hello world')
+
+ def test_capture_plus_logging(self):
+ client, raven, app = self.make_client_and_raven(
+ debug=False, logging=True)
+ client.get('/an-error/')
+ client.get('/log-an-error/')
+ assert len(raven.events) == 2
+
+ def test_get(self):
+ request, response = self.client.get('/an-error/?foo=bar')
+ self.assertEquals(response.status, 500)
+ self.assertEquals(len(self.raven.events), 1)
+
+ event = self.raven.events.pop(0)
+
+ assert 'request' in event
+ http = event['request']
+ self.assertEquals(http['url'], 'http://{0}/an-error/'.format(BASE_URL))
+ self.assertEquals(http['query_string'], 'foo=bar')
+ self.assertEquals(http['method'], 'GET')
+ self.assertEquals(http['data'], {})
+ self.assertTrue('headers' in http)
+ headers = http['headers']
+ self.assertTrue('host' in headers, headers.keys())
+ self.assertEqual(headers['host'], BASE_URL)
+ self.assertTrue('user-agent' in headers, headers.keys())
+ self.assertTrue('aiohttp' in headers['user-agent'])
+
+ def test_post_form(self):
+ request, response = self.client.post('/an-error/?biz=baz', data={'foo': 'bar'})
+ self.assertEquals(response.status, 500)
+ self.assertEquals(len(self.raven.events), 1)
+ event = self.raven.events.pop(0)
+
+ assert 'request' in event
+ http = event['request']
+ self.assertEquals(http['url'], 'http://{0}/an-error/'.format(BASE_URL))
+ self.assertEquals(http['query_string'], 'biz=baz')
+ self.assertEquals(http['method'], 'POST')
+ self.assertEquals(http['data'], {'foo': ['bar']})
+ self.assertTrue('headers' in http)
+ headers = http['headers']
+ self.assertTrue('host' in headers, headers.keys())
+ self.assertEqual(headers['host'], BASE_URL)
+ self.assertTrue('user-agent' in headers, headers.keys())
+ self.assertTrue('aiohttp' in headers['user-agent'])
+
+ def test_post_json(self):
+ request, response = self.client.post(
+ '/an-error/?biz=baz', data=json.dumps({'foo': 'bar'}),
+ headers={'content-type': 'application/json'})
+ self.assertEquals(response.status, 500)
+ self.assertEquals(len(self.raven.events), 1)
+ event = self.raven.events.pop(0)
+ assert 'request' in event
+ http = event['request']
+ self.assertEquals(http['url'], 'http://{0}/an-error/'.format(BASE_URL))
+ self.assertEquals(http['query_string'], 'biz=baz')
+ self.assertEquals(http['method'], 'POST')
+ self.assertEquals(http['data'], {'foo': 'bar'})
+ self.assertTrue('headers' in http)
+ headers = http['headers']
+ self.assertTrue('host' in headers, headers.keys())
+ self.assertEqual(headers['host'], BASE_URL)
+ self.assertTrue('user-agent' in headers, headers.keys())
+ self.assertTrue('aiohttp' in headers['user-agent'])
+
+ def test_captureException_captures_http(self):
+ request, response = self.client.get('/capture/?foo=bar')
+ self.assertEquals(response.status, 200)
+ self.assertEquals(len(self.raven.events), 1)
+
+ event = self.raven.events.pop(0)
+ self.assertEquals(event['event_id'], response.headers['X-Sentry-ID'])
+
+ assert event['message'] == 'ValueError: Boom'
+ print(event)
+ assert 'request' in event
+ assert 'exception' in event
+
+ def test_captureMessage_captures_http(self):
+ request, response = self.client.get('/message/?foo=bar')
+ self.assertEquals(response.status, 200)
+ self.assertEquals(len(self.raven.events), 1)
+
+ event = self.raven.events.pop(0)
+ self.assertEquals(event['event_id'], response.headers['X-Sentry-ID'])
+
+ assert 'sentry.interfaces.Message' in event
+ assert 'request' in event
+
+ def test_captureException_sets_last_event_id(self):
+ try:
+ raise ValueError
+ except Exception:
+ self.middleware.captureException()
+ else:
+ self.fail()
+
+ event_id = self.raven.events.pop(0)['event_id']
+ assert self.middleware.last_event_id == event_id
+
+ def test_captureMessage_sets_last_event_id(self):
+ self.middleware.captureMessage('foo')
+
+ event_id = self.raven.events.pop(0)['event_id']
+ assert self.middleware.last_event_id == event_id
+
+ def test_logging_setup_signal(self):
+ app = Sanic(__name__)
+
+ mock_handler = Mock()
+
+ def receiver(sender, *args, **kwargs):
+ self.assertIn("exclude", kwargs)
+ mock_handler(*args, **kwargs)
+
+ logging_configured.connect(receiver)
+ raven = InMemoryClient()
+
+ Sentry(
+ app, client=raven, logging=True,
+ logging_exclusions=("excluded_logger",))
+
+ mock_handler.assert_called()
+
+ def test_check_client_type(self):
+ self.assertRaises(TypeError, lambda _: Sentry(self.app, "oops, I'm putting my DSN instead"))
+
+ def test_uses_dsn(self):
+ app = Sanic(__name__)
+ sentry = Sentry(app, dsn='http://public:secret@example.com/1')
+ assert sentry.client.remote.base_url == 'http://example.com'
+
+ def test_binds_default_include_paths(self):
+ app = Sanic(__name__)
+ sentry = Sentry(app, dsn='http://public:secret@example.com/1')
+ assert sentry.client.include_paths == set([app.name])
+
+ def test_overrides_default_include_paths(self):
+ app = Sanic(__name__)
+ app.config['SENTRY_CONFIG'] = {'include_paths': ['foo.bar']}
+ sentry = Sentry(app, dsn='http://public:secret@example.com/1')
+ assert sentry.client.include_paths == set(['foo.bar'])