|
30 | 30 | # Datadog libraries |
31 | 31 | from datadog import initialize, statsd |
32 | 32 | from datadog import __version__ as version |
33 | | -from datadog.dogstatsd.base import DEFAULT_BUFFERING_FLUSH_INTERVAL, DEFAULT_HOST, DEFAULT_PORT, DogStatsd, MIN_SEND_BUFFER_SIZE, PendingPayload, SenderQueue, Stop, UDP_OPTIMAL_PAYLOAD_LENGTH, UDS_CONNECT_RETRY_INITIAL_BACKOFF, UDS_OPTIMAL_PAYLOAD_LENGTH |
| 33 | +from datadog.dogstatsd.base import DEFAULT_BUFFERING_FLUSH_INTERVAL, DEFAULT_HOST, DEFAULT_PORT, DogStatsd, MIN_SEND_BUFFER_SIZE, PENDING_PAYLOAD_EXPIRY_SECONDS, PendingPayload, SenderQueue, Stop, UDP_OPTIMAL_PAYLOAD_LENGTH, UDS_CONNECT_RETRY_INITIAL_BACKOFF, UDS_OPTIMAL_PAYLOAD_LENGTH |
34 | 34 | from datadog.dogstatsd.sender_queue import monotonic as sender_queue_clock |
35 | 35 | from datadog.dogstatsd.context import TimedContextManagerDecorator |
36 | 36 | from datadog.util.compat import is_higher_py35, is_p3k |
@@ -2773,32 +2773,34 @@ def test_sender_queue_timeout_blocks_the_calling_thread_through_the_client(self) |
2773 | 2773 | statsd.stop() |
2774 | 2774 |
|
2775 | 2775 | def test_bytes_dropped_queue_counts_actual_bytes(self): |
2776 | | - # Use a queue of size 1 so the second packet forces the first (oldest) |
2777 | | - # one out, then verify bytes_dropped_queue reflects the real byte |
2778 | | - # length of the dropped packet (including the appended newline), and |
2779 | | - # that the newer payload is the one that survives in the queue. |
2780 | | - statsd = DogStatsd( |
2781 | | - disable_background_sender=False, |
2782 | | - sender_queue_size=1, |
| 2776 | + # No sender thread: a live one could drain the first payload before the |
| 2777 | + # third is queued, so nothing would be evicted and the counters below |
| 2778 | + # would describe a schedule that never happened. Size 2 rather than 1 |
| 2779 | + # so the eviction order is observable -- with a single slot the evicted |
| 2780 | + # entry is both the oldest and the newest. |
| 2781 | + statsd = DogStatsd(disable_background_sender=True) |
| 2782 | + statsd._queue = SenderQueue( |
| 2783 | + 2, |
| 2784 | + PENDING_PAYLOAD_EXPIRY_SECONDS, |
| 2785 | + statsd._account_dropped_queue_full, |
| 2786 | + statsd._account_dropped_expired, |
2783 | 2787 | ) |
2784 | | - statsd.socket = FakeSocket() |
2785 | | - |
2786 | | - # Build a packet whose serialised form we know, then compute its length. |
2787 | | - metric_name = "test.metric" |
2788 | 2788 |
|
2789 | | - # Send two packets: the first is evicted (dropped) to make room for the second. |
2790 | | - statsd._send_to_server(metric_name) |
2791 | | - statsd._send_to_server(metric_name + ".second") |
| 2789 | + first, second, third = "test.metric.first", "test.metric.second", "test.metric.third" |
| 2790 | + statsd._send_to_server(first) |
| 2791 | + statsd._send_to_server(second) |
| 2792 | + statsd._send_to_server(third) # evicts the oldest (first) to make room |
2792 | 2793 |
|
2793 | | - expected_bytes = len((metric_name + '\n').encode("utf-8")) |
2794 | | - self.assertEqual(statsd.bytes_dropped_queue, expected_bytes) |
| 2794 | + # bytes_dropped_queue is the real byte length, including the newline |
| 2795 | + # _send_to_server() appends. |
| 2796 | + self.assertEqual(statsd.bytes_dropped_queue, len((first + "\n").encode("utf-8"))) |
2795 | 2797 | self.assertEqual(statsd.packets_dropped_queue, 1) |
2796 | 2798 | self.assertEqual(statsd.bytes_dropped_expired, 0) |
2797 | 2799 | self.assertEqual(statsd.packets_dropped_expired, 0) |
2798 | 2800 |
|
2799 | | - # The surviving (newest) payload is the one the sender thread will send. |
2800 | | - statsd.wait_for_pending() |
2801 | | - self.assertEqual(statsd.socket.payloads[0].decode("utf-8"), metric_name + ".second\n") |
| 2801 | + # Dropping the oldest leaves the two newest queued, in order. |
| 2802 | + survivors = [statsd._queue.get().payload, statsd._queue.get().payload] |
| 2803 | + self.assertEqual(survivors, [second + "\n", third + "\n"]) |
2802 | 2804 |
|
2803 | 2805 | statsd.stop() |
2804 | 2806 |
|
|
0 commit comments