From c44f26eb7e41c28bb13ef9bd31c8ddda9e638862 Mon Sep 17 00:00:00 2001
From: Akihiro Motoki <amotoki@gmail.com>
Date: Wed, 3 May 2017 14:19:27 +0000
Subject: [PATCH] Use cliff formattable columns in network commands

Use cliff formattable columns not to convert complex fields
into a string when a machine readable format like JSON or YAML
is requested.

Partial-Bug: #1687955
Partially implement blueprint osc-formattable-columns

Change-Id: I9878f327e39f56852cc0fb6e4eee9105b7141da9
---
 openstackclient/network/v2/ip_availability.py |  3 +-
 openstackclient/network/v2/network.py         | 30 +++---
 openstackclient/network/v2/network_agent.py   | 23 +++--
 openstackclient/network/v2/port.py            | 31 +++---
 openstackclient/network/v2/router.py          | 47 +++++----
 openstackclient/network/v2/security_group.py  | 15 ++-
 openstackclient/network/v2/subnet.py          | 30 +++---
 openstackclient/network/v2/subnet_pool.py     |  5 +-
 .../tests/functional/network/v2/common.py     | 14 +--
 .../functional/network/v2/test_network.py     | 18 ++--
 .../network/v2/test_network_agent.py          |  4 +-
 .../tests/functional/network/v2/test_port.py  | 29 +++---
 .../functional/network/v2/test_router.py      |  6 +-
 .../functional/network/v2/test_subnet.py      |  4 +-
 .../functional/network/v2/test_subnet_pool.py | 16 +--
 .../unit/network/v2/test_ip_availability.py   | 12 +--
 .../tests/unit/network/v2/test_network.py     | 97 ++++++++++---------
 .../unit/network/v2/test_network_agent.py     | 26 ++---
 .../tests/unit/network/v2/test_port.py        | 87 +++++++++--------
 .../tests/unit/network/v2/test_router.py      | 76 +++++++--------
 .../network/v2/test_security_group_compute.py | 15 ++-
 .../network/v2/test_security_group_network.py | 20 ++--
 .../tests/unit/network/v2/test_subnet.py      | 92 +++++++++---------
 .../tests/unit/network/v2/test_subnet_pool.py | 57 +++++------
 openstackclient/tests/unit/utils.py           | 17 ++++
 25 files changed, 407 insertions(+), 367 deletions(-)

diff --git a/openstackclient/network/v2/ip_availability.py b/openstackclient/network/v2/ip_availability.py
index 1d96358054..ddc88e557e 100644
--- a/openstackclient/network/v2/ip_availability.py
+++ b/openstackclient/network/v2/ip_availability.py
@@ -13,6 +13,7 @@
 
 """IP Availability Info implementations"""
 
+from osc_lib.cli import format_columns
 from osc_lib.command import command
 from osc_lib import utils
 
@@ -21,7 +22,7 @@ from openstackclient.identity import common as identity_common
 from openstackclient.network import sdk_utils
 
 _formatters = {
-    'subnet_ip_availability': utils.format_list_of_dicts,
+    'subnet_ip_availability': format_columns.ListDictColumn,
 }
 
 
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index f5123932a3..63aec71497 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -13,6 +13,8 @@
 
 """Network action implementations"""
 
+from cliff import columns as cliff_columns
+from osc_lib.cli import format_columns
 from osc_lib.command import command
 from osc_lib import utils
 
@@ -23,24 +25,26 @@ from openstackclient.network import sdk_utils
 from openstackclient.network.v2 import _tag
 
 
-def _format_admin_state(item):
-    return 'UP' if item else 'DOWN'
+class AdminStateColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        return 'UP' if self._value else 'DOWN'
 
 
-def _format_router_external(item):
-    return 'External' if item else 'Internal'
+class RouterExternalColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        return 'External' if self._value else 'Internal'
 
 
 _formatters = {
-    'subnets': utils.format_list,
-    'subnet_ids': utils.format_list,
-    'admin_state_up': _format_admin_state,
-    'is_admin_state_up': _format_admin_state,
-    'router:external': _format_router_external,
-    'is_router_external': _format_router_external,
-    'availability_zones': utils.format_list,
-    'availability_zone_hints': utils.format_list,
-    'tags': utils.format_list,
+    'subnets': format_columns.ListColumn,
+    'subnet_ids': format_columns.ListColumn,
+    'admin_state_up': AdminStateColumn,
+    'is_admin_state_up': AdminStateColumn,
+    'router:external': RouterExternalColumn,
+    'is_router_external': RouterExternalColumn,
+    'availability_zones': format_columns.ListColumn,
+    'availability_zone_hints': format_columns.ListColumn,
+    'tags': format_columns.ListColumn,
 }
 
 
diff --git a/openstackclient/network/v2/network_agent.py b/openstackclient/network/v2/network_agent.py
index 46e8d4b21c..1678485434 100644
--- a/openstackclient/network/v2/network_agent.py
+++ b/openstackclient/network/v2/network_agent.py
@@ -15,6 +15,8 @@
 
 import logging
 
+from cliff import columns as cliff_columns
+from osc_lib.cli import format_columns
 from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
@@ -26,19 +28,22 @@ from openstackclient.network import sdk_utils
 LOG = logging.getLogger(__name__)
 
 
-def _format_alive(alive):
-    return ":-)" if alive else "XXX"
+class AliveColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        return ":-)" if self._value else "XXX"
 
 
-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'
+
 
 _formatters = {
-    'is_alive': _format_alive,
-    'alive': _format_alive,
-    'admin_state_up': _format_admin_state,
-    'is_admin_state_up': _format_admin_state,
-    'configurations': utils.format_dict,
+    'is_alive': AliveColumn,
+    'alive': AliveColumn,
+    'admin_state_up': AdminStateColumn,
+    'is_admin_state_up': AdminStateColumn,
+    'configurations': format_columns.DictColumn,
 }
 
 
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py
index f6d6fc7280..6094dfc4d3 100644
--- a/openstackclient/network/v2/port.py
+++ b/openstackclient/network/v2/port.py
@@ -18,6 +18,8 @@ import copy
 import json
 import logging
 
+from cliff import columns as cliff_columns
+from osc_lib.cli import format_columns
 from osc_lib.cli import parseractions
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -33,23 +35,24 @@ from openstackclient.network.v2 import _tag
 LOG = logging.getLogger(__name__)
 
 
-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'
 
 
 _formatters = {
-    'admin_state_up': _format_admin_state,
-    'is_admin_state_up': _format_admin_state,
-    'allowed_address_pairs': utils.format_list_of_dicts,
-    'binding_profile': utils.format_dict,
-    'binding_vif_details': utils.format_dict,
-    'binding:profile': utils.format_dict,
-    'binding:vif_details': utils.format_dict,
-    'dns_assignment': utils.format_list_of_dicts,
-    'extra_dhcp_opts': utils.format_list_of_dicts,
-    'fixed_ips': utils.format_list_of_dicts,
-    'security_group_ids': utils.format_list,
-    'tags': utils.format_list,
+    'admin_state_up': AdminStateColumn,
+    'is_admin_state_up': AdminStateColumn,
+    'allowed_address_pairs': format_columns.ListDictColumn,
+    'binding_profile': format_columns.DictColumn,
+    'binding_vif_details': format_columns.DictColumn,
+    'binding:profile': format_columns.DictColumn,
+    'binding:vif_details': format_columns.DictColumn,
+    'dns_assignment': format_columns.ListDictColumn,
+    'extra_dhcp_opts': format_columns.ListDictColumn,
+    'fixed_ips': format_columns.ListDictColumn,
+    'security_group_ids': format_columns.ListColumn,
+    'tags': format_columns.ListColumn,
 }
 
 
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index 2ec3e2f094..fd6a24fdb9 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -18,6 +18,8 @@ import copy
 import json
 import logging
 
+from cliff import columns as cliff_columns
+from osc_lib.cli import format_columns
 from osc_lib.cli import parseractions
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -32,33 +34,36 @@ from openstackclient.network.v2 import _tag
 LOG = logging.getLogger(__name__)
 
 
-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'
 
 
-def _format_router_info(info):
-    try:
-        return json.dumps(info)
-    except (TypeError, KeyError):
-        return ''
+class RouterInfoColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        try:
+            return json.dumps(self._value)
+        except (TypeError, KeyError):
+            return ''
 
 
-def _format_routes(routes):
-    # Map the route keys to match --route option.
-    for route in routes:
-        if 'nexthop' in route:
-            route['gateway'] = route.pop('nexthop')
-    return utils.format_list_of_dicts(routes)
+class RoutesColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        # Map the route keys to match --route option.
+        for route in self._value:
+            if 'nexthop' in route:
+                route['gateway'] = route.pop('nexthop')
+        return utils.format_list_of_dicts(self._value)
 
 
 _formatters = {
-    'admin_state_up': _format_admin_state,
-    'is_admin_state_up': _format_admin_state,
-    'external_gateway_info': _format_router_info,
-    'availability_zones': utils.format_list,
-    'availability_zone_hints': utils.format_list,
-    'routes': _format_routes,
-    'tags': utils.format_list,
+    'admin_state_up': AdminStateColumn,
+    'is_admin_state_up': AdminStateColumn,
+    'external_gateway_info': RouterInfoColumn,
+    'availability_zones': format_columns.ListColumn,
+    'availability_zone_hints': format_columns.ListColumn,
+    'routes': RoutesColumn,
+    'tags': format_columns.ListColumn,
 }
 
 
