Construct exceptions before passing to retryrequest

The IP allocation failure constructions weren't being constructed
before being passed to RetryRequest so they would fail to be reraised
after the retries were exhausted.

This patch just constructs them and adjusts a few of the unit tests
to execute the full retry life-cycle.

Closes-Bug: #1555387
Change-Id: I1c1ea488886ee3f4790eaa53911ea5845f327334
This commit is contained in:
Kevin Benton 2016-03-09 16:08:06 -08:00
parent 48649d83aa
commit 2dc9d67f6e
4 changed files with 26 additions and 19 deletions

View File

@ -164,7 +164,7 @@ class IpamSubnetManager(object):
first_ip=db_range.first_ip).filter_by(
last_ip=db_range.last_ip).update(opts)
except orm_exc.ObjectDeletedError:
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed)
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed())
def delete_range(self, session, db_range):
"""Return count of deleted ranges
@ -179,7 +179,7 @@ class IpamSubnetManager(object):
first_ip=db_range.first_ip).filter_by(
last_ip=db_range.last_ip).delete()
except orm_exc.ObjectDeletedError:
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed)
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed())
def create_range(self, session, allocation_pool_id,
range_start, range_end):

View File

@ -198,7 +198,7 @@ class NeutronDbSubnet(ipam_base.Subnet):
ip_in_pools = True
# Range exhausted - bye bye
if not self.subnet_manager.delete_range(session, db_range):
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed)
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed())
continue
if initial_ip_set == final_ip_set:
# IP address does not fall within the current range, move
@ -218,7 +218,8 @@ class NeutronDbSubnet(ipam_base.Subnet):
rows = self.subnet_manager.update_range(
session, db_range, first_ip=first_ip, last_ip=last_ip)
if not rows:
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed)
raise db_exc.RetryRequest(
ipam_exc.IPAllocationFailed())
LOG.debug("Adjusted availability range for pool %s",
db_range['allocation_pool_id'])
final_ranges.append(db_range)
@ -235,7 +236,7 @@ class NeutronDbSubnet(ipam_base.Subnet):
# If ip is autogenerated it should be present in allocation pools,
# so retry if it is not there
if auto_generated and not ip_in_pools:
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed)
raise db_exc.RetryRequest(ipam_exc.IPAllocationFailed())
# Most callers might ignore this return value, which is however
# useful for testing purposes
LOG.debug("Availability ranges for subnet id %(subnet_id)s "

View File

@ -15,11 +15,11 @@
import mock
from oslo_db import exception as db_exc
from oslo_utils import uuidutils
from sqlalchemy.orm import exc as orm_exc
from neutron import context
from neutron.db import api as ndb_api
from neutron.ipam.drivers.neutrondb_ipam import db_api
from neutron.ipam.drivers.neutrondb_ipam import db_models
from neutron.ipam import exceptions as ipam_exc
@ -152,11 +152,13 @@ class TestIpamSubnetManager(testlib_api.SqlTestCase):
def test_update_range_reraise_error(self):
session = mock.Mock()
session.query.side_effect = orm_exc.ObjectDeletedError(None, None)
self.assertRaises(db_exc.RetryRequest,
self.subnet_manager.update_range,
session,
mock.Mock(),
first_ip='1.2.3.5')
@ndb_api.retry_db_errors
def go():
self.subnet_manager.update_range(session, mock.Mock(),
first_ip='1.2.3.5')
self.assertRaises(ipam_exc.IPAllocationFailed, go)
def test_delete_range(self):
self._create_pools([self.single_pool])
@ -168,10 +170,12 @@ class TestIpamSubnetManager(testlib_api.SqlTestCase):
def test_delete_range_reraise_error(self):
session = mock.Mock()
session.query.side_effect = orm_exc.ObjectDeletedError(None, None)
self.assertRaises(db_exc.RetryRequest,
self.subnet_manager.delete_range,
session,
mock.Mock())
@ndb_api.retry_db_errors
def go():
self.subnet_manager.delete_range(session, mock.Mock())
self.assertRaises(ipam_exc.IPAllocationFailed, go)
def test_check_unique_allocation(self):
self.assertTrue(self.subnet_manager.check_unique_allocation(

View File

@ -15,12 +15,12 @@
import mock
import netaddr
from oslo_db import exception as db_exc
from neutron.api.v2 import attributes
from neutron.common import constants
from neutron.common import exceptions as n_exc
from neutron import context
from neutron.db import api as ndb_api
from neutron.ipam.drivers.neutrondb_ipam import driver
from neutron.ipam import exceptions as ipam_exc
from neutron.ipam import requests as ipam_req
@ -455,6 +455,8 @@ class TestNeutronDbIpamSubnet(testlib_api.SqlTestCase,
'first_ip': '10.0.0.15', 'last_ip': '10.0.0.15'}]
ipam_subnet.subnet_manager.delete_range.return_value = 0
self.assertRaises(db_exc.RetryRequest,
ipam_subnet._allocate_specific_ip,
self.ctx.session, ip)
@ndb_api.retry_db_errors
def go():
ipam_subnet._allocate_specific_ip(self.ctx.session, ip)
self.assertRaises(ipam_exc.IPAllocationFailed, go)