diff -Nru neutron-18.1.0/AUTHORS neutron-18.1.1/AUTHORS --- neutron-18.1.0/AUTHORS 2021-07-12 10:06:00.000000000 +0000 +++ neutron-18.1.1/AUTHORS 2021-09-10 15:10:02.000000000 +0000 @@ -898,6 +898,7 @@ Takaaki Suzuki Takashi Kajinami Takashi NATSUME +Takashi Natsume Takuma Watanabe Tamerlan Abu Tan Lin diff -Nru neutron-18.1.0/ChangeLog neutron-18.1.1/ChangeLog --- neutron-18.1.0/ChangeLog 2021-07-12 10:05:59.000000000 +0000 +++ neutron-18.1.1/ChangeLog 2021-09-10 15:10:01.000000000 +0000 @@ -1,6 +1,28 @@ CHANGES ======= +18.1.1 +------ + +* Don't use singleton in routes.middleware.RoutesMiddleware +* Skip DVR binding for ports with invalid OFPORT +* ovn: Consider all router ports in is\_lsp\_router\_port() +* Remove dhcp\_extra\_opt value after first newline character +* Do not fail if the agent load is not bumped +* Follow up for replacing assertItemsEqual +* Replace assertItemsEqual with assertCountEqual +* Add missing options to generated neutron.conf +* ovn: Don't fail db-sync if port binding changes +* [OVN] Fix Router Availability Zones for segmented networks +* Use elevated context when getting default SG for tenant +* Fix typo in OVN SUPPORTED\_DHCP\_OPTS\_MAPPING dictionary (ia-addr) +* Add extra logs to the network update callback in L3 agent +* Use elevated context to get default SG from database +* Implement namespace creation method +* Set "floatingip.fixed\_port" as viewonly +* [OVN] Fix ML2/OVN + Neutron DHCP agent use case +* ovn-migration: Delete FIP agent gateway ports + 18.1.0 ------ diff -Nru neutron-18.1.0/debian/changelog neutron-18.1.1/debian/changelog --- neutron-18.1.0/debian/changelog 2021-07-28 20:52:11.000000000 +0000 +++ neutron-18.1.1/debian/changelog 2021-10-01 06:42:37.000000000 +0000 @@ -1,3 +1,25 @@ +neutron (2:18.1.1-0ubuntu2) hirsute; urgency=medium + + * d/p/lp1934912-set-arp-entries-only-for-single-ip.patch: Cherry-pick + upstream patch (LP: #1934912) + + -- Chris MacNaughton Fri, 01 Oct 2021 06:42:37 +0000 + +neutron (2:18.1.1-0ubuntu1) hirsute; urgency=medium + + [ Corey Bryant ] + * d/control: Drop neutron-fwaas dependency as it is no longer maintained + (LP: #1934129). + * d/p/revert-rely-on-worker-count-for-hashring-caching.patch: Dropped. + Fixed upstream by https://review.opendev.org/c/openstack/neutron/+/800679 + in the 18.1.1 stable release. + + [ Chris MacNaughton ] + * New stable point release for OpenStack Wallaby (LP: #1943709). + * d/p/series: Remove reference to removed patch. + + -- Chris MacNaughton Wed, 15 Sep 2021 12:40:12 +0000 + neutron (2:18.1.0-0ubuntu2) hirsute; urgency=medium * d/p/revert-l3-ha-retry-when-setting-ha-router-gw-status.patch: Revert diff -Nru neutron-18.1.0/debian/control neutron-18.1.1/debian/control --- neutron-18.1.0/debian/control 2021-07-28 20:52:11.000000000 +0000 +++ neutron-18.1.1/debian/control 2021-10-01 06:42:37.000000000 +0000 @@ -148,7 +148,6 @@ keepalived, neutron-metadata-agent (= ${source:Version}), python3-neutron (= ${source:Version}), - python3-neutron-fwaas (>= 1:13.0.0~), radvd, ${misc:Depends}, ${python3:Depends}, diff -Nru neutron-18.1.0/debian/patches/lp1934912-set-arp-entries-only-for-single-ip.patch neutron-18.1.1/debian/patches/lp1934912-set-arp-entries-only-for-single-ip.patch --- neutron-18.1.0/debian/patches/lp1934912-set-arp-entries-only-for-single-ip.patch 1970-01-01 00:00:00.000000000 +0000 +++ neutron-18.1.1/debian/patches/lp1934912-set-arp-entries-only-for-single-ip.patch 2021-10-01 06:42:37.000000000 +0000 @@ -0,0 +1,89 @@ +From 5418912b705393b165c455507bc7b09cb9141f58 Mon Sep 17 00:00:00 2001 +From: Slawek Kaplonski +Date: Thu, 08 Jul 2021 15:53:39 +0200 +Subject: [PATCH] [DVR] Set arp entries only for single IPs given as allowed addr pair + +In allowed address pairs of the port there can be given not single IP +address but whole CIDR. In such case ARP entries for IPs from such +cidr will not be added in the DVR router namespace. + +Closes-Bug: #1934912 +Change-Id: I7bdefea943379125f93b116bb899446b874d9505 +(cherry picked from commit 19375b3e78ad6b635793b716e5ecabd53dc73a76) +--- + +diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py +index 135df6a..ff1fb55 100644 +--- a/neutron/agent/l3/dvr_local_router.py ++++ b/neutron/agent/l3/dvr_local_router.py +@@ -365,12 +365,18 @@ + device=device, + device_exists=device_exists) + for allowed_address_pair in p.get('allowed_address_pairs', []): +- self._update_arp_entry(allowed_address_pair['ip_address'], +- allowed_address_pair['mac_address'], +- subnet_id, +- 'add', +- device=device, +- device_exists=device_exists) ++ if ('/' not in str(allowed_address_pair['ip_address']) or ++ common_utils.is_cidr_host( ++ allowed_address_pair['ip_address'])): ++ ip_address = common_utils.cidr_to_ip( ++ allowed_address_pair['ip_address']) ++ self._update_arp_entry( ++ ip_address, ++ allowed_address_pair['mac_address'], ++ subnet_id, ++ 'add', ++ device=device, ++ device_exists=device_exists) + + # subnet_ports does not have snat port if the port is still unbound + # by the time this function is called. So ensure to add arp entry +diff --git a/neutron/tests/functional/agent/l3/test_dvr_router.py b/neutron/tests/functional/agent/l3/test_dvr_router.py +index 5f5a17e..1ef6646 100644 +--- a/neutron/tests/functional/agent/l3/test_dvr_router.py ++++ b/neutron/tests/functional/agent/l3/test_dvr_router.py +@@ -1005,13 +1005,18 @@ + # cache is properly populated. + self.agent.conf.agent_mode = 'dvr_snat' + router_info = self.generate_dvr_router_info(enable_snat=True) +- expected_neighbors = ['35.4.1.10', '10.0.0.10'] ++ expected_neighbors = ['35.4.1.10', '10.0.0.10', '10.200.0.3'] ++ allowed_address_net = netaddr.IPNetwork('10.100.0.0/30') + port_data = { + 'fixed_ips': [{'ip_address': expected_neighbors[0]}], + 'mac_address': 'fa:3e:aa:bb:cc:dd', + 'device_owner': DEVICE_OWNER_COMPUTE, + 'allowed_address_pairs': [ + {'ip_address': expected_neighbors[1], ++ 'mac_address': 'fa:3e:aa:bb:cc:dd'}, ++ {'ip_address': '10.200.0.3/32', ++ 'mac_address': 'fa:3e:aa:bb:cc:dd'}, ++ {'ip_address': str(allowed_address_net), + 'mac_address': 'fa:3e:aa:bb:cc:dd'}] + } + self.agent.plugin_rpc.get_ports_by_subnet.return_value = [port_data] +@@ -1019,11 +1024,18 @@ + internal_device = router1.get_internal_device_name( + router_info['_interfaces'][0]['id']) + for expected_neighbor in expected_neighbors: +- neighbor = ip_lib.dump_neigh_entries(4, internal_device, +- router1.ns_name, +- dst=expected_neighbor) ++ neighbor = ip_lib.dump_neigh_entries( ++ lib_constants.IP_VERSION_4, internal_device, ++ router1.ns_name, ++ dst=expected_neighbor) + self.assertNotEqual([], neighbor) + self.assertEqual(expected_neighbor, neighbor[0]['dst']) ++ for not_expected_neighbor in allowed_address_net: ++ neighbor = ip_lib.dump_neigh_entries( ++ lib_constants.IP_VERSION_4, internal_device, ++ router1.ns_name, ++ dst=str(not_expected_neighbor)) ++ self.assertEqual([], neighbor) + + def _assert_rfp_fpr_mtu(self, router, expected_mtu=1500): + dev_mtu = self.get_device_mtu( diff -Nru neutron-18.1.0/debian/patches/revert-rely-on-worker-count-for-hashring-caching.patch neutron-18.1.1/debian/patches/revert-rely-on-worker-count-for-hashring-caching.patch --- neutron-18.1.0/debian/patches/revert-rely-on-worker-count-for-hashring-caching.patch 2021-07-28 20:52:11.000000000 +0000 +++ neutron-18.1.1/debian/patches/revert-rely-on-worker-count-for-hashring-caching.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -From 8c1f564ce3c3f31836f2e8f7232294f276e55bdb Mon Sep 17 00:00:00 2001 -From: Corey Bryant -Date: Tue, 8 Jun 2021 10:40:17 -0400 -Subject: [PATCH] Revert "Rely on worker count for HashRing caching" - -This reverts commit c4007b0833111a25d24f597161d39ee9ccd37189. ---- - neutron/common/ovn/hash_ring_manager.py | 27 ++++++++++--------- - .../drivers/ovn/mech_driver/mech_driver.py | 19 +++++-------- - neutron/tests/functional/base.py | 5 ---- - .../mech_driver/ovsdb/test_ovsdb_monitor.py | 2 +- - .../unit/common/ovn/test_hash_ring_manager.py | 19 +++++++------ - 5 files changed, 32 insertions(+), 40 deletions(-) - -diff --git a/neutron/common/ovn/hash_ring_manager.py b/neutron/common/ovn/hash_ring_manager.py -index 1d1886b53a..95ea7255b8 100644 ---- a/neutron/common/ovn/hash_ring_manager.py -+++ b/neutron/common/ovn/hash_ring_manager.py -@@ -22,7 +22,6 @@ from tooz import hashring - from neutron.common.ovn import constants - from neutron.common.ovn import exceptions - from neutron.db import ovn_hash_ring_db as db_hash_ring --from neutron import service - from neutron_lib import context - - LOG = log.getLogger(__name__) -@@ -33,7 +32,7 @@ class HashRingManager(object): - def __init__(self, group_name): - self._hash_ring = None - self._last_time_loaded = None -- self._check_hashring_startup = True -+ self._cache_startup_timeout = True - self._group = group_name - self.admin_ctx = context.get_admin_context() - -@@ -42,26 +41,28 @@ class HashRingManager(object): - # NOTE(lucasagomes): Some events are processed at the service's - # startup time and since many services may be started concurrently - # we do not want to use a cached hash ring at that point. This -- # method ensures that we start allowing the use of cached HashRings -- # once the number of HashRing nodes >= the number of api workers. -+ # method checks if the created_at and updated_at columns from the -+ # nodes in the ring from this host is equal, and if so it means -+ # that the service just started. - - # If the startup timeout already expired, there's no reason to - # keep reading from the DB. At this point this will always - # return False -- if not self._check_hashring_startup: -+ if not self._cache_startup_timeout: - return False - -- api_workers = service._get_api_workers() - nodes = db_hash_ring.get_active_nodes( - self.admin_ctx, - constants.HASH_RING_CACHE_TIMEOUT, self._group, from_host=True) -- -- if len(nodes) >= api_workers: -- LOG.debug("Allow caching, nodes %s>=%s", len(nodes), api_workers) -- self._check_hashring_startup = False -- return False -- LOG.debug("Disallow caching, nodes %s<%s", len(nodes), api_workers) -- return True -+ # created_at and updated_at differ in microseonds so we compare their -+ # difference is less than a second to be safe on slow machines -+ dont_cache = nodes and ( -+ nodes[0].updated_at - nodes[0].created_at < datetime.timedelta( -+ seconds=1)) -+ if not dont_cache: -+ self._cache_startup_timeout = False -+ -+ return dont_cache - - def _load_hash_ring(self, refresh=False): - cache_timeout = timeutils.utcnow() - datetime.timedelta( -diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py -index efbf23d226..dcdc25002b 100644 ---- a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py -+++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py -@@ -60,7 +60,6 @@ from neutron.services.logapi.drivers.ovn import driver as log_driver - from neutron.services.qos.drivers.ovn import driver as qos_driver - from neutron.services.segments import db as segment_service_db - from neutron.services.trunk.drivers.ovn import trunk_driver --import neutron.wsgi - - - LOG = log.getLogger(__name__) -@@ -279,22 +278,16 @@ class OVNMechanismDriver(api.MechanismDriver): - else: - raise - -- @staticmethod -- def should_post_fork_initialize(worker_class): -- return worker_class in (neutron.wsgi.WorkerService, -- worker.MaintenanceWorker) -- - def post_fork_initialize(self, resource, event, trigger, payload=None): -- # Initialize API/Maintenance workers with OVN IDL connections -- worker_class = ovn_utils.get_method_class(trigger) -- if not self.should_post_fork_initialize(worker_class): -- return -- -+ # NOTE(rtheis): This will initialize all workers (API, RPC, -+ # plugin service and OVN) with OVN IDL connections. - self._post_fork_event.clear() - self._wait_for_pg_drop_event() - self._ovn_client_inst = None - -- if worker_class == neutron.wsgi.WorkerService: -+ is_maintenance = (ovn_utils.get_method_class(trigger) == -+ worker.MaintenanceWorker) -+ if not is_maintenance: - admin_context = n_context.get_admin_context() - self.node_uuid = ovn_hash_ring_db.add_node(admin_context, - self.hash_ring_group) -@@ -315,7 +308,7 @@ class OVNMechanismDriver(api.MechanismDriver): - # Now IDL connections can be safely used. - self._post_fork_event.set() - -- if worker_class == worker.MaintenanceWorker: -+ if is_maintenance: - # Call the synchronization task if its maintenance worker - # This sync neutron DB to OVN-NB DB only in inconsistent states - self.nb_synchronizer = ovn_db_sync.OvnNbSynchronizer( -diff --git a/neutron/tests/functional/base.py b/neutron/tests/functional/base.py -index 945580a6cf..fd1a5f2d16 100644 ---- a/neutron/tests/functional/base.py -+++ b/neutron/tests/functional/base.py -@@ -44,13 +44,11 @@ from neutron import manager - from neutron.plugins.ml2.drivers.ovn.agent import neutron_agent - from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import worker - from neutron.plugins.ml2.drivers import type_geneve # noqa --from neutron import service # noqa - from neutron.tests import base - from neutron.tests.common import base as common_base - from neutron.tests.common import helpers - from neutron.tests.functional.resources import process - from neutron.tests.unit.plugins.ml2 import test_plugin --import neutron.wsgi - - LOG = log.getLogger(__name__) - -@@ -180,7 +178,6 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase, - ovn_conf.cfg.CONF.set_override('dns_servers', - ['10.10.10.10'], - group='ovn') -- ovn_conf.cfg.CONF.set_override('api_workers', 1) - - self.addCleanup(exts.PluginAwareExtensionManager.clear_instance) - self.ovsdb_server_mgr = None -@@ -310,8 +307,6 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase, - if self.maintenance_worker: - trigger_cls.trigger.__self__.__class__ = worker.MaintenanceWorker - cfg.CONF.set_override('neutron_sync_mode', 'off', 'ovn') -- else: -- trigger_cls.trigger.__self__.__class__ = neutron.wsgi.WorkerService - - self.addCleanup(self.stop) - # NOTE(ralonsoh): do not access to the DB at exit when the SQL -diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py -index 43d1683d96..d0b0479299 100644 ---- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py -+++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py -@@ -286,7 +286,7 @@ class TestNBDbMonitorOverSsl(TestNBDbMonitor): - return 'ssl' - - --class TestOvnIdlProbeInterval(base.TestOVNFunctionalBase): -+class OvnIdlProbeInterval(base.TestOVNFunctionalBase): - def setUp(self): - # We need an OvsdbServer that uses TCP because probe_interval is always - # zero for unix socket connections, which is what the parent uses -diff --git a/neutron/tests/unit/common/ovn/test_hash_ring_manager.py b/neutron/tests/unit/common/ovn/test_hash_ring_manager.py -index f4b9b97141..052cd64d6f 100644 ---- a/neutron/tests/unit/common/ovn/test_hash_ring_manager.py -+++ b/neutron/tests/unit/common/ovn/test_hash_ring_manager.py -@@ -14,6 +14,7 @@ - # under the License. - - import datetime -+import time - from unittest import mock - - from neutron_lib import context -@@ -23,7 +24,6 @@ from neutron.common.ovn import constants - from neutron.common.ovn import exceptions - from neutron.common.ovn import hash_ring_manager - from neutron.db import ovn_hash_ring_db as db_hash_ring --from neutron import service - from neutron.tests.unit import testlib_api - - HASH_RING_TEST_GROUP = 'test_group' -@@ -110,21 +110,24 @@ class TestHashRingManager(testlib_api.SqlTestCaseLight): - # The ring should re-balance and as it was before - self._verify_hashes(hash_dict_before) - -- @mock.patch.object(service, '_get_api_workers', return_value=2) -- def test__wait_startup_before_caching(self, api_workers): -+ def test__wait_startup_before_caching(self): - db_hash_ring.add_node(self.admin_ctx, HASH_RING_TEST_GROUP, 'node-1') -+ db_hash_ring.add_node(self.admin_ctx, HASH_RING_TEST_GROUP, 'node-2') - -- # Assert it will return True until until we equal api_workers -+ # Assert it will return True until created_at != updated_at - self.assertTrue(self.hash_ring_manager._wait_startup_before_caching) -- self.assertTrue(self.hash_ring_manager._check_hashring_startup) -+ self.assertTrue(self.hash_ring_manager._cache_startup_timeout) - -- db_hash_ring.add_node(self.admin_ctx, HASH_RING_TEST_GROUP, 'node-2') -+ # Touch the nodes (== update the updated_at column) -+ time.sleep(1) -+ db_hash_ring.touch_nodes_from_host( -+ self.admin_ctx, HASH_RING_TEST_GROUP) - - # Assert it's now False. Waiting is not needed anymore - self.assertFalse(self.hash_ring_manager._wait_startup_before_caching) -- self.assertFalse(self.hash_ring_manager._check_hashring_startup) -+ self.assertFalse(self.hash_ring_manager._cache_startup_timeout) - -- # Now assert that since the _check_hashring_startup has been -+ # Now assert that since the _cache_startup_timeout has been - # flipped, we no longer will read from the database - with mock.patch.object(hash_ring_manager.db_hash_ring, - 'get_active_nodes') as get_nodes_mock: --- -2.31.1 - diff -Nru neutron-18.1.0/debian/patches/series neutron-18.1.1/debian/patches/series --- neutron-18.1.0/debian/patches/series 2021-07-28 20:52:11.000000000 +0000 +++ neutron-18.1.1/debian/patches/series 2021-10-01 06:42:37.000000000 +0000 @@ -1,3 +1,2 @@ skip-iptest.patch -revert-rely-on-worker-count-for-hashring-caching.patch -revert-l3-ha-retry-when-setting-ha-router-gw-status.patch +lp1934912-set-arp-entries-only-for-single-ip.patch diff -Nru neutron-18.1.0/doc/source/ovn/dhcp_opts.rst neutron-18.1.1/doc/source/ovn/dhcp_opts.rst --- neutron-18.1.0/doc/source/ovn/dhcp_opts.rst 2021-07-12 10:05:20.000000000 +0000 +++ neutron-18.1.1/doc/source/ovn/dhcp_opts.rst 2021-09-10 15:08:48.000000000 +0000 @@ -82,7 +82,7 @@ ================== ============= dns-server dns_server domain-search domain_search -ia-addr ip_addr +ia-addr ia_addr server-id server_id 2 server_id 5 ia_addr diff -Nru neutron-18.1.0/etc/oslo-config-generator/neutron.conf neutron-18.1.1/etc/oslo-config-generator/neutron.conf --- neutron-18.1.0/etc/oslo-config-generator/neutron.conf 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/etc/oslo-config-generator/neutron.conf 2021-09-10 15:08:49.000000000 +0000 @@ -15,7 +15,11 @@ namespace = oslo.concurrency namespace = oslo.messaging namespace = oslo.middleware.cors +namespace = oslo.middleware.healthcheck namespace = oslo.middleware.http_proxy_to_wsgi +namespace = oslo.reports +namespace = oslo.service.periodic_task +namespace = oslo.service.service namespace = oslo.service.sslutils namespace = oslo.service.wsgi namespace = keystonemiddleware.auth_token diff -Nru neutron-18.1.0/HACKING.rst neutron-18.1.1/HACKING.rst --- neutron-18.1.0/HACKING.rst 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/HACKING.rst 2021-09-10 15:08:48.000000000 +0000 @@ -16,6 +16,7 @@ - [N322] Detect common errors with assert_called_once_with - [N328] Detect wrong usage with assertEqual +- [N329] Use assertCountEqual() instead of assertItemsEqual() - [N330] Use assertEqual(*empty*, observed) instead of assertEqual(observed, *empty*) - [N331] Detect wrong usage with assertTrue(isinstance()). diff -Nru neutron-18.1.0/neutron/agent/l3/agent.py neutron-18.1.1/neutron/agent/l3/agent.py --- neutron-18.1.0/neutron/agent/l3/agent.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/agent/l3/agent.py 2021-09-10 15:08:49.000000000 +0000 @@ -593,7 +593,10 @@ def network_update(self, context, **kwargs): network_id = kwargs['network']['id'] + LOG.debug("Got network %s update", network_id) for ri in self.router_info.values(): + LOG.debug("Checking if router %s is plugged to the network %s", + ri, network_id) ports = list(ri.internal_ports) if ri.ex_gw_port: ports.append(ri.ex_gw_port) diff -Nru neutron-18.1.0/neutron/agent/linux/dhcp.py neutron-18.1.1/neutron/agent/linux/dhcp.py --- neutron-18.1.0/neutron/agent/linux/dhcp.py 2021-07-12 10:05:20.000000000 +0000 +++ neutron-18.1.1/neutron/agent/linux/dhcp.py 2021-09-10 15:08:48.000000000 +0000 @@ -1322,10 +1322,11 @@ elif not option.isdigit(): option = 'option:%s' % option if extra_tag: - tags = ('tag:' + tag, extra_tag[:-1], '%s' % option) + tags = ['tag:' + tag, extra_tag[:-1], '%s' % option] else: - tags = ('tag:' + tag, '%s' % option) - return ','.join(tags + args) + tags = ['tag:' + tag, '%s' % option] + + return ','.join(tags + [v.split("\n", 1)[0] for v in args]) @staticmethod def _convert_to_literal_addrs(ip_version, ips): diff -Nru neutron-18.1.0/neutron/api/extensions.py neutron-18.1.1/neutron/api/extensions.py --- neutron-18.1.0/neutron/api/extensions.py 2021-07-12 10:05:20.000000000 +0000 +++ neutron-18.1.1/neutron/api/extensions.py 2021-09-10 15:08:48.000000000 +0000 @@ -200,8 +200,13 @@ controller = req_controllers[request_ext.key] controller.add_handler(request_ext.handler) + # NOTE(slaweq): It seems that using singleton=True in conjunction + # with eventlet monkey patching of the threading library doesn't work + # well and there is memory leak. See + # https://bugs.launchpad.net/neutron/+bug/1942179 for details self._router = routes.middleware.RoutesMiddleware(self._dispatch, - mapper) + mapper, + singleton=False) super(ExtensionMiddleware, self).__init__(application) @classmethod diff -Nru neutron-18.1.0/neutron/common/ovn/constants.py neutron-18.1.1/neutron/common/ovn/constants.py --- neutron-18.1.0/neutron/common/ovn/constants.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/common/ovn/constants.py 2021-09-10 15:08:49.000000000 +0000 @@ -159,7 +159,7 @@ 6: {'server-id': 'server_id', 'dns-server': 'dns_server', 'domain-search': 'domain_search', - 'ia-addr': 'ip_addr', + 'ia-addr': 'ia_addr', '2': 'server_id', '5': 'ia_addr', '24': 'domain_search', diff -Nru neutron-18.1.0/neutron/common/ovn/utils.py neutron-18.1.1/neutron/common/ovn/utils.py --- neutron-18.1.0/neutron/common/ovn/utils.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/common/ovn/utils.py 2021-09-10 15:08:49.000000000 +0000 @@ -367,8 +367,7 @@ def is_lsp_router_port(port): - return port.get('device_owner') in [const.DEVICE_OWNER_ROUTER_INTF, - const.DEVICE_OWNER_ROUTER_GW] + return port.get('device_owner') in const.ROUTER_PORT_OWNERS def get_lrouter_ext_gw_static_route(ovn_router): diff -Nru neutron-18.1.0/neutron/common/utils.py neutron-18.1.1/neutron/common/utils.py --- neutron-18.1.0/neutron/common/utils.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/common/utils.py 2021-09-10 15:08:49.000000000 +0000 @@ -992,3 +992,25 @@ # https://dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html elif sql_dialect_name == mysql_dialect.name: return sql_func.rand + + +def skip_exceptions(exceptions): + """Decorator to catch and hide any provided exception in the argument""" + + # NOTE(ralonsoh): could be rehomed to neutron-lib. + if not isinstance(exceptions, list): + exceptions = [exceptions] + + def decorator(function): + @functools.wraps(function) + def wrapper(*args, **kwargs): + try: + return function(*args, **kwargs) + except Exception as exc: + with excutils.save_and_reraise_exception() as ctx: + if issubclass(type(exc), tuple(exceptions)): + LOG.info('Skipped exception %s when calling method %s', + ctx.value.__repr__(), function.__repr__()) + ctx.reraise = False + return wrapper + return decorator diff -Nru neutron-18.1.0/neutron/db/models/l3.py neutron-18.1.1/neutron/db/models/l3.py --- neutron-18.1.0/neutron/db/models/l3.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/db/models/l3.py 2021-09-10 15:08:48.000000000 +0000 @@ -88,11 +88,11 @@ port = orm.relationship(models_v2.Port, backref=orm.backref('floating_ips', cascade='all,delete-orphan'), - foreign_keys='FloatingIP.floating_port_id') + foreign_keys=floating_port_id) fixed_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id')) fixed_port = orm.relationship(models_v2.Port, - foreign_keys='FloatingIP.fixed_port_id', - lazy='joined') + foreign_keys=fixed_port_id, + lazy='joined', viewonly=True) fixed_ip_address = sa.Column(sa.String(64)) router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id')) # Additional attribute for keeping track of the router where the floating diff -Nru neutron-18.1.0/neutron/db/securitygroups_db.py neutron-18.1.1/neutron/db/securitygroups_db.py --- neutron-18.1.0/neutron/db/securitygroups_db.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/db/securitygroups_db.py 2021-09-10 15:08:49.000000000 +0000 @@ -146,7 +146,14 @@ reservation.reservation_id) # fetch sg from db to load the sg rules with sg model. - sg = sg_obj.SecurityGroup.get_object(context, id=sg.id) + # NOTE(slaweq): With new system/project scopes it may happen that + # project admin will try to list security groups for different + # project and during that call Neutron will ensure that default + # security group is created. In such case elevated context needs to + # be used here otherwise, SG will not be found and error 500 will + # be returned through the API + get_context = context.elevated() if default_sg else context + sg = sg_obj.SecurityGroup.get_object(get_context, id=sg.id) secgroup_dict = self._make_security_group_dict(sg) kwargs['security_group'] = secgroup_dict self._registry_notify(resources.SECURITY_GROUP, @@ -881,8 +888,11 @@ security_groups else []) def _get_default_sg_id(self, context, tenant_id): + # NOTE(slaweq): With new system/project scopes it may happen that + # project admin will try to find default SG for different + # project. In such case elevated context needs to be used. default_group = sg_obj.DefaultSecurityGroup.get_object( - context, + context.elevated(), project_id=tenant_id, ) if default_group: diff -Nru neutron-18.1.0/neutron/hacking/checks.py neutron-18.1.1/neutron/hacking/checks.py --- neutron-18.1.0/neutron/hacking/checks.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/hacking/checks.py 2021-09-10 15:08:48.000000000 +0000 @@ -90,6 +90,16 @@ @core.flake8ext +def check_assertitemsequal(logical_line, filename): + """N329 - Don't use assertItemsEqual.""" + if 'neutron/tests/' in filename: + if re.search(r"assertItemsEqual[\(,]", logical_line): + msg = ("N329: Use assertCountEqual() instead of " + "assertItemsEqual()") + yield (0, msg) + + +@core.flake8ext def check_assertempty(logical_line, filename): """N330 - Enforce using assertEqual parameter ordering in case of empty objects. diff -Nru neutron-18.1.0/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py neutron-18.1.1/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py --- neutron-18.1.0/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py 2021-09-10 15:08:48.000000000 +0000 @@ -646,9 +646,10 @@ "%(ofport)s, rebinding.", {'vif': port.vif_id, 'ofport': port.ofport}) self.unbind_port_from_dvr(port, local_vlan_map) - if port.ofport in (ovs_lib.INVALID_OFPORT, - ovs_lib.UNASSIGNED_OFPORT): - return + + if port.ofport in (ovs_lib.INVALID_OFPORT, + ovs_lib.UNASSIGNED_OFPORT): + return if device_owner == n_const.DEVICE_OWNER_DVR_INTERFACE: self._bind_distributed_router_interface_port(port, diff -Nru neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/db_migration.py neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/db_migration.py --- neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/db_migration.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/db_migration.py 2021-09-10 15:08:48.000000000 +0000 @@ -15,6 +15,7 @@ from neutron_lib.api.definitions import portbindings as pb_api from neutron_lib import context as n_context from neutron_lib.db import api as db_api +from neutron_lib import exceptions from neutron.db.models.plugins.ml2 import geneveallocation from neutron.db.models.plugins.ml2 import vxlanallocation @@ -66,7 +67,13 @@ pass if vif_details != pb.vif_details: pb.vif_details = vif_details - pb.update() + try: + pb.update() + except exceptions.ObjectNotFound: + # When Neutron server is running, it could happen that + # for example gateway port has been rescheduled to a + # different gateway chassis. + pass for trunk in trunk_obj.Trunk.get_objects(ctx): for subport in trunk.sub_ports: diff -Nru neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py --- neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py 2021-09-10 15:08:49.000000000 +0000 @@ -57,6 +57,7 @@ from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_db_sync from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovsdb_monitor from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import worker +from neutron import service from neutron.services.logapi.drivers.ovn import driver as log_driver from neutron.services.qos.drivers.ovn import driver as qos_driver from neutron.services.segments import db as segment_service_db @@ -283,7 +284,8 @@ @staticmethod def should_post_fork_initialize(worker_class): return worker_class in (neutron.wsgi.WorkerService, - worker.MaintenanceWorker) + worker.MaintenanceWorker, + service.RpcWorker) def post_fork_initialize(self, resource, event, trigger, payload=None): # Initialize API/Maintenance workers with OVN IDL connections diff -Nru neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py --- neutron-18.1.0/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py 2021-09-10 15:08:49.000000000 +0000 @@ -1293,7 +1293,7 @@ cms_bmaps.append(chassis) else: bmaps.append(chassis) - candidates = cms_bmaps or bmaps + candidates = cms_bmaps or bmaps or cms # Filter for availability zones if availability_zone_hints: @@ -1307,7 +1307,7 @@ if not cms_bmaps: LOG.debug("No eligible chassis with external connectivity" " through ovn-cms-options for %s", physnet) - LOG.debug("Chassis candidates with external connectivity: %s", + LOG.debug("Chassis candidates for scheduling gateway router ports: %s", candidates) return candidates diff -Nru neutron-18.1.0/neutron/privileged/agent/linux/ip_lib.py neutron-18.1.1/neutron/privileged/agent/linux/ip_lib.py --- neutron-18.1.0/neutron/privileged/agent/linux/ip_lib.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/privileged/agent/linux/ip_lib.py 2021-09-10 15:08:49.000000000 +0000 @@ -538,11 +538,19 @@ :param name: The name of the namespace to create """ - try: - netns.create(name, libc=priv_linux.get_cdll()) - except OSError as e: - if e.errno != errno.EEXIST: - raise + pid = os.fork() + if pid == 0: + try: + netns._create(name, libc=priv_linux.get_cdll()) + except OSError as e: + if e.errno != errno.EEXIST: + os._exit(1) + except Exception: + os._exit(1) + os._exit(0) + else: + if os.waitpid(pid, 0)[1]: + raise RuntimeError(_('Error creating namespace %s' % name)) @privileged.default.entrypoint diff -Nru neutron-18.1.0/neutron/scheduler/base_resource_filter.py neutron-18.1.1/neutron/scheduler/base_resource_filter.py --- neutron-18.1.0/neutron/scheduler/base_resource_filter.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/scheduler/base_resource_filter.py 2021-09-10 15:08:48.000000000 +0000 @@ -16,6 +16,9 @@ import abc from neutron_lib.db import api as db_api +from oslo_db import exception as db_exc + +from neutron.common import utils as n_utils class BaseResourceFilter(object, metaclass=abc.ABCMeta): @@ -24,6 +27,7 @@ def filter_agents(self, plugin, context, resource): """Return the agents that can host the resource.""" + @n_utils.skip_exceptions(db_exc.DBError) def bind(self, context, agents, resource_id, force_scheduling=False): """Bind the resource to the agents.""" with db_api.CONTEXT_WRITER.using(context): diff -Nru neutron-18.1.0/neutron/tests/functional/agent/linux/test_ip_lib.py neutron-18.1.1/neutron/tests/functional/agent/linux/test_ip_lib.py --- neutron-18.1.0/neutron/tests/functional/agent/linux/test_ip_lib.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/agent/linux/test_ip_lib.py 2021-09-10 15:08:49.000000000 +0000 @@ -393,7 +393,7 @@ 'scope': 'link'}] routes = ip_lib.get_routing_table(4, namespace=attr.namespace) - self.assertItemsEqual(expected_routes, routes) + self.assertCountEqual(expected_routes, routes) self.assertIsInstance(routes, list) expected_routes6 = [{'nexthop': "fd00::2", @@ -406,7 +406,7 @@ netaddr.IPNetwork(attr.ip_cidrs[1]).cidr), 'scope': 'universe'}] routes6 = ip_lib.get_routing_table(6, namespace=attr.namespace) - self.assertItemsEqual(expected_routes6, routes6) + self.assertCountEqual(expected_routes6, routes6) self.assertIsInstance(routes6, list) def test_get_routing_table_no_namespace(self): @@ -427,7 +427,7 @@ 'state': 'permanent'}] neighs = device.neigh.dump(4) - self.assertItemsEqual(expected_neighs, neighs) + self.assertCountEqual(expected_neighs, neighs) self.assertIsInstance(neighs, list) device.neigh.delete(TEST_IP_NEIGH, mac_address) @@ -616,7 +616,7 @@ ip_info['scope'], ip_info['broadcast']) for ip_info in device.addr.list()] - self.assertItemsEqual(ip_addresses, device_ips_info) + self.assertCountEqual(ip_addresses, device_ips_info) def _flush_ips(self, device, ip_version): device.addr.flush(ip_version) diff -Nru neutron-18.1.0/neutron/tests/functional/agent/test_ovs_lib.py neutron-18.1.1/neutron/tests/functional/agent/test_ovs_lib.py --- neutron-18.1.0/neutron/tests/functional/agent/test_ovs_lib.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/agent/test_ovs_lib.py 2021-09-10 15:08:48.000000000 +0000 @@ -489,7 +489,7 @@ expected = self.br.initial_protocols.union(protocols) self.br.ovsdb.db_add("Bridge", self.br.br_name, "protocols", *protocols).execute(check_error=True) - self.assertItemsEqual(expected, + self.assertCountEqual(expected, self.br.db_get_val('Bridge', self.br.br_name, "protocols")) @@ -637,4 +637,4 @@ self.assertTrue(tags_present) tags_42 = [t for t in tags_present if t['tag'] == 42] self.assertEqual(tags_42, single_value.result) - self.assertItemsEqual(len_0_list.result, tags_present) + self.assertCountEqual(len_0_list.result, tags_present) diff -Nru neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py --- neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py 2021-09-10 15:08:49.000000000 +0000 @@ -86,7 +86,7 @@ dp, iface, phys = self.api.get_chassis_data_for_ml2_bind_port(host) self.assertEqual('', dp) self.assertEqual('', iface) - self.assertItemsEqual(phys, ['private', 'public']) + self.assertCountEqual(phys, ['private', 'public']) def test_chassis_exists(self): self.assertTrue(self.api.chassis_exists( @@ -226,7 +226,7 @@ exp_values = [(lb['name'], lb['external_ids']) for lb in self.data['lbs']] lbs_values = [(lb.name, lb.external_ids) for lb in lbs] - self.assertItemsEqual(exp_values, lbs_values) + self.assertCountEqual(exp_values, lbs_values) def test_get_router_floatingip_lbs(self): f = self.nbapi.get_router_floatingip_lbs @@ -242,7 +242,7 @@ lbs_values = [(lb.name, lb.external_ids) for lb in f(exp_router_name)] self.assertTrue(exp_values) - self.assertItemsEqual(exp_values, lbs_values) + self.assertCountEqual(exp_values, lbs_values) def test_get_floatingip_in_nat_or_lb(self): f = self.nbapi.get_floatingip_in_nat_or_lb diff -Nru neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py --- neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_resources.py 2021-09-10 15:08:49.000000000 +0000 @@ -58,7 +58,7 @@ 'cidr': row.cidr, 'external_ids': ext_ids, 'options': row.options}) - self.assertItemsEqual(expected_dhcp_options_rows, + self.assertCountEqual(expected_dhcp_options_rows, observed_dhcp_options_rows) def _verify_dhcp_option_row_for_port(self, port_id, @@ -824,7 +824,7 @@ def _verify_port_acls(self, port_id, expected_acls): port_acls = self._get_port_related_acls(port_id) - self.assertItemsEqual(expected_acls, port_acls) + self.assertCountEqual(expected_acls, port_acls) def test_port_security_port_group(self): n1 = self._make_network(self.fmt, 'n1', True) @@ -915,7 +915,7 @@ observed_dns_records.append( {'external_ids': dns_row.external_ids, 'records': dns_row.records}) - self.assertItemsEqual(expected_dns_records, observed_dns_records) + self.assertCountEqual(expected_dns_records, observed_dns_records) def _validate_ls_dns_records(self, lswitch_name, expected_dns_records): ls = idlutils.row_by_value(self.nb_api.idl, @@ -925,7 +925,7 @@ observed_dns_records.append( {'external_ids': dns_row.external_ids, 'records': dns_row.records}) - self.assertItemsEqual(expected_dns_records, observed_dns_records) + self.assertCountEqual(expected_dns_records, observed_dns_records) def setUp(self): ovn_config.cfg.CONF.set_override('dns_domain', 'ovn.test') diff -Nru neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py --- neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py 2021-09-10 15:08:49.000000000 +0000 @@ -921,25 +921,25 @@ if row.name.startswith(ovn_const.OVN_PROVNET_PORT_NAME_PREFIX)] if should_match: - self.assertItemsEqual(db_net_ids, plugin_lswitch_ids) - self.assertItemsEqual(db_net_ids, monitor_lswitch_ids) - self.assertItemsEqual(db_provnet_ports, plugin_provnet_ports) - self.assertItemsEqual(db_provnet_ports, monitor_provnet_ports) + self.assertCountEqual(db_net_ids, plugin_lswitch_ids) + self.assertCountEqual(db_net_ids, monitor_lswitch_ids) + self.assertCountEqual(db_provnet_ports, plugin_provnet_ports) + self.assertCountEqual(db_provnet_ports, monitor_provnet_ports) else: self.assertRaises( - AssertionError, self.assertItemsEqual, db_net_ids, + AssertionError, self.assertCountEqual, db_net_ids, plugin_lswitch_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, db_net_ids, + AssertionError, self.assertCountEqual, db_net_ids, monitor_lswitch_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, db_provnet_ports, + AssertionError, self.assertCountEqual, db_provnet_ports, plugin_provnet_ports) self.assertRaises( - AssertionError, self.assertItemsEqual, db_provnet_ports, + AssertionError, self.assertCountEqual, db_provnet_ports, monitor_provnet_ports) def _validate_metadata_ports(self, should_match=True): @@ -967,9 +967,9 @@ if should_match: # Check that metadata ports exist in both Neutron and OVN dbs. - self.assertItemsEqual(db_metadata_ports_ids, plugin_metadata_ports) + self.assertCountEqual(db_metadata_ports_ids, plugin_metadata_ports) # Check that all networks have one and only one metadata port. - self.assertItemsEqual(db_metadata_ports_nets, db_net_ids) + self.assertCountEqual(db_metadata_ports_nets, db_net_ids) else: metadata_sync = (sorted(db_metadata_ports_ids) == sorted(plugin_metadata_ports)) @@ -1015,23 +1015,23 @@ if row.dhcpv6_options] if should_match: - self.assertItemsEqual(db_port_ids, plugin_lport_ids) - self.assertItemsEqual(db_port_ids, monitor_lport_ids) + self.assertCountEqual(db_port_ids, plugin_lport_ids) + self.assertCountEqual(db_port_ids, monitor_lport_ids) expected_dhcpv4_options_ports_ids = ( db_port_ids_dhcp_valid.difference( set(self.lport_dhcpv4_disabled.keys()))) - self.assertItemsEqual(expected_dhcpv4_options_ports_ids, + self.assertCountEqual(expected_dhcpv4_options_ports_ids, plugin_lport_ids_dhcpv4_enabled) - self.assertItemsEqual(expected_dhcpv4_options_ports_ids, + self.assertCountEqual(expected_dhcpv4_options_ports_ids, monitor_lport_ids_dhcpv4_enabled) expected_dhcpv6_options_ports_ids = ( db_port_ids_dhcp_valid.difference( set(self.lport_dhcpv6_disabled.keys()))) - self.assertItemsEqual(expected_dhcpv6_options_ports_ids, + self.assertCountEqual(expected_dhcpv6_options_ports_ids, plugin_lport_ids_dhcpv6_enabled) - self.assertItemsEqual(expected_dhcpv6_options_ports_ids, + self.assertCountEqual(expected_dhcpv6_options_ports_ids, monitor_lport_ids_dhcpv6_enabled) # Check if unknow address is set for the expected lports. @@ -1042,19 +1042,19 @@ else: self.assertRaises( - AssertionError, self.assertItemsEqual, db_port_ids, + AssertionError, self.assertCountEqual, db_port_ids, plugin_lport_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, db_port_ids, + AssertionError, self.assertCountEqual, db_port_ids, monitor_lport_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, db_port_ids, + AssertionError, self.assertCountEqual, db_port_ids, plugin_lport_ids_dhcpv4_enabled) self.assertRaises( - AssertionError, self.assertItemsEqual, db_port_ids, + AssertionError, self.assertCountEqual, db_port_ids, monitor_lport_ids_dhcpv4_enabled) @staticmethod @@ -1099,18 +1099,18 @@ 'options': opts}) if should_match: - self.assertItemsEqual(self.expected_dhcp_options_rows, + self.assertCountEqual(self.expected_dhcp_options_rows, observed_plugin_dhcp_options_rows) - self.assertItemsEqual(self.expected_dhcp_options_rows, + self.assertCountEqual(self.expected_dhcp_options_rows, observed_monitor_dhcp_options_rows) else: self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, self.expected_dhcp_options_rows, observed_plugin_dhcp_options_rows) self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, self.expected_dhcp_options_rows, observed_monitor_dhcp_options_rows) @@ -1161,14 +1161,14 @@ monitor_acls.append(self._build_acl_to_compare(acl)) if should_match: - self.assertItemsEqual(db_acls, plugin_acls) - self.assertItemsEqual(db_acls, monitor_acls) + self.assertCountEqual(db_acls, plugin_acls) + self.assertCountEqual(db_acls, monitor_acls) else: self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, db_acls, plugin_acls) self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, db_acls, monitor_acls) def _validate_routers_and_router_ports(self, should_match=True): @@ -1229,15 +1229,15 @@ self.nb_api.tables['Logical_Router'].rows.values())] if should_match: - self.assertItemsEqual(db_router_ids, plugin_lrouter_ids) - self.assertItemsEqual(db_router_ids, monitor_lrouter_ids) + self.assertCountEqual(db_router_ids, plugin_lrouter_ids) + self.assertCountEqual(db_router_ids, monitor_lrouter_ids) else: self.assertRaises( - AssertionError, self.assertItemsEqual, db_router_ids, + AssertionError, self.assertCountEqual, db_router_ids, plugin_lrouter_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, db_router_ids, + AssertionError, self.assertCountEqual, db_router_ids, monitor_lrouter_ids) def _get_networks_for_router_port(port): @@ -1323,64 +1323,64 @@ monitor_nats = [] if should_match: - self.assertItemsEqual(r_port_ids, plugin_lrouter_port_ids) - self.assertItemsEqual(r_port_ids, monitor_lrouter_port_ids) + self.assertCountEqual(r_port_ids, plugin_lrouter_port_ids) + self.assertCountEqual(r_port_ids, monitor_lrouter_port_ids) for p in plugin_lport_networks: - self.assertItemsEqual(r_port_networks[p], + self.assertCountEqual(r_port_networks[p], plugin_lport_networks[p]) - self.assertItemsEqual(r_port_ipv6_ra_configs[p], + self.assertCountEqual(r_port_ipv6_ra_configs[p], plugin_lport_ra_configs[p]) for p in monitor_lport_networks: - self.assertItemsEqual(r_port_networks[p], + self.assertCountEqual(r_port_networks[p], monitor_lport_networks[p]) - self.assertItemsEqual(r_port_ipv6_ra_configs[p], + self.assertCountEqual(r_port_ipv6_ra_configs[p], monitor_lport_ra_configs[p]) - self.assertItemsEqual(r_routes, plugin_routes) - self.assertItemsEqual(r_routes, monitor_routes) - self.assertItemsEqual(r_nats, plugin_nats) - self.assertItemsEqual(r_nats, monitor_nats) + self.assertCountEqual(r_routes, plugin_routes) + self.assertCountEqual(r_routes, monitor_routes) + self.assertCountEqual(r_nats, plugin_nats) + self.assertCountEqual(r_nats, monitor_nats) else: self.assertRaises( - AssertionError, self.assertItemsEqual, r_port_ids, + AssertionError, self.assertCountEqual, r_port_ids, plugin_lrouter_port_ids) self.assertRaises( - AssertionError, self.assertItemsEqual, r_port_ids, + AssertionError, self.assertCountEqual, r_port_ids, monitor_lrouter_port_ids) for _p in self.update_lrouter_ports: p = _p[0].replace('lrp-', '') if p in plugin_lport_networks: self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, r_port_networks[p], plugin_lport_networks[p]) self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, r_port_ipv6_ra_configs[p], plugin_lport_ra_configs[p]) if p in monitor_lport_networks: self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, r_port_networks[p], monitor_lport_networks[p]) self.assertRaises( - AssertionError, self.assertItemsEqual, + AssertionError, self.assertCountEqual, r_port_ipv6_ra_configs[p], monitor_lport_ra_configs[p]) self.assertRaises( - AssertionError, self.assertItemsEqual, r_routes, + AssertionError, self.assertCountEqual, r_routes, plugin_routes) self.assertRaises( - AssertionError, self.assertItemsEqual, r_routes, + AssertionError, self.assertCountEqual, r_routes, monitor_routes) self.assertRaises( - AssertionError, self.assertItemsEqual, r_nats, + AssertionError, self.assertCountEqual, r_nats, plugin_nats) self.assertRaises( - AssertionError, self.assertItemsEqual, r_nats, + AssertionError, self.assertCountEqual, r_nats, monitor_nats) def _validate_fip_port_forwarding(self, should_match=True): @@ -1429,9 +1429,9 @@ nb_pfs.append(pf) if should_match: - self.assertItemsEqual(nb_pfs, db_pfs) + self.assertCountEqual(nb_pfs, db_pfs) else: - self.assertRaises(AssertionError, self.assertItemsEqual, + self.assertRaises(AssertionError, self.assertCountEqual, nb_pfs, db_pfs) def _validate_port_groups(self, should_match=True): @@ -1449,12 +1449,12 @@ mn_pgs.append(getattr(row, 'name', '')) if should_match: - self.assertItemsEqual(nb_pgs, db_pgs) - self.assertItemsEqual(mn_pgs, db_pgs) + self.assertCountEqual(nb_pgs, db_pgs) + self.assertCountEqual(mn_pgs, db_pgs) else: - self.assertRaises(AssertionError, self.assertItemsEqual, + self.assertRaises(AssertionError, self.assertCountEqual, nb_pgs, db_pgs) - self.assertRaises(AssertionError, self.assertItemsEqual, + self.assertRaises(AssertionError, self.assertCountEqual, mn_pgs, db_pgs) def _delete_metadata_ports(self): @@ -1495,10 +1495,10 @@ {'external_ids': dns_row.external_ids, 'records': dns_row.records}) if should_match: - self.assertItemsEqual(self.expected_dns_records, + self.assertCountEqual(self.expected_dns_records, observed_dns_records) else: - self.assertRaises(AssertionError, self.assertItemsEqual, + self.assertRaises(AssertionError, self.assertCountEqual, self.expected_dns_records, observed_dns_records) def _validate_resources(self, should_match=True): diff -Nru neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py --- neutron-18.1.0/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py 2021-09-10 15:08:49.000000000 +0000 @@ -644,7 +644,7 @@ expected_ports = expected_ports or [] mech_driver.create_default_drop_port_group(self.api) port_group = self.api.get_port_group(self.PG_NAME) - self.assertItemsEqual( + self.assertCountEqual( expected_ports, [port.name for port in port_group.ports]) def test_with_ports_available(self): diff -Nru neutron-18.1.0/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py neutron-18.1.1/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py --- neutron-18.1.0/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/scheduler/test_dhcp_agent_scheduler.py 2021-09-10 15:08:49.000000000 +0000 @@ -171,7 +171,7 @@ sorted_unscheduled_active_agents = sorted( unscheduled_active_agents, key=attrgetter('load'))[0:self.expected_scheduled_agent_count] - self.assertItemsEqual( + self.assertCountEqual( (agent['id'] for agent in actual_scheduled_agents), (agent['id'] for agent in sorted_unscheduled_active_agents)) self.assertEqual(self.expected_scheduled_agent_count, @@ -409,7 +409,7 @@ network.Network.get_objects(self.ctx, id=hosted_net_ids)] expected_hosted_networks = self.expected_hosted_networks[ 'agent-%s' % host_index] - self.assertItemsEqual( + self.assertCountEqual( hosted_net_names, expected_hosted_networks, msg) diff -Nru neutron-18.1.0/neutron/tests/functional/services/ovn_l3/test_plugin.py neutron-18.1.1/neutron/tests/functional/services/ovn_l3/test_plugin.py --- neutron-18.1.0/neutron/tests/functional/services/ovn_l3/test_plugin.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/services/ovn_l3/test_plugin.py 2021-09-10 15:08:49.000000000 +0000 @@ -85,7 +85,7 @@ 'Logical_Router_Port'].rows.values(): if self._l3_ha_supported(): chassis = [gwc.chassis_name for gwc in row.gateway_chassis] - self.assertItemsEqual(expected, chassis) + self.assertCountEqual(expected, chassis) else: rc = row.options.get(ovn_const.OVN_GATEWAY_CHASSIS_KEY) self.assertIn(rc, expected) @@ -100,7 +100,7 @@ # candidates. def fake_select(*args, **kwargs): - self.assertItemsEqual(candidates, kwargs['candidates']) + self.assertCountEqual(candidates, kwargs['candidates']) # We are not interested in further processing, let us return # INVALID_CHASSIS to avoid erros return [ovn_const.OVN_GATEWAY_INVALID_CHASSIS] @@ -289,7 +289,7 @@ self.assertIsNotNone(gw_port) expected_networks = ['%s/24' % subnet4_ip, '%s/64' % subnet6_ip] - self.assertItemsEqual( + self.assertCountEqual( expected_networks, gw_port.networks, 'networks in ovn port must match fixed_ips in neutron') @@ -341,7 +341,7 @@ self.candidates = [] def fake_select(*args, **kwargs): - self.assertItemsEqual(self.candidates, kwargs['candidates']) + self.assertCountEqual(self.candidates, kwargs['candidates']) # We are not interested in further processing, let us return # INVALID_CHASSIS to avoid erros return [ovn_const.OVN_GATEWAY_INVALID_CHASSIS] diff -Nru neutron-18.1.0/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py neutron-18.1.1/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py --- neutron-18.1.0/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py 2021-09-10 15:08:48.000000000 +0000 @@ -77,7 +77,7 @@ self.context, port_id=subport['port_id'], host='') self.assertEqual(n_consts.PORT_STATUS_ACTIVE, binding['status']) - self.assertItemsEqual(ovn_subports_info, neutron_subports_info) + self.assertCountEqual(ovn_subports_info, neutron_subports_info) self.assertEqual(has_items, len(neutron_subports_info) != 0) if trunk.get('status'): diff -Nru neutron-18.1.0/neutron/tests/unit/agent/linux/openvswitch_firewall/test_iptables.py neutron-18.1.1/neutron/tests/unit/agent/linux/openvswitch_firewall/test_iptables.py --- neutron-18.1.0/neutron/tests/unit/agent/linux/openvswitch_firewall/test_iptables.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/agent/linux/openvswitch_firewall/test_iptables.py 2021-09-10 15:08:48.000000000 +0000 @@ -35,7 +35,7 @@ self.helper.int_br.get_port_name_list.return_value = present_ports expected_hybrid_ports = ['qvo-1234', 'qvo-fghfhfh'] observed = self.helper.get_hybrid_ports() - self.assertItemsEqual(expected_hybrid_ports, observed) + self.assertCountEqual(expected_hybrid_ports, observed) def test_has_not_been_cleaned_no_value(self): other_config = {'foo': 'bar'} diff -Nru neutron-18.1.0/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py neutron-18.1.1/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py --- neutron-18.1.0/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py 2021-09-10 15:08:48.000000000 +0000 @@ -451,7 +451,7 @@ ({'direction': 'ingress', 'ethertype': 'IPv4', 'protocol': 1}, 24)] result = rules.merge_common_rules(rule_conj_list) - self.assertItemsEqual( + self.assertCountEqual( [({'direction': 'ingress', 'ethertype': 'IPv4', 'protocol': 1}, [8, 24]), ({'direction': 'ingress', 'ethertype': 'IPv4', diff -Nru neutron-18.1.0/neutron/tests/unit/agent/linux/test_dhcp.py neutron-18.1.1/neutron/tests/unit/agent/linux/test_dhcp.py --- neutron-18.1.0/neutron/tests/unit/agent/linux/test_dhcp.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/agent/linux/test_dhcp.py 2021-09-10 15:08:49.000000000 +0000 @@ -230,6 +230,9 @@ self.extra_dhcp_opts = [ DhcpOpt(opt_name='dns-server', opt_value='ffea:3ba5:a17a:4ba3::100', + ip_version=constants.IP_VERSION_6), + DhcpOpt(opt_name='malicious-option', + opt_value='aaa\nbbb.ccc\n', ip_version=constants.IP_VERSION_6)] @@ -2838,7 +2841,7 @@ result = dhcp.Dnsmasq.existing_dhcp_networks(self.conf) mock_listdir.assert_called_once_with(path) - self.assertItemsEqual(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + self.assertCountEqual(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'], result) @@ -2909,7 +2912,9 @@ exp_opt_data = ('tag:subnet-eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,' 'option6:domain-search,openstacklocal\n' 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' - 'option6:dns-server,ffea:3ba5:a17a:4ba3::100').lstrip() + 'option6:dns-server,ffea:3ba5:a17a:4ba3::100\n' + 'tag:port-hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,' + 'option6:malicious-option,aaa').lstrip() dm = self._get_dnsmasq(FakeV6NetworkStatelessDHCP()) dm._output_hosts_file() dm._output_opts_file() diff -Nru neutron-18.1.0/neutron/tests/unit/agent/test_resource_cache.py neutron-18.1.1/neutron/tests/unit/agent/test_resource_cache.py --- neutron-18.1.0/neutron/tests/unit/agent/test_resource_cache.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/agent/test_resource_cache.py 2021-09-10 15:08:49.000000000 +0000 @@ -86,7 +86,7 @@ self._pullmock.bulk_pull.assert_called_once_with( mock.ANY, 'goose', filter_kwargs={'id': (67, )}) - self.assertItemsEqual( + self.assertCountEqual( resources, [rec['updated'] for rec in received_kw]) def test_bulk_pull_doesnt_wipe_out_newer_data(self): @@ -106,9 +106,9 @@ self.rcache.record_resource_update(self.ctx, 'goose', goose) is_large = {'size': ('large', )} is_small = {'size': ('small', )} - self.assertItemsEqual([geese[0], geese[2]], + self.assertCountEqual([geese[0], geese[2]], self.rcache.get_resources('goose', is_large)) - self.assertItemsEqual([geese[3]], + self.assertCountEqual([geese[3]], self.rcache.get_resources('goose', is_small)) def test_match_resources_with_func(self): @@ -117,7 +117,7 @@ for goose in geese: self.rcache.record_resource_update(self.ctx, 'goose', goose) has_large = lambda o: 'large' in o.size - self.assertItemsEqual([geese[0], geese[2]], + self.assertCountEqual([geese[0], geese[2]], self.rcache.match_resources_with_func('goose', has_large)) diff -Nru neutron-18.1.0/neutron/tests/unit/api/rpc/handlers/test_resources_rpc.py neutron-18.1.1/neutron/tests/unit/api/rpc/handlers/test_resources_rpc.py --- neutron-18.1.0/neutron/tests/unit/api/rpc/handlers/test_resources_rpc.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/api/rpc/handlers/test_resources_rpc.py 2021-09-10 15:08:48.000000000 +0000 @@ -231,7 +231,7 @@ objs = self.callbacks.bulk_pull( self.context, resource_type=FakeResource.obj_name(), version=TEST_VERSION) - self.assertItemsEqual([r1.obj_to_primitive(), + self.assertCountEqual([r1.obj_to_primitive(), r2.obj_to_primitive()], objs) objs = self.callbacks.bulk_pull( diff -Nru neutron-18.1.0/neutron/tests/unit/common/test_utils.py neutron-18.1.1/neutron/tests/unit/common/test_utils.py --- neutron-18.1.0/neutron/tests/unit/common/test_utils.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/common/test_utils.py 2021-09-10 15:08:48.000000000 +0000 @@ -329,7 +329,7 @@ def compare_port_ranges_results(self, port_min, port_max): observed = utils.port_rule_masking(port_min, port_max) expected = _port_rule_masking(port_min, port_max) - self.assertItemsEqual(expected, observed) + self.assertCountEqual(expected, observed) def test_port_rule_masking_random_ranges(self): # calling randint a bunch of times is really slow @@ -603,3 +603,25 @@ instance_2 = _TestSingletonClass() self.assertEqual(instance_1.__hash__(), instance_2.__hash__()) self.assertEqual('value1', instance_2.variable) + + +class SkipDecoratorTestCase(base.BaseTestCase): + + def test_skip_exception(self): + @utils.skip_exceptions(AttributeError) + def raise_attribute_error_single_exception(): + raise AttributeError() + + @utils.skip_exceptions([AttributeError, IndexError]) + def raise_attribute_error_exception_list(): + raise AttributeError() + + raise_attribute_error_single_exception() + raise_attribute_error_exception_list() + + def test_skip_exception_fail(self): + @utils.skip_exceptions(IndexError) + def raise_attribute_error(): + raise AttributeError() + + self.assertRaises(AttributeError, raise_attribute_error) diff -Nru neutron-18.1.0/neutron/tests/unit/db/test_db_base_plugin_v2.py neutron-18.1.1/neutron/tests/unit/db/test_db_base_plugin_v2.py --- neutron-18.1.0/neutron/tests/unit/db/test_db_base_plugin_v2.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/db/test_db_base_plugin_v2.py 2021-09-10 15:08:49.000000000 +0000 @@ -663,7 +663,7 @@ expected_code=expected_code) if expected_code == webob.exc.HTTPOk.code: resource = resource.replace('-', '_') - self.assertItemsEqual([i['id'] for i in res['%ss' % resource]], + self.assertCountEqual([i['id'] for i in res['%ss' % resource]], [i[resource]['id'] for i in items]) @contextlib.contextmanager @@ -6030,7 +6030,7 @@ initial_subnetpool['subnetpool']['id']) api = self._api_for_resource('subnetpools') res = self.deserialize(self.fmt, req.get_response(api)) - self.assertItemsEqual(res['subnetpool']['prefixes'], + self.assertCountEqual(res['subnetpool']['prefixes'], ['10.10.8.0/21', '3.3.3.0/24', '2.2.2.0/24']) def test_update_subnetpool_prefix_list_compaction(self): @@ -6045,7 +6045,7 @@ initial_subnetpool['subnetpool']['id']) api = self._api_for_resource('subnetpools') res = self.deserialize(self.fmt, req.get_response(api)) - self.assertItemsEqual(res['subnetpool']['prefixes'], + self.assertCountEqual(res['subnetpool']['prefixes'], ['10.10.10.0/23']) def test_illegal_subnetpool_prefix_list_update(self): diff -Nru neutron-18.1.0/neutron/tests/unit/db/test_dvr_mac_db.py neutron-18.1.1/neutron/tests/unit/db/test_dvr_mac_db.py --- neutron-18.1.0/neutron/tests/unit/db/test_dvr_mac_db.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/db/test_dvr_mac_db.py 2021-09-10 15:08:48.000000000 +0000 @@ -210,5 +210,5 @@ dvr_ports = self.mixin.get_ports_on_host_by_subnet( self.ctx, HOST, subnet['subnet']['id']) self.assertEqual(len(expected_ids), len(dvr_ports)) - self.assertItemsEqual(expected_ids, + self.assertCountEqual(expected_ids, [port['id'] for port in dvr_ports]) diff -Nru neutron-18.1.0/neutron/tests/unit/db/test_extraroute_db.py neutron-18.1.1/neutron/tests/unit/db/test_extraroute_db.py --- neutron-18.1.0/neutron/tests/unit/db/test_extraroute_db.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/db/test_extraroute_db.py 2021-09-10 15:08:49.000000000 +0000 @@ -45,7 +45,7 @@ } } router = self._plugin.create_router(ctx, create_request) - self.assertItemsEqual(router['routes'], []) + self.assertCountEqual(router['routes'], []) router_id = router['id'] routes = [ {'destination': '10.0.0.0/24', 'nexthop': '1.1.1.4'}, @@ -71,9 +71,9 @@ update_request) mock_cb.assert_called_with('router', events.PRECOMMIT_UPDATE, self._plugin, payload=mock.ANY) - self.assertItemsEqual(updated_router['routes'], routes) + self.assertCountEqual(updated_router['routes'], routes) got_router = self._plugin.get_router(ctx, router_id) - self.assertItemsEqual(got_router['routes'], routes) + self.assertCountEqual(got_router['routes'], routes) def assertEqualRoutes(self, a, b): """Compare a list of routes without caring for the list order.""" diff -Nru neutron-18.1.0/neutron/tests/unit/db/test_ipam_backend_mixin.py neutron-18.1.1/neutron/tests/unit/db/test_ipam_backend_mixin.py --- neutron-18.1.0/neutron/tests/unit/db/test_ipam_backend_mixin.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/db/test_ipam_backend_mixin.py 2021-09-10 15:08:48.000000000 +0000 @@ -110,9 +110,9 @@ new_ips, owner) - self.assertItemsEqual(expected.add, change.add) - self.assertItemsEqual(expected.original, change.original) - self.assertItemsEqual(expected.remove, change.remove) + self.assertCountEqual(expected.add, change.add) + self.assertCountEqual(expected.original, change.original) + self.assertCountEqual(expected.remove, change.remove) def test__get_changed_ips_for_port(self): new_ips = self._prepare_ips(self.default_new_ips) diff -Nru neutron-18.1.0/neutron/tests/unit/db/test_l3_dvr_db.py neutron-18.1.1/neutron/tests/unit/db/test_l3_dvr_db.py --- neutron-18.1.0/neutron/tests/unit/db/test_l3_dvr_db.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/db/test_l3_dvr_db.py 2021-09-10 15:08:49.000000000 +0000 @@ -1543,7 +1543,7 @@ dvr_subnet_ports = self.mixin.get_ports_under_dvr_connected_subnet( self.ctx, subnet['subnet']['id']) dvr_subnet_ports_ids = [p['id'] for p in dvr_subnet_ports] - self.assertItemsEqual(fake_bound_ports_ids, dvr_subnet_ports_ids) + self.assertCountEqual(fake_bound_ports_ids, dvr_subnet_ports_ids) (self.mixin._core_plugin.get_allowed_address_pairs_for_ports. assert_called_once_with(self.ctx, dvr_subnet_ports_ids)) diff -Nru neutron-18.1.0/neutron/tests/unit/extensions/test_availability_zone.py neutron-18.1.1/neutron/tests/unit/extensions/test_availability_zone.py --- neutron-18.1.0/neutron/tests/unit/extensions/test_availability_zone.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/extensions/test_availability_zone.py 2021-09-10 15:08:49.000000000 +0000 @@ -72,12 +72,12 @@ {'name': 'nova3', 'resource': 'router', 'state': 'unavailable'}] res = self._list('availability_zones') azs = res['availability_zones'] - self.assertItemsEqual(expected, azs) + self.assertCountEqual(expected, azs) # not admin case ctx = context.Context('', 'noadmin') res = self._list('availability_zones', neutron_context=ctx) azs = res['availability_zones'] - self.assertItemsEqual(expected, azs) + self.assertCountEqual(expected, azs) def test_list_availability_zones_with_filter(self): self._register_azs() @@ -90,27 +90,27 @@ {'name': 'nova3', 'resource': 'router', 'state': 'unavailable'}] res = self._list('availability_zones') azs = res['availability_zones'] - self.assertItemsEqual(expected, azs) + self.assertCountEqual(expected, azs) # list with filter of 'name' res = self._list('availability_zones', query_params="name=nova1") azs = res['availability_zones'] - self.assertItemsEqual(expected[:1], azs) + self.assertCountEqual(expected[:1], azs) # list with filter of 'resource' res = self._list('availability_zones', query_params="resource=router") azs = res['availability_zones'] - self.assertItemsEqual(expected[-2:], azs) + self.assertCountEqual(expected[-2:], azs) # list with filter of 'state' as 'available' res = self._list('availability_zones', query_params="state=available") azs = res['availability_zones'] - self.assertItemsEqual(expected[:3], azs) + self.assertCountEqual(expected[:3], azs) # list with filter of 'state' as 'unavailable' res = self._list('availability_zones', query_params="state=unavailable") azs = res['availability_zones'] - self.assertItemsEqual(expected[-1:], azs) + self.assertCountEqual(expected[-1:], azs) def test_list_agent_with_az(self): helpers.register_dhcp_agent(host='host1', az='nova1') @@ -145,7 +145,7 @@ az_hints = ['nova1'] with self.network(availability_zone_hints=az_hints) as net: res = self._show('networks', net['network']['id']) - self.assertItemsEqual(az_hints, + self.assertCountEqual(az_hints, res['network']['availability_zone_hints']) def test_create_network_with_azs(self): @@ -153,7 +153,7 @@ az_hints = ['nova1', 'nova2'] with self.network(availability_zone_hints=az_hints) as net: res = self._show('networks', net['network']['id']) - self.assertItemsEqual(az_hints, + self.assertCountEqual(az_hints, res['network']['availability_zone_hints']) def test_create_network_without_az(self): diff -Nru neutron-18.1.0/neutron/tests/unit/extensions/test_dns.py neutron-18.1.1/neutron/tests/unit/extensions/test_dns.py --- neutron-18.1.0/neutron/tests/unit/extensions/test_dns.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/extensions/test_dns.py 2021-09-10 15:08:48.000000000 +0000 @@ -115,7 +115,7 @@ neutron_context=neutron_context, query_params=query_params) resource = resource.replace('-', '_') - self.assertItemsEqual([i['id'] for i in res['%ss' % resource]], + self.assertCountEqual([i['id'] for i in res['%ss' % resource]], [i[resource]['id'] for i in items]) return res diff -Nru neutron-18.1.0/neutron/tests/unit/extensions/test_router_availability_zone.py neutron-18.1.1/neutron/tests/unit/extensions/test_router_availability_zone.py --- neutron-18.1.0/neutron/tests/unit/extensions/test_router_availability_zone.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/extensions/test_router_availability_zone.py 2021-09-10 15:08:49.000000000 +0000 @@ -63,7 +63,7 @@ az_hints = ['nova2'] with self.router(availability_zone_hints=az_hints) as router: res = self._show('routers', router['router']['id']) - self.assertItemsEqual(az_hints, + self.assertCountEqual(az_hints, res['router']['availability_zone_hints']) def test_create_router_with_azs(self): @@ -71,7 +71,7 @@ az_hints = ['nova2', 'nova3'] with self.router(availability_zone_hints=az_hints) as router: res = self._show('routers', router['router']['id']) - self.assertItemsEqual(az_hints, + self.assertCountEqual(az_hints, res['router']['availability_zone_hints']) def test_create_router_without_az(self): diff -Nru neutron-18.1.0/neutron/tests/unit/objects/qos/test_policy.py neutron-18.1.1/neutron/tests/unit/objects/qos/test_policy.py --- neutron-18.1.0/neutron/tests/unit/objects/qos/test_policy.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/objects/qos/test_policy.py 2021-09-10 15:08:49.000000000 +0000 @@ -114,7 +114,7 @@ objs = self._test_class.get_objects(self.context) self.get_objects_mock.assert_any_call( self._test_class, self.context, _pager=None) - self.assertItemsEqual( + self.assertCountEqual( [test_base.get_obj_persistent_fields(obj) for obj in self.objs], [test_base.get_obj_persistent_fields(obj) for obj in objs]) diff -Nru neutron-18.1.0/neutron/tests/unit/objects/test_base.py neutron-18.1.1/neutron/tests/unit/objects/test_base.py --- neutron-18.1.0/neutron/tests/unit/objects/test_base.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/objects/test_base.py 2021-09-10 15:08:49.000000000 +0000 @@ -844,7 +844,7 @@ obj_db_api, 'get_objects', side_effect=self.fake_get_objects) as get_objects_mock: objs = self._test_class.get_objects(self.context) - self.assertItemsEqual( + self.assertCountEqual( [get_obj_persistent_fields(obj) for obj in self.objs], [get_obj_persistent_fields(obj) for obj in objs]) get_objects_mock.assert_any_call( @@ -908,7 +908,7 @@ objs = self._test_class.get_objects(self.context, validate_filters=False, unknown_filter='value') - self.assertItemsEqual( + self.assertCountEqual( [get_obj_persistent_fields(obj) for obj in self.objs], [get_obj_persistent_fields(obj) for obj in objs]) @@ -919,7 +919,7 @@ obj_db_api, 'get_values', side_effect=self.fake_get_values) as get_values_mock: values = self._test_class.get_values(self.context, field) - self.assertItemsEqual( + self.assertCountEqual( [getattr(obj, field) for obj in self.objs], values) get_values_mock.assert_any_call( self._test_class, self.context, db_field @@ -940,7 +940,7 @@ values = self._test_class.get_values(self.context, field, validate_filters=False, unknown_filter='value') - self.assertItemsEqual( + self.assertCountEqual( [getattr(obj, field) for obj in self.objs], values) def test_get_values_mixed_field(self): @@ -1084,7 +1084,7 @@ fake_field='xxx') def _check_equal(self, expected, observed): - self.assertItemsEqual(get_obj_persistent_fields(expected), + self.assertCountEqual(get_obj_persistent_fields(expected), get_obj_persistent_fields(observed)) def test_count_validate_filters_false(self): @@ -1856,7 +1856,7 @@ else: filters = {field: obj[field]} new = self._test_class.get_objects(self.context, **filters) - self.assertItemsEqual( + self.assertCountEqual( [obj._get_composite_keys()], [obj_._get_composite_keys() for obj_ in new], 'Filtering by %s failed.' % field) diff -Nru neutron-18.1.0/neutron/tests/unit/objects/test_network_segment_range.py neutron-18.1.1/neutron/tests/unit/objects/test_network_segment_range.py --- neutron-18.1.0/neutron/tests/unit/objects/test_network_segment_range.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/objects/test_network_segment_range.py 2021-09-10 15:08:48.000000000 +0000 @@ -136,7 +136,7 @@ physical_network='foo') obj = self._create_network_segment_range(range_minimum, range_maximum) available_alloc = self._test_class._get_available_allocation(obj) - self.assertItemsEqual(not_to_alloc, available_alloc) + self.assertCountEqual(not_to_alloc, available_alloc) def test__get_used_allocation_mapping(self): alloc_mapping = {} diff -Nru neutron-18.1.0/neutron/tests/unit/objects/test_subnetpool.py neutron-18.1.1/neutron/tests/unit/objects/test_subnetpool.py --- neutron-18.1.0/neutron/tests/unit/objects/test_subnetpool.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/objects/test_subnetpool.py 2021-09-10 15:08:48.000000000 +0000 @@ -63,14 +63,14 @@ pool.update() new_pool = self._test_class.get_object(self.context, id=pool.id) - self.assertItemsEqual(prefixes, new_pool.prefixes) + self.assertCountEqual(prefixes, new_pool.prefixes) prefixes.pop() pool.prefixes = prefixes pool.update() new_pool = self._test_class.get_object(self.context, id=pool.id) - self.assertItemsEqual(prefixes, new_pool.prefixes) + self.assertCountEqual(prefixes, new_pool.prefixes) def test_get_objects_queries_constant(self): # TODO(korzen) SubnetPool is using SubnetPoolPrefix object to reload diff -Nru neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_vlanmanager.py neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_vlanmanager.py --- neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_vlanmanager.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_vlanmanager.py 2021-09-10 15:08:48.000000000 +0000 @@ -60,7 +60,7 @@ self.vlan_manager.add(1, None, None, None, None) new_vlan_manager = vlanmanager.LocalVlanManager() self.assertIs(new_vlan_manager, self.vlan_manager) - self.assertItemsEqual(new_vlan_manager.mapping, + self.assertCountEqual(new_vlan_manager.mapping, self.vlan_manager.mapping) def test_in_operator_on_key(self): @@ -74,7 +74,7 @@ self.vlan_manager.add(val, val, val, val, val) created_vlans.append(self.vlan_manager.get(val)) - self.assertItemsEqual(created_vlans, list(self.vlan_manager)) + self.assertCountEqual(created_vlans, list(self.vlan_manager)) def test_get_net_uuid_existing(self): port_id = 'port-id' diff -Nru neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl_ovn.py neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl_ovn.py --- neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl_ovn.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl_ovn.py 2021-09-10 15:08:49.000000000 +0000 @@ -423,7 +423,7 @@ def test_get_all_logical_switches_with_ports(self): # Test empty mapping = self.nb_ovn_idl.get_all_logical_switches_with_ports() - self.assertItemsEqual(mapping, {}) + self.assertCountEqual(mapping, {}) # Test loaded values self._load_nb_db() mapping = self.nb_ovn_idl.get_all_logical_switches_with_ports() @@ -441,12 +441,12 @@ 'ports': ['lsp-id-51', 'lsp-id-52', 'lsp-rp-id-5', 'lsp-vpn-id-5'], 'provnet_ports': []}] - self.assertItemsEqual(mapping, expected) + self.assertCountEqual(mapping, expected) def test_get_all_logical_routers_with_rports(self): # Test empty mapping = self.nb_ovn_idl.get_all_logical_switches_with_ports() - self.assertItemsEqual(mapping, {}) + self.assertCountEqual(mapping, {}) # Test loaded values self._load_nb_db() mapping = self.nb_ovn_idl.get_all_logical_routers_with_rports() @@ -482,7 +482,7 @@ 'snats': [], 'dnat_and_snats': []}, {'name': 'lr-id-e', 'ports': {}, 'static_routes': [], 'snats': [], 'dnat_and_snats': []}] - self.assertItemsEqual(mapping, expected) + self.assertCountEqual(mapping, expected) def test_get_acls_for_lswitches(self): self._load_nb_db() @@ -539,7 +539,7 @@ 'direction': 'to-lport', 'match': 'outport == "lsp-id-52" && ip4.src == $as_ip4_id_5'} ]} - self.assertItemsEqual(acl_values, excepted_acl_values) + self.assertCountEqual(acl_values, excepted_acl_values) self.assertEqual(len(acl_objs), 8) self.assertEqual(len(lswitch_ovsdb_dict), len(lswitches)) @@ -547,7 +547,7 @@ lswitches = ['ls-id-4'] acl_values, acl_objs, lswitch_ovsdb_dict = \ self.nb_ovn_idl.get_acls_for_lswitches(lswitches) - self.assertItemsEqual(acl_values, {}) + self.assertCountEqual(acl_values, {}) self.assertEqual(len(acl_objs), 0) self.assertEqual(len(lswitch_ovsdb_dict), 0) @@ -559,15 +559,15 @@ 'host-2': [utils.ovn_lrouter_port_name('orp-id-b2')], ovn_const.OVN_GATEWAY_INVALID_CHASSIS: [ utils.ovn_name('orp-id-a3')]} - self.assertItemsEqual(bindings, expected) + self.assertCountEqual(bindings, expected) bindings = self.nb_ovn_idl.get_all_chassis_gateway_bindings([]) - self.assertItemsEqual(bindings, expected) + self.assertCountEqual(bindings, expected) bindings = self.nb_ovn_idl.get_all_chassis_gateway_bindings(['host-1']) expected = {'host-1': [utils.ovn_lrouter_port_name('orp-id-a1'), utils.ovn_lrouter_port_name('orp-id-a2')]} - self.assertItemsEqual(bindings, expected) + self.assertCountEqual(bindings, expected) def test_get_gateway_chassis_binding(self): self._load_nb_db() @@ -601,13 +601,13 @@ port_physnet_dict, {'host-1': 'physnet1', 'host-2': 'physnet3'}, ['host-1', 'host-2']) expected = ['lrp-orp-id-a3'] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) # Test both host-1, host-2 in valid list unhosted_gateways = self.nb_ovn_idl.get_unhosted_gateways( port_physnet_dict, {'host-1': 'physnet1', 'host-2': 'physnet2'}, ['host-1', 'host-2']) expected = ['lrp-orp-id-a3', 'lrp-orp-id-b6'] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) def test_get_unhosted_gateways_deleted_physnet(self): self._load_nb_db() @@ -623,12 +623,12 @@ ['host-1', 'host-2']) # Make sure that lrp is rescheduled, because host-1 has physet1 expected = ['lrp-orp-id-a1'] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) # Spoof that there is no valid host with required physnet. unhosted_gateways = self.nb_ovn_idl.get_unhosted_gateways( port_physnet_dict, {'host-1': 'physnet4', 'host-2': 'physnet3'}, ['host-1', 'host-2']) - self.assertItemsEqual(unhosted_gateways, []) + self.assertCountEqual(unhosted_gateways, []) def _test_get_unhosted_gateway_max_chassis(self, r): gw_chassis_table = fakes.FakeOvsdbTable.create_one_ovsdb_table() @@ -651,7 +651,7 @@ ['host-%s' % x for x in range(1, 7)]) # We don't have required number of chassis expected = [] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) def test_get_unhosted_gateway_max_chassis(self): # We have required number of chassis, and lrp @@ -664,7 +664,7 @@ 'host-5': 'physnet1', 'host-6': 'physnet1'}, ['host-%s' % x for x in range(1, 7)]) expected = [] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) def test_get_unhosed_gateway_schedule_to_max(self): # The LRP is not yet scheduled on all chassis @@ -677,7 +677,7 @@ 'host-5': 'physnet1', 'host-6': 'physnet1'}, ['host-%s' % x for x in range(1, 7)]) expected = ['lrp-orp-id-a1'] - self.assertItemsEqual(unhosted_gateways, expected) + self.assertCountEqual(unhosted_gateways, expected) def test_get_subnet_dhcp_options(self): self._load_nb_db() @@ -702,7 +702,7 @@ # Test empty subnet_options = self.nb_ovn_idl.get_subnet_dhcp_options( 'subnet-id-10-0-1-0', with_ports=True) - self.assertItemsEqual({'subnet': None, 'ports': []}, subnet_options) + self.assertCountEqual({'subnet': None, 'ports': []}, subnet_options) # Test loaded values self._load_nb_db() # Test getting both subnet and port dhcp options @@ -715,7 +715,7 @@ 'external_ids': dhcp_row.external_ids, 'options': dhcp_row.options, 'uuid': dhcp_row.uuid} for dhcp_row in dhcp_rows] - self.assertItemsEqual(expected_rows, [ + self.assertCountEqual(expected_rows, [ subnet_options['subnet']] + subnet_options['ports']) # Test getting only subnet dhcp options subnet_options = self.nb_ovn_idl.get_subnet_dhcp_options( @@ -726,12 +726,12 @@ 'external_ids': dhcp_row.external_ids, 'options': dhcp_row.options, 'uuid': dhcp_row.uuid} for dhcp_row in dhcp_rows] - self.assertItemsEqual(expected_rows, [ + self.assertCountEqual(expected_rows, [ subnet_options['subnet']] + subnet_options['ports']) # Test getting no dhcp options subnet_options = self.nb_ovn_idl.get_subnet_dhcp_options( 'subnet-id-11-0-2-0', with_ports=True) - self.assertItemsEqual({'subnet': None, 'ports': []}, subnet_options) + self.assertCountEqual({'subnet': None, 'ports': []}, subnet_options) def test_get_subnets_dhcp_options(self): self._load_nb_db() @@ -746,13 +746,13 @@ get_row_dict( self._find_ovsdb_fake_row(self.dhcp_table, 'cidr', cidr)) for cidr in ('10.0.1.0/24', '10.0.2.0/24')] - self.assertItemsEqual(expected_rows, subnets_options) + self.assertCountEqual(expected_rows, subnets_options) subnets_options = self.nb_ovn_idl.get_subnets_dhcp_options( ['subnet-id-11-0-2-0', 'subnet-id-20-0-1-0']) expected_row = get_row_dict( self._find_ovsdb_fake_row(self.dhcp_table, 'cidr', '20.0.1.0/24')) - self.assertItemsEqual([expected_row], subnets_options) + self.assertCountEqual([expected_row], subnets_options) subnets_options = self.nb_ovn_idl.get_subnets_dhcp_options( ['port-id-30-0-1-0', 'fake-not-exist']) diff -Nru neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py --- neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py 2021-09-10 15:08:49.000000000 +0000 @@ -113,20 +113,20 @@ ovn_event = mock.Mock() unknown_event = mock.Mock() - self.assertItemsEqual(set(), self.watched_events) + self.assertCountEqual(set(), self.watched_events) expected_events.add(networking_event) self.handler.watch_event(networking_event) - self.assertItemsEqual(expected_events, self.watched_events) + self.assertCountEqual(expected_events, self.watched_events) expected_events.add(ovn_event) self.handler.watch_events([ovn_event]) - self.assertItemsEqual(expected_events, self.watched_events) + self.assertCountEqual(expected_events, self.watched_events) self.handler.unwatch_events([networking_event, ovn_event]) self.handler.unwatch_event(unknown_event) self.handler.unwatch_events([unknown_event]) - self.assertItemsEqual(set(), self.watched_events) + self.assertCountEqual(set(), self.watched_events) def test_shutdown(self): self.handler.shutdown() diff -Nru neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py --- neutron-18.1.0/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py 2021-09-10 15:08:48.000000000 +0000 @@ -12,10 +12,13 @@ # License for the specific language governing permissions and limitations # under the License. +from unittest import mock + from neutron_lib.api.definitions import portbindings as pb from neutron_lib.api.definitions import provider_net as pnet from neutron_lib import context as n_context from neutron_lib.db import api as db_api +from neutron_lib import exceptions from oslo_utils import uuidutils from neutron.db.models.plugins.ml2 import geneveallocation @@ -156,3 +159,25 @@ self._create_ml2_ovs_test_resources(vif_details_list) db_migration.migrate_neutron_database_to_ovn(self.mech_driver._plugin) self._validate_resources_after_migration(expected_vif_details) + + def test_db_migration_with_pb_not_found(self): + vif_details_list = [ + {pb.CAP_PORT_FILTER: "true", + pb.OVS_HYBRID_PLUG: "true", + pb.VIF_DETAILS_BRIDGE_NAME: "foo", + pb.VIF_DETAILS_CONNECTIVITY: "l2"}, + {pb.CAP_PORT_FILTER: "true", + pb.VIF_DETAILS_BRIDGE_NAME: "foo"}, + {"foo": "bar"}, + {}, + ] + + self._create_ml2_ovs_test_resources(vif_details_list) + with mock.patch.object( + port_obj.PortBinding, 'update', + side_effect=exceptions.ObjectNotFound(id='foo')): + with mock.patch.object(trunk_obj.Trunk, 'get_objects', + return_value=[]): + db_migration.migrate_neutron_database_to_ovn( + self.mech_driver._plugin) + self._validate_resources_after_migration(vif_details_list) diff -Nru neutron-18.1.0/neutron/tests/unit/scheduler/test_l3_agent_scheduler.py neutron-18.1.1/neutron/tests/unit/scheduler/test_l3_agent_scheduler.py --- neutron-18.1.0/neutron/tests/unit/scheduler/test_l3_agent_scheduler.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/scheduler/test_l3_agent_scheduler.py 2021-09-10 15:08:49.000000000 +0000 @@ -2097,7 +2097,7 @@ self.assertEqual(len(self.expected_agent_modes), len(l3_agents)) returned_agent_modes = [self._get_agent_mode(agent) for agent in l3_agents] - self.assertItemsEqual(self.expected_agent_modes, returned_agent_modes) + self.assertCountEqual(self.expected_agent_modes, returned_agent_modes) class TestGetL3AgentsWithHostFilter(TestGetL3AgentsWithFilter): diff -Nru neutron-18.1.0/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py neutron-18.1.1/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py --- neutron-18.1.0/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py 2021-09-10 15:08:48.000000000 +0000 @@ -119,7 +119,7 @@ mapping = self.fake_chassis_gateway_mappings['Multiple1'] gateway_name = self.new_gateway_name chassis = self.select(mapping, gateway_name) - self.assertItemsEqual(chassis, mapping.get('Chassis')) + self.assertCountEqual(chassis, mapping.get('Chassis')) def test_filter_existing_chassis(self): # filter_existing_chassis is scheduler independent, but calling @@ -182,7 +182,7 @@ mapping = self.fake_chassis_gateway_mappings['Multiple1'] gateway_name = self.new_gateway_name chassis = self.select(mapping, gateway_name) - self.assertItemsEqual(chassis, mapping.get('Chassis')) + self.assertCountEqual(chassis, mapping.get('Chassis')) # least loaded will be the first one in the list, # networking-ovn will assign highest priority to this first element self.assertEqual(['hv5', 'hv4', 'hv3', 'hv2', 'hv1'], chassis) @@ -222,7 +222,7 @@ chassis_info.append(('lrp', 2)) actual = self.l3_scheduler._get_chassis_load_by_prios(chassis_info) expected = {1: 5, 2: 5} - self.assertItemsEqual(expected.items(), actual) + self.assertCountEqual(expected.items(), actual) def test__get_chassis_load_by_prios_no_ports(self): self.assertFalse(self.l3_scheduler._get_chassis_load_by_prios([])) diff -Nru neutron-18.1.0/neutron/tests/unit/services/ovn_l3/test_plugin.py neutron-18.1.1/neutron/tests/unit/services/ovn_l3/test_plugin.py --- neutron-18.1.0/neutron/tests/unit/services/ovn_l3/test_plugin.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/services/ovn_l3/test_plugin.py 2021-09-10 15:08:49.000000000 +0000 @@ -352,7 +352,7 @@ self.l3_inst._ovn.update_lrouter_port.call_args_list[0][1]) self.assertEqual(1, self.l3_inst._ovn.update_lrouter_port.call_count) - self.assertItemsEqual(fake_rtr_intf_networks, + self.assertCountEqual(fake_rtr_intf_networks, called_args_dict.get('networks', [])) self.l3_inst._ovn.set_lrouter_port_in_lswitch_port.\ assert_called_once_with( diff -Nru neutron-18.1.0/neutron/tests/unit/services/trunk/rpc/test_server.py neutron-18.1.1/neutron/tests/unit/services/trunk/rpc/test_server.py --- neutron-18.1.0/neutron/tests/unit/services/trunk/rpc/test_server.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/services/trunk/rpc/test_server.py 2021-09-10 15:08:48.000000000 +0000 @@ -67,7 +67,7 @@ self.mock_registry_provide.assert_called_with( server.trunk_by_port_provider, resources.TRUNK) - self.assertItemsEqual(('trunk', [test_obj],), + self.assertCountEqual(('trunk', [test_obj],), mock_conn.mock_calls[1][1]) def test_update_subport_bindings(self): diff -Nru neutron-18.1.0/neutron/tests/unit/tests/test_base.py neutron-18.1.1/neutron/tests/unit/tests/test_base.py --- neutron-18.1.0/neutron/tests/unit/tests/test_base.py 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/neutron/tests/unit/tests/test_base.py 2021-09-10 15:08:48.000000000 +0000 @@ -70,7 +70,7 @@ self.fail('SystemExit escaped!') self.assertEqual([], result.errors) - self.assertItemsEqual(set(id(t) for t in expectedFails), + self.assertCountEqual(set(id(t) for t in expectedFails), set(id(t) for (t, traceback) in result.failures)) diff -Nru neutron-18.1.0/neutron.egg-info/pbr.json neutron-18.1.1/neutron.egg-info/pbr.json --- neutron-18.1.0/neutron.egg-info/pbr.json 2021-07-12 10:06:00.000000000 +0000 +++ neutron-18.1.1/neutron.egg-info/pbr.json 2021-09-10 15:10:02.000000000 +0000 @@ -1 +1 @@ -{"git_version": "c1390d86a0", "is_release": true} \ No newline at end of file +{"git_version": "c5e86f4f8f", "is_release": true} \ No newline at end of file diff -Nru neutron-18.1.0/neutron.egg-info/PKG-INFO neutron-18.1.1/neutron.egg-info/PKG-INFO --- neutron-18.1.0/neutron.egg-info/PKG-INFO 2021-07-12 10:06:00.000000000 +0000 +++ neutron-18.1.1/neutron.egg-info/PKG-INFO 2021-09-10 15:10:02.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: neutron -Version: 18.1.0 +Version: 18.1.1 Summary: OpenStack Networking Home-page: https://docs.openstack.org/neutron/latest/ Author: OpenStack diff -Nru neutron-18.1.0/neutron.egg-info/SOURCES.txt neutron-18.1.1/neutron.egg-info/SOURCES.txt --- neutron-18.1.0/neutron.egg-info/SOURCES.txt 2021-07-12 10:06:01.000000000 +0000 +++ neutron-18.1.1/neutron.egg-info/SOURCES.txt 2021-09-10 15:10:02.000000000 +0000 @@ -2577,6 +2577,7 @@ releasenotes/notes/fix-mac-learning-in-case--ovs-offload-26193bf1638fd673.yaml releasenotes/notes/fix-mtu-for-existing-networks-5a476cde9bc46a53.yaml releasenotes/notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml +releasenotes/notes/fix-newline-chars-in-dhcp-extra-options-bf86d30371556d63.yaml releasenotes/notes/fix-ovsdb-ssl-connection-4058caf4fdcb33ab.yaml releasenotes/notes/fix-port-dns-assignment-9d916d77522abd65.yaml releasenotes/notes/fix-remote-security-group-no-port-on-host-9177e66d4b16e90c.yaml diff -Nru neutron-18.1.0/PKG-INFO neutron-18.1.1/PKG-INFO --- neutron-18.1.0/PKG-INFO 2021-07-12 10:06:02.340417400 +0000 +++ neutron-18.1.1/PKG-INFO 2021-09-10 15:10:03.601523600 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: neutron -Version: 18.1.0 +Version: 18.1.1 Summary: OpenStack Networking Home-page: https://docs.openstack.org/neutron/latest/ Author: OpenStack diff -Nru neutron-18.1.0/releasenotes/notes/fix-newline-chars-in-dhcp-extra-options-bf86d30371556d63.yaml neutron-18.1.1/releasenotes/notes/fix-newline-chars-in-dhcp-extra-options-bf86d30371556d63.yaml --- neutron-18.1.0/releasenotes/notes/fix-newline-chars-in-dhcp-extra-options-bf86d30371556d63.yaml 1970-01-01 00:00:00.000000000 +0000 +++ neutron-18.1.1/releasenotes/notes/fix-newline-chars-in-dhcp-extra-options-bf86d30371556d63.yaml 2021-09-10 15:08:48.000000000 +0000 @@ -0,0 +1,6 @@ +--- +security: + - | + Fix `bug 1939733 `_ by + dropping from the dhcp extra option values everything what is after first + newline (``\n``) character before passing them to the dnsmasq. diff -Nru neutron-18.1.0/tools/ovn_migration/tripleo_environment/playbooks/roles/delete-neutron-resources/templates/delete-neutron-resources.sh.j2 neutron-18.1.1/tools/ovn_migration/tripleo_environment/playbooks/roles/delete-neutron-resources/templates/delete-neutron-resources.sh.j2 --- neutron-18.1.0/tools/ovn_migration/tripleo_environment/playbooks/roles/delete-neutron-resources/templates/delete-neutron-resources.sh.j2 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/tools/ovn_migration/tripleo_environment/playbooks/roles/delete-neutron-resources/templates/delete-neutron-resources.sh.j2 2021-09-10 15:08:48.000000000 +0000 @@ -26,4 +26,7 @@ openstack network delete $i done +# Delete DVR gateway ports +openstack port delete $(openstack port list --device-owner "network:floatingip_agent_gateway" -c id -f value) + exit 0 diff -Nru neutron-18.1.0/tox.ini neutron-18.1.1/tox.ini --- neutron-18.1.0/tox.ini 2021-07-12 10:05:21.000000000 +0000 +++ neutron-18.1.1/tox.ini 2021-09-10 15:08:49.000000000 +0000 @@ -182,6 +182,7 @@ # Checks specific to neutron repo N322 = neutron.hacking.checks:check_assert_called_once_with N328 = neutron.hacking.checks:check_asserttruefalse + N329 = neutron.hacking.checks:check_assertitemsequal N330 = neutron.hacking.checks:check_assertempty N331 = neutron.hacking.checks:check_assertisinstance N332 = neutron.hacking.checks:check_assertequal_for_httpcode