@@ -720,7 +725,7 @@ class ShowRouter(command.ShowOne):
 
         setattr(obj, 'interfaces_info', interfaces_info)
         display_columns, columns = _get_columns(obj)
-        _formatters['interfaces_info'] = _format_router_info
+        _formatters['interfaces_info'] = RouterInfoColumn
         data = utils.get_item_properties(obj, columns, formatters=_formatters)
 
         return (display_columns, data)
diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py
index ed6c8d7c24..e389473828 100644
--- a/openstackclient/network/v2/security_group.py
+++ b/openstackclient/network/v2/security_group.py
@@ -15,6 +15,7 @@
 
 import argparse
 
+from cliff import columns as cliff_columns
 from osc_lib.command import command
 from osc_lib import utils
 import six
@@ -65,13 +66,23 @@ def _format_compute_security_group_rules(sg_rules):
     return utils.format_list(rules, separator='\n')
 
 
+class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        return _format_network_security_group_rules(self._value)
+
+
+class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        return _format_compute_security_group_rules(self._value)
+
+
 _formatters_network = {
-    'security_group_rules': _format_network_security_group_rules,
+    'security_group_rules': NetworkSecurityGroupRulesColumn,
 }
 
 
 _formatters_compute = {
-    'rules': _format_compute_security_group_rules,
+    'rules': ComputeSecurityGroupRulesColumn,
 }
 
 
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index 0733f37c8a..1f0c2d9478 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -16,6 +16,8 @@
 import copy
 import logging
 
+from cliff import columns as cliff_columns
+from osc_lib.cli import format_columns
 from osc_lib.cli import parseractions
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -40,23 +42,27 @@ def _update_arguments(obj_list, parsed_args_list, option):
             raise exceptions.CommandError(msg)
 
 
-def _format_allocation_pools(data):
-    pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
-                      for pool in data]
-    return ','.join(pool_formatted)
+class AllocationPoolsColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        pool_formatted = ['%s-%s' % (pool.get('start', ''),
+                                     pool.get('end', ''))
+                          for pool in self._value]
+        return ','.join(pool_formatted)
 
 
-def _format_host_routes(data):
-    # Map the host route keys to match --host-route option.
-    return utils.format_list_of_dicts(convert_entries_to_gateway(data))
+class HostRoutesColumn(cliff_columns.FormattableColumn):
+    def human_readable(self):
+        # Map the host route keys to match --host-route option.
+        return utils.format_list_of_dicts(
+            convert_entries_to_gateway(self._value))
 
 
 _formatters = {
-    'allocation_pools': _format_allocation_pools,
-    'dns_nameservers': utils.format_list,
-    'host_routes': _format_host_routes,
-    'service_types': utils.format_list,
-    'tags': utils.format_list,
+    'allocation_pools': AllocationPoolsColumn,
+    'dns_nameservers': format_columns.ListColumn,
+    'host_routes': HostRoutesColumn,
+    'service_types': format_columns.ListColumn,
+    'tags': format_columns.ListColumn,
 }
 
 
diff --git a/openstackclient/network/v2/subnet_pool.py b/openstackclient/network/v2/subnet_pool.py
index ba0b6c452c..7ece263a36 100644
--- a/openstackclient/network/v2/subnet_pool.py
+++ b/openstackclient/network/v2/subnet_pool.py
@@ -15,6 +15,7 @@
 
 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
@@ -41,8 +42,8 @@ def _get_columns(item):
 
 
 _formatters = {
-    'prefixes': utils.format_list,
-    'tags': utils.format_list,
+    'prefixes': format_columns.ListColumn,
+    'tags': format_columns.ListColumn,
 }
 
 
diff --git a/openstackclient/tests/functional/network/v2/common.py b/openstackclient/tests/functional/network/v2/common.py
index 5243ecd0b9..2287f32930 100644
--- a/openstackclient/tests/functional/network/v2/common.py
+++ b/openstackclient/tests/functional/network/v2/common.py
@@ -62,21 +62,13 @@ class NetworkTagTests(NetworkTests):
         self._set_resource_and_tag_check('unset', name1, '--all-tag', [])
         self._set_resource_and_tag_check('set', name2, '--no-tag', [])
 
-    def _assertTagsEqual(self, expected, actual):
-        # TODO(amotoki): Should migrate to cliff format columns.
-        # At now, unit test assert method needs to be replaced
-        # to handle format columns, so format_list() is used.
-        # NOTE: The order of tag is undeterminestic.
-        actual_tags = filter(bool, actual.split(', '))
-        self.assertEqual(set(expected), set(actual_tags))
-
     def _list_tag_check(self, project_id, expected):
         cmd_output = json.loads(self.openstack(
             '{} list --long --project {} -f json'.format(self.base_command,
                                                          project_id)))
         for name, tags in expected:
             net = [n for n in cmd_output if n['Name'] == name][0]
-            self._assertTagsEqual(tags, net['Tags'])
+            self.assertEqual(set(tags), set(net['Tags']))
 
     def _create_resource_for_tag_test(self, name, args):
         return json.loads(self.openstack(
@@ -89,7 +81,7 @@ class NetworkTagTests(NetworkTests):
         self.addCleanup(
             self.openstack, '{} delete {}'.format(self.base_command, name))
         self.assertIsNotNone(cmd_output["id"])
-        self._assertTagsEqual(expected, cmd_output['tags'])
+        self.assertEqual(set(expected), set(cmd_output['tags']))
         return name
 
     def _set_resource_and_tag_check(self, command, name, args, expected):
@@ -100,4 +92,4 @@ class NetworkTagTests(NetworkTests):
         cmd_output = json.loads(self.openstack(
             '{} show -f json {}'.format(self.base_command, name)
         ))
-        self._assertTagsEqual(expected, cmd_output['tags'])
+        self.assertEqual(set(expected), set(cmd_output['tags']))
diff --git a/openstackclient/tests/functional/network/v2/test_network.py b/openstackclient/tests/functional/network/v2/test_network.py
index 1a74496968..71b533ed22 100644
--- a/openstackclient/tests/functional/network/v2/test_network.py
+++ b/openstackclient/tests/functional/network/v2/test_network.py
@@ -120,14 +120,14 @@ class NetworkTests(common.NetworkTagTests):
             cmd_output["description"],
         )
         self.assertEqual(
-            'UP',
+            True,
             cmd_output["admin_state_up"],
         )
         self.assertFalse(
             cmd_output["shared"],
         )
         self.assertEqual(
-            'Internal',
+            False,
             cmd_output["router:external"],
         )
 
@@ -231,12 +231,12 @@ class NetworkTests(common.NetworkTagTests):
             )
             # Check the default values
             self.assertEqual(
-                'UP',
+                True,
                 cmd_output["admin_state_up"],
             )
             self.assertFalse(cmd_output["shared"])
             self.assertEqual(
-                'Internal',
+                False,
                 cmd_output["router:external"],
             )
             self.assertFalse(cmd_output["is_default"])
@@ -266,7 +266,7 @@ class NetworkTests(common.NetworkTagTests):
                 cmd_output["description"],
             )
             self.assertEqual(
-                'DOWN',
+                False,
                 cmd_output["admin_state_up"],
             )
             self.assertTrue(cmd_output["shared"])
@@ -398,12 +398,12 @@ class NetworkTests(common.NetworkTagTests):
             cmd_output["description"],
         )
         self.assertEqual(
-            'UP',
+            True,
             cmd_output["admin_state_up"],
         )
         self.assertFalse(cmd_output["shared"])
         self.assertEqual(
-            'Internal',
+            False,
             cmd_output["router:external"],
         )
 
@@ -432,12 +432,12 @@ class NetworkTests(common.NetworkTagTests):
             cmd_output["description"],
         )
         self.assertEqual(
-            'DOWN',
+            False,
             cmd_output["admin_state_up"],
         )
         self.assertTrue(cmd_output["shared"])
         self.assertEqual(
-            'External',
+            True,
             cmd_output["router:external"],
         )
         self.assertFalse(cmd_output["is_default"])
diff --git a/openstackclient/tests/functional/network/v2/test_network_agent.py b/openstackclient/tests/functional/network/v2/test_network_agent.py
index 86769e0c8d..963227de48 100644
--- a/openstackclient/tests/functional/network/v2/test_network_agent.py
+++ b/openstackclient/tests/functional/network/v2/test_network_agent.py
@@ -59,7 +59,7 @@ class NetworkAgentTests(common.NetworkTests):
             'network agent show -f json %s' % agent_ids[0]
         ))
         self.assertEqual(
-            "DOWN",
+            False,
             cmd_output['admin_state_up'],
         )
 
