From f3927ffb3d5e8803115a436f27d15cf52f61d2e0 Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Wed, 18 Nov 2020 20:05:48 +0900 Subject: [PATCH] Fix create/update_port with python3 unescape_port_kwargs() in api/neutron.py changes a key of dict during the iteration and it is not allowed in python3. Change-Id: Ifc1b9a0191aacd32e8c8ecc082b6313f04003f63 Closes-Bug: #1900851 --- openstack_dashboard/api/neutron.py | 3 ++- .../test/unit/api/test_neutron.py | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/openstack_dashboard/api/neutron.py b/openstack_dashboard/api/neutron.py index 7bd3e29fb8..9d7496e87b 100644 --- a/openstack_dashboard/api/neutron.py +++ b/openstack_dashboard/api/neutron.py @@ -1360,7 +1360,8 @@ def port_get(request, port_id, **params): def unescape_port_kwargs(**kwargs): - for key in kwargs: + keys = list(kwargs) + for key in keys: if '__' in key: kwargs[':'.join(key.split('__'))] = kwargs.pop(key) return kwargs diff --git a/openstack_dashboard/test/unit/api/test_neutron.py b/openstack_dashboard/test/unit/api/test_neutron.py index 4a42b8d454..59a2299591 100644 --- a/openstack_dashboard/test/unit/api/test_neutron.py +++ b/openstack_dashboard/test/unit/api/test_neutron.py @@ -581,21 +581,24 @@ class NeutronApiTests(test.APIMockTestCase): @mock.patch.object(api.neutron, 'neutronclient') def test_port_create(self, mock_neutronclient): - port = {'port': self.api_ports.first()} - params = {'network_id': port['port']['network_id'], - 'tenant_id': port['port']['tenant_id'], - 'name': port['port']['name'], - 'device_id': port['port']['device_id']} + port = self.api_ports.first() + params = {'network_id': port['network_id'], + 'tenant_id': port['tenant_id'], + 'name': port['name'], + 'device_id': port['device_id']} + api_params = params.copy() + params['binding__vnic_type'] = port['binding:vnic_type'] + api_params['binding:vnic_type'] = port['binding:vnic_type'] neutronclient = mock_neutronclient.return_value - neutronclient.create_port.return_value = port + neutronclient.create_port.return_value = {'port': port} ret_val = api.neutron.port_create(self.request, **params) self.assertIsInstance(ret_val, api.neutron.Port) - self.assertEqual(api.neutron.Port(port['port']).id, ret_val.id) + self.assertEqual(api.neutron.Port(port).id, ret_val.id) neutronclient.create_port.assert_called_once_with( - body={'port': params}) + body={'port': api_params}) @mock.patch.object(api.neutron, 'neutronclient') def test_port_update(self, mock_neutronclient): @@ -603,6 +606,9 @@ class NeutronApiTests(test.APIMockTestCase): port_id = port_data['id'] params = {'name': port_data['name'], 'device_id': port_data['device_id']} + api_params = params.copy() + params['binding__vnic_type'] = port_data['binding:vnic_type'] + api_params['binding:vnic_type'] = port_data['binding:vnic_type'] neutronclient = mock_neutronclient.return_value neutronclient.update_port.return_value = {'port': port_data} @@ -612,7 +618,7 @@ class NeutronApiTests(test.APIMockTestCase): self.assertIsInstance(ret_val, api.neutron.Port) self.assertEqual(api.neutron.Port(port_data).id, ret_val.id) neutronclient.update_port.assert_called_once_with( - port_id, body={'port': params}) + port_id, body={'port': api_params}) @mock.patch.object(api.neutron, 'neutronclient') def test_port_delete(self, mock_neutronclient):