Change flag check order in wait_until_address_ready()
When DAD fails on an IPv6 address, both the 'dadfailed' and 'tentative' flags will be set. So change the code to check for 'dadfailed' first, just to be explicit. Added better unit testing to cover more cases as well. Trivialfix Change-Id: I2dddc296826e5ab5e057c32a554e353577cc36e8
This commit is contained in:
parent
b71b25820b
commit
1d22cfa99a
|
@ -586,9 +586,10 @@ class IpAddrCommand(IpDeviceCommandBase):
|
||||||
return filtered_devices
|
return filtered_devices
|
||||||
|
|
||||||
def wait_until_address_ready(self, address, wait_time=30):
|
def wait_until_address_ready(self, address, wait_time=30):
|
||||||
"""Wait until an address is no longer marked 'tentative'
|
"""Wait until an address is no longer marked 'tentative' or 'dadfailed'
|
||||||
|
|
||||||
raises AddressNotReady if times out or address not present on interface
|
raises AddressNotReady if times out, address not present on interface
|
||||||
|
or DAD fails
|
||||||
"""
|
"""
|
||||||
def is_address_ready():
|
def is_address_ready():
|
||||||
try:
|
try:
|
||||||
|
@ -597,12 +598,14 @@ class IpAddrCommand(IpDeviceCommandBase):
|
||||||
raise AddressNotReady(
|
raise AddressNotReady(
|
||||||
address=address,
|
address=address,
|
||||||
reason=_('Address not present on interface'))
|
reason=_('Address not present on interface'))
|
||||||
if not addr_info['tentative']:
|
# Since both 'dadfailed' and 'tentative' will be set if DAD fails,
|
||||||
return True
|
# check 'dadfailed' first just to be explicit
|
||||||
if addr_info['dadfailed']:
|
if addr_info['dadfailed']:
|
||||||
raise AddressNotReady(
|
raise AddressNotReady(
|
||||||
address=address, reason=_('Duplicate address detected'))
|
address=address, reason=_('Duplicate address detected'))
|
||||||
return False
|
if addr_info['tentative']:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
errmsg = _("Exceeded %s second limit waiting for "
|
errmsg = _("Exceeded %s second limit waiting for "
|
||||||
"address to leave the tentative state.") % wait_time
|
"address to leave the tentative state.") % wait_time
|
||||||
common_utils.wait_until_true(
|
common_utils.wait_until_true(
|
||||||
|
|
|
@ -777,7 +777,8 @@ class TestIpAddrCommand(TestIPCmdBase):
|
||||||
6, self.parent.name, self.addr_cmd._parent.namespace)
|
6, self.parent.name, self.addr_cmd._parent.namespace)
|
||||||
|
|
||||||
def test_wait_until_address_ready(self):
|
def test_wait_until_address_ready(self):
|
||||||
self.addr_cmd.list = mock.Mock(return_value=[{'tentative': False}])
|
self.addr_cmd.list = mock.Mock(
|
||||||
|
return_value=[{'tentative': False, 'dadfailed': False}])
|
||||||
# this address is not tentative or failed so it should return
|
# this address is not tentative or failed so it should return
|
||||||
self.assertIsNone(self.addr_cmd.wait_until_address_ready(
|
self.assertIsNone(self.addr_cmd.wait_until_address_ready(
|
||||||
'2001:470:9:1224:fd91:272:581e:3a32'))
|
'2001:470:9:1224:fd91:272:581e:3a32'))
|
||||||
|
@ -787,6 +788,24 @@ class TestIpAddrCommand(TestIPCmdBase):
|
||||||
with testtools.ExpectedException(ip_lib.AddressNotReady):
|
with testtools.ExpectedException(ip_lib.AddressNotReady):
|
||||||
self.addr_cmd.wait_until_address_ready('abcd::1234')
|
self.addr_cmd.wait_until_address_ready('abcd::1234')
|
||||||
|
|
||||||
|
def test_wait_until_address_dadfailed(self):
|
||||||
|
self.addr_cmd.list = mock.Mock(
|
||||||
|
return_value=[{'tentative': True, 'dadfailed': True}])
|
||||||
|
with testtools.ExpectedException(ip_lib.AddressNotReady):
|
||||||
|
self.addr_cmd.wait_until_address_ready('abcd::1234')
|
||||||
|
|
||||||
|
@mock.patch.object(common_utils, 'wait_until_true')
|
||||||
|
def test_wait_until_address_ready_success_one_timeout(self, mock_wuntil):
|
||||||
|
tentative_address = 'fe80::3023:39ff:febc:22ae'
|
||||||
|
self.addr_cmd.list = mock.Mock(return_value=[
|
||||||
|
dict(scope='link', dadfailed=False, tentative=True, dynamic=False,
|
||||||
|
cidr=tentative_address + '/64'),
|
||||||
|
dict(scope='link', dadfailed=False, tentative=False, dynamic=False,
|
||||||
|
cidr=tentative_address + '/64')])
|
||||||
|
self.assertIsNone(self.addr_cmd.wait_until_address_ready(
|
||||||
|
tentative_address, wait_time=3))
|
||||||
|
self.assertEqual(1, mock_wuntil.call_count)
|
||||||
|
|
||||||
def test_wait_until_address_ready_timeout(self):
|
def test_wait_until_address_ready_timeout(self):
|
||||||
tentative_address = 'fe80::3023:39ff:febc:22ae'
|
tentative_address = 'fe80::3023:39ff:febc:22ae'
|
||||||
self.addr_cmd.list = mock.Mock(return_value=[
|
self.addr_cmd.list = mock.Mock(return_value=[
|
||||||
|
|
Loading…
Reference in New Issue