diff --git a/requires/development.txt b/requires/development.txt index e8a3b99..2df164b 100644 --- a/requires/development.txt +++ b/requires/development.txt @@ -1,3 +1,3 @@ -r testing.txt -coverage>=3.7,<4.1 +coverage==4.5.1 Sphinx diff --git a/setup.cfg b/setup.cfg index d7cd6f9..f768660 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,11 @@ universal = 1 [nosetests] cover-package = sprockets.mixins.metrics cover-branches = 1 +cover-erase = 1 +cover-html = 1 +cover-html-dir = build/coverage +cover-xml = 1 +match = ((?:^|[\b_.-])(:?[Tt]est|When|should|[Dd]escribe)) +verbosity = 2 +with-coverage = 1 +with-xunit = 1 diff --git a/sprockets/mixins/metrics/statsd.py b/sprockets/mixins/metrics/statsd.py index 2d3d972..f0e3817 100644 --- a/sprockets/mixins/metrics/statsd.py +++ b/sprockets/mixins/metrics/statsd.py @@ -120,6 +120,7 @@ class StatsDCollector(object): self._address = (self._host, self._port) self._namespace = namespace self._prepend_metric_type = prepend_metric_type + self._tcp_reconnect_sleep = 5 if protocol == 'tcp': self._tcp = True @@ -145,10 +146,9 @@ class StatsDCollector(object): @gen.engine def _tcp_on_closed(self): """Invoked when the socket is closed.""" - sleep = 5 LOGGER.warning('Not connected to statsd, connecting in %s seconds', - sleep) - yield gen.sleep(sleep) + self._tcp_reconnect_sleep) + yield gen.sleep(self._tcp_reconnect_sleep) self._sock = self._tcp_socket() def _tcp_on_connected(self): diff --git a/tests.py b/tests.py index 17c6d4e..2161d9e 100644 --- a/tests.py +++ b/tests.py @@ -44,6 +44,22 @@ def assert_between(low, value, high): value, low, high)) +class MisconfiguredStatsdMetricCollectionTests(testing.AsyncHTTPTestCase): + + def get_app(self): + self.application = web.Application([ + web.url('/', examples.statsd.SimpleHandler), + web.url('/counters/(.*)/([.0-9]*)', CounterBumper), + web.url('/status_code', DefaultStatusCode), + ]) + + def test_bad_protocol_raises_ValueError(self): + with self.assertRaises(ValueError): + statsd.StatsDCollector(host='127.0.0.1', + port=8125, + protocol='bad_protocol') + + class TCPStatsdMetricCollectionTests(testing.AsyncHTTPTestCase): def get_app(self): @@ -67,6 +83,24 @@ class TCPStatsdMetricCollectionTests(testing.AsyncHTTPTestCase): 'protocol': 'tcp', 'prepend_metric_type': True}) + def test_tcp_reconnect_on_stream_close(self): + path_sleep = 'tornado.gen.sleep' + path_statsd = self.application.statsd + with mock.patch(path_sleep) as gen_sleep, \ + patch.object(path_statsd, '_tcp_socket') as mock_tcp_socket: + f = web.Future() + f.set_result(None) + gen_sleep.return_value = f + + self.application.statsd._tcp_on_closed() + mock_tcp_socket.assert_called_once_with() + + @patch.object(iostream.IOStream, 'write') + def test_write_not_executed_when_connection_is_closed(self, mock_write): + self.application.statsd._sock.close() + self.application.statsd.send('foo', 500, 'c') + mock_write.assert_not_called() + @patch.object(iostream.IOStream, 'write') def test_expected_counters_data_written(self, mock_sock): path = ('foo', 'bar')