diff --git a/neutron/pecan_wsgi/controllers/utils.py b/neutron/pecan_wsgi/controllers/utils.py index 83dd9eaeabc..7cf6cd9f214 100644 --- a/neutron/pecan_wsgi/controllers/utils.py +++ b/neutron/pecan_wsgi/controllers/utils.py @@ -181,11 +181,13 @@ class NeutronPecanController(object): def build_field_list(self, request_fields): added_fields = [] combined_fields = [] - if request_fields: - req_fields_set = set(request_fields) + req_fields_set = {f for f in request_fields if f} + if req_fields_set: added_fields = self._mandatory_fields - req_fields_set combined_fields = req_fields_set | self._mandatory_fields - return list(combined_fields), list(added_fields) + # field sorting is to match old behavior of legacy API and to make + # this drop-in compatible with the old API unit tests + return sorted(combined_fields), list(added_fields) @property def plugin(self): diff --git a/neutron/tests/functional/pecan_wsgi/test_controllers.py b/neutron/tests/functional/pecan_wsgi/test_controllers.py index eb0c218de18..e47303f4648 100644 --- a/neutron/tests/functional/pecan_wsgi/test_controllers.py +++ b/neutron/tests/functional/pecan_wsgi/test_controllers.py @@ -386,6 +386,17 @@ class TestResourceController(TestRootController): self._check_item(['id', 'tenant_id'], jsonutils.loads(item_resp.body)['port']) + def test_duped_and_empty_fields_stripped(self): + mock_get = mock.patch.object(self.plugin, 'get_ports', + return_value=[]).start() + self.app.get( + '/v2.0/ports.json?fields=id&fields=name&fields=&fields=name', + headers={'X-Project-Id': 'tenid'} + ) + received = mock_get.mock_calls[-1][2]['fields'] + self.assertNotIn('', received) + self.assertEqual(len(received), len(set(received))) + def test_post(self): response = self.app.post_json( '/v2.0/ports.json',