def test_sets_client_transport_when_connected(self):
        """Set the transport as an attribute of the client."""
        self.client = TwistedStatsDClient('localhost', 8000)
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport, transport)
    def test_sets_ip_when_host_resolves(self):
        """As soon as the host is resolved, set the IP as the host."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()
        self.assertEqual(self.client.host, 'localhost')

        self.client.host_resolved('127.0.0.1')
        self.assertEqual(self.client.host, '127.0.0.1')
    def test_sets_gateway_transport_when_connected(self):
        """Set the transport as an attribute of the TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.client.host_resolved('127.0.0.1')
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport_gateway.transport, transport)
    def test_sets_transport_gateway_when_host_resolves(self):
        """As soon as the host is resolved, set the transport gateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.transport_gateway = None

        self.client.host_resolved('127.0.0.1')
        self.assertIsInstance(self.client.transport_gateway, TransportGateway)
    def test_passes_reactor_to_gateway(self):
        """The client passes the reactor to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        self.assertEqual(self.client.transport_gateway.reactor,
                         self.client.reactor)
    def test_calls_connect_callback_when_host_resolves(self):
        """As soon as the host is resolved, call back the connect_callback."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.connect_callback = Mock()

        self.client.host_resolved('127.0.0.1')
        self.assertTrue(self.client.connect_callback.called)
        self.client.connect_callback.assert_called_once_with()
    def test_sends_messages_to_queue_before_host_resolves(self):
        """Before the host is resolved, send messages to the DataQueue."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        message = 'some data'
        self.client.data_queue = Mock(spec=DataQueue)
        callback = Mock()
        self.client.data_queue.write.return_value = None
        result = self.client.write(message, callback)
        self.client.data_queue.write.assert_called_once_with(message, callback)
        self.assertEqual(result, None)
    def test_twistedstatsd_write(self):
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d
 def __init__(self,
              statsd_host="localhost",
              statsd_port=8125,
              namespace="aplt"):
     self.client = TwistedStatsDClient.create(statsd_host, statsd_port)
     self._metric = Metrics(connection=self.client, namespace=namespace)
     self._stat_protocol = None
Exemple #10
0
    def _realise_connection(cls, async):
        """Return a configured statsd client connection."""
        servers = config.statsd.servers
        if servers is None:
            raise LookupError('Unable to obtain the statsd configuration')

        servers = map(None, [server.strip() for server in servers.split(";")])
        if not servers:
            raise LookupError('Unable to obtain the statsd configuration')

        connections = []
        for server in servers:
            statsd_host, statsd_port = server.split(":")
            statsd_port = int(statsd_port)

            if async:
                connection = TwistedStatsDClient.create(
                    statsd_host, statsd_port)
                connection.disconnect_callback = \
                    lambda: cls._disconnect_connection(connection)
                protocol = StatsDClientProtocol(connection)

                from twisted.internet import reactor
                reactor.listenUDP(0, protocol)
            else:
                connection = UdpStatsDClient(statsd_host, statsd_port)
                connection.connect()

            connections.append(connection)

        if len(connections) == 1:
            return connections[0]

        return ConsistentHashingClient(connections)
    def _realise_connection(cls, async):
        """Return a configured statsd client connection."""
        servers = config.statsd.servers
        if servers is None:
            raise LookupError('Unable to obtain the statsd configuration')

        servers = map(None, [server.strip() for server in servers.split(";")])
        if not servers:
            raise LookupError('Unable to obtain the statsd configuration')

        connections = []
        for server in servers:
            statsd_host, statsd_port = server.split(":")
            statsd_port = int(statsd_port)

            if async:
                connection = TwistedStatsDClient.create(statsd_host,
                                                        statsd_port)
                connection.disconnect_callback = \
                    lambda: cls._disconnect_connection(connection)
                protocol = StatsDClientProtocol(connection)

                from twisted.internet import reactor
                reactor.listenUDP(0, protocol)
            else:
                connection = UdpStatsDClient(statsd_host, statsd_port)
                connection.connect()

            connections.append(connection)

        if len(connections) == 1:
            return connections[0]

        return ConsistentHashingClient(connections)
    def test_sends_messages_to_gateway_after_host_resolves(self):
        """After the host is resolved, send messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        message = 'some data'
        bytes_sent = len(message)
        self.client.data_queue = Mock(spec=DataQueue)
        self.client.transport_gateway = Mock(spec=TransportGateway)
        callback = Mock()
        self.client.transport_gateway.write.return_value = bytes_sent
        self.assertEqual(self.client.write(message, callback), bytes_sent)
        self.client.transport_gateway.write.assert_called_once_with(
            message, callback)
Exemple #13
0
    def test_sets_client_transport_when_connected(self):
        """Set the transport as an attribute of the client."""
        self.client = TwistedStatsDClient("localhost", 8000)
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport, transport)
Exemple #14
0
    def test_sets_ip_when_host_resolves(self):
        """As soon as the host is resolved, set the IP as the host."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()
        self.assertEqual(self.client.host, "localhost")

        self.client.host_resolved("127.0.0.1")
        self.assertEqual(self.client.host, "127.0.0.1")
