Merge "Add sort support to project list"

This commit is contained in:
Jenkins 2017-03-16 13:01:56 +00:00 committed by Gerrit Code Review
commit 9184e19288
7 changed files with 121 additions and 0 deletions

View File

@ -96,6 +96,7 @@ List projects
[--domain <domain>]
[--user <user>]
[--long]
[--sort <key>[:<direction>,<key>:<direction>,..]]
.. option:: --domain <domain>
@ -113,6 +114,12 @@ List projects
List additional fields in output
.. option:: --sort <key>[:<direction>,<key>:<direction>,..]
Sort output by selected keys and directions (asc or desc) (default: asc),
multiple keys and directions can be specified --sort
<key>[:<direction>,<key>:<direction>,..]
project set
-----------

View File

@ -150,6 +150,13 @@ class ListProject(command.Lister):
default=False,
help=_('List additional fields in output'),
)
parser.add_argument(
'--sort',
metavar='<key>[:<direction>]',
help=_('Sort output by selected keys and directions (asc or desc) '
'(default: asc), repeat this option to specify multiple '
'keys and directions.'),
)
return parser
def take_action(self, parsed_args):
@ -158,6 +165,8 @@ class ListProject(command.Lister):
else:
columns = ('ID', 'Name')
data = self.app.client_manager.identity.tenants.list()
if parsed_args.sort:
data = utils.sort_items(data, parsed_args.sort)
return (columns,
(utils.get_item_properties(
s, columns,

View File

@ -194,6 +194,13 @@ class ListProject(command.Lister):
default=False,
help=_('List additional fields in output'),
)
parser.add_argument(
'--sort',
metavar='<key>[:<direction>]',
help=_('Sort output by selected keys and directions (asc or desc) '
'(default: asc), repeat this option to specify multiple '
'keys and directions.'),
)
return parser
def take_action(self, parsed_args):
@ -222,6 +229,8 @@ class ListProject(command.Lister):
kwargs['user'] = user_id
data = identity_client.projects.list(**kwargs)
if parsed_args.sort:
data = utils.sort_items(data, parsed_args.sort)
return (columns,
(utils.get_item_properties(
s, columns,

View File

@ -26,6 +26,7 @@ from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
class TestProject(identity_fakes.TestIdentityv2):
fake_project = identity_fakes.FakeProject.create_one_project()
fake_projects = identity_fakes.FakeProject.create_projects()
columns = (
'description',
@ -39,6 +40,12 @@ class TestProject(identity_fakes.TestIdentityv2):
fake_project.id,
fake_project.name,
)
datalists = (
(fake_projects[0].description, True,
fake_projects[0].id, fake_projects[0].name,),
(fake_projects[1].description, True,
fake_projects[1].id, fake_projects[1].name,),
)
def setUp(self):
super(TestProject, self).setUp()
@ -386,6 +393,35 @@ class TestProjectList(TestProject):
), )
self.assertEqual(datalist, tuple(data))
def test_project_list_sort(self):
self.projects_mock.list.return_value = self.fake_projects
arglist = ['--sort', 'name:asc', ]
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
(columns, data) = self.cmd.take_action(parsed_args)
self.projects_mock.list.assert_called_with()
collist = ('ID', 'Name')
self.assertEqual(collist, columns)
if self.fake_projects[0].name > self.fake_projects[1].name:
datalists = (
(self.fake_projects[1].id, self.fake_projects[1].name),
(self.fake_projects[0].id, self.fake_projects[0].name),
)
else:
datalists = (
(self.fake_projects[0].id, self.fake_projects[0].name),
(self.fake_projects[1].id, self.fake_projects[1].name),
)
self.assertEqual(datalists, tuple(data))
class TestProjectSet(TestProject):

View File

@ -622,6 +622,23 @@ class FakeProject(object):
loaded=True)
return project
@staticmethod
def create_projects(attrs=None, count=2):
"""Create multiple fake projects.
:param Dictionary attrs:
A dictionary with all attributes
:param int count:
The number of projects to fake
:return:
A list of FakeResource objects faking the projects
"""
projects = []
for i in range(0, count):
projects.append(FakeProject.create_one_project(attrs))
return projects
class FakeDomain(object):
"""Fake one or more domain."""

View File

@ -479,6 +479,7 @@ class TestProjectList(TestProject):
domain = identity_fakes.FakeDomain.create_one_domain()
project = identity_fakes.FakeProject.create_one_project(
attrs={'domain_id': domain.id})
projects = identity_fakes.FakeProject.create_projects()
columns = (
'ID',
@ -490,6 +491,12 @@ class TestProjectList(TestProject):
project.name,
),
)
datalists = (
(projects[0].description, True,
projects[0].id, projects[0].name,),
(projects[1].description, True,
projects[1].id, projects[1].name,),
)
def setUp(self):
super(TestProjectList, self).setUp()
@ -580,6 +587,36 @@ class TestProjectList(TestProject):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_project_list_sort(self):
self.projects_mock.list.return_value = self.projects
arglist = ['--sort', 'name:asc', ]
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
(columns, data) = self.cmd.take_action(parsed_args)
self.projects_mock.list.assert_called_with()
collist = ('ID', 'Name')
self.assertEqual(collist, columns)
if self.projects[0].name > self.projects[1].name:
datalists = (
(self.projects[1].id, self.projects[1].name),
(self.projects[0].id, self.projects[0].name),
)
else:
datalists = (
(self.projects[0].id, self.projects[0].name),
(self.projects[1].id, self.projects[1].name),
)
self.assertEqual(datalists, tuple(data))
class TestProjectSet(TestProject):

View File

@ -0,0 +1,6 @@
---
features:
- |
Add ``--sort`` support to ``project list`` by sorting items in client side
By default project list will be sorted by name.
[Bug `1596818 <https://bugs.launchpad.net/bugs/1596818>`_]