From 29edea058848ad034e9440fbdf8b2231058227cf Mon Sep 17 00:00:00 2001 From: Hunt Xu Date: Sun, 23 Apr 2017 20:25:18 +0800 Subject: [PATCH] Fix errors in PrefixDelegation.remove_stale_ri_ifname Firstly fix a typo (iteriterms -> iteritems) introduced by [1]. Then a "dictionary changed size during iteration" RuntimeError is reported by the newly added unit test. [1] I17df98128c7a88e72e31251687f30f569df6b860. TrivialFix Change-Id: I70c548eab2264b3f94ba1a215f933046345411a7 Signed-off-by: Hunt Xu --- neutron/agent/linux/pd.py | 8 ++++++-- neutron/tests/unit/agent/linux/test_pd.py | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/neutron/agent/linux/pd.py b/neutron/agent/linux/pd.py index 32b882d117b..2899bcb6861 100644 --- a/neutron/agent/linux/pd.py +++ b/neutron/agent/linux/pd.py @@ -191,10 +191,14 @@ class PrefixDelegation(object): def remove_stale_ri_ifname(self, router_id, stale_ifname): router = self.routers.get(router_id) if router is not None: - for subnet_id, pd_info in six.iteriterms(router['subnets']): + subnet_to_delete = None + for subnet_id, pd_info in six.iteritems(router['subnets']): if pd_info.ri_ifname == stale_ifname: self._delete_pd(router, pd_info) - del router['subnets'][subnet_id] + subnet_to_delete = subnet_id + break + if subnet_to_delete: + del router['subnets'][subnet_to_delete] @staticmethod def _get_lla(mac): diff --git a/neutron/tests/unit/agent/linux/test_pd.py b/neutron/tests/unit/agent/linux/test_pd.py index e4b4c336ed1..525cca65e08 100644 --- a/neutron/tests/unit/agent/linux/test_pd.py +++ b/neutron/tests/unit/agent/linux/test_pd.py @@ -93,3 +93,23 @@ class TestPrefixDelegation(tests_base.DietTestCase): with mock.patch.object(pd.LOG, 'exception') as log: pd.update_router(None, None, l3_agent, router=router) self.assertTrue(log.called) + + def test_remove_stale_ri_ifname(self): + pd_info_1 = mock.Mock() + pd_info_1.ri_ifname = 'STALE' + pd_info_2 = mock.Mock() + pd_info_2.ri_ifname = 'NOT_STALE' + router = { + 'subnets': { + 'FAKE_SUBNET_ID1': pd_info_1, + 'FAKE_SUBNET_ID2': pd_info_2}} + + class FakePD(pd.PrefixDelegation): + def __init__(self, router): + self.routers = {'FAKE_ROUTER_ID': router} + + fake_pd = FakePD(router) + fake_pd._delete_pd = mock.Mock() + fake_pd.remove_stale_ri_ifname('FAKE_ROUTER_ID', 'STALE') + fake_pd._delete_pd.assert_called_with(router, pd_info_1) + self.assertEqual(len(router['subnets'].keys()), 1)