Exemple #15
0
    def test_sets_gateway_transport_when_connected(self):
        """Set the transport as an attribute of the TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.client.host_resolved("127.0.0.1")
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport_gateway.transport, transport)
Exemple #16
0
    def test_passes_reactor_to_gateway(self):
        """The client passes the reactor to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        self.assertEqual(self.client.transport_gateway.reactor, self.client.reactor)
Exemple #17
0
    def test_passes_transport_to_gateway(self):
        """The client passes the transport to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        self.assertEqual(self.client.transport_gateway.transport,
                         self.client.transport)
Exemple #18
0
    def test_sets_transport_gateway_when_host_resolves(self):
        """As soon as the host is resolved, set the transport gateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.transport_gateway = None

        self.client.host_resolved("127.0.0.1")
        self.assertIsInstance(self.client.transport_gateway, TransportGateway)
Exemple #19
0
    def test_calls_connect_callback_when_host_resolves(self):
        """As soon as the host is resolved, call back the connect_callback."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.connect_callback = self.mocker.mock()
        expect(self.client.connect_callback())

        with self.mocker:
            self.client.host_resolved('127.0.0.1')
Exemple #20
0
    def test_calls_connect_callback_when_host_resolves(self):
        """As soon as the host is resolved, call back the connect_callback."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.connect_callback = Mock()

        self.client.host_resolved("127.0.0.1")
        self.assertTrue(self.client.connect_callback.called)
        self.client.connect_callback.assert_called_once_with()
Exemple #21
0
def setup_statsd(config):
    from txstatsd.client import TwistedStatsDClient, StatsDClientProtocol
    from txstatsd.metrics.metrics import Metrics
    global metrics
    statsd = TwistedStatsDClient(config['statsd']['host'],
                                 config['statsd']['port'])
    metrics = Metrics(connection=statsd,
                      namespace='smap-archiver.' + config['statsd']['prefix'])
    protocol = StatsDClientProtocol(statsd)
    reactor.listenUDP(0, protocol)
    def test_flushes_queued_messages_to_the_gateway_when_host_resolves(self):
        """As soon as the host is resolved, flush all messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.data_queue.write('data 1', 'callback 1')
        self.client.data_queue.write('data 2', 'callback 2')
        self.client.data_queue.write('data 3', 'callback 3')

        mock_gateway_write = Mock()
        self.patch(TransportGateway, 'write', mock_gateway_write)
        self.client.host_resolved('127.0.0.1')
        self.assertTrue(mock_gateway_write.call_count, 3)
        expected = [
            call('data 1', 'callback 1'),
            call('data 2', 'callback 2'),
            call('data 3', 'callback 3')
        ]
        self.assertEqual(mock_gateway_write.call_args_list, expected)
Exemple #23
0
    def test_sends_messages_to_queue_before_host_resolves(self):
        """Before the host is resolved, send messages to the DataQueue."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        message = "some data"
        self.client.data_queue = Mock(spec=DataQueue)
        callback = Mock()
        self.client.data_queue.write.return_value = None
        result = self.client.write(message, callback)
        self.client.data_queue.write.assert_called_once_with(message, callback)
        self.assertEqual(result, None)
