2424 ServiceStateChange ,
2525 Zeroconf ,
2626 ZeroconfServiceTypes ,
27+ _EXPIRE_REFRESH_TIME_PERCENT ,
2728)
2829
2930log = logging .getLogger ('zeroconf' )
@@ -1237,16 +1238,18 @@ def mock_incoming_msg(service_state_change: r.ServiceStateChange) -> r.DNSIncomi
12371238 assert service_removed_count == 1
12381239
12391240 finally :
1241+ assert len (zeroconf .listeners ) == 1
12401242 service_browser .cancel ()
1243+ assert len (zeroconf .listeners ) == 0
12411244 zeroconf .remove_all_service_listeners ()
12421245 zeroconf .close ()
12431246
12441247
12451248class TestServiceBrowserMultipleTypes (unittest .TestCase ):
12461249 def test_update_record (self ):
12471250
1248- service_names = ['name._type._tcp.local.' , 'name._type._udp.local' ]
1249- service_types = ['_type._tcp.local.' , '_type._udp.local.' ]
1251+ service_names = ['name2._type2._tcp.local.' , ' name._type._tcp.local.' , 'name._type._udp.local' ]
1252+ service_types = ['_type2._tcp.local.' , ' _type._tcp.local.' , '_type._udp.local.' ]
12501253
12511254 service_added_count = 0
12521255 service_removed_count = 0
@@ -1257,25 +1260,19 @@ class MyServiceListener(r.ServiceListener):
12571260 def add_service (self , zc , type_ , name ) -> None :
12581261 nonlocal service_added_count
12591262 service_added_count += 1
1260- if service_added_count == 2 :
1263+ if service_added_count == 3 :
12611264 service_add_event .set ()
12621265
12631266 def remove_service (self , zc , type_ , name ) -> None :
12641267 nonlocal service_removed_count
12651268 service_removed_count += 1
1266- if service_removed_count == 2 :
1269+ if service_removed_count == 3 :
12671270 service_removed_event .set ()
12681271
12691272 def mock_incoming_msg (
1270- service_state_change : r .ServiceStateChange , service_type : str , service_name : str
1273+ service_state_change : r .ServiceStateChange , service_type : str , service_name : str , ttl : int
12711274 ) -> r .DNSIncoming :
12721275 generated = r .DNSOutgoing (r ._FLAGS_QR_RESPONSE )
1273-
1274- if service_state_change == r .ServiceStateChange .Removed :
1275- ttl = 0
1276- else :
1277- ttl = 120
1278-
12791276 generated .add_answer_at_time (
12801277 r .DNSPointer (service_type , r ._TYPE_PTR , r ._CLASS_IN , ttl , service_name ), 0
12811278 )
@@ -1287,30 +1284,54 @@ def mock_incoming_msg(
12871284 try :
12881285 wait_time = 3
12891286
1290- # both services added
1287+ # all three services added
1288+ zeroconf .handle_response (
1289+ mock_incoming_msg (r .ServiceStateChange .Added , service_types [0 ], service_names [0 ], 120 )
1290+ )
12911291 zeroconf .handle_response (
1292- mock_incoming_msg (r .ServiceStateChange .Added , service_types [0 ], service_names [0 ] )
1292+ mock_incoming_msg (r .ServiceStateChange .Added , service_types [1 ], service_names [1 ], 120 )
12931293 )
12941294 zeroconf .handle_response (
1295- mock_incoming_msg (r .ServiceStateChange .Added , service_types [1 ], service_names [1 ] )
1295+ mock_incoming_msg (r .ServiceStateChange .Added , service_types [2 ], service_names [2 ], 120 )
12961296 )
1297+
1298+ called_with_refresh_time_check = False
1299+
1300+ def _mock_get_expiration_time (self , percent ):
1301+ nonlocal called_with_refresh_time_check
1302+ if percent == _EXPIRE_REFRESH_TIME_PERCENT :
1303+ called_with_refresh_time_check = True
1304+ return 0
1305+ return self .created + (percent * self .ttl * 10 )
1306+
1307+ # Set an expire time that will force a refresh
1308+ with unittest .mock .patch ("zeroconf.DNSRecord.get_expiration_time" , new = _mock_get_expiration_time ):
1309+ zeroconf .handle_response (
1310+ mock_incoming_msg (r .ServiceStateChange .Added , service_types [2 ], service_names [2 ], 120 )
1311+ )
12971312 service_add_event .wait (wait_time )
1298- assert service_added_count == 2
1313+ assert called_with_refresh_time_check is True
1314+ assert service_added_count == 3
12991315 assert service_removed_count == 0
13001316
1301- # both services removed
1317+ # all three services removed
1318+ zeroconf .handle_response (
1319+ mock_incoming_msg (r .ServiceStateChange .Removed , service_types [0 ], service_names [0 ], 0 )
1320+ )
13021321 zeroconf .handle_response (
1303- mock_incoming_msg (r .ServiceStateChange .Removed , service_types [0 ], service_names [0 ] )
1322+ mock_incoming_msg (r .ServiceStateChange .Removed , service_types [1 ], service_names [1 ], 0 )
13041323 )
13051324 zeroconf .handle_response (
1306- mock_incoming_msg (r .ServiceStateChange .Removed , service_types [1 ], service_names [1 ] )
1325+ mock_incoming_msg (r .ServiceStateChange .Removed , service_types [2 ], service_names [2 ], 0 )
13071326 )
13081327 service_removed_event .wait (wait_time )
1309- assert service_added_count == 2
1310- assert service_removed_count == 2
1328+ assert service_added_count == 3
1329+ assert service_removed_count == 3
13111330
13121331 finally :
1332+ assert len (zeroconf .listeners ) == 1
13131333 service_browser .cancel ()
1334+ assert len (zeroconf .listeners ) == 0
13141335 zeroconf .remove_all_service_listeners ()
13151336 zeroconf .close ()
13161337
0 commit comments