def test_when_client_is_removed_the_socket_batch_client_socket_is_not_closed(self):
     batch_client = TCPBatchClient("localhost")
     unit_client = batch_client.unit_client()
     sock = batch_client._socket
     del batch_client
     gc.collect()
     self.assertFalse(sock.closed)
    def test_client_creates_stopwatch(self):
        test_start_timestamp = time()
        one_minute_before_test = test_start_timestamp - 60
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        stopwatch = client.stopwatch("event")
        self.assertIsInstance(stopwatch, Stopwatch)
        self.assertEqual(stopwatch.client, client)
        self.assertEqual(stopwatch.rate, 1)
        self.assertGreaterEqual(stopwatch.reference, test_start_timestamp)

        stopwatch_low_rate = client.stopwatch("low_rate", rate=0.001)
        self.assertEqual(stopwatch_low_rate.rate, 0.001)
        self.assertGreaterEqual(stopwatch.reference, test_start_timestamp)

        stopwatch_1min_ref = client.stopwatch("low_rate", reference=one_minute_before_test)
        self.assertGreaterEqual(test_start_timestamp, stopwatch_1min_ref.reference)

        with client.stopwatch("something"):
            sleep(0.01)

        self.assertEqual(self.mock_sendall.call_count, 0)
        client.flush()
        self.assertEqual(self.mock_sendall.call_count, 1)
        request_args = self.mock_sendall.call_args[0]
        self.assertEqual(len(request_args), 1)
        request = request_args[0]
        self.assertRegex(request.decode(), "something:[1-9]\d{0,3}\|ms")
 def test_create_unit_client(self):
     batch_client = TCPBatchClient("localhost")
     batch_client._socket = self.mock_socket
     client = batch_client.unit_client()
     self.assertIsInstance(client, TCPClient)
     self.assertEqual(batch_client.host, client.host)
     self.assertEqual(batch_client.port, client.port)
     self.assertEqual(
         batch_client._remote_address,
         client._remote_address
     )
     self.assertEqual(
         batch_client._socket,
         client._socket
     )
 def test_client_creates_chronometer(self):
     client = TCPBatchClient("localhost")
     chronometer = client.chronometer()
     self.assertIsInstance(chronometer, Chronometer)
     self.assertEqual(chronometer.client, client)
 def test_clear(self):
     client = TCPBatchClient("localhost", batch_size=20)
     client._socket = self.mock_socket
     client.increment("first")
     client.decrement("second")
     client.timing("db.query", 1)
     client.clear()
     client.flush()
     self.assertEqual(self.mock_sendall.call_count, 0)
    def test_set(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.set("username", 'first')
        client.flush()
        self.mock_sendall.assert_called_with(
            bytearray("username:first|s\n".encode())
        )
        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.set("user", 'second')
        client.set("user", 'third', 0.2)
        client.set("user", 'last', rate=0.5)
        client.flush()

        self.mock_sendall.assert_called_once_with(
            bytearray("pre.user:second|s\npre.user:last|s|@0.5\n".encode())
        )
 def test_metrics_partitioned_into_batches(self):
     client = TCPBatchClient("localhost", batch_size=20)
     client._socket = self.mock_socket
     client.increment("fit.a.batch.123")
     client.timing("_", 1)
     client.increment("larger.than.batch.becomes.a.batch", 5, 0.9)
     client.decrement("12")
     client.set("ab", 'z')
     client.timing("small", 9)
     client.gauge("overflow.previous", 10)
     client.gauge_delta("next", -10)
     client.increment("_")
     client.flush()
     expected_calls = [
             mock.call(bytearray("fit.a.batch.123:1|c\n".encode())),
             mock.call(bytearray("_:1|ms\n".encode())),
             mock.call(bytearray("larger.than.batch.becomes.a.batch:5|c|@0.9\n".encode())),
             mock.call(bytearray("12:-1|c\nab:z|s\n".encode())),
             mock.call(bytearray("small:9|ms\n".encode())),
             mock.call(bytearray("overflow.previous:10|g\n".encode())),
             mock.call(bytearray("next:-10|g\n_:1|c\n".encode()))
     ]
     self.assertEqual(self.mock_sendall.mock_calls, expected_calls)
    def test_gauge(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.gauge("memory", 10240)
        client.flush()
        self.mock_sendall.assert_called_with(
            bytearray("memory:10240|g\n".encode())
        )
        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.gauge("memory", 2048)
        client.gauge("memory", 8096, 0.2)
        client.gauge("storage", 512, rate=0.6)
        client.flush()

        self.mock_sendall.assert_called_once_with(
            bytearray("pre.memory:2048|g\npre.storage:512|g|@0.6\n".encode())
        )
    def test_gauge_delta(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.gauge_delta("memory", -512)
        client.flush()
        self.mock_sendall.assert_called_with(
            bytearray("memory:-512|g\n".encode())
        )
        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.gauge_delta("memory", 2048)
        client.gauge_delta("memory", 8096, 0.2)
        client.gauge_delta("storage", -128, rate=0.7)
        client.flush()

        self.mock_sendall.assert_called_once_with(
            bytearray("pre.memory:+2048|g\npre.storage:-128|g|@0.7\n".encode())
        )
    def test_timing_since_with_timestamp_as_number(self):
        start_time = time()
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket

        self.assertRaises(AssertionError, client.timing_since, "negative", -1)

        sleep(0.01)
        client.timing_since("event", start_time)
        client.timing_since("other_event", start_time)
        client.flush()
        self.assertEqual(self.mock_sendall.call_count, 1)
        socket_sendall_args = self.mock_sendall.call_args[0]
        self.assertEqual(len(socket_sendall_args), 1)
        request = socket_sendall_args[0]
        self.assertRegex(request.decode(), "event:[1-9]+\d{0,3}\|ms\nother_event:[1-9]\d{0,3}\|ms")
        self.mock_sendall.reset_mock()

        client.timing_since("low.rate", start_time, rate=0.1)
        client.flush()
        self.assertEqual(self.mock_sendall.call_count, 0)
    def test_timing_since_with_datetime_timestamp(self):
        start_time = datetime.now()
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket

        sleep(0.01)
        client.timing_since("event", start_time)
        client.timing_since("other_event", start_time)
        client.flush()
        self.assertEqual(self.mock_sendall.call_count, 1)
        socket_sendall_args = self.mock_sendall.call_args[0]
        self.assertEqual(len(socket_sendall_args), 1)
        request = socket_sendall_args[0]
        self.assertRegex(request.decode(), "event:[1-9]\d{0,3}\|ms\nother_event:[1-9]\d{0,3}\|ms")
        self.mock_sendall.reset_mock()

        client.timing_since("low.rate", start_time, rate=0.01)
        client.flush()
        self.assertEqual(self.mock_sendall.call_count, 0)
    def test_timing(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.timing("event", 10, 0.4)
        client.flush()
        self.mock_sendall.assert_called_with(
            bytearray("event:10|ms|@0.4\n".encode())
        )
        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.timing("query", 3)
        client.timing("process.request", 2, 0.2)
        client.timing("query.user", 350, rate=0.6)
        client.flush()

        self.mock_sendall.assert_called_once_with(
            bytearray("pre.query:3|ms\npre.query.user:350|ms|@0.6\n".encode())
        )
    def test_decrement(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.decrement("event", 3, 0.7)
        client.flush()
        self.mock_sendall.assert_called_with(
            bytearray("event:-3|c|@0.7\n".encode())
        )
        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.decrement("session")
        client.decrement("session.fail", 2, 0.2)
        client.decrement("session.ok", rate=0.6)
        client.flush()

        self.mock_sendall.assert_called_once_with(
            bytearray("pre.session:-1|c\npre.session.ok:-1|c|@0.6\n".encode())
        )
    def test_increment(self):
        client = TCPBatchClient("localhost")
        client._socket = self.mock_socket
        client.increment("event", 2, 0.5)
        client.flush()
        self.mock_sendall.assert_called_once_with(
            bytearray("event:2|c|@0.5\n".encode()),
        )

        self.mock_sendall.reset_mock()
        client.prefix = "pre."
        client.increment("login")
        client.increment("login.fail", 5, 0.2)
        client.increment("login.ok", rate=0.8)
        client.flush()
        self.mock_sendall.assert_called_once_with(
            bytearray("pre.login:1|c\npre.login.ok:1|c|@0.8\n".encode())
        )
    def test_sending_batch_metrics(self):
        start = datetime.now()
        start_timestamp = time()
        client = TCPBatchClient("localhost", self.__class__.port)
        client.increment("1.test", 8)
        client.increment("2.login")
        client.timing("3.query", 9600)
        client.gauge("4.memory", 102600)
        client.gauge_delta("5.memory", 2560)
        client.gauge_delta("6.memory", -1280)
        client.set("7.ip", "127.0.0.2")
        client.flush()

        expected = [
            "1.test:8|c",
            "2.login:1|c",
            "3.query:9600|ms",
            "4.memory:102600|g",
            "5.memory:+2560|g",
            "6.memory:-1280|g",
            "7.ip:127.0.0.2|s",
        ]

        self.assert_server_received_expected_requests(expected)

        client.timing_since("1.query", start_timestamp)
        client.timing_since("2.other_query", start)
        client.flush()

        chronometer = client.chronometer()
        chronometer.time_callable("3.sleepy", sleep, 1, (0.02, ))

        @chronometer.wrap("4.wait_a_sec")
        def wait_a_sec():
            sleep(0.01)

        wait_a_sec()

        with client.stopwatch("5.my_with_block"):
            sleep(0.02)

        client.flush()

        expected_patterns = [
            "1.query:[1-9]\d{0,4}\|ms",
            "2.other_query:[1-9]\d{0,4}\|ms",
            "3.sleepy:[1-9]\d{0,4}\|ms",
            "4.wait_a_sec:[1-9]\d{0,4}\|ms",
            "5.my_with_block:[1-9]\d{0,4}\|ms",
        ]
        self.assert_server_received_expected_request_regex(expected_patterns)
    def test_sending_batch_metrics(self):
        start = datetime.now()
        start_timestamp = time()
        client = TCPBatchClient("localhost", self.__class__.port)
        client.increment("1.test", 8)
        client.increment("2.login")
        client.timing("3.query", 9600)
        client.gauge("4.memory", 102600)
        client.gauge_delta("5.memory", 2560)
        client.gauge_delta("6.memory", -1280)
        client.set("7.ip", "127.0.0.2")
        client.flush()

        expected = [
                "1.test:8|c",
                "2.login:1|c",
                "3.query:9600|ms",
                "4.memory:102600|g",
                "5.memory:+2560|g",
                "6.memory:-1280|g",
                "7.ip:127.0.0.2|s",
        ]

        self.assert_server_received_expected_requests(expected)

        client.timing_since("1.query", start_timestamp)
        client.timing_since("2.other_query", start)
        client.flush()

        chronometer = client.chronometer()
        chronometer.time_callable("3.sleepy", sleep, 1, (0.02,))

        @chronometer.wrap("4.wait_a_sec")
        def wait_a_sec():
            sleep(0.01)

        wait_a_sec()

        with client.stopwatch("5.my_with_block"):
            sleep(0.02)

        client.flush()

        expected_patterns = [
            "1.query:[1-9]\d{0,4}\|ms",
            "2.other_query:[1-9]\d{0,4}\|ms",
            "3.sleepy:[1-9]\d{0,4}\|ms",
            "4.wait_a_sec:[1-9]\d{0,4}\|ms",
            "5.my_with_block:[1-9]\d{0,4}\|ms",
        ]
        self.assert_server_received_expected_request_regex(expected_patterns)