Skip to content

Commit

Permalink
Merge pull request #6 from nvllsvm/routing
Browse files Browse the repository at this point in the history
Add support for Tornado >= 4.5
  • Loading branch information
gmr committed Nov 22, 2018
2 parents 66fc155 + b951e55 commit 0e6eb02
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ env2
env3
.idea
docs/_build
.tox
.coverage*
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python:
install:
- pip install -r requires/testing.txt
- pip install wheel
script: nosetests --with-coverage
script: tox
after_success:
- codecov
deploy:
Expand Down
1 change: 1 addition & 0 deletions requires/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ nose>=1.3,<2
coverage>=4.1,<5
codecov
pycurl==7.43.0
tox>=2.9,<3
-r installation.txt
53 changes: 45 additions & 8 deletions sprockets_influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
logging.critical('Could not import Tornado')
concurrent, httpclient, ioloop = None, None, None

try:
from tornado import routing
except ImportError: # Not needed for Tornado<4.5
pass


version_info = (2, 1, 0)
__version__ = '.'.join(str(v) for v in version_info)
__all__ = ['__version__', 'version_info', 'add_measurement', 'flush',
Expand Down Expand Up @@ -100,15 +106,46 @@ def __init__(self, application, request, **kwargs):
handler = '{}.{}'.format(self.__module__, self.__class__.__name__)
self.influxdb.set_tags({'handler': handler,
'method': request.method})
for host, handlers in application.handlers:
if not host.match(request.host):
continue

pattern = None
if hasattr(application, 'handlers'):
pattern = self._get_path_pattern_tornado4()
else:
pattern = self._get_path_pattern_tornado45()
if pattern:
endpoint = pattern.rstrip('$')
else:
LOGGER.warning('Unable to determine routing pattern')
endpoint = request.path
self.influxdb.set_tags({'endpoint': endpoint})

def _get_path_pattern_tornado4(self):
"""Return the path pattern used when routing a request. (Tornado<4.5)
:rtype: str
"""
for host, handlers in self.application.handlers:
if host.match(self.request.host):
for handler in handlers:
match = handler.regex.match(request.path)
if match:
self.influxdb.set_tag(
'endpoint', handler.regex.pattern.rstrip('$'))
break
if handler.regex.match(self.request.path):
return handler.regex.pattern

def _get_path_pattern_tornado45(self, router=None):
"""Return the path pattern used when routing a request. (Tornado>=4.5)
:param tornado.routing.Router router: (Optional) The router to scan.
Defaults to the application's router.
:rtype: str
"""
if router is None:
router = self.application.default_router
for rule in router.rules:
if rule.matcher.match(self.request) is not None:
if isinstance(rule.matcher, routing.PathMatches):
return rule.matcher.regex.pattern
elif isinstance(rule.target, routing.Router):
return self._get_path_pattern_tornado45(rule.target)

def on_finish(self):
if _enabled:
Expand Down
66 changes: 66 additions & 0 deletions tests/mixin_tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import mock
import socket
import time
import unittest

import tornado

from . import base

Expand Down Expand Up @@ -66,3 +70,65 @@ def test_measurement_with_param_endpoint(self):
self.assertEqual(measurement.tags['method'], 'GET')
self.assertEqual(measurement.tags['endpoint'], '/param/(?P<id>\d+)')
self.assertEqual(measurement.fields['content_length'], 13)

def test_measurement_with_specific_host(self):
self.application.add_handlers(
'some_host', [('/host/(?P<id>\d+)', base.ParamRequestHandler)])
result = self.fetch('/host/100', headers={'Host': 'some_host'})
self.assertEqual(result.code, 200)
measurement = self.get_measurement()
self.assertIsNotNone(measurement)
self.assertEqual(measurement.db, 'database-name')
self.assertEqual(measurement.name, 'my-service')
self.assertEqual(measurement.tags['status_code'], '200')
self.assertEqual(measurement.tags['method'], 'GET')
self.assertEqual(measurement.tags['endpoint'], '/host/(?P<id>\d+)')
self.assertEqual(measurement.fields['content_length'], 13)

@unittest.skipIf(tornado.version_info >= (4, 5),
'legacy routing removed in 4.5')
@mock.patch(
'sprockets_influxdb.InfluxDBMixin._get_path_pattern_tornado45')
@mock.patch(
'sprockets_influxdb.InfluxDBMixin._get_path_pattern_tornado4')
def test_mesurement_with_ambiguous_route_4(self, mock_4, mock_45):
mock_4.return_value = None
mock_45.return_value = None

result = self.fetch('/param/100')
self.assertEqual(result.code, 200)
measurement = self.get_measurement()
self.assertIsNotNone(measurement)
self.assertEqual(measurement.db, 'database-name')
self.assertEqual(measurement.name, 'my-service')
self.assertEqual(measurement.tags['status_code'], '200')
self.assertEqual(measurement.tags['method'], 'GET')
self.assertEqual(measurement.tags['endpoint'], '/param/100')
self.assertEqual(measurement.fields['content_length'], 13)

self.assertEqual(1, mock_4.call_count)
self.assertEqual(0, mock_45.call_count)

@unittest.skipIf(tornado.version_info < (4, 5),
'routing module introduced in tornado 4.5')
@mock.patch(
'sprockets_influxdb.InfluxDBMixin._get_path_pattern_tornado45')
@mock.patch(
'sprockets_influxdb.InfluxDBMixin._get_path_pattern_tornado4')
def test_mesurement_with_ambiguous_route_45(self, mock_4, mock_45):
mock_4.return_value = None
mock_45.return_value = None

result = self.fetch('/param/100')
self.assertEqual(result.code, 200)
measurement = self.get_measurement()
self.assertIsNotNone(measurement)
self.assertEqual(measurement.db, 'database-name')
self.assertEqual(measurement.name, 'my-service')
self.assertEqual(measurement.tags['status_code'], '200')
self.assertEqual(measurement.tags['method'], 'GET')
self.assertEqual(measurement.tags['endpoint'], '/param/100')
self.assertEqual(measurement.fields['content_length'], 13)

self.assertEqual(0, mock_4.call_count)
self.assertEqual(1, mock_45.call_count)
24 changes: 24 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[tox]
envlist =
tornado42
tornado45

[testenv]
setenv =
COVERAGE_FILE=.coverage.{envname}
commands =
nosetests --with-coverage

[testenv:tornado42]
deps =
coverage
mock
nose
tornado==4.2.1

[testenv:tornado45]
deps =
coverage
mock
nose
tornado==4.5.3

0 comments on commit 0e6eb02

Please sign in to comment.