Add a --uuids-only option to rally task list
This option prints the list of UUIDs only. The motivation for this option is scripting, for example: for x in $(rally task list --status passed --uuids-only); \ do \ rally task report --tasks $x --out $x.html; \ done Change-Id: Ia967071bc3e4454116adbc59a790ab684efff15c Signed-off-by: Andrew McDermott <andrew.mcdermott@linaro.org>
This commit is contained in:
parent
a580bce1c5
commit
7126848b5b
@ -29,7 +29,7 @@ _rally()
|
|||||||
OPTS["task_abort"]="--uuid"
|
OPTS["task_abort"]="--uuid"
|
||||||
OPTS["task_delete"]="--force --uuid"
|
OPTS["task_delete"]="--force --uuid"
|
||||||
OPTS["task_detailed"]="--uuid --iterations-data"
|
OPTS["task_detailed"]="--uuid --iterations-data"
|
||||||
OPTS["task_list"]="--deployment --all-deployments --status"
|
OPTS["task_list"]="--deployment --all-deployments --status --uuids-only"
|
||||||
OPTS["task_report"]="--tasks --out --open"
|
OPTS["task_report"]="--tasks --out --open"
|
||||||
OPTS["task_results"]="--uuid"
|
OPTS["task_results"]="--uuid"
|
||||||
OPTS["task_sla_check"]="--uuid --json"
|
OPTS["task_sla_check"]="--uuid --json"
|
||||||
|
@ -84,7 +84,9 @@ def validate_args(fn, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def print_list(objs, fields, formatters=None, sortby_index=0,
|
def print_list(objs, fields, formatters=None, sortby_index=0,
|
||||||
mixed_case_fields=None, field_labels=None):
|
mixed_case_fields=None, field_labels=None,
|
||||||
|
print_header=True, print_border=True,
|
||||||
|
out=sys.stdout):
|
||||||
"""Print a list or objects as a table, one row per object.
|
"""Print a list or objects as a table, one row per object.
|
||||||
|
|
||||||
:param objs: iterable of :class:`Resource`
|
:param objs: iterable of :class:`Resource`
|
||||||
@ -95,6 +97,9 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
|
|||||||
have mixed case names (e.g., 'serverId')
|
have mixed case names (e.g., 'serverId')
|
||||||
:param field_labels: Labels to use in the heading of the table, default to
|
:param field_labels: Labels to use in the heading of the table, default to
|
||||||
fields.
|
fields.
|
||||||
|
:param print_header: print table header.
|
||||||
|
:param print_border: print table border.
|
||||||
|
:param out: stream to write output to.
|
||||||
"""
|
"""
|
||||||
formatters = formatters or {}
|
formatters = formatters or {}
|
||||||
mixed_case_fields = mixed_case_fields or []
|
mixed_case_fields = mixed_case_fields or []
|
||||||
@ -125,10 +130,19 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
|
|||||||
row.append(data)
|
row.append(data)
|
||||||
pt.add_row(row)
|
pt.add_row(row)
|
||||||
|
|
||||||
|
if not print_border or not print_header:
|
||||||
|
pt.set_style(prettytable.PLAIN_COLUMNS)
|
||||||
|
pt.left_padding_width = 0
|
||||||
|
pt.right_padding_width = 1
|
||||||
|
|
||||||
|
outstr = pt.get_string(header=print_header,
|
||||||
|
border=print_border,
|
||||||
|
**kwargs) + "\n"
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode())
|
out.write(encodeutils.safe_encode(outstr).decode())
|
||||||
else:
|
else:
|
||||||
print(encodeutils.safe_encode(pt.get_string(**kwargs)))
|
out.write(encodeutils.safe_encode(outstr))
|
||||||
|
|
||||||
|
|
||||||
def make_header(text, size=80, symbol="-"):
|
def make_header(text, size=80, symbol="-"):
|
||||||
|
@ -443,8 +443,11 @@ class TaskCommands(object):
|
|||||||
@cliutils.args("--status", type=str, dest="status",
|
@cliutils.args("--status", type=str, dest="status",
|
||||||
help="List tasks with specified status."
|
help="List tasks with specified status."
|
||||||
" Available statuses: %s" % ", ".join(consts.TaskStatus))
|
" Available statuses: %s" % ", ".join(consts.TaskStatus))
|
||||||
|
@cliutils.args("--uuids-only", action="store_true",
|
||||||
|
dest="uuids_only", help="List task UUIDs only")
|
||||||
@envutils.with_default_deployment(cli_arg_name="deployment")
|
@envutils.with_default_deployment(cli_arg_name="deployment")
|
||||||
def list(self, deployment=None, all_deployments=False, status=None):
|
def list(self, deployment=None, all_deployments=False, status=None,
|
||||||
|
uuids_only=False):
|
||||||
"""List tasks, started and finished.
|
"""List tasks, started and finished.
|
||||||
|
|
||||||
Displayed tasks could be filtered by status or deployment.
|
Displayed tasks could be filtered by status or deployment.
|
||||||
@ -454,6 +457,7 @@ class TaskCommands(object):
|
|||||||
:param status: task status to filter by.
|
:param status: task status to filter by.
|
||||||
Available task statuses are in rally.consts.TaskStatus
|
Available task statuses are in rally.consts.TaskStatus
|
||||||
:param all_deployments: display tasks from all deployments
|
:param all_deployments: display tasks from all deployments
|
||||||
|
:param uuids_only: list task UUIDs only
|
||||||
"""
|
"""
|
||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
@ -477,7 +481,12 @@ class TaskCommands(object):
|
|||||||
for x in task_list:
|
for x in task_list:
|
||||||
x["duration"] = x["updated_at"] - x["created_at"]
|
x["duration"] = x["updated_at"] - x["created_at"]
|
||||||
|
|
||||||
if task_list:
|
if uuids_only:
|
||||||
|
if task_list:
|
||||||
|
cliutils.print_list(task_list, ["uuid"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=False)
|
||||||
|
elif task_list:
|
||||||
cliutils.print_list(
|
cliutils.print_list(
|
||||||
task_list,
|
task_list,
|
||||||
headers, sortby_index=headers.index("created_at"))
|
headers, sortby_index=headers.index("created_at"))
|
||||||
|
@ -231,6 +231,36 @@ class TaskTestCase(unittest.TestCase):
|
|||||||
self.assertRaises(utils.RallyCmdError,
|
self.assertRaises(utils.RallyCmdError,
|
||||||
rally, "task list --status not_existing_status")
|
rally, "task list --status not_existing_status")
|
||||||
|
|
||||||
|
def test_list_with_print_uuids_option(self):
|
||||||
|
rally = utils.Rally()
|
||||||
|
cfg = self._get_sample_task_config()
|
||||||
|
config = utils.TaskConfig(cfg)
|
||||||
|
|
||||||
|
# Validate against zero tasks
|
||||||
|
self.assertEqual("", rally("task list --uuids-only"))
|
||||||
|
|
||||||
|
# Validate against a single task
|
||||||
|
res = rally("task start --task %s" % config.filename)
|
||||||
|
task_uuids = list()
|
||||||
|
for line in res.splitlines():
|
||||||
|
if "finished" in line:
|
||||||
|
task_uuids.append(line.split(" ")[1][:-1])
|
||||||
|
self.assertTrue(len(task_uuids))
|
||||||
|
self.assertIn(task_uuids[0],
|
||||||
|
rally("task list --uuids-only --deployment MAIN"))
|
||||||
|
|
||||||
|
# Validate against multiple tasks
|
||||||
|
for i in range(2):
|
||||||
|
rally("task start --task %s" % config.filename)
|
||||||
|
self.assertIn("finished", rally("task list --deployment MAIN"))
|
||||||
|
res = rally("task list --uuids-only --deployment MAIN")
|
||||||
|
task_uuids = res.split()
|
||||||
|
self.assertEqual(3, len(task_uuids))
|
||||||
|
res = rally("task list --uuids-only --deployment MAIN "
|
||||||
|
"--status finished")
|
||||||
|
for uuid in task_uuids:
|
||||||
|
self.assertIn(uuid, res)
|
||||||
|
|
||||||
def test_validate_is_valid(self):
|
def test_validate_is_valid(self):
|
||||||
rally = utils.Rally()
|
rally = utils.Rally()
|
||||||
cfg = self._get_sample_task_config()
|
cfg = self._get_sample_task_config()
|
||||||
|
@ -504,6 +504,26 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
mock_objects_list.return_value, headers,
|
mock_objects_list.return_value, headers,
|
||||||
sortby_index=headers.index("created_at"))
|
sortby_index=headers.index("created_at"))
|
||||||
|
|
||||||
|
@mock.patch("rally.cmd.commands.task.cliutils.print_list")
|
||||||
|
@mock.patch("rally.cmd.commands.task.envutils.get_global",
|
||||||
|
return_value="123456789")
|
||||||
|
@mock.patch("rally.cmd.commands.task.objects.Task.list",
|
||||||
|
return_value=[fakes.FakeTask(uuid="a",
|
||||||
|
created_at=date.datetime.now(),
|
||||||
|
updated_at=date.datetime.now(),
|
||||||
|
status="c",
|
||||||
|
tag="d",
|
||||||
|
deployment_name="some_name")])
|
||||||
|
def test_list_uuids_only(self, mock_objects_list, mock_default,
|
||||||
|
mock_print_list):
|
||||||
|
self.task.list(status="running", uuids_only=True)
|
||||||
|
mock_objects_list.assert_called_once_with(
|
||||||
|
deployment=mock_default.return_value,
|
||||||
|
status=consts.TaskStatus.RUNNING)
|
||||||
|
mock_print_list.assert_called_once_with(
|
||||||
|
mock_objects_list.return_value, ["uuid"],
|
||||||
|
print_header=False, print_border=False)
|
||||||
|
|
||||||
def test_list_wrong_status(self):
|
def test_list_wrong_status(self):
|
||||||
self.assertEqual(1, self.task.list(deployment="fake",
|
self.assertEqual(1, self.task.list(deployment="fake",
|
||||||
status="wrong non existing status"))
|
status="wrong non existing status"))
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
from six import moves
|
||||||
|
|
||||||
from rally.cmd import cliutils
|
from rally.cmd import cliutils
|
||||||
from rally.cmd.commands import deployment
|
from rally.cmd.commands import deployment
|
||||||
@ -170,6 +171,171 @@ class CliUtilsTestCase(test.TestCase):
|
|||||||
{"failure": FailuresCommands})
|
{"failure": FailuresCommands})
|
||||||
self.assertEqual(1, ret)
|
self.assertEqual(1, ret)
|
||||||
|
|
||||||
|
def test_print_list(self):
|
||||||
|
class TestObj(object):
|
||||||
|
x = 1
|
||||||
|
y = 2
|
||||||
|
z = 3.142857142857143
|
||||||
|
aOrB = 3 # mixed case field
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x", "y"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=True,
|
||||||
|
sortby_index=None,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+---+---+\n"
|
||||||
|
"| x | y |\n"
|
||||||
|
"+---+---+\n"
|
||||||
|
"| 1 | 2 |\n"
|
||||||
|
"+---+---+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
formatter = cliutils.pretty_float_formatter("z", 5)
|
||||||
|
cliutils.print_list([TestObj()], ["z"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=True,
|
||||||
|
sortby_index=None,
|
||||||
|
formatters={"z": formatter},
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+---------+\n"
|
||||||
|
"| z |\n"
|
||||||
|
"+---------+\n"
|
||||||
|
"| 3.14286 |\n"
|
||||||
|
"+---------+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+---+\n"
|
||||||
|
"| x |\n"
|
||||||
|
"+---+\n"
|
||||||
|
"| 1 |\n"
|
||||||
|
"+---+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x", "y"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+---+---+\n"
|
||||||
|
"| x | y |\n"
|
||||||
|
"+---+---+\n"
|
||||||
|
"| 1 | 2 |\n"
|
||||||
|
"+---+---+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("1",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x", "y"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("1 2",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("x \n1",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x", "y"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("x y \n1 2",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+--+\n"
|
||||||
|
"|1 |\n"
|
||||||
|
"+--+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["x", "y"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+--+--+\n"
|
||||||
|
"|1 |2 |\n"
|
||||||
|
"+--+--+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["aOrB"],
|
||||||
|
mixed_case_fields=["aOrB"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+------+\n"
|
||||||
|
"| aOrB |\n"
|
||||||
|
"+------+\n"
|
||||||
|
"| 3 |\n"
|
||||||
|
"+------+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["aOrB"],
|
||||||
|
mixed_case_fields=["aOrB"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=True,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("+--+\n"
|
||||||
|
"|3 |\n"
|
||||||
|
"+--+",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["aOrB"],
|
||||||
|
mixed_case_fields=["aOrB"],
|
||||||
|
print_header=True,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("aOrB \n"
|
||||||
|
"3",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
cliutils.print_list([TestObj()], ["aOrB"],
|
||||||
|
mixed_case_fields=["aOrB"],
|
||||||
|
print_header=False,
|
||||||
|
print_border=False,
|
||||||
|
out=out)
|
||||||
|
self.assertEqual("3",
|
||||||
|
out.getvalue().strip())
|
||||||
|
|
||||||
|
out = moves.StringIO()
|
||||||
|
self.assertRaisesRegexp(ValueError,
|
||||||
|
"Field labels list.*has different number "
|
||||||
|
"of elements than fields list",
|
||||||
|
cliutils.print_list,
|
||||||
|
[TestObj()],
|
||||||
|
["x"],
|
||||||
|
field_labels=["x", "y"],
|
||||||
|
sortby_index=None,
|
||||||
|
out=out)
|
||||||
|
|
||||||
|
|
||||||
class ValidateArgsTest(test.TestCase):
|
class ValidateArgsTest(test.TestCase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user