@@ -146,6 +146,37 @@ def test_on_add_excludes_host_from_query_plan_when_pool_future_fails(self):
146146 finally :
147147 cluster .shutdown ()
148148
149+ def test_on_add_failure_does_not_allow_reentrant_add_during_cleanup (self ):
150+ cluster = Cluster (protocol_version = 4 )
151+ host = Host ("127.0.0.1" , SimpleConvictionPolicy , datacenter = "dc1" , rack = "rack1" , host_id = uuid .uuid4 ())
152+ failed_future = Future ()
153+ successful_future = Future ()
154+ successful_future .set_result (True )
155+ session = Mock ()
156+ session .add_or_renew_pool .side_effect = [failed_future , successful_future ]
157+ session .update_created_pools .return_value = set ()
158+ cluster .sessions = [session ]
159+
160+ original_on_down = cluster .profile_manager .on_down
161+
162+ def reentrant_add_while_cleanup_removes_host (cleanup_host ):
163+ cluster .on_add (host , refresh_nodes = False )
164+ original_on_down (cleanup_host )
165+
166+ cluster .profile_manager .on_down = Mock (side_effect = reentrant_add_while_cleanup_removes_host )
167+
168+ try :
169+ cluster .on_add (host , refresh_nodes = False )
170+
171+ failed_future .set_result (False )
172+
173+ load_balancer = cluster .profile_manager .default .load_balancing_policy
174+ assert host not in list (load_balancer .make_query_plan ())
175+ assert host .is_up is False
176+ assert session .add_or_renew_pool .call_count == 1
177+ finally :
178+ cluster .shutdown ()
179+
149180 def test_on_add_waits_for_all_session_pool_futures_before_marking_host_up (self ):
150181 cluster = Cluster (protocol_version = 4 )
151182 host = Host ("127.0.0.1" , SimpleConvictionPolicy , host_id = uuid .uuid4 ())
0 commit comments