Skip to content

Commit

Permalink
Add the -l/--limit option to verdi group show (#3857)
Browse files Browse the repository at this point in the history
This is a very useful flag that used to be there at some point.
  • Loading branch information
sphuber authored Mar 22, 2020
1 parent d0b89c1 commit b90a629
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 37 deletions.
12 changes: 9 additions & 3 deletions aiida/cmdline/commands/cmd_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def group_description(group, description):

@verdi_group.command('show')
@options.RAW(help='Show only a space-separated list of PKs of the calculations in the group')
@options.LIMIT()
@click.option(
'-u',
'--uuid',
Expand All @@ -132,18 +133,23 @@ def group_description(group, description):
)
@arguments.GROUP()
@with_dbenv()
def group_show(group, raw, uuid):
def group_show(group, raw, limit, uuid):
"""Show information for a given group."""
from tabulate import tabulate

from aiida.common.utils import str_timedelta
from aiida.common import timezone

if limit:
node_iterator = group.nodes[:limit]
else:
node_iterator = group.nodes

if raw:
if uuid:
echo.echo(' '.join(str(_.uuid) for _ in group.nodes))
echo.echo(' '.join(str(_.uuid) for _ in node_iterator))
else:
echo.echo(' '.join(str(_.pk) for _ in group.nodes))
echo.echo(' '.join(str(_.pk) for _ in node_iterator))
else:
type_string = group.type_string
desc = group.description
Expand Down
87 changes: 53 additions & 34 deletions tests/cmdline/commands/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@
# For further information please visit http://www.aiida.net #
###########################################################################
"""Tests for the `verdi group` command."""

from aiida import orm
from aiida.backends.testbase import AiidaTestCase
from aiida.common import exceptions
from aiida.cmdline.commands.cmd_group import (
group_list, group_create, group_delete, group_relabel, group_description, group_add_nodes, group_remove_nodes,
group_show, group_copy
)
from aiida.cmdline.commands import cmd_group


class TestVerdiGroup(AiidaTestCase):
Expand All @@ -37,72 +33,72 @@ def test_help(self):
options = ['--help']

# verdi group list
result = self.cli_runner.invoke(group_list, options)
result = self.cli_runner.invoke(cmd_group.group_list, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group create
result = self.cli_runner.invoke(group_create, options)
result = self.cli_runner.invoke(cmd_group.group_create, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group delete
result = self.cli_runner.invoke(group_delete, options)
result = self.cli_runner.invoke(cmd_group.group_delete, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group relabel
result = self.cli_runner.invoke(group_relabel, options)
result = self.cli_runner.invoke(cmd_group.group_relabel, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group description
result = self.cli_runner.invoke(group_description, options)
result = self.cli_runner.invoke(cmd_group.group_description, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group addnodes
result = self.cli_runner.invoke(group_add_nodes, options)
result = self.cli_runner.invoke(cmd_group.group_add_nodes, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group removenodes
result = self.cli_runner.invoke(group_remove_nodes, options)
result = self.cli_runner.invoke(cmd_group.group_remove_nodes, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group show
result = self.cli_runner.invoke(group_show, options)
result = self.cli_runner.invoke(cmd_group.group_show, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

# verdi group copy
result = self.cli_runner.invoke(group_copy, options)
result = self.cli_runner.invoke(cmd_group.group_copy, options)
self.assertIsNone(result.exception, result.output)
self.assertIn('Usage', result.output)

def test_create(self):
"""Test `verdi group create` command."""
result = self.cli_runner.invoke(group_create, ['dummygroup5'])
result = self.cli_runner.invoke(cmd_group.group_create, ['dummygroup5'])
self.assertClickResultNoException(result)

# check if newly added group in present in list
result = self.cli_runner.invoke(group_list)
result = self.cli_runner.invoke(cmd_group.group_list)
self.assertClickResultNoException(result)

self.assertIn('dummygroup5', result.output)

def test_list(self):
"""Test `verdi group list` command."""
result = self.cli_runner.invoke(group_list)
result = self.cli_runner.invoke(cmd_group.group_list)
self.assertClickResultNoException(result)

for grp in ['dummygroup1', 'dummygroup2']:
self.assertIn(grp, result.output)

def test_copy(self):
"""Test `verdi group copy` command."""
result = self.cli_runner.invoke(group_copy, ['dummygroup1', 'dummygroup2'])
result = self.cli_runner.invoke(cmd_group.group_copy, ['dummygroup1', 'dummygroup2'])
self.assertClickResultNoException(result)

self.assertIn('Success', result.output)
Expand All @@ -112,11 +108,11 @@ def test_delete(self):
orm.Group(label='group_test_delete_01').store()
orm.Group(label='group_test_delete_02').store()

result = self.cli_runner.invoke(group_delete, ['--force', 'group_test_delete_01'])
result = self.cli_runner.invoke(cmd_group.group_delete, ['--force', 'group_test_delete_01'])
self.assertClickResultNoException(result)

# Verify that removed group is not present in list
result = self.cli_runner.invoke(group_list)
result = self.cli_runner.invoke(cmd_group.group_list)
self.assertClickResultNoException(result)
self.assertNotIn('group_test_delete_01', result.output)

Expand All @@ -129,49 +125,72 @@ def test_delete(self):
self.assertEqual(group.count(), 2)

# Calling delete on a group without the `--clear` option should raise
result = self.cli_runner.invoke(group_delete, ['--force', 'group_test_delete_02'])
result = self.cli_runner.invoke(cmd_group.group_delete, ['--force', 'group_test_delete_02'])
self.assertIsNotNone(result.exception, result.output)

# With `--clear` option should delete group and nodes
result = self.cli_runner.invoke(group_delete, ['--force', '--clear', 'group_test_delete_02'])
result = self.cli_runner.invoke(cmd_group.group_delete, ['--force', '--clear', 'group_test_delete_02'])
self.assertClickResultNoException(result)

with self.assertRaises(exceptions.NotExistent):
group = orm.load_group(label='group_test_delete_02')

def test_show(self):
"""Test `verdi group show` command."""
result = self.cli_runner.invoke(group_show, ['dummygroup1'])
result = self.cli_runner.invoke(cmd_group.group_show, ['dummygroup1'])
self.assertClickResultNoException(result)

for grpline in [
'Group label', 'dummygroup1', 'Group type_string', 'user', 'Group description', '<no description>'
]:
self.assertIn(grpline, result.output)

def test_show_limit(self):
"""Test `--limit` option of the `verdi group show` command."""
label = 'test_group_limit'
nodes = [orm.Data().store(), orm.Data().store()]
group = orm.Group(label=label).store()
group.add_nodes(nodes)

# Default should include all nodes in the output
result = self.cli_runner.invoke(cmd_group.group_show, [label])
self.assertClickResultNoException(result)

for node in nodes:
self.assertIn(str(node.pk), result.output)

# Repeat test with `limit=1`, use also the `--raw` option to only display nodes
result = self.cli_runner.invoke(cmd_group.group_show, [label, '--limit', '1', '--raw'])
self.assertClickResultNoException(result)

# The current `verdi group show` does not support ordering so we cannot rely on that for now to test if only
# one of the nodes is shown
self.assertEqual(len(result.output.strip().split('\n')), 1)
self.assertTrue(str(nodes[0].pk) in result.output or str(nodes[1].pk) in result.output)

def test_description(self):
"""Test `verdi group description` command."""
description = 'It is a new description'
group = orm.load_group(label='dummygroup2')
self.assertNotEqual(group.description, description)

# Change the description of the group
result = self.cli_runner.invoke(group_description, [group.label, description])
result = self.cli_runner.invoke(cmd_group.group_description, [group.label, description])
self.assertClickResultNoException(result)
self.assertEqual(group.description, description)

# When no description argument is passed the command should just echo the current description
result = self.cli_runner.invoke(group_description, [group.label])
result = self.cli_runner.invoke(cmd_group.group_description, [group.label])
self.assertClickResultNoException(result)
self.assertIn(description, result.output)

def test_relabel(self):
"""Test `verdi group relabel` command."""
result = self.cli_runner.invoke(group_relabel, ['dummygroup4', 'relabeled_group'])
result = self.cli_runner.invoke(cmd_group.group_relabel, ['dummygroup4', 'relabeled_group'])
self.assertIsNone(result.exception, result.output)

# check if group list command shows changed group name
result = self.cli_runner.invoke(group_list)
result = self.cli_runner.invoke(cmd_group.group_list)
self.assertClickResultNoException(result)
self.assertNotIn('dummygroup4', result.output)
self.assertIn('relabeled_group', result.output)
Expand All @@ -182,21 +201,21 @@ def test_add_remove_nodes(self):
node_02 = orm.CalculationNode().store()
node_03 = orm.CalculationNode().store()

result = self.cli_runner.invoke(group_add_nodes, ['--force', '--group=dummygroup1', node_01.uuid])
result = self.cli_runner.invoke(cmd_group.group_add_nodes, ['--force', '--group=dummygroup1', node_01.uuid])
self.assertClickResultNoException(result)

# Check if node is added in group using group show command
result = self.cli_runner.invoke(group_show, ['dummygroup1'])
result = self.cli_runner.invoke(cmd_group.group_show, ['dummygroup1'])
self.assertClickResultNoException(result)
self.assertIn('CalculationNode', result.output)
self.assertIn(str(node_01.pk), result.output)

# Remove same node
result = self.cli_runner.invoke(group_remove_nodes, ['--force', '--group=dummygroup1', node_01.uuid])
result = self.cli_runner.invoke(cmd_group.group_remove_nodes, ['--force', '--group=dummygroup1', node_01.uuid])
self.assertIsNone(result.exception, result.output)

# Check if node is added in group using group show command
result = self.cli_runner.invoke(group_show, ['-r', 'dummygroup1'])
result = self.cli_runner.invoke(cmd_group.group_show, ['-r', 'dummygroup1'])
self.assertClickResultNoException(result)
self.assertNotIn('CalculationNode', result.output)
self.assertNotIn(str(node_01.pk), result.output)
Expand All @@ -206,7 +225,7 @@ def test_add_remove_nodes(self):
group.add_nodes([node_01, node_02, node_03])
self.assertEqual(group.count(), 3)

result = self.cli_runner.invoke(group_remove_nodes, ['--force', '--clear', '--group=dummygroup1'])
result = self.cli_runner.invoke(cmd_group.group_remove_nodes, ['--force', '--clear', '--group=dummygroup1'])
self.assertClickResultNoException(result)
self.assertEqual(group.count(), 0)

Expand All @@ -224,7 +243,7 @@ def test_copy_existing_group(self):

# Copy using `verdi group copy` - making sure all is successful
options = [source_label, dest_label]
result = self.cli_runner.invoke(group_copy, options)
result = self.cli_runner.invoke(cmd_group.group_copy, options)
self.assertClickResultNoException(result)
self.assertIn(
'Success: Nodes copied from group<{}> to group<{}>'.format(source_label, dest_label), result.output,
Expand All @@ -238,7 +257,7 @@ def test_copy_existing_group(self):
self.assertSetEqual(nodes_source_group, nodes_dest_group)

# Copy again, making sure an abort error is raised, since no user input can be made and default is abort
result = self.cli_runner.invoke(group_copy, options)
result = self.cli_runner.invoke(cmd_group.group_copy, options)
self.assertIsNotNone(result.exception, result.output)
self.assertIn(
'Warning: Destination group<{}> already exists and is not empty.'.format(dest_label), result.output,
Expand Down

0 comments on commit b90a629

Please sign in to comment.