Exemple #24
0
    def test_twistedstatsd_with_malformed_address_and_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.client = TwistedStatsDClient.create("256.0.0.0", 1, resolver_errback=capture_exception_raised)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)
Exemple #25
0
    def test_sends_messages_to_queue_before_host_resolves(self):
        """Before the host is resolved, send messages to the DataQueue."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        message = 'some data'
        bytes_sent = len(message)
        self.client.data_queue = self.mocker.mock(spec=DataQueue)
        callback = self.mocker.mock()
        expect(self.client.data_queue.write(message, callback)).result(None)

        with self.mocker:
            self.assertEqual(self.client.write(message, callback), None)
    def test_twistedstatsd_with_malformed_address_and_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.client = TwistedStatsDClient.create(
            '256.0.0.0', 1, resolver_errback=capture_exception_raised)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)
Exemple #27
0
    def test_twistedstatsd_write(self):
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len("message"))

        def exercise(callback):
            self.client.write("message", callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d
Exemple #28
0
    def test_twistedstatsd_write_with_wellformed_address(self):
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        protocol = StatsDClientProtocol(self.client)
        reactor.listenUDP(0, protocol)

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d
Exemple #29
0
    def test_sends_messages_to_gateway_after_host_resolves(self):
        """After the host is resolved, send messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        message = "some data"
        bytes_sent = len(message)
        self.client.data_queue = Mock(spec=DataQueue)
        self.client.transport_gateway = Mock(spec=TransportGateway)
        callback = Mock()
        self.client.transport_gateway.write.return_value = bytes_sent
        self.assertEqual(self.client.write(message, callback), bytes_sent)
        self.client.transport_gateway.write.assert_called_once_with(message, callback)
    def test_twistedstatsd_write_with_host_resolved(self):
        self.client = TwistedStatsDClient.create('localhost', 8000)
        self.build_protocol()
        yield self.client.resolve_later

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))
            self.assertEqual(self.client.host, '127.0.0.1')

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        yield d
Exemple #31
0
    def test_flushes_queued_messages_to_the_gateway_when_host_resolves(self):
        """As soon as the host is resolved, flush all messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.data_queue.write("data 1", "callback 1")
        self.client.data_queue.write("data 2", "callback 2")
        self.client.data_queue.write("data 3", "callback 3")

        mock_gateway_write = Mock()
        self.patch(TransportGateway, "write", mock_gateway_write)
        self.client.host_resolved("127.0.0.1")
        self.assertTrue(mock_gateway_write.call_count, 3)
        expected = [call("data 1", "callback 1"), call("data 2", "callback 2"), call("data 3", "callback 3")]
        self.assertEqual(mock_gateway_write.call_args_list, expected)
Exemple #32
0
    def test_twistedstatsd_write_with_host_resolved(self):
        self.client = TwistedStatsDClient.create("localhost", 8000)
        self.build_protocol()
        yield self.client.resolve_later

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len("message"))
            self.assertEqual(self.client.host, "127.0.0.1")

        def exercise(callback):
            self.client.write("message", callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        yield d
Exemple #33
0
    def test_sends_messages_to_gateway_after_host_resolves(self):
        """After the host is resolved, send messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        message = 'some data'
        bytes_sent = len(message)
        self.client.data_queue = self.mocker.mock(spec=DataQueue)  # not called
        self.client.transport_gateway = self.mocker.mock(spec=TransportGateway)
        callback = self.mocker.mock()
        expect(self.client.transport_gateway.write(message, callback)).result(
            bytes_sent)

        with self.mocker:
            self.assertEqual(self.client.write(message, callback), bytes_sent)
