Fix potential race condition in lbaas v2 logic

In the event that multiple resources under the same loadbalancer get
the affirmative that the loadbalancer is no longer updating before
either of those resources actually perform their action, neutron will
throw a PENDING_UPDATE error when the second resource attempts to
perform its action.

This patch implements the "better to ask forgiveness than to ask for
permmission" adage. Instead of checking whether the loadbalancer is
ready for an action to be performed, we should just try the action.
If it fails, we catch the error and try again later.

Closes-Bug: #1552724

Change-Id: I9f6e164ed838aa298a41b4ed2a6061a927787a4c
This commit is contained in:
Jenkins 2016-03-02 13:47:46 +00:00 committed by Bryan Jones
parent e37e73e63d
commit 8a799a42ed
9 changed files with 178 additions and 139 deletions

View File

@ -68,6 +68,9 @@ class NeutronClientPlugin(client_plugin.ClientPlugin):
def is_no_unique(self, ex):
return isinstance(ex, exceptions.NeutronClientNoUniqueMatch)
def is_invalid(self, ex):
return isinstance(ex, exceptions.StateInvalidClient)
def find_resourceid_by_name_or_id(self, resource, name_or_id,
cmd_resource=None):
return self._find_resource_id(self.context.tenant_id,

View File

@ -172,16 +172,17 @@ class HealthMonitor(neutron.NeutronResource):
return properties
def check_create_complete(self, properties):
if not self._check_lb_status():
return False
if self.resource_id is None:
healthmonitor = self.client().create_lbaas_healthmonitor(
{'healthmonitor': properties})['healthmonitor']
self.resource_id_set(healthmonitor['id'])
return False
try:
healthmonitor = self.client().create_lbaas_healthmonitor(
{'healthmonitor': properties})['healthmonitor']
self.resource_id_set(healthmonitor['id'])
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
return True
return self._check_lb_status()
def _show_resource(self):
return self.client().show_lbaas_healthmonitor(
@ -195,15 +196,17 @@ class HealthMonitor(neutron.NeutronResource):
if not prop_diff:
return True
if self._update_called:
return self._check_lb_status()
if not self._update_called:
try:
self.client().update_lbaas_healthmonitor(
self.resource_id, {'healthmonitor': prop_diff})
self._update_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
if self._check_lb_status():
self.client().update_lbaas_healthmonitor(
self.resource_id, {'healthmonitor': prop_diff})
self._update_called = True
return False
return self._check_lb_status()
def handle_delete(self):
self._delete_called = False
@ -212,15 +215,18 @@ class HealthMonitor(neutron.NeutronResource):
if self.resource_id is None:
return True
if self._delete_called:
return self._check_lb_status()
if self._check_lb_status():
with self.client_plugin().ignore_not_found:
if not self._delete_called:
try:
self.client().delete_lbaas_healthmonitor(self.resource_id)
self._delete_called = True
self._delete_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
elif self.client_plugin().is_not_found(ex):
return True
raise
return False
return self._check_lb_status()
def resource_mapping():

View File

@ -174,16 +174,17 @@ class Listener(neutron.NeutronResource):
return properties
def check_create_complete(self, properties):
if not self._check_lb_status():
return False
if self.resource_id is None:
listener = self.client().create_listener(
{'listener': properties})['listener']
self.resource_id_set(listener['id'])
return False
try:
listener = self.client().create_listener(
{'listener': properties})['listener']
self.resource_id_set(listener['id'])
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
return True
return self._check_lb_status()
def _show_resource(self):
return self.client().show_listener(
@ -197,15 +198,17 @@ class Listener(neutron.NeutronResource):
if not prop_diff:
return True
if self._update_called:
return self._check_lb_status()
if not self._update_called:
try:
self.client().update_listener(self.resource_id,
{'listener': prop_diff})
self._update_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
if self._check_lb_status():
self.client().update_listener(self.resource_id,
{'listener': prop_diff})
self._update_called = True
return False
return self._check_lb_status()
def handle_delete(self):
self._delete_called = False
@ -214,15 +217,18 @@ class Listener(neutron.NeutronResource):
if self.resource_id is None:
return True
if self._delete_called:
return self._check_lb_status()
if self._check_lb_status():
with self.client_plugin().ignore_not_found:
if not self._delete_called:
try:
self.client().delete_listener(self.resource_id)
self._delete_called = True
self._delete_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
elif self.client_plugin().is_not_found(ex):
return True
raise
return False
return self._check_lb_status()
def resource_mapping():

View File

@ -197,16 +197,17 @@ class Pool(neutron.NeutronResource):
return properties
def check_create_complete(self, properties):
if not self._check_lb_status():
return False
if self.resource_id is None:
pool = self.client().create_lbaas_pool(
{'pool': properties})['pool']
self.resource_id_set(pool['id'])
return False
try:
pool = self.client().create_lbaas_pool(
{'pool': properties})['pool']
self.resource_id_set(pool['id'])
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
return True
return self._check_lb_status()
def _show_resource(self):
return self.client().show_lbaas_pool(self.resource_id)['pool']
@ -219,15 +220,17 @@ class Pool(neutron.NeutronResource):
if not prop_diff:
return True
if self._update_called:
return self._check_lb_status()
if not self._update_called:
try:
self.client().update_lbaas_pool(
self.resource_id, {'pool': prop_diff})
self._update_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
if self._check_lb_status():
self.client().update_lbaas_pool(
self.resource_id, {'pool': prop_diff})
self._update_called = True
return False
return self._check_lb_status()
def handle_delete(self):
self._delete_called = False
@ -236,15 +239,18 @@ class Pool(neutron.NeutronResource):
if self.resource_id is None:
return True
if self._delete_called:
return self._check_lb_status()
if self._check_lb_status():
with self.client_plugin().ignore_not_found:
if not self._delete_called:
try:
self.client().delete_lbaas_pool(self.resource_id)
self._delete_called = True
self._delete_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
elif self.client_plugin().is_not_found(ex):
return True
raise
return False
return self._check_lb_status()
def resource_mapping():

View File

@ -142,6 +142,7 @@ class PoolMember(neutron.NeutronResource):
self.client_plugin().resolve_pool(
properties, self.POOL, 'pool_id')
properties.pop('pool_id')
if self.SUBNET in properties:
self.client_plugin().resolve_subnet(
@ -150,18 +151,17 @@ class PoolMember(neutron.NeutronResource):
return properties
def check_create_complete(self, properties):
if not self._check_lb_status():
return False
if self.resource_id is None:
pool_id = properties.pop('pool_id')
try:
member = self.client().create_lbaas_member(
self.pool_id, {'member': properties})['member']
self.resource_id_set(member['id'])
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
member = self.client().create_lbaas_member(
pool_id, {'member': properties})['member']
self.resource_id_set(member['id'])
return False
return True
return self._check_lb_status()
def _show_resource(self):
member = self.client().show_lbaas_member(self.resource_id,
@ -176,15 +176,18 @@ class PoolMember(neutron.NeutronResource):
if not prop_diff:
return True
if self._update_called:
return self._check_lb_status()
if not self._update_called:
try:
self.client().update_lbaas_member(self.resource_id,
self.pool_id,
{'member': prop_diff})
self._update_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
raise
if self._check_lb_status():
self.client().update_lbaas_member(self.resource_id, self.pool_id,
{'member': prop_diff})
self._update_called = True
return False
return self._check_lb_status()
def handle_delete(self):
self._delete_called = False
@ -193,16 +196,19 @@ class PoolMember(neutron.NeutronResource):
if self.resource_id is None:
return True
if self._delete_called:
return self._check_lb_status()
if self._check_lb_status():
with self.client_plugin().ignore_not_found:
if not self._delete_called:
try:
self.client().delete_lbaas_member(self.resource_id,
self.pool_id)
self._delete_called = True
self._delete_called = True
except Exception as ex:
if self.client_plugin().is_invalid(ex):
return False
elif self.client_plugin().is_not_found(ex):
return True
raise
return False
return self._check_lb_status()
def resource_mapping():

View File

@ -54,10 +54,13 @@ class HealthMonitorTest(common.HeatTestCase):
self._create_stack()
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.create_lbaas_healthmonitor.side_effect = [
exceptions.StateInvalidClient,
{'healthmonitor': {'id': '1234'}}
]
expected = {
'healthmonitor': {
'admin_state_up': True,
@ -75,6 +78,8 @@ class HealthMonitorTest(common.HeatTestCase):
props = self.healthmonitor.handle_create()
self.assertFalse(self.healthmonitor.check_create_complete(props))
self.neutron_client.create_lbaas_healthmonitor.assert_called_with(
expected)
self.assertFalse(self.healthmonitor.check_create_complete(props))
self.neutron_client.create_lbaas_healthmonitor.assert_called_with(
expected)
@ -95,10 +100,11 @@ class HealthMonitorTest(common.HeatTestCase):
self.healthmonitor.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.update_lbaas_healthmonitor.side_effect = [
exceptions.StateInvalidClient, None]
prop_diff = {
'admin_state_up': False,
}
@ -107,6 +113,8 @@ class HealthMonitorTest(common.HeatTestCase):
self.assertFalse(self.healthmonitor.check_update_complete(prop_diff))
self.assertFalse(self.healthmonitor._update_called)
self.neutron_client.update_lbaas_healthmonitor.assert_called_with(
'1234', {'healthmonitor': prop_diff})
self.assertFalse(self.healthmonitor.check_update_complete(prop_diff))
self.assertTrue(self.healthmonitor._update_called)
self.neutron_client.update_lbaas_healthmonitor.assert_called_with(
@ -119,15 +127,18 @@ class HealthMonitorTest(common.HeatTestCase):
self.healthmonitor.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_healthmonitor.side_effect = [
exceptions.StateInvalidClient, None]
self.healthmonitor.handle_delete()
self.assertFalse(self.healthmonitor.check_delete_complete(None))
self.assertFalse(self.healthmonitor._delete_called)
self.neutron_client.delete_lbaas_healthmonitor.assert_called_with(
'1234')
self.assertFalse(self.healthmonitor.check_delete_complete(None))
self.assertTrue(self.healthmonitor._delete_called)
self.neutron_client.delete_lbaas_healthmonitor.assert_called_with(
@ -138,16 +149,11 @@ class HealthMonitorTest(common.HeatTestCase):
def test_delete_already_gone(self):
self._create_stack()
self.healthmonitor.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_healthmonitor.side_effect = (
exceptions.NotFound)
self.healthmonitor.handle_delete()
self.assertFalse(self.healthmonitor.check_delete_complete(None))
self.assertTrue(self.healthmonitor.check_delete_complete(None))
self.neutron_client.delete_lbaas_healthmonitor.assert_called_with(
'1234')
@ -155,9 +161,6 @@ class HealthMonitorTest(common.HeatTestCase):
def test_delete_failed(self):
self._create_stack()
self.healthmonitor.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_healthmonitor.side_effect = (
exceptions.Unauthorized)

View File

@ -66,10 +66,13 @@ class ListenerTest(common.HeatTestCase):
self._create_stack()
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.create_listener.side_effect = [
exceptions.StateInvalidClient,
{'listener': {'id': '1234'}}
]
expected = {
'listener': {
'protocol_port': 80,
@ -88,6 +91,7 @@ class ListenerTest(common.HeatTestCase):
props = self.listener.handle_create()
self.assertFalse(self.listener.check_create_complete(props))
self.neutron_client.create_listener.assert_called_with(expected)
self.assertFalse(self.listener.check_create_complete(props))
self.neutron_client.create_listener.assert_called_with(expected)
self.assertFalse(self.listener.check_create_complete(props))
@ -109,10 +113,11 @@ class ListenerTest(common.HeatTestCase):
self.listener.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.update_listener.side_effect = [
exceptions.StateInvalidClient, None]
prop_diff = {
'admin_state_up': False,
'name': 'your_listener',
@ -122,6 +127,8 @@ class ListenerTest(common.HeatTestCase):
self.assertFalse(self.listener.check_update_complete(prop_diff))
self.assertFalse(self.listener._update_called)
self.neutron_client.update_listener.assert_called_with(
'1234', {'listener': prop_diff})
self.assertFalse(self.listener.check_update_complete(prop_diff))
self.assertTrue(self.listener._update_called)
self.neutron_client.update_listener.assert_called_with(
@ -134,15 +141,17 @@ class ListenerTest(common.HeatTestCase):
self.listener.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_listener.side_effect = [
exceptions.StateInvalidClient, None]
self.listener.handle_delete()
self.assertFalse(self.listener.check_delete_complete(None))
self.assertFalse(self.listener._delete_called)
self.neutron_client.delete_listener.assert_called_with('1234')
self.assertFalse(self.listener.check_delete_complete(None))
self.assertTrue(self.listener._delete_called)
self.neutron_client.delete_listener.assert_called_with('1234')
@ -152,23 +161,15 @@ class ListenerTest(common.HeatTestCase):
def test_delete_already_gone(self):
self._create_stack()
self.listener.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_listener.side_effect = (
exceptions.NotFound)
self.listener.handle_delete()
self.assertFalse(self.listener.check_delete_complete(None))
self.assertTrue(self.listener.check_delete_complete(None))
def test_delete_failed(self):
self._create_stack()
self.listener.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_listener.side_effect = (
exceptions.Unauthorized)

View File

@ -84,10 +84,13 @@ class PoolTest(common.HeatTestCase):
self._create_stack()
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.create_lbaas_pool.side_effect = [
exceptions.StateInvalidClient,
{'pool': {'id': '1234'}}
]
expected = {
'pool': {
'name': 'my_pool',
@ -105,6 +108,7 @@ class PoolTest(common.HeatTestCase):
props = self.pool.handle_create()
self.assertFalse(self.pool.check_create_complete(props))
self.neutron_client.create_lbaas_pool.assert_called_with(expected)
self.assertFalse(self.pool.check_create_complete(props))
self.neutron_client.create_lbaas_pool.assert_called_with(expected)
self.assertFalse(self.pool.check_create_complete(props))
@ -135,10 +139,11 @@ class PoolTest(common.HeatTestCase):
self.pool.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.update_lbaas_pool.side_effect = [
exceptions.StateInvalidClient, None]
prop_diff = {
'admin_state_up': False,
'name': 'your_pool',
@ -149,6 +154,8 @@ class PoolTest(common.HeatTestCase):
self.assertFalse(self.pool.check_update_complete(prop_diff))
self.assertFalse(self.pool._update_called)
self.neutron_client.update_lbaas_pool.assert_called_with(
'1234', {'pool': prop_diff})
self.assertFalse(self.pool.check_update_complete(prop_diff))
self.assertTrue(self.pool._update_called)
self.neutron_client.update_lbaas_pool.assert_called_with(
@ -161,10 +168,11 @@ class PoolTest(common.HeatTestCase):
self.pool.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_pool.side_effect = [
exceptions.StateInvalidClient, None]
self.pool.handle_delete()
@ -179,23 +187,15 @@ class PoolTest(common.HeatTestCase):
def test_delete_already_gone(self):
self._create_stack()
self.pool.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_pool.side_effect = (
exceptions.NotFound)
self.pool.handle_delete()
self.assertFalse(self.pool.check_delete_complete(None))
self.assertTrue(self.pool.check_delete_complete(None))
def test_delete_failed(self):
self._create_stack()
self.pool.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_pool.side_effect = (
exceptions.Unauthorized)

View File

@ -51,10 +51,13 @@ class PoolMemberTest(common.HeatTestCase):
self._create_stack()
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.create_lbaas_member.side_effect = [
exceptions.StateInvalidClient,
{'member': {'id': '1234'}}
]
expected = {
'member': {
'address': '1.2.3.4',
@ -68,6 +71,8 @@ class PoolMemberTest(common.HeatTestCase):
props = self.member.handle_create()
self.assertFalse(self.member.check_create_complete(props))
self.neutron_client.create_lbaas_member.assert_called_with('123',
expected)
self.assertFalse(self.member.check_create_complete(props))
self.neutron_client.create_lbaas_member.assert_called_with('123',
expected)
@ -89,10 +94,13 @@ class PoolMemberTest(common.HeatTestCase):
self._create_stack(tmpl=tmpl)
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.create_lbaas_member.side_effect = [
exceptions.StateInvalidClient,
{'member': {'id': '1234'}}
]
expected = {
'member': {
'address': '1.2.3.4',
@ -105,6 +113,8 @@ class PoolMemberTest(common.HeatTestCase):
props = self.member.handle_create()
self.assertFalse(self.member.check_create_complete(props))
self.neutron_client.create_lbaas_member.assert_called_with('123',
expected)
self.assertFalse(self.member.check_create_complete(props))
self.neutron_client.create_lbaas_member.assert_called_with('123',
expected)
@ -127,10 +137,11 @@ class PoolMemberTest(common.HeatTestCase):
self.member.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.update_lbaas_member.side_effect = [
exceptions.StateInvalidClient, None]
prop_diff = {
'admin_state_up': False,
'weight': 2,
@ -140,6 +151,8 @@ class PoolMemberTest(common.HeatTestCase):
self.assertFalse(self.member.check_update_complete(prop_diff))
self.assertFalse(self.member._update_called)
self.neutron_client.update_lbaas_member.assert_called_with(
'1234', '123', {'member': prop_diff})
self.assertFalse(self.member.check_update_complete(prop_diff))
self.assertTrue(self.member._update_called)
self.neutron_client.update_lbaas_member.assert_called_with(
@ -152,15 +165,18 @@ class PoolMemberTest(common.HeatTestCase):
self.member.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'PENDING_UPDATE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_member.side_effect = [
exceptions.StateInvalidClient, None]
self.member.handle_delete()
self.assertFalse(self.member.check_delete_complete(None))
self.assertFalse(self.member._delete_called)
self.neutron_client.delete_lbaas_member.assert_called_with('1234',
'123')
self.assertFalse(self.member.check_delete_complete(None))
self.assertTrue(self.member._delete_called)
self.neutron_client.delete_lbaas_member.assert_called_with('1234',
@ -171,24 +187,16 @@ class PoolMemberTest(common.HeatTestCase):
def test_delete_already_gone(self):
self._create_stack()
self.member.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_member.side_effect = (
exceptions.NotFound)
self.member.handle_delete()
self.assertFalse(self.member.check_delete_complete(None))
self.assertTrue(self.member.check_delete_complete(None))
def test_delete_failed(self):
self._create_stack()
self.member.resource_id_set('1234')
self.neutron_client.show_loadbalancer.side_effect = [
{'loadbalancer': {'provisioning_status': 'ACTIVE'}},
]
self.neutron_client.delete_lbaas_member.side_effect = (
exceptions.Unauthorized)