@@ -72,7 +72,7 @@ class NetworkAgentTests(common.NetworkTests):
             'network agent show -f json %s' % agent_ids[0]
         ))
         self.assertEqual(
-            "UP",
+            True,
             cmd_output['admin_state_up'],
         )
 
diff --git a/openstackclient/tests/functional/network/v2/test_port.py b/openstackclient/tests/functional/network/v2/test_port.py
index e3067d90a3..a20d2043fd 100644
--- a/openstackclient/tests/functional/network/v2/test_port.py
+++ b/openstackclient/tests/functional/network/v2/test_port.py
@@ -155,7 +155,7 @@ class PortTests(common.NetworkTagTests):
         self.addCleanup(self.openstack, 'port delete %s' % id1)
         self.assertEqual(name, json_output.get('name'))
         self.assertEqual('xyzpdq', json_output.get('description'))
-        self.assertEqual('DOWN', json_output.get('admin_state_up'))
+        self.assertEqual(False, json_output.get('admin_state_up'))
 
         raw_output = self.openstack(
             'port set --enable %s' %
@@ -166,11 +166,11 @@ class PortTests(common.NetworkTagTests):
         json_output = json.loads(self.openstack(
             'port show -f json %s' % name
         ))
-        sg_id = json_output.get('security_group_ids')
+        sg_id = json_output.get('security_group_ids')[0]
 
         self.assertEqual(name, json_output.get('name'))
         self.assertEqual('xyzpdq', json_output.get('description'))
-        self.assertEqual('UP', json_output.get('admin_state_up'))
+        self.assertEqual(True, json_output.get('admin_state_up'))
         self.assertIsNotNone(json_output.get('mac_address'))
 
         raw_output = self.openstack(
@@ -180,7 +180,7 @@ class PortTests(common.NetworkTagTests):
         json_output = json.loads(self.openstack(
             'port show -f json %s' % name
         ))
-        self.assertEqual('', json_output.get('security_group_ids'))
+        self.assertEqual([], json_output.get('security_group_ids'))
 
     def test_port_admin_set(self):
         """Test create, set (as admin), show, delete"""
@@ -229,7 +229,7 @@ class PortTests(common.NetworkTagTests):
         id1 = json_output.get('id')
         self.addCleanup(self.openstack, 'port delete %s' % id1)
         self.assertEqual(name, json_output.get('name'))
-        self.assertEqual(sg_id1, json_output.get('security_group_ids'))
+        self.assertEqual([sg_id1], json_output.get('security_group_ids'))
 
         raw_output = self.openstack(
             'port set '
@@ -242,16 +242,10 @@ class PortTests(common.NetworkTagTests):
             'port show -f json %s' % name
         ))
         self.assertEqual(name, json_output.get('name'))
-        self.assertIn(
-            # TODO(dtroyer): output formatters should not mess with JSON!
-            sg_id1,
-            json_output.get('security_group_ids'),
-        )
-        self.assertIn(
-            # TODO(dtroyer): output formatters should not mess with JSON!
-            sg_id2,
-            json_output.get('security_group_ids'),
-        )
+        # NOTE(amotoki): The order of the field is not predictable,
+        self.assertIsInstance(json_output.get('security_group_ids'), list)
+        self.assertEqual(sorted([sg_id1, sg_id2]),
+                         sorted(json_output.get('security_group_ids')))
 
         raw_output = self.openstack(
             'port unset --security-group %s %s' % (sg_id1, id1))
@@ -261,9 +255,8 @@ class PortTests(common.NetworkTagTests):
             'port show -f json %s' % name
         ))
         self.assertEqual(
-            # TODO(dtroyer): output formatters should do this on JSON!
-            sg_id2,
-            json_output.get('security_group_ids'),
+            [sg_id2],
+            json_output.get('security_group_ids')
         )
 
     def _create_resource_for_tag_test(self, name, args):
diff --git a/openstackclient/tests/functional/network/v2/test_router.py b/openstackclient/tests/functional/network/v2/test_router.py
index 9d5beff059..05aad7a013 100644
--- a/openstackclient/tests/functional/network/v2/test_router.py
+++ b/openstackclient/tests/functional/network/v2/test_router.py
@@ -90,7 +90,7 @@ class RouterTests(common.NetworkTagTests):
             cmd_output["name"],
         )
         self.assertEqual(
-            "DOWN",
+            False,
             cmd_output["admin_state_up"],
         )
         self.assertEqual(
@@ -109,7 +109,7 @@ class RouterTests(common.NetworkTagTests):
             cmd_output["name"],
         )
         self.assertEqual(
-            "UP",
+            True,
             cmd_output["admin_state_up"],
         )
         self.assertEqual(
@@ -230,7 +230,7 @@ class RouterTests(common.NetworkTagTests):
             cmd_output["description"],
         )
         self.assertEqual(
-            'DOWN',
+            False,
             cmd_output["admin_state_up"],
         )
 
diff --git a/openstackclient/tests/functional/network/v2/test_subnet.py b/openstackclient/tests/functional/network/v2/test_subnet.py
index d5309ee674..38030e0198 100644
--- a/openstackclient/tests/functional/network/v2/test_subnet.py
+++ b/openstackclient/tests/functional/network/v2/test_subnet.py
@@ -236,7 +236,7 @@ class SubnetTests(common.NetworkTagTests):
             cmd_output["gateway_ip"],
         )
         self.assertEqual(
-            'network:floatingip_agent_gateway',
+            ['network:floatingip_agent_gateway'],
             cmd_output["service_types"],
         )
 
@@ -253,7 +253,7 @@ class SubnetTests(common.NetworkTagTests):
             new_name
         ))
         self.assertEqual(
-            '',
+            [],
             cmd_output["service_types"],
         )
 
diff --git a/openstackclient/tests/functional/network/v2/test_subnet_pool.py b/openstackclient/tests/functional/network/v2/test_subnet_pool.py
index 46aa6f1433..dad97f8457 100644
--- a/openstackclient/tests/functional/network/v2/test_subnet_pool.py
+++ b/openstackclient/tests/functional/network/v2/test_subnet_pool.py
@@ -38,7 +38,7 @@ class SubnetPoolTests(common.NetworkTagTests):
             cmd_output["name"]
         )
         self.assertEqual(
-            pool_prefix,
+            [pool_prefix],
             cmd_output["prefixes"]
         )
 
@@ -50,7 +50,7 @@ class SubnetPoolTests(common.NetworkTagTests):
             cmd_output["name"]
         )
         self.assertEqual(
-            pool_prefix,
+            [pool_prefix],
             cmd_output["prefixes"]
         )
 
@@ -104,7 +104,7 @@ class SubnetPoolTests(common.NetworkTagTests):
             cmd_output["project_id"],
         )
         self.assertEqual(
-            pool_prefix,
+            [pool_prefix],
             cmd_output["prefixes"],
         )
 
@@ -126,7 +126,7 @@ class SubnetPoolTests(common.NetworkTagTests):
             cmd_output["project_id"],
         )
         self.assertEqual(
-            pool_prefix,
+            [pool_prefix],
             cmd_output["prefixes"],
         )
 
@@ -193,7 +193,7 @@ class SubnetPoolTests(common.NetworkTagTests):
             cmd_output["description"],
         )
         self.assertEqual(
-            pool_prefix,
+            [pool_prefix],
             cmd_output["prefixes"],
         )
         self.assertEqual(
@@ -239,9 +239,9 @@ class SubnetPoolTests(common.NetworkTagTests):
             'bbbb',
             cmd_output["description"],
         )