Exemple #34
0
    def test_flushes_queued_messages_to_the_gateway_when_host_resolves(self):
        """As soon as the host is resolved, flush all messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.data_queue.write('data 1', 'callback 1')
        self.client.data_queue.write('data 2', 'callback 2')
        self.client.data_queue.write('data 3', 'callback 3')

        mock_gateway_write = self.mocker.mock()
        self.patch(TransportGateway, 'write', mock_gateway_write)
        expect(mock_gateway_write('data 1', 'callback 1'))
        expect(mock_gateway_write('data 2', 'callback 2'))
        expect(mock_gateway_write('data 3', 'callback 3'))

        with self.mocker:
            self.client.host_resolved('127.0.0.1')
Exemple #35
0
    def build_target_redirect_udp(self, host, port):
        if self.service is None:
            return lambda *args: True

        port = int(port)
        d = defer.Deferred()
        self.ready.addCallback(lambda _: d)

        client = TwistedStatsDClient.create(
            host, port, connect_callback=lambda: d.callback(None))
        protocol = StatsDClientProtocol(client)

        udp_service = UDPServer(0, protocol)
        udp_service.setServiceParent(self.service)

        def redirect_udp_target(metric_type, key, fields):
            message = self.rebuild_message(metric_type, key, fields)
            client.write(message)
            yield metric_type, key, fields
        return redirect_udp_target
Exemple #36
0
    def build_target_redirect_udp(self, host, port):
        if self.service is None:
            return lambda *args: True

        port = int(port)
        d = defer.Deferred()
        self.ready.addCallback(lambda _: d)

        client = TwistedStatsDClient.create(
            host, port, connect_callback=lambda: d.callback(None))
        protocol = StatsDClientProtocol(client)

        udp_service = UDPServer(0, protocol)
        udp_service.setServiceParent(self.service)

        def redirect_udp_target(metric_type, key, fields):
            message = self.rebuild_message(metric_type, key, fields)
            client.write(message)
            yield metric_type, key, fields

        return redirect_udp_target
Exemple #37
0
def makeService(host='127.0.0.1', port=8125, sample_rate=1.0, prefix=''):
    client = TwistedStatsDClient(host, port)
    metrics = Metrics(connection=client, namespace=prefix)
    reporting = ReportingService()

    for report in PROCESS_STATS:
        reporting.schedule(report, sample_rate, metrics.gauge)

    for report in COUNTER_STATS:
        reporting.schedule(report, sample_rate, metrics.gauge)

    # Attach log observer to collect metrics for us
    metric_collector = MetricCollector()
    metric_collector.start()

    metric_reporter = MetricReporter(metrics, metric_collector)
    reporting.schedule(metric_reporter.report_metrics, sample_rate, None)

    protocol = StatsDClientProtocol(client)
    reactor.listenUDP(0, protocol)
    return reporting
    def test_starts_without_transport_gateway_if_not_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is None)
    def test_starts_with_data_queue(self):
        """The client starts with a DataQueue."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()

        self.assertIsInstance(self.client.data_queue, DataQueue)
