@@ -212,34 +212,36 @@ def test_same_name(self):
212
212
r .DNSIncoming (generated .packet ())
213
213
214
214
def test_lots_of_names (self ):
215
+
215
216
# instantiate a zeroconf instance
216
- zeroconf = Zeroconf (interfaces = ['127.0.0.1' ])
217
+ zc = Zeroconf (interfaces = ['127.0.0.1' ])
217
218
218
219
# we are going to monkey patch the zeroconf send to check packet sizes
219
- old_send = zeroconf .send
220
+ old_send = zc .send
220
221
221
222
# needs to be a list so that we can modify it in our phony send
222
- longest_packet = [0 ]
223
+ longest_packet = [0 , None ]
223
224
224
225
def send (out , addr = r ._MDNS_ADDR , port = r ._MDNS_PORT ):
225
226
"""Sends an outgoing packet."""
226
227
packet = out .packet ()
227
228
if longest_packet [0 ] < len (packet ):
228
229
longest_packet [0 ] = len (packet )
230
+ longest_packet [1 ] = out
229
231
old_send (out , addr = addr , port = port )
230
232
231
233
# monkey patch the zeroconf send
232
- zeroconf .send = send
234
+ zc .send = send
233
235
234
236
# create a bunch of servers
235
237
type_ = "_my-service._tcp.local."
236
238
server_count = 300
237
239
records_per_server = 2
238
240
for i in range (int (server_count / 10 )):
239
- self .generate_many_hosts (zeroconf , type_ , 10 )
241
+ self .generate_many_hosts (zc , type_ , 10 )
240
242
sleep_count = 0
241
- while sleep_count < 20 and server_count * records_per_server > len (
242
- zeroconf .cache .entries_with_name (type_ )):
243
+ while sleep_count < 100 and server_count * records_per_server > len (
244
+ zc .cache .entries_with_name (type_ )):
243
245
sleep_count += 1
244
246
time .sleep (0.01 )
245
247
@@ -248,13 +250,88 @@ def on_service_state_change(zeroconf, service_type, state_change, name):
248
250
pass
249
251
250
252
# start a browser and run for a bit
251
- browser = ServiceBrowser (zeroconf , type_ , [on_service_state_change ])
252
- time .sleep (0.1 )
253
+ browser = ServiceBrowser (zc , type_ , [on_service_state_change ])
254
+ sleep_count = 0
255
+ while sleep_count < 100 and \
256
+ longest_packet [0 ] < r ._MAX_MSG_ABSOLUTE - 100 :
257
+ sleep_count += 1
258
+ time .sleep (0.1 )
259
+
253
260
browser .cancel ()
254
- zeroconf .close ()
261
+ time .sleep (0.5 )
262
+
263
+ import zeroconf
264
+ zeroconf .log .debug ('sleep_count %d, sized %d' ,
265
+ sleep_count , longest_packet [0 ])
255
266
256
267
# now the browser has sent at least one request, verify the size
257
268
assert longest_packet [0 ] < r ._MAX_MSG_ABSOLUTE
269
+ assert longest_packet [0 ] >= r ._MAX_MSG_ABSOLUTE - 100
270
+
271
+ # mock zeroconf's logger warning() and debug()
272
+ from mock import patch
273
+ patch_warn = patch ('zeroconf.log.warning' )
274
+ patch_debug = patch ('zeroconf.log.debug' )
275
+ mocked_log_warn = patch_warn .start ()
276
+ mocked_log_debug = patch_debug .start ()
277
+
278
+ # now that we have a long packet in our possession, let's verify the
279
+ # exception handling.
280
+ out = longest_packet [1 ]
281
+ out .data .append (b'\0 ' * 1000 )
282
+
283
+ # mock the zeroconf logger and check for the correct logging backoff
284
+ call_counts = mocked_log_warn .call_count , mocked_log_debug .call_count
285
+ # try to send an oversized packet
286
+ zc .send (out )
287
+ assert mocked_log_warn .call_count == call_counts [0 ] + 1
288
+ assert mocked_log_debug .call_count == call_counts [0 ]
289
+ zc .send (out )
290
+ assert mocked_log_warn .call_count == call_counts [0 ] + 1
291
+ assert mocked_log_debug .call_count == call_counts [0 ] + 1
292
+
293
+ # force a receive of an oversized packet
294
+ packet = out .packet ()
295
+ s = zc ._respond_sockets [0 ]
296
+
297
+ # mock the zeroconf logger and check for the correct logging backoff
298
+ call_counts = mocked_log_warn .call_count , mocked_log_debug .call_count
299
+ # force receive on oversized packet
300
+ s .sendto (packet , 0 , (r ._MDNS_ADDR , r ._MDNS_PORT ))
301
+ s .sendto (packet , 0 , (r ._MDNS_ADDR , r ._MDNS_PORT ))
302
+ time .sleep (2.0 )
303
+ zeroconf .log .debug ('warn %d debug %d was %s' ,
304
+ mocked_log_warn .call_count ,
305
+ mocked_log_debug .call_count ,
306
+ call_counts )
307
+ assert mocked_log_debug .call_count > call_counts [0 ]
308
+
309
+ # close our zeroconf which will close the sockets
310
+ zc .close ()
311
+
312
+ # pop the big chunk off the end of the data and send on a closed socket
313
+ out .data .pop ()
314
+ zc ._GLOBAL_DONE = False
315
+
316
+ # mock the zeroconf logger and check for the correct logging backoff
317
+ call_counts = mocked_log_warn .call_count , mocked_log_debug .call_count
318
+ # send on a closed socket (force a socket error)
319
+ zc .send (out )
320
+ zeroconf .log .debug ('warn %d debug %d was %s' ,
321
+ mocked_log_warn .call_count ,
322
+ mocked_log_debug .call_count ,
323
+ call_counts )
324
+ assert mocked_log_warn .call_count > call_counts [0 ]
325
+ assert mocked_log_debug .call_count > call_counts [0 ]
326
+ zc .send (out )
327
+ zeroconf .log .debug ('warn %d debug %d was %s' ,
328
+ mocked_log_warn .call_count ,
329
+ mocked_log_debug .call_count ,
330
+ call_counts )
331
+ assert mocked_log_debug .call_count > call_counts [0 ] + 2
332
+
333
+ mocked_log_warn .stop ()
334
+ mocked_log_debug .stop ()
258
335
259
336
def generate_many_hosts (self , zc , type_ , number_hosts ):
260
337
import random
0 commit comments