10
10
# Standard libraries
11
11
from collections import deque
12
12
from contextlib import closing
13
+ import struct
13
14
from threading import Thread
14
15
import errno
15
16
import os
@@ -41,13 +42,17 @@ class FakeSocket(object):
41
42
42
43
FLUSH_GRACE_PERIOD = 0.2
43
44
44
- def __init__ (self , flush_interval = DEFAULT_BUFFERING_FLUSH_INTERVAL ):
45
+ def __init__ (self , flush_interval = DEFAULT_BUFFERING_FLUSH_INTERVAL , socket_kind = socket . SOCK_DGRAM ):
45
46
self .payloads = deque ()
46
47
47
48
self ._flush_interval = flush_interval
48
49
self ._flush_wait = False
50
+ self ._socket_kind = socket_kind
49
51
self .timeout = () # unit tuple = settimeout was not called
50
52
53
+ def sendall (self , payload ):
54
+ self .send (payload )
55
+
51
56
def send (self , payload ):
52
57
if is_p3k ():
53
58
assert isinstance (payload , bytes )
@@ -64,17 +69,29 @@ def recv(self, count=1, reset_wait=False, no_wait=False):
64
69
time .sleep (self ._flush_interval + self .FLUSH_GRACE_PERIOD )
65
70
self ._flush_wait = True
66
71
67
- if count > len (self .payloads ):
72
+ payload_len = len (self .payloads )
73
+ if self ._socket_kind == socket .SOCK_STREAM :
74
+ if payload_len % 2 != 0 or count > (payload_len / 2 ):
75
+ return None
76
+ elif count > len (self .payloads ):
68
77
return None
69
78
70
79
out = []
71
80
for _ in range (count ):
72
- out .append (self .payloads .popleft ().decode ('utf-8' ))
81
+ if self ._socket_kind == socket .SOCK_DGRAM :
82
+ out .append (self .payloads .popleft ().decode ('utf-8' ))
83
+ else :
84
+ length = struct .unpack ('<I' , self .payloads .popleft ())[0 ]
85
+ pl = self .payloads .popleft ()[:length ].decode ('utf-8' )
86
+ out .append (pl )
73
87
return '\n ' .join (out )
74
88
75
89
def close (self ):
76
90
pass
77
91
92
+ def getsockopt (self , * args ):
93
+ return self ._socket_kind
94
+
78
95
def __repr__ (self ):
79
96
return str (self .payloads )
80
97
@@ -1061,47 +1078,71 @@ def test_batching(self):
1061
1078
telemetry = telemetry_metrics (metrics = 2 , bytes_sent = len (expected ))
1062
1079
)
1063
1080
1064
- def test_flush (self ):
1081
+ def test_flush_dgram (self ):
1082
+ self ._test_flush (socket .SOCK_DGRAM )
1083
+
1084
+ def test_flush_stream (self ):
1085
+ self ._test_flush (socket .SOCK_STREAM )
1086
+
1087
+ def _test_flush (self , socket_kind ):
1065
1088
dogstatsd = DogStatsd (disable_buffering = False , telemetry_min_flush_interval = 0 )
1066
- fake_socket = FakeSocket ()
1089
+ fake_socket = FakeSocket (socket_kind = socket_kind )
1067
1090
dogstatsd .socket = fake_socket
1068
1091
1069
- dogstatsd .increment ('page.views' )
1092
+ dogstatsd .increment ('page.® views® ' )
1070
1093
self .assertIsNone (fake_socket .recv (no_wait = True ))
1071
1094
dogstatsd .flush ()
1072
- self .assert_equal_telemetry ('page.views:1|c\n ' , fake_socket .recv (2 ))
1095
+ self .assert_equal_telemetry ('page.®views®:1|c\n ' , fake_socket .recv (2 ))
1096
+
1097
+ def test_flush_interval_dgram (self ):
1098
+ self ._test_flush_interval (socket .SOCK_DGRAM )
1099
+
1100
+ def test_flush_interval_stream (self ):
1101
+ self ._test_flush_interval (socket .SOCK_STREAM )
1073
1102
1074
- def test_flush_interval (self ):
1103
+ def _test_flush_interval (self , socket_kind ):
1075
1104
dogstatsd = DogStatsd (disable_buffering = False , flush_interval = 1 , telemetry_min_flush_interval = 0 )
1076
- fake_socket = FakeSocket ()
1105
+ fake_socket = FakeSocket (socket_kind = socket_kind )
1077
1106
dogstatsd .socket = fake_socket
1078
1107
1079
- dogstatsd .increment ('page.views' )
1108
+ dogstatsd .increment ('page.® views® ' )
1080
1109
self .assertIsNone (fake_socket .recv (no_wait = True ))
1081
1110
1082
1111
time .sleep (0.3 )
1083
1112
self .assertIsNone (fake_socket .recv (no_wait = True ))
1084
1113
1085
1114
time .sleep (1 )
1086
1115
self .assert_equal_telemetry (
1087
- 'page.views:1|c\n ' ,
1116
+ 'page.® views® :1|c\n ' ,
1088
1117
fake_socket .recv (2 , no_wait = True )
1089
1118
)
1090
1119
1091
- def test_aggregation_buffering_simultaneously (self ):
1120
+ def test_aggregation_buffering_simultaneously_dgram (self ):
1121
+ self ._test_aggregation_buffering_simultaneously (socket .SOCK_DGRAM )
1122
+
1123
+ def test_aggregation_buffering_simultaneously_stream (self ):
1124
+ self ._test_aggregation_buffering_simultaneously (socket .SOCK_STREAM )
1125
+
1126
+ def _test_aggregation_buffering_simultaneously (self , socket_kind ):
1092
1127
dogstatsd = DogStatsd (disable_buffering = False , disable_aggregation = False , telemetry_min_flush_interval = 0 )
1093
- fake_socket = FakeSocket ()
1128
+ fake_socket = FakeSocket (socket_kind = socket_kind )
1094
1129
dogstatsd .socket = fake_socket
1095
1130
for _ in range (10 ):
1096
- dogstatsd .increment ('test.aggregation_and_buffering ' )
1131
+ dogstatsd .increment ('test.ÀggregÀtion_and_buffering ' )
1097
1132
self .assertIsNone (fake_socket .recv (no_wait = True ))
1098
1133
dogstatsd .flush_aggregated_metrics ()
1099
1134
dogstatsd .flush ()
1100
- self .assert_equal_telemetry ('test.aggregation_and_buffering:10|c\n ' , fake_socket .recv (2 ))
1135
+ self .assert_equal_telemetry ('test.ÀggregÀtion_and_buffering:10|c\n ' , fake_socket .recv (2 ))
1136
+
1137
+ def test_aggregation_buffering_simultaneously_with_interval_dgram (self ):
1138
+ self ._test_aggregation_buffering_simultaneously_with_interval (socket .SOCK_DGRAM )
1101
1139
1102
- def test_aggregation_buffering_simultaneously_with_interval (self ):
1140
+ def test_aggregation_buffering_simultaneously_with_interval_stream (self ):
1141
+ self ._test_aggregation_buffering_simultaneously_with_interval (socket .SOCK_STREAM )
1142
+
1143
+ def _test_aggregation_buffering_simultaneously_with_interval (self , socket_kind ):
1103
1144
dogstatsd = DogStatsd (disable_buffering = False , disable_aggregation = False , flush_interval = 1 , telemetry_min_flush_interval = 0 )
1104
- fake_socket = FakeSocket ()
1145
+ fake_socket = FakeSocket (socket_kind = socket_kind )
1105
1146
dogstatsd .socket = fake_socket
1106
1147
for _ in range (10 ):
1107
1148
dogstatsd .increment ('test.aggregation_and_buffering_with_interval' )
@@ -1185,12 +1226,18 @@ def test_batching_sequential(self):
1185
1226
)
1186
1227
)
1187
1228
1188
- def test_batching_runtime_changes (self ):
1229
+ def test_batching_runtime_changes_dgram (self ):
1230
+ self ._test_batching_runtime_changes (socket .SOCK_DGRAM )
1231
+
1232
+ def test_batching_runtime_changes_stream (self ):
1233
+ self ._test_batching_runtime_changes (socket .SOCK_STREAM )
1234
+
1235
+ def _test_batching_runtime_changes (self , socket_kind ):
1189
1236
dogstatsd = DogStatsd (
1190
1237
disable_buffering = True ,
1191
1238
telemetry_min_flush_interval = 0
1192
1239
)
1193
- dogstatsd .socket = FakeSocket ()
1240
+ dogstatsd .socket = FakeSocket (socket_kind = socket_kind )
1194
1241
1195
1242
# Send some unbuffered metrics and verify we got it immediately
1196
1243
last_telemetry_size = self .send_and_assert (
0 commit comments