Exemple #40
0
class TestClient(TestCase):
    def setUp(self):
        super(TestClient, self).setUp()
        self.client = None
        self.exception = None

    def tearDown(self):
        if self.client:
            self.client.transport.stopListening()
        super(TestClient, self).tearDown()

    def build_protocol(self):
        protocol = StatsDClientProtocol(self.client)
        reactor.listenUDP(0, protocol)

    def test_twistedstatsd_write(self):
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len("message"))

        def exercise(callback):
            self.client.write("message", callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d

    @inlineCallbacks
    def test_twistedstatsd_write_with_host_resolved(self):
        self.client = TwistedStatsDClient.create("localhost", 8000)
        self.build_protocol()
        yield self.client.resolve_later

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len("message"))
            self.assertEqual(self.client.host, "127.0.0.1")

        def exercise(callback):
            self.client.write("message", callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        yield d

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.client = TwistedStatsDClient.create("256.0.0.0", 1, resolver_errback=capture_exception_raised)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_no_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.patch(log, "err", capture_exception_raised)

        self.client = TwistedStatsDClient.create("256.0.0.0", 1)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)

    def test_udpstatsd_wellformed_address(self):
        client = UdpStatsDClient("localhost", 8000)
        self.assertEqual(client.host, "127.0.0.1")
        client = UdpStatsDClient(None, None)
        self.assertEqual(client.host, None)

    def test_udpstatsd_malformed_address(self):
        self.assertRaises(ValueError, UdpStatsDClient, "localhost", -1)
        self.assertRaises(ValueError, UdpStatsDClient, "localhost", "malformed")
        self.assertRaises(ValueError, UdpStatsDClient, 0, 8000)

    def test_udpstatsd_socket_nonblocking(self):
        client = UdpStatsDClient("localhost", 8000)
        client.connect()
        # According to the python docs (and the source, I've checked)
        # setblocking(0) is the same as settimeout(0.0).
        self.assertEqual(client.socket.gettimeout(), 0.0)

    def test_udp_client_can_be_imported_without_twisted(self):
        """Ensure that the twisted-less client can be used without twisted."""
        unloaded = [(name, mod) for (name, mod) in sys.modules.items() if "twisted" in name]

        def restore_modules():
            for name, mod in unloaded:
                sys.modules[name] = mod
            reload(txstatsd.client)
            reload(txstatsd.metrics.metrics)
            reload(txstatsd.metrics.metric)

        self.addCleanup(restore_modules)

        # Mark everything twistedish as unavailable
        for name, mod in unloaded:
            sys.modules[name] = None

        reload(txstatsd.client)
        reload(txstatsd.metrics.metrics)
        reload(txstatsd.metrics.metric)
        for mod in sys.modules:
            if "twisted" in mod:
                self.assertTrue(sys.modules[mod] is None)

    def test_starts_with_data_queue(self):
        """The client starts with a DataQueue."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()

        self.assertIsInstance(self.client.data_queue, DataQueue)

    def test_starts_with_transport_gateway_if_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is not None)

    def test_starts_without_transport_gateway_if_not_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is None)

    def test_passes_transport_to_gateway(self):
        """The client passes the transport to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        self.assertEqual(self.client.transport_gateway.transport, self.client.transport)

    def test_passes_reactor_to_gateway(self):
        """The client passes the reactor to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        self.assertEqual(self.client.transport_gateway.reactor, self.client.reactor)

    def test_sets_ip_when_host_resolves(self):
        """As soon as the host is resolved, set the IP as the host."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()
        self.assertEqual(self.client.host, "localhost")

        self.client.host_resolved("127.0.0.1")
        self.assertEqual(self.client.host, "127.0.0.1")

    def test_sets_transport_gateway_when_host_resolves(self):
        """As soon as the host is resolved, set the transport gateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.transport_gateway = None

        self.client.host_resolved("127.0.0.1")
        self.assertIsInstance(self.client.transport_gateway, TransportGateway)

    def test_calls_connect_callback_when_host_resolves(self):
        """As soon as the host is resolved, call back the connect_callback."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.connect_callback = Mock()

        self.client.host_resolved("127.0.0.1")
        self.assertTrue(self.client.connect_callback.called)
        self.client.connect_callback.assert_called_once_with()

    def test_sends_messages_to_gateway_after_host_resolves(self):
        """After the host is resolved, send messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()
        self.client.host_resolved("127.0.0.1")

        message = "some data"
        bytes_sent = len(message)
        self.client.data_queue = Mock(spec=DataQueue)
        self.client.transport_gateway = Mock(spec=TransportGateway)
        callback = Mock()
        self.client.transport_gateway.write.return_value = bytes_sent
        self.assertEqual(self.client.write(message, callback), bytes_sent)
        self.client.transport_gateway.write.assert_called_once_with(message, callback)

    def test_sends_messages_to_queue_before_host_resolves(self):
        """Before the host is resolved, send messages to the DataQueue."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        message = "some data"
        self.client.data_queue = Mock(spec=DataQueue)
        callback = Mock()
        self.client.data_queue.write.return_value = None
        result = self.client.write(message, callback)
        self.client.data_queue.write.assert_called_once_with(message, callback)
        self.assertEqual(result, None)

    def test_flushes_queued_messages_to_the_gateway_when_host_resolves(self):
        """As soon as the host is resolved, flush all messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.client.data_queue.write("data 1", "callback 1")
        self.client.data_queue.write("data 2", "callback 2")
        self.client.data_queue.write("data 3", "callback 3")

        mock_gateway_write = Mock()
        self.patch(TransportGateway, "write", mock_gateway_write)
        self.client.host_resolved("127.0.0.1")
        self.assertTrue(mock_gateway_write.call_count, 3)
        expected = [call("data 1", "callback 1"), call("data 2", "callback 2"), call("data 3", "callback 3")]
        self.assertEqual(mock_gateway_write.call_args_list, expected)

    def test_sets_client_transport_when_connected(self):
        """Set the transport as an attribute of the client."""
        self.client = TwistedStatsDClient("localhost", 8000)
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport, transport)

    def test_sets_gateway_transport_when_connected(self):
        """Set the transport as an attribute of the TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.client.host_resolved("127.0.0.1")
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport_gateway.transport, transport)
class TestClient(TestCase):
    def setUp(self):
        super(TestClient, self).setUp()
        self.client = None
        self.exception = None

    def tearDown(self):
        if self.client:
            self.client.transport.stopListening()
        super(TestClient, self).tearDown()

    def build_protocol(self):
        protocol = StatsDClientProtocol(self.client)
        reactor.listenUDP(0, protocol)

    def test_twistedstatsd_write(self):
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d

    @inlineCallbacks
    def test_twistedstatsd_write_with_host_resolved(self):
        self.client = TwistedStatsDClient.create('localhost', 8000)
        self.build_protocol()
        yield self.client.resolve_later

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))
            self.assertEqual(self.client.host, '127.0.0.1')

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        yield d

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.client = TwistedStatsDClient.create(
            '256.0.0.0', 1, resolver_errback=capture_exception_raised)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_no_errback(self):
        exceptions_captured = []

        def capture_exception_raised(failure):
            exception = failure.getErrorMessage()
            self.assertTrue(exception.startswith("DNS lookup failed"))
            exceptions_captured.append(exception)

        self.patch(log, "err", capture_exception_raised)

        self.client = TwistedStatsDClient.create('256.0.0.0', 1)
        self.build_protocol()
        yield self.client.resolve_later

        self.assertEqual(len(exceptions_captured), 1)

    def test_udpstatsd_wellformed_address(self):
        client = UdpStatsDClient('localhost', 8000)
        self.assertEqual(client.host, '127.0.0.1')
        client = UdpStatsDClient(None, None)
        self.assertEqual(client.host, None)

    def test_udpstatsd_malformed_address(self):
        self.assertRaises(ValueError, UdpStatsDClient, 'localhost', -1)
        self.assertRaises(ValueError, UdpStatsDClient, 'localhost',
                          'malformed')
        self.assertRaises(ValueError, UdpStatsDClient, 0, 8000)

    def test_udpstatsd_socket_nonblocking(self):
        client = UdpStatsDClient('localhost', 8000)
        client.connect()
        # According to the python docs (and the source, I've checked)
        # setblocking(0) is the same as settimeout(0.0).
        self.assertEqual(client.socket.gettimeout(), 0.0)

    def test_udp_client_can_be_imported_without_twisted(self):
        """Ensure that the twisted-less client can be used without twisted."""
        unloaded = [(name, mod) for (name, mod) in sys.modules.items()
                    if 'twisted' in name]

        def restore_modules():
            for name, mod in unloaded:
                sys.modules[name] = mod
            reload(txstatsd.client)
            reload(txstatsd.metrics.metrics)
            reload(txstatsd.metrics.metric)

        self.addCleanup(restore_modules)

        # Mark everything twistedish as unavailable
        for name, mod in unloaded:
            sys.modules[name] = None

        reload(txstatsd.client)
        reload(txstatsd.metrics.metrics)
        reload(txstatsd.metrics.metric)
        for mod in sys.modules:
            if 'twisted' in mod:
                self.assertTrue(sys.modules[mod] is None)

    def test_starts_with_data_queue(self):
        """The client starts with a DataQueue."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()

        self.assertIsInstance(self.client.data_queue, DataQueue)

    def test_starts_with_transport_gateway_if_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is not None)

    def test_starts_without_transport_gateway_if_not_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is None)

    def test_passes_transport_to_gateway(self):
        """The client passes the transport to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        self.assertEqual(self.client.transport_gateway.transport,
                         self.client.transport)

    def test_passes_reactor_to_gateway(self):
        """The client passes the reactor to the gateway as soon as the client
        is connected."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        self.assertEqual(self.client.transport_gateway.reactor,
                         self.client.reactor)

    def test_sets_ip_when_host_resolves(self):
        """As soon as the host is resolved, set the IP as the host."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()
        self.assertEqual(self.client.host, 'localhost')

        self.client.host_resolved('127.0.0.1')
        self.assertEqual(self.client.host, '127.0.0.1')

    def test_sets_transport_gateway_when_host_resolves(self):
        """As soon as the host is resolved, set the transport gateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.transport_gateway = None

        self.client.host_resolved('127.0.0.1')
        self.assertIsInstance(self.client.transport_gateway, TransportGateway)

    def test_calls_connect_callback_when_host_resolves(self):
        """As soon as the host is resolved, call back the connect_callback."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.connect_callback = Mock()

        self.client.host_resolved('127.0.0.1')
        self.assertTrue(self.client.connect_callback.called)
        self.client.connect_callback.assert_called_once_with()

    def test_sends_messages_to_gateway_after_host_resolves(self):
        """After the host is resolved, send messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()
        self.client.host_resolved('127.0.0.1')

        message = 'some data'
        bytes_sent = len(message)
        self.client.data_queue = Mock(spec=DataQueue)
        self.client.transport_gateway = Mock(spec=TransportGateway)
        callback = Mock()
        self.client.transport_gateway.write.return_value = bytes_sent
        self.assertEqual(self.client.write(message, callback), bytes_sent)
        self.client.transport_gateway.write.assert_called_once_with(
            message, callback)

    def test_sends_messages_to_queue_before_host_resolves(self):
        """Before the host is resolved, send messages to the DataQueue."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        message = 'some data'
        self.client.data_queue = Mock(spec=DataQueue)
        callback = Mock()
        self.client.data_queue.write.return_value = None
        result = self.client.write(message, callback)
        self.client.data_queue.write.assert_called_once_with(message, callback)
        self.assertEqual(result, None)

    def test_flushes_queued_messages_to_the_gateway_when_host_resolves(self):
        """As soon as the host is resolved, flush all messages to the
        TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.build_protocol()

        self.client.data_queue.write('data 1', 'callback 1')
        self.client.data_queue.write('data 2', 'callback 2')
        self.client.data_queue.write('data 3', 'callback 3')

        mock_gateway_write = Mock()
        self.patch(TransportGateway, 'write', mock_gateway_write)
        self.client.host_resolved('127.0.0.1')
        self.assertTrue(mock_gateway_write.call_count, 3)
        expected = [
            call('data 1', 'callback 1'),
            call('data 2', 'callback 2'),
            call('data 3', 'callback 3')
        ]
        self.assertEqual(mock_gateway_write.call_args_list, expected)

    def test_sets_client_transport_when_connected(self):
        """Set the transport as an attribute of the client."""
        self.client = TwistedStatsDClient('localhost', 8000)
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport, transport)

    def test_sets_gateway_transport_when_connected(self):
        """Set the transport as an attribute of the TransportGateway."""
        self.client = TwistedStatsDClient('localhost', 8000)
        self.client.host_resolved('127.0.0.1')
        transport = DummyTransport()
        self.client.connect(transport)

        self.assertEqual(self.client.transport_gateway.transport, transport)
Exemple #42
0
def install_stats(host, port, scheme):
    global metrics

    statsd_client = TwistedStatsDClient(host, port)
    metrics = Metrics(connection=statsd_client, namespace=scheme)
    return StatsDClientProtocol(statsd_client)
Exemple #43
0
class TestClient(TestCase):

    def setUp(self):
        super(TestClient, self).setUp()
        self.client = None
        self.exception = None

    def tearDown(self):
        if self.client:
            self.client.transport.stopListening()
        super(TestClient, self).tearDown()

    def test_twistedstatsd_write_with_wellformed_address(self):
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        protocol = StatsDClientProtocol(self.client)
        reactor.listenUDP(0, protocol)

        def ensure_bytes_sent(bytes_sent):
            self.assertEqual(bytes_sent, len('message'))

        def exercise(callback):
            self.client.write('message', callback=callback)

        d = Deferred()
        d.addCallback(ensure_bytes_sent)
        reactor.callWhenRunning(exercise, d.callback)
        return d

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_errback(self):
        def ensure_exception_raised(ignore):
            self.assertTrue(self.exception.startswith("DNS lookup failed"))

        def capture_exception_raised(failure):
            self.exception = failure.getErrorMessage()

        yield TwistedStatsDClient(
            '256.0.0.0', 1,
            resolver_errback=capture_exception_raised)

        d = Deferred()
        d.addCallback(ensure_exception_raised)
        reactor.callLater(.5, d.callback, None)
        yield d

    @inlineCallbacks
    def test_twistedstatsd_with_malformed_address_and_no_errback(self):
        def ensure_exception_raised(ignore):
            self.assertTrue(self.exception.startswith("DNS lookup failed"))

        def capture_exception_raised(failure):
            self.exception = failure.getErrorMessage()

        self.patch(log, "err", capture_exception_raised)

        yield TwistedStatsDClient('256.0.0.0', 1)

        d = Deferred()
        d.addCallback(ensure_exception_raised)
        reactor.callLater(.5, d.callback, None)
        yield d

    def test_udpstatsd_wellformed_address(self):
        client = UdpStatsDClient('localhost', 8000)
        self.assertEqual(client.host, '127.0.0.1')
        client = UdpStatsDClient(None, None)
        self.assertEqual(client.host, None)

    def test_udpstatsd_malformed_address(self):
        self.assertRaises(ValueError,
                          UdpStatsDClient, 'localhost', -1)
        self.assertRaises(ValueError,
                          UdpStatsDClient, 'localhost', 'malformed')
        self.assertRaises(ValueError,
                          UdpStatsDClient, 0, 8000)

    def test_udpstatsd_socket_nonblocking(self):
        client = UdpStatsDClient('localhost', 8000)
        client.connect()
        # According to the python docs (and the source, I've checked)
        # setblocking(0) is the same as settimeout(0.0).
        self.assertEqual(client.socket.gettimeout(), 0.0)
    def test_starts_with_transport_gateway_if_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient('127.0.0.1', 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is not None)
Exemple #45
0
 def __init__(self, statsd_host="localhost", statsd_port=8125):
     self.client = TwistedStatsDClient(statsd_host, statsd_port)
     self._metric = Metrics(connection=self.client, namespace="autopush")
Exemple #46
0
    def test_starts_with_data_queue(self):
        """The client starts with a DataQueue."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()

        self.assertIsInstance(self.client.data_queue, DataQueue)
Exemple #47
0
    def test_starts_with_transport_gateway_if_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient("127.0.0.1", 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is not None)
Exemple #48
0
    def test_starts_without_transport_gateway_if_not_ip(self):
        """The client starts without a TransportGateway."""
        self.client = TwistedStatsDClient("localhost", 8000)
        self.build_protocol()

        self.assertTrue(self.client.transport_gateway is None)