Merge "[cli] "rally task list" improvements"

This commit is contained in:
Jenkins 2017-07-16 14:08:32 +00:00 committed by Gerrit Code Review
commit 19b85d4e6d
3 changed files with 110 additions and 72 deletions

View File

@ -554,8 +554,8 @@ class TaskCommands(object):
"""
filters = {}
headers = ["uuid", "deployment_name", "created_at", "duration",
"status", "tags"]
headers = ["UUID", "Deployment name", "Created at", "Load duration",
"Status", "Tag(s)"]
if status in consts.TaskStatus:
filters["status"] = status
@ -576,20 +576,24 @@ class TaskCommands(object):
if uuids_only:
if task_list:
cliutils.print_list(task_list, ["uuid"],
print_header=False,
print_border=False)
print("\n".join([t["uuid"] for t in task_list]))
elif task_list:
def tags_formatter(t):
if not t["tags"]:
return ""
return "'%s'" % "', '".join(t["tags"])
formatters = {
"Tag(s)": tags_formatter,
"Load duration": cliutils.pretty_float_formatter(
"task_duration", 3),
"Created at": lambda t: t["created_at"].replace("T", " ")
}
cliutils.print_list(
task_list,
headers,
sortby_index=headers.index("created_at"),
formatters={"tags": tags_formatter})
task_list, fields=headers, normalize_field_names=True,
sortby_index=headers.index("Created at"),
formatters=formatters)
else:
if status:
print(_("There are no tasks in '%s' status. "

View File

@ -22,6 +22,7 @@ import unittest
import mock
from rally import api
from tests.functional import utils
@ -93,6 +94,11 @@ class TaskTestCase(unittest.TestCase):
r"Using deployment: (?P<uuid>[0-9a-f\-]{36})",
output).group("uuid")
def _get_task_uuid(self, output):
return re.search(
r"\trally task results (?P<uuid>[0-9a-f\-]{36})",
output).group("uuid")
def test_status(self):
rally = utils.Rally()
cfg = self._get_sample_task_config()
@ -404,9 +410,37 @@ class TaskTestCase(unittest.TestCase):
rally = utils.Rally()
cfg = self._get_sample_task_config()
config = utils.TaskConfig(cfg)
rally("task start --task %s" % config.filename)
output = rally("task start --task %s --tag foo" % config.filename)
task_uuid = self._get_task_uuid(output)
# obtain the task object from the database, to check that CLI prints
# everything right
rapi = api.API(config_file=rally.config_filename)
task = rapi.task.get(task_id=task_uuid)
self.assertIn("finished", rally("task list --deployment MAIN"))
actual = rally("task list --deployment MAIN")
duration = "%s" % round(task["task_duration"], 3)
duration += " " * (13 - len(duration))
expected = (
"+--------------------------------------+-----------------+"
"---------------------+---------------+----------+--------+\n"
"| UUID | Deployment name "
"| Created at | Load duration | Status | Tag(s) |\n"
"+--------------------------------------+-----------------+"
"---------------------+---------------+----------+--------+\n"
"| %(uuid)s | MAIN | %(created_at)s "
"| %(duration)s | finished | 'foo' |\n"
"+--------------------------------------+-----------------+"
"---------------------+---------------+----------+--------+\n" % {
"uuid": task_uuid,
"created_at": task["created_at"].replace("T", " "),
"duration": duration})
# self.assertEqual is not used here, since it doesn't show a big diff
# and error message become useless
if expected != actual:
self.fail("AssertionError: Expected output is not equal to actual."
"\nExpected:\"\"\"\n%s\n\"\"\""
"\nActual:\"\"\"\n%s\n\"\"\"" % (expected, actual))
self.assertIn("There are no tasks",
rally("task list --status crashed"))
@ -414,7 +448,7 @@ class TaskTestCase(unittest.TestCase):
self.assertIn("finished", rally("task list --status finished"))
self.assertIn(
"deployment_name", rally("task list --all-deployments"))
"Deployment name", rally("task list --all-deployments"))
self.assertRaises(utils.RallyCliError,
rally, "task list --status not_existing_status")
@ -428,26 +462,26 @@ class TaskTestCase(unittest.TestCase):
self.assertEqual("", rally("task list --uuids-only"))
# Validate against a single task
res = rally("task start --task %s" % config.filename)
task_uuids = []
for line in res.splitlines():
if "finished" in line:
task_uuids.append(line.split(" ")[1][:-1])
self.assertGreater(len(task_uuids), 0)
self.assertIn(task_uuids[0],
rally("task list --uuids-only --deployment MAIN"))
res = rally("task start --task %s --tag " % config.filename)
task_uuid = self._get_task_uuid(res)
self.assertEqual(
task_uuid,
rally("task list --uuids-only --deployment MAIN").strip())
self.assertIn("finished", rally("task status --uuid %s" % task_uuid))
# Validate against multiple tasks
task_uuids = [task_uuid]
for i in range(2):
rally("task start --task %s" % config.filename)
self.assertIn("finished", rally("task list --deployment MAIN"))
out = rally("task start --task %s" % config.filename)
task_uuid = self._get_task_uuid(out)
task_uuids.append(task_uuid)
self.assertIn("finished",
rally("task status --uuid %s" % task_uuid))
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)
self.assertEqual(set(task_uuids), set(res.strip().split("\n")))
res2 = rally("task list --uuids-only --deployment MAIN "
"--status finished")
self.assertEqual(res, res2)
def test_validate_is_valid(self):
rally = utils.Rally()

View File

@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import datetime as dt
import json
import os.path
import sys
import ddt
import mock
@ -775,43 +775,43 @@ class TaskCommandsTestCase(test.TestCase):
return_value="123456789")
def test_list(self, mock_get_global, mock_print_list):
self.fake_api.task.list.return_value = [
fakes.FakeTask(uuid="a",
created_at=dt.datetime.now(),
updated_at=dt.datetime.now(),
status="c",
tags=["d"],
deployment_name="some_name")]
{"uuid": "a",
"created_at": "2007-01-01T00:00:01",
"updated_at": "2007-01-01T00:00:03",
"status": consts.TaskStatus.RUNNING,
"tags": ["d"],
"deployment_name": "some_name"}]
self.task.list(self.fake_api, status="running")
self.fake_api.task.list.assert_called_once_with(
deployment=mock_get_global.return_value,
status=consts.TaskStatus.RUNNING)
headers = ["uuid", "deployment_name", "created_at", "duration",
"status", "tags"]
headers = ["UUID", "Deployment name", "Created at", "Load duration",
"Status", "Tag(s)"]
mock_print_list.assert_called_once_with(
self.fake_api.task.list.return_value, headers,
sortby_index=headers.index("created_at"),
self.fake_api.task.list.return_value, fields=headers,
normalize_field_names=True,
sortby_index=headers.index("Created at"),
formatters=mock.ANY)
@mock.patch("rally.cli.commands.task.cliutils.print_list")
@mock.patch("rally.cli.commands.task.envutils.get_global",
return_value="123456789")
def test_list_uuids_only(self, mock_get_global, mock_print_list):
def test_list_uuids_only(self, mock_get_global):
self.fake_api.task.list.return_value = [
fakes.FakeTask(uuid="a",
created_at=dt.datetime.now(),
updated_at=dt.datetime.now(),
status="c",
tag="d",
deployment_name="some_name")]
self.task.list(self.fake_api, status="running", uuids_only=True)
{"uuid": "a",
"created_at": "2007-01-01T00:00:01",
"updated_at": "2007-01-01T00:00:03",
"status": consts.TaskStatus.RUNNING,
"tags": ["d"],
"deployment_name": "some_name"}]
out = six.StringIO()
with mock.patch.object(sys, "stdout", new=out):
self.task.list(self.fake_api, status="running", uuids_only=True)
self.assertEqual("a\n", out.getvalue())
self.fake_api.task.list.assert_called_once_with(
deployment=mock_get_global.return_value,
status=consts.TaskStatus.RUNNING)
mock_print_list.assert_called_once_with(
self.fake_api.task.list.return_value, ["uuid"],
print_header=False, print_border=False)
def test_list_wrong_status(self):
self.assertEqual(1, self.task.list(self.fake_api, deployment="fake",
@ -833,18 +833,18 @@ class TaskCommandsTestCase(test.TestCase):
return_value="123456789")
def test_list_output(self, mock_get_global):
self.fake_api.task.list.return_value = [
fakes.FakeTask(uuid="UUID-1",
created_at="2007-01-01T00:00:01",
duration="0:00:00.000009",
status="init",
tags=[],
deployment_name="some_name"),
fakes.FakeTask(uuid="UUID-2",
created_at="2007-02-01T00:00:01",
duration="0:00:00.000010",
status="finished",
tags=["tag-1", "tag-2"],
deployment_name="some_name")]
{"uuid": "UUID-1",
"created_at": "2007-01-01T00:00:01",
"task_duration": 0.0000009,
"status": consts.TaskStatus.INIT,
"tags": [],
"deployment_name": "some_name"},
{"uuid": "UUID-2",
"created_at": "2007-02-01T00:00:01",
"task_duration": 123.99992,
"status": consts.TaskStatus.FINISHED,
"tags": ["tag-1", "tag-2"],
"deployment_name": "some_name"}]
# It is a hard task to mock default value of function argument, so we
# need to apply this workaround
@ -864,17 +864,17 @@ class TaskCommandsTestCase(test.TestCase):
self.assertEqual(
"+--------+-----------------+---------------------"
"+----------------+----------+------------------+\n"
"| uuid | deployment_name | created_at "
"| duration | status | tags |\n"
"+---------------+----------+------------------+\n"
"| UUID | Deployment name | Created at "
"| Load duration | Status | Tag(s) |\n"
"+--------+-----------------+---------------------"
"+----------------+----------+------------------+\n"
"| UUID-1 | some_name | 2007-01-01T00:00:01 "
"| 0:00:00.000009 | init | |\n"
"| UUID-2 | some_name | 2007-02-01T00:00:01 "
"| 0:00:00.000010 | finished | 'tag-1', 'tag-2' |\n"
"+---------------+----------+------------------+\n"
"| UUID-1 | some_name | 2007-01-01 00:00:01 "
"| 0.0 | init | |\n"
"| UUID-2 | some_name | 2007-02-01 00:00:01 "
"| 124.0 | finished | 'tag-1', 'tag-2' |\n"
"+--------+-----------------+---------------------"
"+----------------+----------+------------------+\n",
"+---------------+----------+------------------+\n",
print_list_calls[0].getvalue())
def test_delete(self):