-        self.assertInOutput(
-            "10.110.0.0/16",
-            cmd_output["prefixes"],
+        self.assertEqual(
+            sorted(["10.110.0.0/16", pool_prefix]),
+            sorted(cmd_output["prefixes"]),
         )
         self.assertEqual(
             8,
diff --git a/openstackclient/tests/unit/network/v2/test_ip_availability.py b/openstackclient/tests/unit/network/v2/test_ip_availability.py
index c7c5a9b49e..21508a8df1 100644
--- a/openstackclient/tests/unit/network/v2/test_ip_availability.py
+++ b/openstackclient/tests/unit/network/v2/test_ip_availability.py
@@ -13,7 +13,7 @@
 
 import mock
 
-from osc_lib import utils as common_utils
+from osc_lib.cli import format_columns
 
 from openstackclient.network.v2 import ip_availability
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@@ -75,7 +75,7 @@ class TestListIPAvailability(TestIPAvailability):
         self.network.network_ip_availabilities.assert_called_once_with(
             **filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_ip_version(self):
         arglist = [
@@ -93,7 +93,7 @@ class TestListIPAvailability(TestIPAvailability):
         self.network.network_ip_availabilities.assert_called_once_with(
             **filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_project(self):
         arglist = [
@@ -113,7 +113,7 @@ class TestListIPAvailability(TestIPAvailability):
         self.network.network_ip_availabilities.assert_called_once_with(
             **filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
 
 class TestShowIPAvailability(TestIPAvailability):
@@ -135,7 +135,7 @@ class TestShowIPAvailability(TestIPAvailability):
         _ip_availability.network_id,
         _ip_availability.network_name,
         _ip_availability.tenant_id,
-        common_utils.format_list(
+        format_columns.ListDictColumn(
             _ip_availability.subnet_ip_availability),
         _ip_availability.total_ips,
         _ip_availability.used_ips,
@@ -176,4 +176,4 @@ class TestShowIPAvailability(TestIPAvailability):
             self._ip_availability.network_name,
             ignore_missing=False)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py
index 0f57f0eec9..5c97c363f5 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -15,8 +15,9 @@ import random
 
 import mock
 from mock import call
+
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.network.v2 import network
 from openstackclient.tests.unit import fakes
@@ -81,9 +82,9 @@ class TestCreateNetworkIdentityV3(TestNetwork):
     )
 
     data = (
-        network._format_admin_state(_network.admin_state_up),
-        utils.format_list(_network.availability_zone_hints),
-        utils.format_list(_network.availability_zones),
+        network.AdminStateColumn(_network.admin_state_up),
+        format_columns.ListColumn(_network.availability_zone_hints),
+        format_columns.ListColumn(_network.availability_zones),
         _network.description,
         _network.dns_domain,
         _network.id,
@@ -98,11 +99,11 @@ class TestCreateNetworkIdentityV3(TestNetwork):
         _network.provider_physical_network,
         _network.provider_segmentation_id,
         _network.qos_policy_id,
-        network._format_router_external(_network.is_router_external),
+        network.RouterExternalColumn(_network.is_router_external),
         _network.shared,
         _network.status,
-        utils.format_list(_network.subnets),
-        utils.format_list(_network.tags),
+        format_columns.ListColumn(_network.subnets),
+        format_columns.ListColumn(_network.tags),
     )
 
     def setUp(self):
@@ -146,7 +147,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_all_options(self):
         arglist = [
@@ -211,7 +212,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
             'dns_domain': 'example.org.',
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_other_options(self):
         arglist = [
@@ -238,7 +239,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
             'port_security_enabled': False,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_tag(self, add_tags=True):
         arglist = [self._network.name]
@@ -270,7 +271,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -313,9 +314,9 @@ class TestCreateNetworkIdentityV2(TestNetwork):
     )
 
     data = (
-        network._format_admin_state(_network.admin_state_up),
-        utils.format_list(_network.availability_zone_hints),
-        utils.format_list(_network.availability_zones),
+        network.AdminStateColumn(_network.admin_state_up),
+        format_columns.ListColumn(_network.availability_zone_hints),
+        format_columns.ListColumn(_network.availability_zones),
         _network.description,
         _network.dns_domain,
         _network.id,
@@ -330,11 +331,11 @@ class TestCreateNetworkIdentityV2(TestNetwork):
         _network.provider_physical_network,
         _network.provider_segmentation_id,
         _network.qos_policy_id,
-        network._format_router_external(_network.is_router_external),
+        network.RouterExternalColumn(_network.is_router_external),
         _network.shared,
         _network.status,
-        utils.format_list(_network.subnets),
-        utils.format_list(_network.tags),
+        format_columns.ListColumn(_network.subnets),
+        format_columns.ListColumn(_network.tags),
     )
 
     def setUp(self):
@@ -385,7 +386,7 @@ class TestCreateNetworkIdentityV2(TestNetwork):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_domain_identityv2(self):
         arglist = [
@@ -525,7 +526,7 @@ class TestListNetwork(TestNetwork):
         data.append((
             net.id,
             net.name,
-            utils.format_list(net.subnets),
+            format_columns.ListColumn(net.subnets),
         ))
 
     data_long = []
@@ -535,13 +536,13 @@ class TestListNetwork(TestNetwork):
             net.name,
             net.status,
             net.project_id,
-            network._format_admin_state(net.admin_state_up),
+            network.AdminStateColumn(net.admin_state_up),
             net.shared,
-            utils.format_list(net.subnets),
+            format_columns.ListColumn(net.subnets),
             net.provider_network_type,
-            network._format_router_external(net.is_router_external),
-            utils.format_list(net.availability_zones),
-            utils.format_list(net.tags),
+            network.RouterExternalColumn(net.is_router_external),
+            format_columns.ListColumn(net.availability_zones),
+            format_columns.ListColumn(net.tags),
         ))
 
     def setUp(self):
@@ -577,7 +578,7 @@ class TestListNetwork(TestNetwork):
 
         self.network.networks.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_external(self):
         arglist = [
@@ -598,7 +599,7 @@ class TestListNetwork(TestNetwork):
             **{'router:external': True, 'is_router_external': True}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_internal(self):
         arglist = [
@@ -615,7 +616,7 @@ class TestListNetwork(TestNetwork):
             **{'router:external': False, 'is_router_external': False}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_long(self):
         arglist = [
@@ -634,7 +635,7 @@ class TestListNetwork(TestNetwork):
 
         self.network.networks.assert_called_once_with()
         self.assertEqual(self.columns_long, columns)
-        self.assertEqual(self.data_long, list(data))
+        self.assertListItemEqual(self.data_long, list(data))
 
     def test_list_name(self):
         test_name = "fakename"
@@ -653,7 +654,7 @@ class TestListNetwork(TestNetwork):
             **{'name': test_name}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_enable(self):
         arglist = [
@@ -671,7 +672,7 @@ class TestListNetwork(TestNetwork):
             **{'admin_state_up': True, 'is_admin_state_up': True}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_disable(self):
         arglist = [
@@ -689,7 +690,7 @@ class TestListNetwork(TestNetwork):
             **{'admin_state_up': False, 'is_admin_state_up': False}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_project(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -708,7 +709,7 @@ class TestListNetwork(TestNetwork):
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_project_domain(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -727,7 +728,7 @@ class TestListNetwork(TestNetwork):
 
         self.network.networks.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_share(self):
         arglist = [
@@ -744,7 +745,7 @@ class TestListNetwork(TestNetwork):
             **{'shared': True, 'is_shared': True}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_no_share(self):
         arglist = [
@@ -761,7 +762,7 @@ class TestListNetwork(TestNetwork):
             **{'shared': False, 'is_shared': False}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_status(self):
         choices = ['ACTIVE', 'BUILD', 'DOWN', 'ERROR']
@@ -780,7 +781,7 @@ class TestListNetwork(TestNetwork):
             **{'status': test_status}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_provider_network_type(self):
         network_type = self._network[0].provider_network_type
@@ -798,7 +799,7 @@ class TestListNetwork(TestNetwork):
                'provider_network_type': network_type}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_provider_physical_network(self):
         physical_network = self._network[0].provider_physical_network
@@ -816,7 +817,7 @@ class TestListNetwork(TestNetwork):
                'provider_physical_network': physical_network}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_provider_segment(self):
         segmentation_id = self._network[0].provider_segmentation_id
@@ -834,7 +835,7 @@ class TestListNetwork(TestNetwork):
                'provider_segmentation_id': segmentation_id}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_list_dhcp_agent(self):
         arglist = [
@@ -853,7 +854,7 @@ class TestListNetwork(TestNetwork):
             *attrs)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(list(data), list(self.data))
+        self.assertListItemEqual(list(data), list(self.data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -878,7 +879,7 @@ class TestListNetwork(TestNetwork):
                'not_any_tags': 'black,white'}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
 
 class TestSetNetwork(TestNetwork):
@@ -1057,9 +1058,9 @@ class TestShowNetwork(TestNetwork):
     )
 
     data = (
-        network._format_admin_state(_network.admin_state_up),
-        utils.format_list(_network.availability_zone_hints),
-        utils.format_list(_network.availability_zones),
+        network.AdminStateColumn(_network.admin_state_up),
+        format_columns.ListColumn(_network.availability_zone_hints),
+        format_columns.ListColumn(_network.availability_zones),
         _network.description,
         _network.dns_domain,
         _network.id,
@@ -1074,11 +1075,11 @@ class TestShowNetwork(TestNetwork):
         _network.provider_physical_network,
         _network.provider_segmentation_id,
         _network.qos_policy_id,
-        network._format_router_external(_network.is_router_external),
+        network.RouterExternalColumn(_network.is_router_external),
         _network.shared,
         _network.status,
-        utils.format_list(_network.subnets),
-        utils.format_list(_network.tags),
+        format_columns.ListColumn(_network.subnets),
+        format_columns.ListColumn(_network.tags),
     )
 
     def setUp(self):
@@ -1111,7 +1112,7 @@ class TestShowNetwork(TestNetwork):
             self._network.name, ignore_missing=False)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 class TestUnsetNetwork(TestNetwork):
diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py
index 709fb1c6cd..8500d08ea6 100644
--- a/openstackclient/tests/unit/network/v2/test_network_agent.py
+++ b/openstackclient/tests/unit/network/v2/test_network_agent.py
@@ -14,8 +14,8 @@
 import mock
 from mock import call
 
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.network.v2 import network_agent
 from openstackclient.tests.unit.network.v2 import fakes as network_fakes
@@ -207,8 +207,8 @@ class TestListNetworkAgent(TestNetworkAgent):
             agent.agent_type,
             agent.host,
             agent.availability_zone,
-            network_agent._format_alive(agent.alive),
-            network_agent._format_admin_state(agent.admin_state_up),
+            network_agent.AliveColumn(agent.alive),
+            network_agent.AdminStateColumn(agent.admin_state_up),
             agent.binary,
         ))
 
@@ -246,7 +246,7 @@ class TestListNetworkAgent(TestNetworkAgent):
 
         self.network.agents.assert_called_once_with(**{})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_agents_list_agent_type(self):
         arglist = [
@@ -263,7 +263,7 @@ class TestListNetworkAgent(TestNetworkAgent):
             'agent_type': 'DHCP agent',
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_agents_list_host(self):
         arglist = [
@@ -280,7 +280,7 @@ class TestListNetworkAgent(TestNetworkAgent):
             'host': self.network_agents[0].host,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_agents_list_networks(self):
         arglist = [
@@ -298,7 +298,7 @@ class TestListNetworkAgent(TestNetworkAgent):
         self.network.network_hosting_dhcp_agents.assert_called_once_with(
             *attrs)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_agents_list_routers(self):
         arglist = [
@@ -318,7 +318,7 @@ class TestListNetworkAgent(TestNetworkAgent):
             *attrs)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_network_agents_list_routers_with_long_option(self):
         arglist = [
@@ -343,7 +343,7 @@ class TestListNetworkAgent(TestNetworkAgent):
         router_agent_data = [d + ('',) for d in self.data]
 
         self.assertEqual(router_agent_columns, columns)
-        self.assertEqual(router_agent_data, list(data))
+        self.assertListItemEqual(router_agent_data, list(data))
 
 
 class TestRemoveNetworkFromAgent(TestNetworkAgent):
@@ -531,12 +531,12 @@ class TestShowNetworkAgent(TestNetworkAgent):
         'id',
     )
     data = (
-        network_agent._format_admin_state(_network_agent.is_admin_state_up),
+        network_agent.AdminStateColumn(_network_agent.admin_state_up),
         _network_agent.agent_type,
-        network_agent._format_alive(_network_agent.is_alive),
+        network_agent.AliveColumn(_network_agent.is_alive),
         _network_agent.availability_zone,
         _network_agent.binary,
-        utils.format_dict(_network_agent.configurations),
+        format_columns.DictColumn(_network_agent.configurations),
         _network_agent.host,
         _network_agent.id,
     )
@@ -571,4 +571,4 @@ class TestShowNetworkAgent(TestNetworkAgent):
         self.network.get_agent.assert_called_once_with(
             self._network_agent.id)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(list(self.data), list(data))
+        self.assertItemEqual(list(self.data), list(data))
diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index 8ac3e54f4a..acf85f4652 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -15,6 +15,7 @@ import argparse
 
 import mock
 from mock import call
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
 from osc_lib import utils
 
@@ -68,22 +69,22 @@ class TestPort(network_fakes.TestNetworkV2):
         )
 
         data = (
-            port._format_admin_state(fake_port.admin_state_up),
-            utils.format_list_of_dicts(fake_port.allowed_address_pairs),
+            port.AdminStateColumn(fake_port.admin_state_up),
+            format_columns.ListDictColumn(fake_port.allowed_address_pairs),
             fake_port.binding_host_id,
-            utils.format_dict(fake_port.binding_profile),
-            utils.format_dict(fake_port.binding_vif_details),
+            format_columns.DictColumn(fake_port.binding_profile),
+            format_columns.DictColumn(fake_port.binding_vif_details),
             fake_port.binding_vif_type,
             fake_port.binding_vnic_type,
             fake_port.data_plane_status,
             fake_port.description,
             fake_port.device_id,
             fake_port.device_owner,
-            utils.format_list_of_dicts(fake_port.dns_assignment),
+            format_columns.ListDictColumn(fake_port.dns_assignment),
             fake_port.dns_domain,
             fake_port.dns_name,
-            utils.format_list_of_dicts(fake_port.extra_dhcp_opts),
-            utils.format_list_of_dicts(fake_port.fixed_ips),
+            format_columns.ListDictColumn(fake_port.extra_dhcp_opts),
+            format_columns.ListDictColumn(fake_port.fixed_ips),
             fake_port.id,
             fake_port.mac_address,
             fake_port.name,
@@ -91,9 +92,9 @@ class TestPort(network_fakes.TestNetworkV2):
             fake_port.port_security_enabled,
             fake_port.project_id,
             fake_port.qos_policy_id,
-            utils.format_list(fake_port.security_group_ids),
+            format_columns.ListColumn(fake_port.security_group_ids),
             fake_port.status,
-            utils.format_list(fake_port.tags),
+            format_columns.ListColumn(fake_port.tags),
             fake_port.uplink_status_propagation,
         )
 
@@ -141,7 +142,7 @@ class TestCreatePort(TestPort):
         self.assertFalse(self.network.set_tags.called)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_full_options(self):
         arglist = [
@@ -199,7 +200,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_invalid_json_binding_profile(self):
         arglist = [
@@ -250,7 +251,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_security_group(self):
         secgroup = network_fakes.FakeSecurityGroup.create_one_security_group()
@@ -279,7 +280,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_port_with_dns_name(self):
         arglist = [
@@ -305,7 +306,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_security_groups(self):
         sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group()
@@ -335,7 +336,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_no_security_groups(self):
         arglist = [
@@ -361,7 +362,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_no_fixed_ips(self):
         arglist = [
@@ -387,7 +388,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_port_with_allowed_address_pair_ipaddr(self):
         pairs = [{'ip_address': '192.168.1.123'},
@@ -417,7 +418,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_port_with_allowed_address_pair(self):
         pairs = [{'ip_address': '192.168.1.123',
@@ -453,7 +454,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_port_with_qos(self):
         qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
@@ -481,7 +482,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_port_security_enabled(self):
         arglist = [
@@ -565,7 +566,7 @@ class TestCreatePort(TestPort):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -602,7 +603,7 @@ class TestCreatePort(TestPort):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_uplink_status_propagation_enabled(self):
         self._test_create_with_uplink_status_propagation(enable=True)
@@ -719,7 +720,7 @@ class TestListPort(TestPort):
             prt.id,
             prt.name,
             prt.mac_address,
-            utils.format_list_of_dicts(prt.fixed_ips),
+            format_columns.ListDictColumn(prt.fixed_ips),
             prt.status,
         ))
 
@@ -729,11 +730,11 @@ class TestListPort(TestPort):
             prt.id,
             prt.name,
             prt.mac_address,
-            utils.format_list_of_dicts(prt.fixed_ips),
+            format_columns.ListDictColumn(prt.fixed_ips),
             prt.status,
-            utils.format_list(prt.security_group_ids),
+            format_columns.ListColumn(prt.security_group_ids),
             prt.device_owner,
-            utils.format_list(prt.tags),
+            format_columns.ListColumn(prt.tags),
         ))
 
     def setUp(self):
@@ -762,7 +763,7 @@ class TestListPort(TestPort):
 
         self.network.ports.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_router_opt(self):
         arglist = [
@@ -781,7 +782,7 @@ class TestListPort(TestPort):
             'device_id': 'fake-router-id'
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     @mock.patch.object(utils, 'find_resource')
     def test_port_list_with_server_option(self, mock_find):
@@ -801,7 +802,7 @@ class TestListPort(TestPort):
             device_id=fake_server.id)
         mock_find.assert_called_once_with(mock.ANY, 'fake-server-name')
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_device_id_opt(self):
         arglist = [
@@ -820,7 +821,7 @@ class TestListPort(TestPort):
             'device_id': self._ports[0].device_id
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_device_owner_opt(self):
         arglist = [
@@ -839,7 +840,7 @@ class TestListPort(TestPort):
             'device_owner': self._ports[0].device_owner
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_all_opt(self):
         arglist = [
@@ -867,7 +868,7 @@ class TestListPort(TestPort):
             'mac_address': self._ports[0].mac_address
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_mac_address_opt(self):
         arglist = [
@@ -886,7 +887,7 @@ class TestListPort(TestPort):
             'mac_address': self._ports[0].mac_address
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_fixed_ip_opt_ip_address(self):
         ip_address = self._ports[0].fixed_ips[0]['ip_address']
@@ -904,7 +905,7 @@ class TestListPort(TestPort):
         self.network.ports.assert_called_once_with(**{
             'fixed_ips': ['ip_address=%s' % ip_address]})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_fixed_ip_opt_ip_address_substr(self):
         ip_address_ss = self._ports[0].fixed_ips[0]['ip_address'][:-1]
@@ -922,7 +923,7 @@ class TestListPort(TestPort):
         self.network.ports.assert_called_once_with(**{
             'fixed_ips': ['ip_address_substr=%s' % ip_address_ss]})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_fixed_ip_opt_subnet_id(self):
         subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
@@ -942,7 +943,7 @@ class TestListPort(TestPort):
         self.network.ports.assert_called_once_with(**{
             'fixed_ips': ['subnet_id=%s' % subnet_id]})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_fixed_ip_opts(self):
         subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
@@ -966,7 +967,7 @@ class TestListPort(TestPort):
             'fixed_ips': ['subnet_id=%s' % subnet_id,
                           'ip_address=%s' % ip_address]})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_fixed_ips(self):
         subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
@@ -990,7 +991,7 @@ class TestListPort(TestPort):
             'fixed_ips': ['subnet_id=%s' % subnet_id,
                           'ip_address=%s' % ip_address]})
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_port_with_long(self):
         arglist = [
@@ -1007,7 +1008,7 @@ class TestListPort(TestPort):
 
         self.network.ports.assert_called_once_with()
         self.assertEqual(self.columns_long, columns)
-        self.assertEqual(self.data_long, list(data))
+        self.assertListItemEqual(self.data_long, list(data))
 
     def test_port_list_project(self):
         project = identity_fakes.FakeProject.create_one_project()
@@ -1025,7 +1026,7 @@ class TestListPort(TestPort):
 
         self.network.ports.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_port_list_project_domain(self):
         project = identity_fakes.FakeProject.create_one_project()
@@ -1045,7 +1046,7 @@ class TestListPort(TestPort):
 
         self.network.ports.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -1070,7 +1071,7 @@ class TestListPort(TestPort):
                'not_any_tags': 'black,white'}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
 
 class TestSetPort(TestPort):
@@ -1644,7 +1645,7 @@ class TestShowPort(TestPort):
             self._port.name, ignore_missing=False)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 class TestUnsetPort(TestPort):
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index 618adf3516..3e5ceac436 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -14,8 +14,8 @@
 import mock
 from mock import call
 
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils as osc_utils
 
 from openstackclient.network.v2 import router
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
@@ -132,19 +132,19 @@ class TestCreateRouter(TestRouter):
         'tags',
     )
     data = (
-        router._format_admin_state(new_router.admin_state_up),
-        osc_utils.format_list(new_router.availability_zone_hints),
-        osc_utils.format_list(new_router.availability_zones),
+        router.AdminStateColumn(new_router.admin_state_up),
+        format_columns.ListColumn(new_router.availability_zone_hints),
+        format_columns.ListColumn(new_router.availability_zones),
         new_router.description,
         new_router.distributed,
-        router._format_router_info(new_router.external_gateway_info),
+        router.RouterInfoColumn(new_router.external_gateway_info),
         new_router.ha,
         new_router.id,
         new_router.name,
         new_router.tenant_id,
-        router._format_routes(new_router.routes),
+        router.RoutesColumn(new_router.routes),
         new_router.status,
-        osc_utils.format_list(new_router.tags),
+        format_columns.ListColumn(new_router.tags),
     )
 
     def setUp(self):
@@ -184,7 +184,7 @@ class TestCreateRouter(TestRouter):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_ha_options(self, option, ha):
         arglist = [
@@ -208,7 +208,7 @@ class TestCreateRouter(TestRouter):
             'ha': ha,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_ha_option(self):
         self._test_create_with_ha_options('--ha', True)
@@ -237,7 +237,7 @@ class TestCreateRouter(TestRouter):
             'distributed': distributed,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_distributed_option(self):
         self._test_create_with_distributed_options('--distributed', True)
@@ -268,7 +268,7 @@ class TestCreateRouter(TestRouter):
         })
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_tag(self, add_tags=True):
         arglist = [self.new_router.name]
@@ -301,7 +301,7 @@ class TestCreateRouter(TestRouter):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -422,7 +422,7 @@ class TestListRouter(TestRouter):
             r.id,
             r.name,
             r.status,
-            router._format_admin_state(r.admin_state_up),
+            router.AdminStateColumn(r.admin_state_up),
             r.tenant_id,
             r.distributed,
             r.ha,
@@ -447,10 +447,10 @@ class TestListRouter(TestRouter):
         r = routers[i]
         data_long.append(
             data[i] + (
-                router._format_routes(r.routes),
-                router._format_router_info(r.external_gateway_info),
-                osc_utils.format_list(r.availability_zones),
-                osc_utils.format_list(r.tags),
+                router.RoutesColumn(r.routes),
+                router.RouterInfoColumn(r.external_gateway_info),
+                format_columns.ListColumn(r.availability_zones),
+                format_columns.ListColumn(r.tags),
             )
         )
     data_long_no_az = []
@@ -458,9 +458,9 @@ class TestListRouter(TestRouter):
         r = routers[i]
         data_long_no_az.append(
             data[i] + (
-                router._format_routes(r.routes),
-                router._format_router_info(r.external_gateway_info),
-                osc_utils.format_list(r.tags),
+                router.RoutesColumn(r.routes),
+                router.RouterInfoColumn(r.external_gateway_info),
+                format_columns.ListColumn(r.tags),
             )
         )
 
@@ -494,7 +494,7 @@ class TestListRouter(TestRouter):
 
         self.network.routers.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_no_ha_no_distributed(self):
         _routers = network_fakes.FakeRouter.create_routers({
@@ -531,7 +531,7 @@ class TestListRouter(TestRouter):
 
         self.network.routers.assert_called_once_with()
         self.assertEqual(self.columns_long, columns)
-        self.assertEqual(self.data_long, list(data))
+        self.assertListItemEqual(self.data_long, list(data))
 
     def test_router_list_long_no_az(self):
         arglist = [
@@ -552,7 +552,7 @@ class TestListRouter(TestRouter):
 
         self.network.routers.assert_called_once_with()
         self.assertEqual(self.columns_long_no_az, columns)
-        self.assertEqual(self.data_long_no_az, list(data))
+        self.assertListItemEqual(self.data_long_no_az, list(data))
 
     def test_list_name(self):
         test_name = "fakename"
@@ -570,7 +570,7 @@ class TestListRouter(TestRouter):
             **{'name': test_name}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_enable(self):
         arglist = [
@@ -587,7 +587,7 @@ class TestListRouter(TestRouter):
             **{'admin_state_up': True, 'is_admin_state_up': True}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_disable(self):
         arglist = [
@@ -605,7 +605,7 @@ class TestListRouter(TestRouter):
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_project(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -623,7 +623,7 @@ class TestListRouter(TestRouter):
 
         self.network.routers.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_project_domain(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -643,7 +643,7 @@ class TestListRouter(TestRouter):
 
         self.network.routers.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_router_list_agents_no_args(self):
         arglist = [
@@ -671,7 +671,7 @@ class TestListRouter(TestRouter):
         self.network.agent_hosted_routers(
             *attrs)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -696,7 +696,7 @@ class TestListRouter(TestRouter):
                'not_any_tags': 'black,white'}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
 
 class TestRemovePortFromRouter(TestRouter):
@@ -1260,20 +1260,20 @@ class TestShowRouter(TestRouter):
         'tags',
     )
     data = (
-        router._format_admin_state(_router.admin_state_up),
-        osc_utils.format_list(_router.availability_zone_hints),
-        osc_utils.format_list(_router.availability_zones),
+        router.AdminStateColumn(_router.admin_state_up),
+        format_columns.ListColumn(_router.availability_zone_hints),
+        format_columns.ListColumn(_router.availability_zones),
         _router.description,
         _router.distributed,
-        router._format_router_info(_router.external_gateway_info),
+        router.RouterInfoColumn(_router.external_gateway_info),
         _router.ha,
         _router.id,
-        router._format_router_info(_router.interfaces_info),
+        router.RouterInfoColumn(_router.interfaces_info),
         _router.name,
         _router.tenant_id,
-        router._format_routes(_router.routes),
+        router.RoutesColumn(_router.routes),
         _router.status,
-        osc_utils.format_list(_router.tags),
+        format_columns.ListColumn(_router.tags),
     )
 
     def setUp(self):
@@ -1309,7 +1309,7 @@ class TestShowRouter(TestRouter):
             'device_id': self._router.id
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_show_no_ha_no_distributed(self):
         _router = network_fakes.FakeRouter.create_one_router({
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_compute.py b/openstackclient/tests/unit/network/v2/test_security_group_compute.py
index c949e2c82d..df36006899 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_compute.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_compute.py
@@ -56,7 +56,7 @@ class TestCreateSecurityGroupCompute(TestSecurityGroupCompute):
         _security_group['id'],
         _security_group['name'],
         _security_group['tenant_id'],
-        '',
+        security_group.ComputeSecurityGroupRulesColumn([]),
     )
 
     def setUp(self):
@@ -88,7 +88,7 @@ class TestCreateSecurityGroupCompute(TestSecurityGroupCompute):
             self._security_group['name'],
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_security_group_create_all_options(self, sg_mock):
         sg_mock.return_value = self._security_group
@@ -109,7 +109,7 @@ class TestCreateSecurityGroupCompute(TestSecurityGroupCompute):
             self._security_group['description'],
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 @mock.patch(
@@ -255,7 +255,7 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute):
         kwargs = {'search_opts': {'all_tenants': False}}
         sg_mock.assert_called_once_with(**kwargs)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_security_group_list_all_projects(self, sg_mock):
         sg_mock.return_value = self._security_groups
@@ -272,7 +272,7 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute):
         kwargs = {'search_opts': {'all_tenants': True}}
         sg_mock.assert_called_once_with(**kwargs)
         self.assertEqual(self.columns_all_projects, columns)
-        self.assertEqual(self.data_all_projects, list(data))
+        self.assertListItemEqual(self.data_all_projects, list(data))
 
 
 @mock.patch(
@@ -372,8 +372,7 @@ class TestShowSecurityGroupCompute(TestSecurityGroupCompute):
         _security_group['id'],
         _security_group['name'],
         _security_group['tenant_id'],
-        security_group._format_compute_security_group_rules(
-            [_security_group_rule]),
+        security_group.ComputeSecurityGroupRulesColumn([_security_group_rule]),
     )
 
     def setUp(self):
@@ -402,4 +401,4 @@ class TestShowSecurityGroupCompute(TestSecurityGroupCompute):
 
         sg_mock.assert_called_once_with(self._security_group['id'])
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_network.py b/openstackclient/tests/unit/network/v2/test_security_group_network.py
index 83208287cc..57698ec586 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_network.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_network.py
@@ -57,7 +57,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
         _security_group.id,
         _security_group.name,
         _security_group.project_id,
-        '',
+        security_group.NetworkSecurityGroupRulesColumn([]),
         _security_group.tags,
     )
 
@@ -94,7 +94,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
             'name': self._security_group.name,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_all_options(self):
         arglist = [
@@ -119,7 +119,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
             'tenant_id': self.project.id,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_tag(self, add_tags=True):
         arglist = [self._security_group.name]
@@ -150,7 +150,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -287,7 +287,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
 
         self.network.security_groups.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_security_group_list_all_projects(self):
         arglist = [
@@ -302,7 +302,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
 
         self.network.security_groups.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_security_group_list_project(self):
         project = identity_fakes.FakeProject.create_one_project()
@@ -320,7 +320,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
 
         self.network.security_groups.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_security_group_list_project_domain(self):
         project = identity_fakes.FakeProject.create_one_project()
@@ -340,7 +340,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
 
         self.network.security_groups.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -490,7 +490,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
         _security_group.id,
         _security_group.name,
         _security_group.project_id,
-        security_group._format_network_security_group_rules(
+        security_group.NetworkSecurityGroupRulesColumn(
             [_security_group_rule._info]),
         _security_group.tags,
     )
@@ -522,7 +522,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
         self.network.find_security_group.assert_called_once_with(
             self._security_group.id, ignore_missing=False)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 class TestUnsetSecurityGroupNetwork(TestSecurityGroupNetwork):
diff --git a/openstackclient/tests/unit/network/v2/test_subnet.py b/openstackclient/tests/unit/network/v2/test_subnet.py
index 39cb4f537d..9903b0423a 100644
--- a/openstackclient/tests/unit/network/v2/test_subnet.py
+++ b/openstackclient/tests/unit/network/v2/test_subnet.py
@@ -14,8 +14,8 @@
 import mock
 from mock import call
 
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.network.v2 import subnet as subnet_v2
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
@@ -131,13 +131,13 @@ class TestCreateSubnet(TestSubnet):
         )
 
         self.data = (
-            subnet_v2._format_allocation_pools(self._subnet.allocation_pools),
+            subnet_v2.AllocationPoolsColumn(self._subnet.allocation_pools),
             self._subnet.cidr,
             self._subnet.description,
-            utils.format_list(self._subnet.dns_nameservers),
+            format_columns.ListColumn(self._subnet.dns_nameservers),
             self._subnet.enable_dhcp,
             self._subnet.gateway_ip,
-            subnet_v2._format_host_routes(self._subnet.host_routes),
+            subnet_v2.HostRoutesColumn(self._subnet.host_routes),
             self._subnet.id,
             self._subnet.ip_version,
             self._subnet.ipv6_address_mode,
@@ -146,20 +146,20 @@ class TestCreateSubnet(TestSubnet):
             self._subnet.network_id,
             self._subnet.project_id,
             self._subnet.segment_id,
-            utils.format_list(self._subnet.service_types),
+            format_columns.ListColumn(self._subnet.service_types),
             self._subnet.subnetpool_id,
-            utils.format_list(self._subnet.tags),
+            format_columns.ListColumn(self._subnet.tags),
         )
 
         self.data_subnet_pool = (
-            subnet_v2._format_allocation_pools(
+            subnet_v2.AllocationPoolsColumn(
                 self._subnet_from_pool.allocation_pools),
             self._subnet_from_pool.cidr,
             self._subnet_from_pool.description,
-            utils.format_list(self._subnet_from_pool.dns_nameservers),
+            format_columns.ListColumn(self._subnet_from_pool.dns_nameservers),
             self._subnet_from_pool.enable_dhcp,
             self._subnet_from_pool.gateway_ip,
-            subnet_v2._format_host_routes(self._subnet_from_pool.host_routes),
+            subnet_v2.HostRoutesColumn(self._subnet_from_pool.host_routes),
             self._subnet_from_pool.id,
             self._subnet_from_pool.ip_version,
             self._subnet_from_pool.ipv6_address_mode,
@@ -168,20 +168,20 @@ class TestCreateSubnet(TestSubnet):
             self._subnet_from_pool.network_id,
             self._subnet_from_pool.project_id,
             self._subnet_from_pool.segment_id,
-            utils.format_list(self._subnet_from_pool.service_types),
+            format_columns.ListColumn(self._subnet_from_pool.service_types),
             self._subnet_from_pool.subnetpool_id,
-            utils.format_list(self._subnet.tags),
+            format_columns.ListColumn(self._subnet_from_pool.tags),
         )
 
         self.data_ipv6 = (
-            subnet_v2._format_allocation_pools(
+            subnet_v2.AllocationPoolsColumn(
                 self._subnet_ipv6.allocation_pools),
             self._subnet_ipv6.cidr,
             self._subnet_ipv6.description,
-            utils.format_list(self._subnet_ipv6.dns_nameservers),
+            format_columns.ListColumn(self._subnet_ipv6.dns_nameservers),
             self._subnet_ipv6.enable_dhcp,
             self._subnet_ipv6.gateway_ip,
-            subnet_v2._format_host_routes(self._subnet_ipv6.host_routes),
+            subnet_v2.HostRoutesColumn(self._subnet_ipv6.host_routes),
             self._subnet_ipv6.id,
             self._subnet_ipv6.ip_version,
             self._subnet_ipv6.ipv6_address_mode,
@@ -190,9 +190,9 @@ class TestCreateSubnet(TestSubnet):
             self._subnet_ipv6.network_id,
             self._subnet_ipv6.project_id,
             self._subnet_ipv6.segment_id,
-            utils.format_list(self._subnet_ipv6.service_types),
+            format_columns.ListColumn(self._subnet_ipv6.service_types),
             self._subnet_ipv6.subnetpool_id,
-            utils.format_list(self._subnet.tags),
+            format_columns.ListColumn(self._subnet_ipv6.tags),
         )
 
     def setUp(self):
@@ -255,7 +255,7 @@ class TestCreateSubnet(TestSubnet):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_from_subnet_pool_options(self):
         # Mock SDK calls for this test.
@@ -317,7 +317,7 @@ class TestCreateSubnet(TestSubnet):
             'service_types': self._subnet_from_pool.service_types,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data_subnet_pool, data)
+        self.assertItemEqual(self.data_subnet_pool, data)
 
     def test_create_options_subnet_range_ipv6(self):
         # Mock SDK calls for this test.
@@ -390,7 +390,7 @@ class TestCreateSubnet(TestSubnet):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data_ipv6, data)
+        self.assertItemEqual(self.data_ipv6, data)
 
     def test_create_with_network_segment(self):
         # Mock SDK calls for this test.
@@ -424,7 +424,7 @@ class TestCreateSubnet(TestSubnet):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_description(self):
         # Mock SDK calls for this test.
@@ -458,7 +458,7 @@ class TestCreateSubnet(TestSubnet):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_tag(self, add_tags=True):
         arglist = [
@@ -497,7 +497,7 @@ class TestCreateSubnet(TestSubnet):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -625,13 +625,13 @@ class TestListSubnet(TestSubnet):
             subnet.cidr,
             subnet.tenant_id,
             subnet.enable_dhcp,
-            utils.format_list(subnet.dns_nameservers),
-            subnet_v2._format_allocation_pools(subnet.allocation_pools),
-            utils.format_list(subnet.host_routes),
+            format_columns.ListColumn(subnet.dns_nameservers),
+            subnet_v2.AllocationPoolsColumn(subnet.allocation_pools),
+            subnet_v2.HostRoutesColumn(subnet.host_routes),
             subnet.ip_version,
             subnet.gateway_ip,
-            utils.format_list(subnet.service_types),
-            utils.format_list(subnet.tags),
+            format_columns.ListColumn(subnet.service_types),
+            format_columns.ListColumn(subnet.tags),
         ))
 
     def setUp(self):
@@ -653,7 +653,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_long(self):
         arglist = [
@@ -668,7 +668,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with()
         self.assertEqual(self.columns_long, columns)
-        self.assertEqual(self.data_long, list(data))
+        self.assertListItemEqual(self.data_long, list(data))
 
     def test_subnet_list_ip_version(self):
         arglist = [
@@ -684,7 +684,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_dhcp(self):
         arglist = [
@@ -700,7 +700,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_no_dhcp(self):
         arglist = [
@@ -716,7 +716,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_service_type(self):
         arglist = [
@@ -731,7 +731,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_project(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -749,7 +749,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_service_type_multiple(self):
         arglist = [
@@ -767,7 +767,7 @@ class TestListSubnet(TestSubnet):
                                      'network:floatingip_agent_gateway']}
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_project_domain(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -787,7 +787,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_network(self):
         network = network_fakes.FakeNetwork.create_one_network()
@@ -805,7 +805,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_gateway(self):
         subnet = network_fakes.FakeSubnet.create_one_subnet()
@@ -823,7 +823,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_name(self):
         subnet = network_fakes.FakeSubnet.create_one_subnet()
@@ -841,7 +841,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_list_subnet_range(self):
         subnet = network_fakes.FakeSubnet.create_one_subnet()
@@ -859,7 +859,7 @@ class TestListSubnet(TestSubnet):
 
         self.network.subnets.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -1154,13 +1154,13 @@ class TestShowSubnet(TestSubnet):
     )
 
     data = (
-        subnet_v2._format_allocation_pools(_subnet.allocation_pools),
+        subnet_v2.AllocationPoolsColumn(_subnet.allocation_pools),
         _subnet.cidr,
         _subnet.description,
-        utils.format_list(_subnet.dns_nameservers),
+        format_columns.ListColumn(_subnet.dns_nameservers),
         _subnet.enable_dhcp,
         _subnet.gateway_ip,
-        utils.format_list(_subnet.host_routes),
+        subnet_v2.HostRoutesColumn(_subnet.host_routes),
         _subnet.id,
         _subnet.ip_version,
         _subnet.ipv6_address_mode,
@@ -1169,9 +1169,9 @@ class TestShowSubnet(TestSubnet):
         _subnet.network_id,
         _subnet.tenant_id,
         _subnet.segment_id,
-        utils.format_list(_subnet.service_types),
+        format_columns.ListColumn(_subnet.service_types),
         _subnet.subnetpool_id,
-        utils.format_list(_subnet.tags),
+        format_columns.ListColumn(_subnet.tags),
     )
 
     def setUp(self):
@@ -1206,7 +1206,7 @@ class TestShowSubnet(TestSubnet):
             self._subnet.name, ignore_missing=False)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 class TestUnsetSubnet(TestSubnet):
diff --git a/openstackclient/tests/unit/network/v2/test_subnet_pool.py b/openstackclient/tests/unit/network/v2/test_subnet_pool.py
index 3d8f1028e6..2271c08944 100644
--- a/openstackclient/tests/unit/network/v2/test_subnet_pool.py
+++ b/openstackclient/tests/unit/network/v2/test_subnet_pool.py
@@ -15,8 +15,9 @@ import argparse
 
 import mock
 from mock import call
+
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.network.v2 import subnet_pool
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
@@ -73,10 +74,10 @@ class TestCreateSubnetPool(TestSubnetPool):
         _subnet_pool.max_prefixlen,
         _subnet_pool.min_prefixlen,
         _subnet_pool.name,
-        utils.format_list(_subnet_pool.prefixes),
+        format_columns.ListColumn(_subnet_pool.prefixes),
         _subnet_pool.project_id,
         _subnet_pool.shared,
-        utils.format_list(_subnet_pool.tags),
+        format_columns.ListColumn(_subnet_pool.tags),
     )
 
     def setUp(self):
@@ -133,7 +134,7 @@ class TestCreateSubnetPool(TestSubnetPool):
         })
         self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_prefixlen_options(self):
         arglist = [
@@ -163,7 +164,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'name': self._subnet_pool.name,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_len_negative(self):
         arglist = [
@@ -201,7 +202,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'name': self._subnet_pool.name,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_address_scope_option(self):
         arglist = [
@@ -224,7 +225,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'name': self._subnet_pool.name,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_default_and_shared_options(self):
         arglist = [
@@ -250,7 +251,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'shared': True,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_description(self):
         arglist = [
@@ -273,7 +274,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'description': self._subnet_pool.description,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_default_quota(self):
         arglist = [
@@ -294,7 +295,7 @@ class TestCreateSubnetPool(TestSubnetPool):
             'default_quota': 10,
         })
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def _test_create_with_tag(self, add_tags=True):
         arglist = [
@@ -328,7 +329,7 @@ class TestCreateSubnetPool(TestSubnetPool):
         else:
             self.assertFalse(self.network.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -441,7 +442,7 @@ class TestListSubnetPool(TestSubnetPool):
         data.append((
             pool.id,
             pool.name,
-            utils.format_list(pool.prefixes),
+            format_columns.ListColumn(pool.prefixes),
         ))
 
     data_long = []
@@ -449,12 +450,12 @@ class TestListSubnetPool(TestSubnetPool):
         data_long.append((
             pool.id,
             pool.name,
-            utils.format_list(pool.prefixes),
+            format_columns.ListColumn(pool.prefixes),
             pool.default_prefixlen,
             pool.address_scope_id,
             pool.is_default,
             pool.shared,
-            utils.format_list(pool.tags),
+            format_columns.ListColumn(pool.tags),
         ))
 
     def setUp(self):
@@ -476,7 +477,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with()
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_long(self):
         arglist = [
@@ -491,7 +492,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with()
         self.assertEqual(self.columns_long, columns)
-        self.assertEqual(self.data_long, list(data))
+        self.assertListItemEqual(self.data_long, list(data))
 
     def test_subnet_pool_list_no_share(self):
         arglist = [
@@ -507,7 +508,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_share(self):
         arglist = [
@@ -523,7 +524,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_no_default(self):
         arglist = [
@@ -539,7 +540,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_default(self):
         arglist = [
@@ -555,7 +556,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_project(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -573,7 +574,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_project_domain(self):
         project = identity_fakes_v3.FakeProject.create_one_project()
@@ -593,7 +594,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_name(self):
         subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool()
@@ -611,7 +612,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_subnet_pool_list_address_scope(self):
         addr_scope = network_fakes.FakeAddressScope.create_one_address_scope()
@@ -629,7 +630,7 @@ class TestListSubnetPool(TestSubnetPool):
 
         self.network.subnet_pools.assert_called_once_with(**filters)
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
     def test_list_with_tag_options(self):
         arglist = [
@@ -654,7 +655,7 @@ class TestListSubnetPool(TestSubnetPool):
                'not_any_tags': 'black,white'}
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, list(data))
+        self.assertListItemEqual(self.data, list(data))
 
 
 class TestSetSubnetPool(TestSubnetPool):
@@ -969,10 +970,10 @@ class TestShowSubnetPool(TestSubnetPool):
         _subnet_pool.max_prefixlen,
         _subnet_pool.min_prefixlen,
         _subnet_pool.name,
-        utils.format_list(_subnet_pool.prefixes),
+        format_columns.ListColumn(_subnet_pool.prefixes),
         _subnet_pool.tenant_id,
         _subnet_pool.shared,
-        utils.format_list(_subnet_pool.tags),
+        format_columns.ListColumn(_subnet_pool.tags),
     )
 
     def setUp(self):
@@ -1008,7 +1009,7 @@ class TestShowSubnetPool(TestSubnetPool):
             ignore_missing=False
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.assertItemEqual(self.data, data)
 
 
 class TestUnsetSubnetPool(TestSubnetPool):
diff --git a/openstackclient/tests/unit/utils.py b/openstackclient/tests/unit/utils.py
index 926dad87ea..c15d8bbfe2 100644
--- a/openstackclient/tests/unit/utils.py
+++ b/openstackclient/tests/unit/utils.py
@@ -19,6 +19,8 @@ import os
 import fixtures
 import testtools
 
+from cliff import columns as cliff_columns
+
 from openstackclient.tests.unit import fakes
 
 
@@ -80,3 +82,18 @@ class TestCommand(TestCase):
                 self.assertIn(attr, parsed_args)
                 self.assertEqual(value, getattr(parsed_args, attr))
         return parsed_args
+
+    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)
+
+    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)