From e40669237b1972e90d448001933644ae1d0c835c Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Sun, 14 May 2017 19:33:03 +0000 Subject: [PATCH] Machine-readable output for JSON/YAML format Currently even if machine-readable format like JSON or YAML is specified, formatted output is displayed. When machine-readable format is used, they should not be converted by formatters. Change-Id: I5f1e90ff60f30380106e1aa730f96a1f72c7a166 Closes-Bug: #1687955 --- neutronclient/osc/v2/fwaas/firewallgroup.py | 2 +- neutronclient/osc/v2/fwaas/firewallrule.py | 9 ++++-- .../osc/v2/networking_bgpvpn/bgpvpn.py | 13 ++++---- neutronclient/osc/v2/trunk/network_trunk.py | 5 +-- neutronclient/osc/v2/utils.py | 7 ++-- neutronclient/tests/unit/osc/v2/fakes.py | 18 +++++++++++ .../tests/unit/osc/v2/fwaas/common.py | 4 +-- .../unit/osc/v2/fwaas/test_firewallgroup.py | 10 +++--- .../unit/osc/v2/fwaas/test_firewallrule.py | 8 ++--- .../osc/v2/networking_bgpvpn/test_bgpvpn.py | 31 ++++++++++-------- .../unit/osc/v2/trunk/test_network_trunk.py | 32 +++++++++---------- 11 files changed, 85 insertions(+), 54 deletions(-) diff --git a/neutronclient/osc/v2/fwaas/firewallgroup.py b/neutronclient/osc/v2/fwaas/firewallgroup.py index b84442f13..ce7aac3c0 100644 --- a/neutronclient/osc/v2/fwaas/firewallgroup.py +++ b/neutronclient/osc/v2/fwaas/firewallgroup.py @@ -28,7 +28,7 @@ from neutronclient.osc.v2 import utils as v2_utils LOG = logging.getLogger(__name__) _formatters = { - 'admin_state_up': v2_utils.format_admin_state, + 'admin_state_up': v2_utils.AdminStateColumn, } _attr_map = ( diff --git a/neutronclient/osc/v2/fwaas/firewallrule.py b/neutronclient/osc/v2/fwaas/firewallrule.py index 00b3b216e..f2eeb1945 100644 --- a/neutronclient/osc/v2/fwaas/firewallrule.py +++ b/neutronclient/osc/v2/fwaas/firewallrule.py @@ -16,6 +16,7 @@ import copy import logging +from cliff import columns as cliff_columns from osc_lib.command import command from osc_lib import exceptions from osc_lib import utils @@ -181,10 +182,12 @@ def _get_common_attrs(client_manager, parsed_args, is_create=True): return attrs -def format_protocol(protocol): - return protocol if protocol else 'any' +class ProtocolColumn(cliff_columns.FormattableColumn): + def human_readable(self): + return self._value if self._value else 'any' -_formatters = {'protocol': format_protocol} + +_formatters = {'protocol': ProtocolColumn} class CreateFirewallRule(command.ShowOne): diff --git a/neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py b/neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py index af7414ede..96d72ddfe 100644 --- a/neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py +++ b/neutronclient/osc/v2/networking_bgpvpn/bgpvpn.py @@ -16,6 +16,7 @@ import logging +from osc_lib.cli import format_columns from osc_lib.cli.parseractions import KeyValueAction from osc_lib.command import command from osc_lib import exceptions @@ -41,12 +42,12 @@ _attr_map = ( ('routers', 'Associated Routers', nc_osc_utils.LIST_LONG_ONLY), ) _formatters = { - 'route_targets': osc_utils.format_list, - 'import_targets': osc_utils.format_list, - 'export_targets': osc_utils.format_list, - 'route_distinguishers': osc_utils.format_list, - 'networks': osc_utils.format_list, - 'routers': osc_utils.format_list, + 'route_targets': format_columns.ListColumn, + 'import_targets': format_columns.ListColumn, + 'export_targets': format_columns.ListColumn, + 'route_distinguishers': format_columns.ListColumn, + 'networks': format_columns.ListColumn, + 'routers': format_columns.ListColumn, } diff --git a/neutronclient/osc/v2/trunk/network_trunk.py b/neutronclient/osc/v2/trunk/network_trunk.py index a6aadbb85..26cb52be9 100644 --- a/neutronclient/osc/v2/trunk/network_trunk.py +++ b/neutronclient/osc/v2/trunk/network_trunk.py @@ -17,6 +17,7 @@ """Network trunk and subports action implementations""" import logging +from osc_lib.cli import format_columns from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions @@ -310,8 +311,8 @@ class UnsetNetworkTrunk(command.Command): _formatters = { - 'admin_state_up': v2_utils.format_admin_state, - 'sub_ports': osc_utils.format_list_of_dicts, + 'admin_state_up': v2_utils.AdminStateColumn, + 'sub_ports': format_columns.ListDictColumn, } diff --git a/neutronclient/osc/v2/utils.py b/neutronclient/osc/v2/utils.py index 9e9040179..b03e29c3d 100644 --- a/neutronclient/osc/v2/utils.py +++ b/neutronclient/osc/v2/utils.py @@ -16,6 +16,9 @@ to Networking v2 API and its extensions. """ +from cliff import columns as cliff_columns -def format_admin_state(state): - return 'UP' if state else 'DOWN' + +class AdminStateColumn(cliff_columns.FormattableColumn): + def human_readable(self): + return 'UP' if self._value else 'DOWN' diff --git a/neutronclient/tests/unit/osc/v2/fakes.py b/neutronclient/tests/unit/osc/v2/fakes.py index 75277a952..db962d2e5 100644 --- a/neutronclient/tests/unit/osc/v2/fakes.py +++ b/neutronclient/tests/unit/osc/v2/fakes.py @@ -14,6 +14,7 @@ import argparse import mock +from cliff import columns as cliff_columns from osc_lib.tests import utils @@ -25,3 +26,20 @@ class TestNeutronClientOSCV2(utils.TestCommand): self.app.client_manager.session = mock.Mock() self.app.client_manager.neutronclient = mock.Mock() self.neutronclient = self.app.client_manager.neutronclient + + # TODO(amotoki): Move this to osc_lib + def assertListItemEqual(self, expected, actual): + self.assertEqual(len(expected), len(actual)) + for item_expected, item_actual in zip(expected, actual): + self.assertItemEqual(item_expected, item_actual) + + # TODO(amotoki): Move this to osc_lib + def assertItemEqual(self, expected, actual): + self.assertEqual(len(expected), len(actual)) + for col_expected, col_actual in zip(expected, actual): + if isinstance(col_expected, cliff_columns.FormattableColumn): + self.assertIsInstance(col_actual, col_expected.__class__) + self.assertEqual(col_expected.human_readable(), + col_actual.human_readable()) + else: + self.assertEqual(col_expected, col_actual) diff --git a/neutronclient/tests/unit/osc/v2/fwaas/common.py b/neutronclient/tests/unit/osc/v2/fwaas/common.py index b9ea7841b..cfd4df9c9 100644 --- a/neutronclient/tests/unit/osc/v2/fwaas/common.py +++ b/neutronclient/tests/unit/osc/v2/fwaas/common.py @@ -42,7 +42,7 @@ class TestListFWaaS(test_fakes.TestNeutronClientOSCV2): self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) - self.assertEqual([self.data], list(data)) + self.assertListItemEqual([self.data], list(data)) class TestShowFWaaS(test_fakes.TestNeutronClientOSCV2): @@ -67,7 +67,7 @@ class TestShowFWaaS(test_fakes.TestNeutronClientOSCV2): self.mocked.assert_called_once_with(target) self.assertEqual(self.ordered_headers, headers) - self.assertEqual(self.ordered_data, data) + self.assertItemEqual(self.ordered_data, data) class TestCreateFWaaS(test_fakes.TestNeutronClientOSCV2): diff --git a/neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py b/neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py index cc074ff2f..0a15f2b6d 100644 --- a/neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py +++ b/neutronclient/tests/unit/osc/v2/fwaas/test_firewallgroup.py @@ -24,6 +24,7 @@ from osc_lib.tests import utils from neutronclient.osc import utils as osc_utils from neutronclient.osc.v2.fwaas import constants as const from neutronclient.osc.v2.fwaas import firewallgroup +from neutronclient.osc.v2 import utils as v2_utils from neutronclient.tests.unit.osc.v2 import fakes as test_fakes from neutronclient.tests.unit.osc.v2.fwaas import common from neutronclient.tests.unit.osc.v2.fwaas import fakes @@ -46,7 +47,8 @@ CONVERT_MAP = { def _generate_response(ordered_dict=None, data=None): source = ordered_dict if ordered_dict else _fwg - up = {'admin_state_up': 'UP' if source['admin_state_up'] else 'DOWN'} + up = {'admin_state_up': + v2_utils.AdminStateColumn(source['admin_state_up'])} if data: up.append(data) source.update(up) @@ -81,7 +83,7 @@ class TestFirewallGroup(test_fakes.TestNeutronClientOSCV2): req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) - self.assertEqual(self.ordered_data, data) + self.assertItemEqual(self.ordered_data, data) def setUp(self): super(TestFirewallGroup, self).setUp() @@ -127,7 +129,7 @@ class TestFirewallGroup(test_fakes.TestNeutronClientOSCV2): _fwg['ports'], _fwg['tenant_id'], _fwg['public'], - 'UP' if _fwg['admin_state_up'] else 'DOWN', + v2_utils.AdminStateColumn(_fwg['admin_state_up']), _fwg['status'], ) self.ordered_columns = ( @@ -180,7 +182,7 @@ class TestCreateFirewallGroup(TestFirewallGroup, common.TestCreateFWaaS): headers, data = self.cmd.take_action(parsed_args) self.assertEqual(self.ordered_headers, headers) - self.assertEqual(self.ordered_data, data) + self.assertItemEqual(self.ordered_data, data) def test_create_with_port(self): # firewall_group-create with 'port' diff --git a/neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py b/neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py index c77d84920..d09bbbe98 100644 --- a/neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py +++ b/neutronclient/tests/unit/osc/v2/fwaas/test_firewallrule.py @@ -52,7 +52,7 @@ def _replace_display_columns(key, val): if val is None: return val if key == 'protocol': - return firewallrule.format_protocol(val) + return firewallrule.ProtocolColumn(val) return val @@ -86,7 +86,7 @@ class TestFirewallRule(test_fakes.TestNeutronClientOSCV2): req_body = {self.res: exp_req} self.mocked.assert_called_once_with(req_body) self.assertEqual(self.ordered_headers, headers) - self.assertEqual(self.ordered_data, data) + self.assertItemEqual(self.ordered_data, data) def setUp(self): super(TestFirewallRule, self).setUp() @@ -329,7 +329,7 @@ class TestListFirewallRule(TestFirewallRule): self.mocked.assert_called_once_with() self.assertEqual(list(self.headers), headers) - self.assertEqual([self.data], list(data)) + self.assertListItemEqual([self.data], list(data)) def test_list_with_no_option(self): arglist = [] @@ -339,7 +339,7 @@ class TestListFirewallRule(TestFirewallRule): self.mocked.assert_called_once_with() self.assertEqual(list(self.short_header), headers) - self.assertEqual([self.short_data], list(data)) + self.assertListItemEqual([self.short_data], list(data)) class TestShowFirewallRule(TestFirewallRule, common.TestShowFWaaS): diff --git a/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py b/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py index 3d8348824..aa688277d 100644 --- a/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py +++ b/neutronclient/tests/unit/osc/v2/networking_bgpvpn/test_bgpvpn.py @@ -76,7 +76,7 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.create_bgpvpn.assert_called_once_with( {constants.BGPVPN: {'type': 'l3'}}) self.assertEqual(sorted_headers, cols) - self.assertEqual(_get_data(fake_bgpvpn), data) + self.assertItemEqual(_get_data(fake_bgpvpn), data) def test_create_bgpvpn_with_all_args(self): attrs = { @@ -125,7 +125,7 @@ class TestCreateBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.create_bgpvpn.assert_called_once_with( {constants.BGPVPN: fake_bgpvpn_call}) self.assertEqual(sorted_headers, cols) - self.assertEqual(_get_data(fake_bgpvpn), data) + self.assertItemEqual(_get_data(fake_bgpvpn), data) class TestSetBgpvpn(fakes.TestNeutronClientBgpvpn): @@ -409,9 +409,10 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.list_bgpvpns.assert_called_once() self.assertEqual(headers, list(headers_short)) - self.assertEqual(list(data), - [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn - in fake_bgpvpns[constants.BGPVPNS]]) + self.assertListItemEqual( + list(data), + [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn + in fake_bgpvpns[constants.BGPVPNS]]) def test_list_all_bgpvpn_long_mode(self): count = 3 @@ -430,9 +431,10 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.list_bgpvpns.assert_called_once() self.assertEqual(headers, list(headers_long)) - self.assertEqual(list(data), - [_get_data(fake_bgpvpn, columns_long) for fake_bgpvpn - in fake_bgpvpns[constants.BGPVPNS]]) + self.assertListItemEqual( + list(data), + [_get_data(fake_bgpvpn, columns_long) for fake_bgpvpn + in fake_bgpvpns[constants.BGPVPNS]]) def test_list_project_bgpvpn(self): count = 3 @@ -455,9 +457,10 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.list_bgpvpns.assert_called_once_with( tenant_id=project_id) self.assertEqual(headers, list(headers_short)) - self.assertEqual(list(data), - [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn - in fake_bgpvpns[constants.BGPVPNS]]) + self.assertListItemEqual( + list(data), + [_get_data(fake_bgpvpn, columns_short) for fake_bgpvpn + in fake_bgpvpns[constants.BGPVPNS]]) def test_list_bgpvpn_with_filters(self): count = 3 @@ -485,8 +488,8 @@ class TestListBgpvpn(fakes.TestNeutronClientBgpvpn): name=name, type=layer_type) self.assertEqual(headers, list(headers_short)) - self.assertEqual(list(data), - [_get_data(returned_bgpvpn, columns_short)]) + self.assertListItemEqual(list(data), + [_get_data(returned_bgpvpn, columns_short)]) class TestShowBgpvpn(fakes.TestNeutronClientBgpvpn): @@ -512,4 +515,4 @@ class TestShowBgpvpn(fakes.TestNeutronClientBgpvpn): self.neutronclient.show_bgpvpn.assert_called_once_with( fake_bgpvpn['id']) self.assertEqual(sorted_headers, headers) - self.assertEqual(_get_data(fake_bgpvpn), data) + self.assertItemEqual(_get_data(fake_bgpvpn), data) diff --git a/neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py b/neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py index 8408f7edf..8b7aaa0d5 100644 --- a/neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py +++ b/neutronclient/tests/unit/osc/v2/trunk/test_network_trunk.py @@ -19,9 +19,9 @@ import mock from mock import call import testtools +from osc_lib.cli import format_columns from osc_lib import exceptions from osc_lib.tests import utils as tests_utils -from osc_lib import utils from neutronclient.osc.v2.trunk import network_trunk as trunk from neutronclient.osc.v2 import utils as v2_utils @@ -50,14 +50,14 @@ class TestCreateNetworkTrunk(test_fakes.TestNeutronClientOSCV2): def get_data(self): return ( - v2_utils.format_admin_state(self._trunk['admin_state_up']), + v2_utils.AdminStateColumn(self._trunk['admin_state_up']), self._trunk['description'], self._trunk['id'], self._trunk['name'], self._trunk['port_id'], self._trunk['project_id'], self._trunk['status'], - utils.format_list_of_dicts(self._trunk['sub_ports']), + format_columns.ListDictColumn(self._trunk['sub_ports']), ) def setUp(self): @@ -97,7 +97,7 @@ class TestCreateNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) - self.assertEqual(self.data, data) + self.assertItemEqual(self.data, data) def test_create_full_options(self): self._trunk['description'] = 'foo description' @@ -137,7 +137,7 @@ class TestCreateNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) - self.assertEqual(self.data, data) + self.assertItemEqual(self.data, data) def test_create_trunk_with_subport_invalid_segmentation_id_fail(self): subport = self._trunk['sub_ports'][0] @@ -191,7 +191,7 @@ class TestCreateNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'port_id': self._trunk['port_id']} }) self.assertEqual(self.columns, columns) - self.assertEqual(self.data, data) + self.assertItemEqual(self.data, data) def test_create_network_trunk_subports_without_required_key_fail(self): subport = self._trunk['sub_ports'][0] @@ -301,14 +301,14 @@ class TestShowNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'sub_ports', ) data = ( - v2_utils.format_admin_state(_trunk['admin_state_up']), + v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['description'], _trunk['id'], _trunk['name'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], - utils.format_list_of_dicts(_trunk['sub_ports']), + format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self): @@ -343,7 +343,7 @@ class TestShowNetworkTrunk(test_fakes.TestNeutronClientOSCV2): self.neutronclient.show_trunk.assert_called_once_with( self._trunk['id']) self.assertEqual(self.columns, columns) - self.assertEqual(self.data, data) + self.assertItemEqual(self.data, data) class TestListNetworkTrunk(test_fakes.TestNeutronClientOSCV2): @@ -380,7 +380,7 @@ class TestListNetworkTrunk(test_fakes.TestNeutronClientOSCV2): t['port_id'], t['description'], t['status'], - v2_utils.format_admin_state(t['admin_state_up']), + v2_utils.AdminStateColumn(t['admin_state_up']), '2001-01-01 00:00:00', '2001-01-01 00:00:00', )) @@ -404,7 +404,7 @@ class TestListNetworkTrunk(test_fakes.TestNeutronClientOSCV2): self.neutronclient.list_trunks.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertEqual(self.data, list(data)) + self.assertListItemEqual(self.data, list(data)) def test_trunk_list_long(self): arglist = [ @@ -419,7 +419,7 @@ class TestListNetworkTrunk(test_fakes.TestNeutronClientOSCV2): self.neutronclient.list_trunks.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertEqual(self.data_long, list(data)) + self.assertListItemEqual(self.data_long, list(data)) class TestSetNetworkTrunk(test_fakes.TestNeutronClientOSCV2): @@ -437,14 +437,14 @@ class TestSetNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'sub_ports', ) data = ( - v2_utils.format_admin_state(_trunk['admin_state_up']), + v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['id'], _trunk['name'], _trunk['description'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], - utils.format_list_of_dicts(_trunk['sub_ports']), + format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self): @@ -717,13 +717,13 @@ class TestUnsetNetworkTrunk(test_fakes.TestNeutronClientOSCV2): 'sub_ports', ) data = ( - v2_utils.format_admin_state(_trunk['admin_state_up']), + v2_utils.AdminStateColumn(_trunk['admin_state_up']), _trunk['id'], _trunk['name'], _trunk['port_id'], _trunk['project_id'], _trunk['status'], - utils.format_list_of_dicts(_trunk['sub_ports']), + format_columns.ListDictColumn(_trunk['sub_ports']), ) def setUp(self):