diff --git a/nodepool/tests/test_launcher.py b/nodepool/tests/test_launcher.py index 7bb3cee96..6e121f7d6 100644 --- a/nodepool/tests/test_launcher.py +++ b/nodepool/tests/test_launcher.py @@ -961,8 +961,9 @@ class TestLauncher(tests.DBTestCase): req2 = self.waitForNodeRequest(req2, zk.PENDING) # Delete node attached to provider2 this will cause provider2 to - # fulfill the request it had pending. Simply unlocking here should - # cause it to be deleted. + # fulfill the request it had pending. + provider2_first.state = zk.DELETING + self.zk.storeNode(provider2_first) self.zk.unlockNode(provider2_first) self.waitForNodeDeletion(provider2_first) @@ -1005,9 +1006,10 @@ class TestLauncher(tests.DBTestCase): request_handler.launch_manager.launch = raise_KeyError - # Delete instance in fake-provider by unlocking it and allowing it to - # become unused. This should cause provider2 to service the request - # that was held pending by fake-provider. + # Delete instance in fake-provider. This should cause provider2 + # to service the request that was held pending by fake-provider. + provider1_first.state = zk.DELETING + self.zk.storeNode(provider1_first) self.zk.unlockNode(provider1_first) # Request is fulfilled by provider 2 diff --git a/nodepool/zk.py b/nodepool/zk.py index 3bb9cdc79..6e123ccde 100755 --- a/nodepool/zk.py +++ b/nodepool/zk.py @@ -1671,7 +1671,11 @@ class ZooKeeper(object): candidates = [] for node in self.nodeIterator(): if node.provider == provider_name and node.pool == pool_name: - if node.state == READY: + # A READY node that has been allocated will not be considered + # a candidate at this point. If allocated_to gets reset during + # the cleanup phase b/c the request disappears, then it can + # become a candidate. + if node.state == READY and not node.allocated_to: candidates.append(node) elif (node.state == DELETING and (time.time() - node.state_time / 1000) < MAX_DELETE_AGE