Skip to content

Commit d4b3efc

Browse files
authored
Merge pull request #42 from stackhpc/upstream/yoga-2023-04-24
Synchronise yoga with upstream
2 parents c961363 + b3dc3ff commit d4b3efc

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

neutron/agent/linux/ip_lib.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,10 @@ def filter_device(device, filters):
578578
return filtered_devices
579579

580580
def wait_until_address_ready(self, address, wait_time=30):
581-
"""Wait until an address is no longer marked 'tentative'
581+
"""Wait until an address is no longer marked 'tentative' or 'dadfailed'
582582
583-
raises AddressNotReady if times out or address not present on interface
583+
raises AddressNotReady if times out, address not present on interface
584+
or DAD fails
584585
"""
585586
def is_address_ready():
586587
try:
@@ -589,12 +590,14 @@ def is_address_ready():
589590
raise AddressNotReady(
590591
address=address,
591592
reason=_('Address not present on interface'))
592-
if not addr_info['tentative']:
593-
return True
593+
# Since both 'dadfailed' and 'tentative' will be set if DAD fails,
594+
# check 'dadfailed' first just to be explicit
594595
if addr_info['dadfailed']:
595596
raise AddressNotReady(
596597
address=address, reason=_('Duplicate address detected'))
597-
return False
598+
if addr_info['tentative']:
599+
return False
600+
return True
598601
errmsg = _("Exceeded %s second limit waiting for "
599602
"address to leave the tentative state.") % wait_time
600603
common_utils.wait_until_true(

neutron/tests/unit/agent/linux/test_ip_lib.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@ def test_flush(self, flush):
776776
6, self.parent.name, self.addr_cmd._parent.namespace)
777777

778778
def test_wait_until_address_ready(self):
779-
self.addr_cmd.list = mock.Mock(return_value=[{'tentative': False}])
779+
self.addr_cmd.list = mock.Mock(
780+
return_value=[{'tentative': False, 'dadfailed': False}])
780781
# this address is not tentative or failed so it should return
781782
self.assertIsNone(self.addr_cmd.wait_until_address_ready(
782783
'2001:470:9:1224:fd91:272:581e:3a32'))
@@ -786,6 +787,24 @@ def test_wait_until_address_ready_non_existent_address(self):
786787
with testtools.ExpectedException(ip_lib.AddressNotReady):
787788
self.addr_cmd.wait_until_address_ready('abcd::1234')
788789

790+
def test_wait_until_address_dadfailed(self):
791+
self.addr_cmd.list = mock.Mock(
792+
return_value=[{'tentative': True, 'dadfailed': True}])
793+
with testtools.ExpectedException(ip_lib.AddressNotReady):
794+
self.addr_cmd.wait_until_address_ready('abcd::1234')
795+
796+
@mock.patch.object(common_utils, 'wait_until_true')
797+
def test_wait_until_address_ready_success_one_timeout(self, mock_wuntil):
798+
tentative_address = 'fe80::3023:39ff:febc:22ae'
799+
self.addr_cmd.list = mock.Mock(return_value=[
800+
dict(scope='link', dadfailed=False, tentative=True, dynamic=False,
801+
cidr=tentative_address + '/64'),
802+
dict(scope='link', dadfailed=False, tentative=False, dynamic=False,
803+
cidr=tentative_address + '/64')])
804+
self.assertIsNone(self.addr_cmd.wait_until_address_ready(
805+
tentative_address, wait_time=3))
806+
self.assertEqual(1, mock_wuntil.call_count)
807+
789808
def test_wait_until_address_ready_timeout(self):
790809
tentative_address = 'fe80::3023:39ff:febc:22ae'
791810
self.addr_cmd.list = mock.Mock(return_value=[

0 commit comments

Comments
 (0)