Extend tags feature of tasks
* Add ability to setup multiple tags for a task. The database supports an unlimited number of tags per tasks. It would be nice to support that feature from user side too. * The tags feature is a bit useless, if there is no way to filter by them. This patch adds this ability to `rally task list` command. Change-Id: I959fa904a38f193f77f25b53ba3ee86760fff91c
This commit is contained in:
parent
91577f0f1f
commit
26cc4be584
@ -33,7 +33,7 @@ _rally()
|
|||||||
OPTS["task_detailed"]="--uuid --iterations-data"
|
OPTS["task_detailed"]="--uuid --iterations-data"
|
||||||
OPTS["task_export"]="--uuid --type --to"
|
OPTS["task_export"]="--uuid --type --to"
|
||||||
OPTS["task_import"]="--file --deployment --tag"
|
OPTS["task_import"]="--file --deployment --tag"
|
||||||
OPTS["task_list"]="--deployment --all-deployments --status --uuids-only"
|
OPTS["task_list"]="--deployment --all-deployments --status --tag --uuids-only"
|
||||||
OPTS["task_report"]="--out --open --html --html-static --uuid"
|
OPTS["task_report"]="--out --open --html --html-static --uuid"
|
||||||
OPTS["task_results"]="--uuid"
|
OPTS["task_results"]="--uuid"
|
||||||
OPTS["task_sla-check"]="--uuid --json"
|
OPTS["task_sla-check"]="--uuid --json"
|
||||||
|
11
rally/api.py
11
rally/api.py
@ -381,14 +381,14 @@ class _Task(APIGroup):
|
|||||||
|
|
||||||
@api_wrapper(path=API_REQUEST_PREFIX + "/task/create",
|
@api_wrapper(path=API_REQUEST_PREFIX + "/task/create",
|
||||||
method="POST")
|
method="POST")
|
||||||
def create(self, deployment, tag):
|
def create(self, deployment, tags=None):
|
||||||
"""Create a task without starting it.
|
"""Create a task without starting it.
|
||||||
|
|
||||||
Task is a list of benchmarks that will be called one by one, results of
|
Task is a list of benchmarks that will be called one by one, results of
|
||||||
execution will be stored in DB.
|
execution will be stored in DB.
|
||||||
|
|
||||||
:param deployment: UUID or name of the deployment
|
:param deployment: UUID or name of the deployment
|
||||||
:param tag: tag for this task
|
:param tags: a list of tags for this task
|
||||||
:returns: Task object
|
:returns: Task object
|
||||||
"""
|
"""
|
||||||
deployment = objects.Deployment.get(deployment)
|
deployment = objects.Deployment.get(deployment)
|
||||||
@ -399,7 +399,7 @@ class _Task(APIGroup):
|
|||||||
status=deployment["status"])
|
status=deployment["status"])
|
||||||
|
|
||||||
return objects.Task(deployment_uuid=deployment["uuid"],
|
return objects.Task(deployment_uuid=deployment["uuid"],
|
||||||
tag=tag).to_dict()
|
tags=tags).to_dict()
|
||||||
|
|
||||||
@api_wrapper(path=API_REQUEST_PREFIX + "/task/validate",
|
@api_wrapper(path=API_REQUEST_PREFIX + "/task/validate",
|
||||||
method="GET")
|
method="GET")
|
||||||
@ -548,7 +548,7 @@ class _Task(APIGroup):
|
|||||||
|
|
||||||
@api_wrapper(path=API_REQUEST_PREFIX + "/task/import_results",
|
@api_wrapper(path=API_REQUEST_PREFIX + "/task/import_results",
|
||||||
method="POST")
|
method="POST")
|
||||||
def import_results(self, deployment, task_results, tag=None):
|
def import_results(self, deployment, task_results, tags=None):
|
||||||
"""Import json results of a test into rally database"""
|
"""Import json results of a test into rally database"""
|
||||||
deployment = objects.Deployment.get(deployment)
|
deployment = objects.Deployment.get(deployment)
|
||||||
if deployment["status"] != consts.DeployStatus.DEPLOY_FINISHED:
|
if deployment["status"] != consts.DeployStatus.DEPLOY_FINISHED:
|
||||||
@ -557,7 +557,8 @@ class _Task(APIGroup):
|
|||||||
uuid=deployment["uuid"],
|
uuid=deployment["uuid"],
|
||||||
status=deployment["status"])
|
status=deployment["status"])
|
||||||
|
|
||||||
task_inst = objects.Task(deployment_uuid=deployment["uuid"], tag=tag)
|
task_inst = objects.Task(deployment_uuid=deployment["uuid"],
|
||||||
|
tags=tags)
|
||||||
task_inst.update_status(consts.TaskStatus.RUNNING)
|
task_inst.update_status(consts.TaskStatus.RUNNING)
|
||||||
for result in task_results:
|
for result in task_results:
|
||||||
subtask_obj = task_inst.add_subtask(title=result["key"]["name"])
|
subtask_obj = task_inst.add_subtask(title=result["key"]["name"])
|
||||||
|
@ -194,7 +194,8 @@ class TaskCommands(object):
|
|||||||
help="Path to the file with input task args (dict in "
|
help="Path to the file with input task args (dict in "
|
||||||
"JSON/YAML). These args are used "
|
"JSON/YAML). These args are used "
|
||||||
"to render the Jinja2 template in the input task.")
|
"to render the Jinja2 template in the input task.")
|
||||||
@cliutils.args("--tag", help="Tag for this task")
|
@cliutils.args("--tag", nargs="+", dest="tags", type=str, required=False,
|
||||||
|
help="Mark the task with a tag or a few tags.")
|
||||||
@cliutils.args("--no-use", action="store_false", dest="do_use",
|
@cliutils.args("--no-use", action="store_false", dest="do_use",
|
||||||
help="Don't set new task as default for future operations.")
|
help="Don't set new task as default for future operations.")
|
||||||
@cliutils.args("--abort-on-sla-failure", action="store_true",
|
@cliutils.args("--abort-on-sla-failure", action="store_true",
|
||||||
@ -204,7 +205,7 @@ class TaskCommands(object):
|
|||||||
@envutils.with_default_deployment(cli_arg_name="deployment")
|
@envutils.with_default_deployment(cli_arg_name="deployment")
|
||||||
@plugins.ensure_plugins_are_loaded
|
@plugins.ensure_plugins_are_loaded
|
||||||
def start(self, api, task_file, deployment=None, task_args=None,
|
def start(self, api, task_file, deployment=None, task_args=None,
|
||||||
task_args_file=None, tag=None, do_use=False,
|
task_args_file=None, tags=None, do_use=False,
|
||||||
abort_on_sla_failure=False):
|
abort_on_sla_failure=False):
|
||||||
"""Start benchmark task.
|
"""Start benchmark task.
|
||||||
|
|
||||||
@ -221,26 +222,25 @@ class TaskCommands(object):
|
|||||||
used to render the Jinja2 template in
|
used to render the Jinja2 template in
|
||||||
the input task.
|
the input task.
|
||||||
:param deployment: UUID or name of the deployment
|
:param deployment: UUID or name of the deployment
|
||||||
:param tag: optional tag for this task
|
:param tags: optional tag for this task
|
||||||
:param do_use: if True, the new task will be stored as the default one
|
:param do_use: if True, the new task will be stored as the default one
|
||||||
for future operations
|
for future operations
|
||||||
:param abort_on_sla_failure: if True, the execution of a benchmark
|
:param abort_on_sla_failure: if True, the execution of a benchmark
|
||||||
scenario will stop when any SLA check
|
scenario will stop when any SLA check
|
||||||
for it fails
|
for it fails
|
||||||
"""
|
"""
|
||||||
|
|
||||||
input_task = self._load_and_validate_task(api, task_file,
|
input_task = self._load_and_validate_task(api, task_file,
|
||||||
raw_args=task_args,
|
raw_args=task_args,
|
||||||
args_file=task_args_file)
|
args_file=task_args_file)
|
||||||
print("Running Rally version", version.version_string())
|
print("Running Rally version", version.version_string())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
task_instance = api.task.create(deployment=deployment, tag=tag)
|
task_instance = api.task.create(deployment=deployment, tags=tags)
|
||||||
|
tags = "[tags: '%s']" % "', '".join(tags) if tags else ""
|
||||||
|
|
||||||
print(cliutils.make_header(
|
print(cliutils.make_header(
|
||||||
_("Task %(tag)s %(uuid)s: started")
|
_("Task %(tags)s %(uuid)s: started")
|
||||||
% {"uuid": task_instance["uuid"],
|
% {"uuid": task_instance["uuid"], "tags": tags}))
|
||||||
"tag": task_instance["tag"]}))
|
|
||||||
print("Benchmarking... This can take a while...\n")
|
print("Benchmarking... This can take a while...\n")
|
||||||
print("To track task status use:\n")
|
print("To track task status use:\n")
|
||||||
print("\trally task status\n\tor\n\trally task detailed\n")
|
print("\trally task status\n\tor\n\trally task detailed\n")
|
||||||
@ -498,11 +498,13 @@ 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("--tag", nargs="+", dest="tags", type=str, required=False,
|
||||||
|
help="Tags to filter tasks by.")
|
||||||
@cliutils.args("--uuids-only", action="store_true",
|
@cliutils.args("--uuids-only", action="store_true",
|
||||||
dest="uuids_only", help="List task UUIDs only.")
|
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, api, deployment=None, all_deployments=False, status=None,
|
def list(self, api, deployment=None, all_deployments=False, status=None,
|
||||||
uuids_only=False):
|
tags=None, uuids_only=False):
|
||||||
"""List tasks, started and finished.
|
"""List tasks, started and finished.
|
||||||
|
|
||||||
Displayed tasks can be filtered by status or deployment. By
|
Displayed tasks can be filtered by status or deployment. By
|
||||||
@ -518,10 +520,10 @@ class TaskCommands(object):
|
|||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
headers = ["uuid", "deployment_name", "created_at", "duration",
|
headers = ["uuid", "deployment_name", "created_at", "duration",
|
||||||
"status", "tag"]
|
"status", "tags"]
|
||||||
|
|
||||||
if status in consts.TaskStatus:
|
if status in consts.TaskStatus:
|
||||||
filters.setdefault("status", status)
|
filters["status"] = status
|
||||||
elif status:
|
elif status:
|
||||||
print(_("Error: Invalid task status '%s'.\n"
|
print(_("Error: Invalid task status '%s'.\n"
|
||||||
"Available statuses: %s") % (
|
"Available statuses: %s") % (
|
||||||
@ -530,7 +532,10 @@ class TaskCommands(object):
|
|||||||
return(1)
|
return(1)
|
||||||
|
|
||||||
if not all_deployments:
|
if not all_deployments:
|
||||||
filters.setdefault("deployment", deployment)
|
filters["deployment"] = deployment
|
||||||
|
|
||||||
|
if tags:
|
||||||
|
filters["tags"] = tags
|
||||||
|
|
||||||
task_list = api.task.list(**filters)
|
task_list = api.task.list(**filters)
|
||||||
|
|
||||||
@ -540,9 +545,16 @@ class TaskCommands(object):
|
|||||||
print_header=False,
|
print_header=False,
|
||||||
print_border=False)
|
print_border=False)
|
||||||
elif task_list:
|
elif task_list:
|
||||||
|
def tags_formatter(t):
|
||||||
|
if not t["tags"]:
|
||||||
|
return ""
|
||||||
|
return "'%s'" % "', '".join(t["tags"])
|
||||||
|
|
||||||
cliutils.print_list(
|
cliutils.print_list(
|
||||||
task_list,
|
task_list,
|
||||||
headers, sortby_index=headers.index("created_at"))
|
headers,
|
||||||
|
sortby_index=headers.index("created_at"),
|
||||||
|
formatters={"tags": tags_formatter})
|
||||||
else:
|
else:
|
||||||
if status:
|
if status:
|
||||||
print(_("There are no tasks in '%s' status. "
|
print(_("There are no tasks in '%s' status. "
|
||||||
@ -885,26 +897,26 @@ class TaskCommands(object):
|
|||||||
@cliutils.args("--deployment", dest="deployment", type=str,
|
@cliutils.args("--deployment", dest="deployment", type=str,
|
||||||
metavar="<uuid>", required=False,
|
metavar="<uuid>", required=False,
|
||||||
help="UUID or name of a deployment.")
|
help="UUID or name of a deployment.")
|
||||||
@cliutils.args("--tag", help="Tag for this task")
|
@cliutils.args("--tag", nargs="+", dest="tags", type=str, required=False,
|
||||||
|
help="Mark the task with a tag or a few tags.")
|
||||||
@envutils.with_default_deployment(cli_arg_name="deployment")
|
@envutils.with_default_deployment(cli_arg_name="deployment")
|
||||||
@cliutils.alias("import")
|
@cliutils.alias("import")
|
||||||
@cliutils.suppress_warnings
|
@cliutils.suppress_warnings
|
||||||
def import_results(self, api, deployment=None, task_file=None, tag=None):
|
def import_results(self, api, deployment=None, task_file=None, tags=None):
|
||||||
"""Import json results of a test into rally database
|
"""Import json results of a test into rally database
|
||||||
|
|
||||||
:param task_file: list, pathes files with tasks results
|
:param task_file: list, pathes files with tasks results
|
||||||
:param deployment: UUID or name of the deployment
|
:param deployment: UUID or name of the deployment
|
||||||
:param tag: optional tag for this task
|
:param tags: optional tag for this task
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if os.path.exists(os.path.expanduser(task_file)):
|
if os.path.exists(os.path.expanduser(task_file)):
|
||||||
tasks_results = self._load_task_results_file(api, task_file)
|
tasks_results = self._load_task_results_file(api, task_file)
|
||||||
task = api.task.import_results(deployment=deployment,
|
task = api.task.import_results(deployment=deployment,
|
||||||
task_results=tasks_results,
|
task_results=tasks_results,
|
||||||
tag=tag)
|
tags=tags)
|
||||||
print(_("Task UUID: %s.") % task["uuid"])
|
print(_("Task UUID: %s.") % task["uuid"])
|
||||||
else:
|
else:
|
||||||
print(_("ERROR: Invalid file name passed: %s"
|
print(_("ERROR: Invalid file name passed: %s") % task_file,
|
||||||
) % task_file,
|
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
@ -197,7 +197,7 @@ def task_update_status(task_uuid, status, allowed_statuses):
|
|||||||
status)
|
status)
|
||||||
|
|
||||||
|
|
||||||
def task_list(status=None, deployment=None):
|
def task_list(status=None, deployment=None, tags=None):
|
||||||
"""Get a list of tasks.
|
"""Get a list of tasks.
|
||||||
|
|
||||||
:param status: Task status to filter the returned list on. If set to
|
:param status: Task status to filter the returned list on. If set to
|
||||||
@ -205,9 +205,12 @@ def task_list(status=None, deployment=None):
|
|||||||
:param deployment: Deployment UUID to filter the returned list on.
|
:param deployment: Deployment UUID to filter the returned list on.
|
||||||
If set to None, tasks from all deployments will be
|
If set to None, tasks from all deployments will be
|
||||||
returned.
|
returned.
|
||||||
|
:param tags: A list of tags to filter tasks by.
|
||||||
:returns: A list of dicts with data on the tasks.
|
:returns: A list of dicts with data on the tasks.
|
||||||
"""
|
"""
|
||||||
return get_impl().task_list(status=status, deployment=deployment)
|
return get_impl().task_list(status=status,
|
||||||
|
deployment=deployment,
|
||||||
|
tags=tags)
|
||||||
|
|
||||||
|
|
||||||
def task_delete(uuid, status=None):
|
def task_delete(uuid, status=None):
|
||||||
|
@ -205,8 +205,7 @@ class Connection(object):
|
|||||||
return task
|
return task
|
||||||
|
|
||||||
def _make_old_task(self, task):
|
def _make_old_task(self, task):
|
||||||
tags = self._tags_get(task.uuid, consts.TagType.TASK)
|
tags = sorted(self._tags_get(task.uuid, consts.TagType.TASK))
|
||||||
tag = tags[0] if tags else ""
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": task.id,
|
"id": task.id,
|
||||||
@ -215,7 +214,7 @@ class Connection(object):
|
|||||||
"status": task.status,
|
"status": task.status,
|
||||||
"created_at": task.created_at,
|
"created_at": task.created_at,
|
||||||
"updated_at": task.updated_at,
|
"updated_at": task.updated_at,
|
||||||
"tag": tag,
|
"tags": tags,
|
||||||
"verification_log": json.dumps(task.validation_result)
|
"verification_log": json.dumps(task.validation_result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,9 +301,9 @@ class Connection(object):
|
|||||||
task["results"] = self._task_result_get_all_by_uuid(task["uuid"])
|
task["results"] = self._task_result_get_all_by_uuid(task["uuid"])
|
||||||
return task
|
return task
|
||||||
|
|
||||||
# @db_api.serialize
|
@db_api.serialize
|
||||||
def task_create(self, values):
|
def task_create(self, values):
|
||||||
new_tag = values.pop("tag", None)
|
tags = values.pop("tags", None)
|
||||||
# TODO(ikhudoshyn): currently 'input_task'
|
# TODO(ikhudoshyn): currently 'input_task'
|
||||||
# does not come in 'values'
|
# does not come in 'values'
|
||||||
# After completely switching to the new
|
# After completely switching to the new
|
||||||
@ -317,34 +316,32 @@ class Connection(object):
|
|||||||
task.update(values)
|
task.update(values)
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
if new_tag:
|
if tags:
|
||||||
tag = models.Tag()
|
for t in set(tags):
|
||||||
tag.update({
|
tag = models.Tag()
|
||||||
"uuid": task.uuid,
|
tag.update({"uuid": task.uuid,
|
||||||
"type": consts.TagType.TASK,
|
"type": consts.TagType.TASK,
|
||||||
"tag": new_tag
|
"tag": t})
|
||||||
})
|
tag.save()
|
||||||
tag.save()
|
task.tags = sorted(self._tags_get(task.uuid, consts.TagType.TASK))
|
||||||
|
return task
|
||||||
return self._make_old_task(task)
|
|
||||||
|
|
||||||
# @db_api.serialize
|
# @db_api.serialize
|
||||||
def task_update(self, uuid, values):
|
def task_update(self, uuid, values):
|
||||||
session = get_session()
|
session = get_session()
|
||||||
values.pop("uuid", None)
|
values.pop("uuid", None)
|
||||||
new_tag = values.pop("tag", None)
|
tags = values.pop("tags", None)
|
||||||
with session.begin():
|
with session.begin():
|
||||||
task = self._task_get(uuid, session=session)
|
task = self._task_get(uuid, session=session)
|
||||||
task.update(values)
|
task.update(values)
|
||||||
|
|
||||||
if new_tag:
|
if tags:
|
||||||
tag = models.Tag()
|
for t in set(tags):
|
||||||
tag.update({
|
tag = models.Tag()
|
||||||
"uuid": uuid,
|
tag.update({"uuid": task.uuid,
|
||||||
"type": consts.TagType.TASK,
|
"type": consts.TagType.TASK,
|
||||||
"tag": new_tag
|
"tag": t})
|
||||||
})
|
tag.save()
|
||||||
tag.save()
|
|
||||||
|
|
||||||
return self._make_old_task(task)
|
return self._make_old_task(task)
|
||||||
|
|
||||||
@ -365,18 +362,24 @@ class Connection(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
# @db_api.serialize
|
# @db_api.serialize
|
||||||
def task_list(self, status=None, deployment=None):
|
def task_list(self, status=None, deployment=None, tags=None):
|
||||||
query = self.model_query(models.Task)
|
session = get_session()
|
||||||
|
with session.begin():
|
||||||
|
query = self.model_query(models.Task)
|
||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
if status is not None:
|
if status is not None:
|
||||||
filters["status"] = status
|
filters["status"] = status
|
||||||
if deployment is not None:
|
if deployment is not None:
|
||||||
filters["deployment_uuid"] = self.deployment_get(
|
filters["deployment_uuid"] = self.deployment_get(
|
||||||
deployment)["uuid"]
|
deployment)["uuid"]
|
||||||
|
if filters:
|
||||||
|
query = query.filter_by(**filters)
|
||||||
|
|
||||||
if filters:
|
if tags:
|
||||||
query = query.filter_by(**filters)
|
uuids = self._uuids_by_tags_get(
|
||||||
|
consts.TagType.TASK, tags)
|
||||||
|
query = query.filter(models.Task.uuid.in_(uuids))
|
||||||
|
|
||||||
return [self._make_old_task(task) for task in query.all()]
|
return [self._make_old_task(task) for task in query.all()]
|
||||||
|
|
||||||
|
@ -406,8 +406,9 @@ class Task(object):
|
|||||||
return db.task_get_status(uuid)
|
return db.task_get_status(uuid)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list(status=None, deployment=None):
|
def list(status=None, deployment=None, tags=None):
|
||||||
return [Task(db_task) for db_task in db.task_list(status, deployment)]
|
return [Task(db_task) for db_task in db.task_list(
|
||||||
|
status, deployment=deployment, tags=tags)]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_by_uuid(uuid, status=None):
|
def delete_by_uuid(uuid, status=None):
|
||||||
|
@ -19,9 +19,11 @@ import os.path
|
|||||||
|
|
||||||
import ddt
|
import ddt
|
||||||
import mock
|
import mock
|
||||||
|
import six
|
||||||
|
|
||||||
import rally
|
import rally
|
||||||
from rally import api
|
from rally import api
|
||||||
|
from rally.cli import cliutils
|
||||||
from rally.cli.commands import task
|
from rally.cli.commands import task
|
||||||
from rally.common import yamlutils as yaml
|
from rally.common import yamlutils as yaml
|
||||||
from rally import consts
|
from rally import consts
|
||||||
@ -201,7 +203,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
mock_version):
|
mock_version):
|
||||||
deployment_id = "e0617de9-77d1-4875-9b49-9d5789e29f20"
|
deployment_id = "e0617de9-77d1-4875-9b49-9d5789e29f20"
|
||||||
task_path = "path_to_config.json"
|
task_path = "path_to_config.json"
|
||||||
fake_task = fakes.FakeTask(uuid="some_new_uuid", tag="tag")
|
fake_task = fakes.FakeTask(uuid="some_new_uuid", tags=["tag"])
|
||||||
self.fake_api.task.create.return_value = fake_task
|
self.fake_api.task.create.return_value = fake_task
|
||||||
self.fake_api.task.validate.return_value = fakes.FakeTask(
|
self.fake_api.task.validate.return_value = fakes.FakeTask(
|
||||||
some="json", uuid="some_uuid", temporary=True)
|
some="json", uuid="some_uuid", temporary=True)
|
||||||
@ -209,7 +211,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
self.task.start(self.fake_api, task_path, deployment_id, do_use=True)
|
self.task.start(self.fake_api, task_path, deployment_id, do_use=True)
|
||||||
mock_version.version_string.assert_called_once_with()
|
mock_version.version_string.assert_called_once_with()
|
||||||
self.fake_api.task.create.assert_called_once_with(
|
self.fake_api.task.create.assert_called_once_with(
|
||||||
deployment=deployment_id, tag=None)
|
deployment=deployment_id, tags=None)
|
||||||
self.fake_api.task.start.assert_called_once_with(
|
self.fake_api.task.start.assert_called_once_with(
|
||||||
deployment=deployment_id,
|
deployment=deployment_id,
|
||||||
config=mock__load_and_validate_task.return_value,
|
config=mock__load_and_validate_task.return_value,
|
||||||
@ -238,7 +240,8 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
status=consts.DeployStatus.DEPLOY_INIT)
|
status=consts.DeployStatus.DEPLOY_INIT)
|
||||||
self.fake_api.task.create.side_effect = exc
|
self.fake_api.task.create.side_effect = exc
|
||||||
self.assertEqual(1, self.task.start(self.fake_api, task_path,
|
self.assertEqual(1, self.task.start(self.fake_api, task_path,
|
||||||
deployment="any", tag="some_tag"))
|
deployment="any",
|
||||||
|
tags=["some_tag"]))
|
||||||
self.assertFalse(mock_detailed.called)
|
self.assertFalse(mock_detailed.called)
|
||||||
|
|
||||||
@mock.patch("rally.cli.commands.task.TaskCommands.detailed")
|
@mock.patch("rally.cli.commands.task.TaskCommands.detailed")
|
||||||
@ -246,9 +249,9 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
return_value="some_config")
|
return_value="some_config")
|
||||||
def test_start_with_task_args(self, mock__load_and_validate_task,
|
def test_start_with_task_args(self, mock__load_and_validate_task,
|
||||||
mock_detailed):
|
mock_detailed):
|
||||||
fake_task = fakes.FakeTask(uuid="new_uuid", tag="some_tag")
|
fake_task = fakes.FakeTask(uuid="new_uuid", tags=["some_tag"])
|
||||||
self.fake_api.task.create.return_value = fakes.FakeTask(
|
self.fake_api.task.create.return_value = fakes.FakeTask(
|
||||||
uuid="new_uuid", tag="some_tag")
|
uuid="new_uuid", tags=["some_tag"])
|
||||||
self.fake_api.task.validate.return_value = fakes.FakeTask(
|
self.fake_api.task.validate.return_value = fakes.FakeTask(
|
||||||
uuid="some_id")
|
uuid="some_id")
|
||||||
|
|
||||||
@ -257,7 +260,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
task_args_file = "task_args_file"
|
task_args_file = "task_args_file"
|
||||||
self.task.start(self.fake_api, task_path, deployment="any",
|
self.task.start(self.fake_api, task_path, deployment="any",
|
||||||
task_args=task_args, task_args_file=task_args_file,
|
task_args=task_args, task_args_file=task_args_file,
|
||||||
tag="some_tag")
|
tags=["some_tag"])
|
||||||
|
|
||||||
mock__load_and_validate_task.assert_called_once_with(
|
mock__load_and_validate_task.assert_called_once_with(
|
||||||
self.fake_api, task_path, raw_args=task_args,
|
self.fake_api, task_path, raw_args=task_args,
|
||||||
@ -272,7 +275,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
self.fake_api,
|
self.fake_api,
|
||||||
task_id=fake_task["uuid"])
|
task_id=fake_task["uuid"])
|
||||||
self.fake_api.task.create.assert_called_once_with(
|
self.fake_api.task.create.assert_called_once_with(
|
||||||
deployment="any", tag="some_tag")
|
deployment="any", tags=["some_tag"])
|
||||||
|
|
||||||
@mock.patch("rally.cli.commands.task.envutils.get_global")
|
@mock.patch("rally.cli.commands.task.envutils.get_global")
|
||||||
def test_start_no_deployment_id(self, mock_get_global):
|
def test_start_no_deployment_id(self, mock_get_global):
|
||||||
@ -292,7 +295,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(exceptions.InvalidTaskException,
|
self.assertRaises(exceptions.InvalidTaskException,
|
||||||
self.task.start, self.fake_api, "task_path",
|
self.task.start, self.fake_api, "task_path",
|
||||||
"deployment", tag="tag")
|
"deployment", tags=["tag"])
|
||||||
|
|
||||||
self.assertFalse(self.fake_api.task.create.called)
|
self.assertFalse(self.fake_api.task.create.called)
|
||||||
self.assertFalse(self.fake_api.task.start.called)
|
self.assertFalse(self.fake_api.task.start.called)
|
||||||
@ -304,10 +307,10 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(KeyError,
|
self.assertRaises(KeyError,
|
||||||
self.task.start, self.fake_api, "task_path",
|
self.task.start, self.fake_api, "task_path",
|
||||||
"deployment", tag="tag")
|
"deployment", tags=["tag"])
|
||||||
|
|
||||||
self.fake_api.task.create.assert_called_once_with(
|
self.fake_api.task.create.assert_called_once_with(
|
||||||
deployment="deployment", tag="tag")
|
deployment="deployment", tags=["tag"])
|
||||||
|
|
||||||
self.fake_api.task.start.assert_called_once_with(
|
self.fake_api.task.start.assert_called_once_with(
|
||||||
deployment="deployment", config=task_cfg,
|
deployment="deployment", config=task_cfg,
|
||||||
@ -835,7 +838,7 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
created_at=dt.datetime.now(),
|
created_at=dt.datetime.now(),
|
||||||
updated_at=dt.datetime.now(),
|
updated_at=dt.datetime.now(),
|
||||||
status="c",
|
status="c",
|
||||||
tag="d",
|
tags=["d"],
|
||||||
deployment_name="some_name")]
|
deployment_name="some_name")]
|
||||||
self.task.list(self.fake_api, status="running")
|
self.task.list(self.fake_api, status="running")
|
||||||
self.fake_api.task.list.assert_called_once_with(
|
self.fake_api.task.list.assert_called_once_with(
|
||||||
@ -843,11 +846,12 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
status=consts.TaskStatus.RUNNING)
|
status=consts.TaskStatus.RUNNING)
|
||||||
|
|
||||||
headers = ["uuid", "deployment_name", "created_at", "duration",
|
headers = ["uuid", "deployment_name", "created_at", "duration",
|
||||||
"status", "tag"]
|
"status", "tags"]
|
||||||
|
|
||||||
mock_print_list.assert_called_once_with(
|
mock_print_list.assert_called_once_with(
|
||||||
self.fake_api.task.list.return_value, headers,
|
self.fake_api.task.list.return_value, headers,
|
||||||
sortby_index=headers.index("created_at"))
|
sortby_index=headers.index("created_at"),
|
||||||
|
formatters=mock.ANY)
|
||||||
|
|
||||||
@mock.patch("rally.cli.commands.task.cliutils.print_list")
|
@mock.patch("rally.cli.commands.task.cliutils.print_list")
|
||||||
@mock.patch("rally.cli.commands.task.envutils.get_global",
|
@mock.patch("rally.cli.commands.task.envutils.get_global",
|
||||||
@ -884,6 +888,54 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
self.fake_api.task.list.assert_called_once_with(
|
self.fake_api.task.list.assert_called_once_with(
|
||||||
deployment="d", status=consts.TaskStatus.RUNNING)
|
deployment="d", status=consts.TaskStatus.RUNNING)
|
||||||
|
|
||||||
|
@mock.patch("rally.cli.commands.task.envutils.get_global",
|
||||||
|
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")]
|
||||||
|
|
||||||
|
# It is a hard task to mock default value of function argument, so we
|
||||||
|
# need to apply this workaround
|
||||||
|
original_print_list = cliutils.print_list
|
||||||
|
print_list_calls = []
|
||||||
|
|
||||||
|
def print_list(*args, **kwargs):
|
||||||
|
print_list_calls.append(six.StringIO())
|
||||||
|
kwargs["out"] = print_list_calls[-1]
|
||||||
|
original_print_list(*args, **kwargs)
|
||||||
|
|
||||||
|
with mock.patch.object(task.cliutils, "print_list",
|
||||||
|
new=print_list):
|
||||||
|
self.task.list(self.fake_api, status="running")
|
||||||
|
|
||||||
|
self.assertEqual(1, len(print_list_calls))
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"+--------+-----------------+---------------------"
|
||||||
|
"+----------------+----------+------------------+\n"
|
||||||
|
"| uuid | deployment_name | created_at "
|
||||||
|
"| duration | status | tags |\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",
|
||||||
|
print_list_calls[0].getvalue())
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
task_uuid = "8dcb9c5e-d60b-4022-8975-b5987c7833f7"
|
task_uuid = "8dcb9c5e-d60b-4022-8975-b5987c7833f7"
|
||||||
force = False
|
force = False
|
||||||
@ -1117,13 +1169,14 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.task.import_results(self.fake_api,
|
self.task.import_results(self.fake_api,
|
||||||
"deployment_uuid",
|
"deployment_uuid",
|
||||||
"task_file", "tag")
|
"task_file", tags=["tag"])
|
||||||
|
|
||||||
self.task._load_task_results_file.assert_called_once_with(
|
self.task._load_task_results_file.assert_called_once_with(
|
||||||
self.fake_api, "task_file"
|
self.fake_api, "task_file"
|
||||||
)
|
)
|
||||||
self.fake_api.task.import_results.assert_called_once_with(
|
self.fake_api.task.import_results.assert_called_once_with(
|
||||||
deployment="deployment_uuid", task_results=["results"], tag="tag")
|
deployment="deployment_uuid", task_results=["results"],
|
||||||
|
tags=["tag"])
|
||||||
|
|
||||||
# not exist
|
# not exist
|
||||||
mock_os_path.exists.return_value = False
|
mock_os_path.exists.return_value = False
|
||||||
@ -1131,5 +1184,5 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
1,
|
1,
|
||||||
self.task.import_results(self.fake_api,
|
self.task.import_results(self.fake_api,
|
||||||
"deployment_uuid",
|
"deployment_uuid",
|
||||||
"task_file", "tag")
|
"task_file", ["tag"])
|
||||||
)
|
)
|
||||||
|
@ -122,12 +122,12 @@ class TasksTestCase(test.DBTestCase):
|
|||||||
self.assertEqual(db_task["status"], consts.TaskStatus.INIT)
|
self.assertEqual(db_task["status"], consts.TaskStatus.INIT)
|
||||||
|
|
||||||
def test_task_create_with_tag(self):
|
def test_task_create_with_tag(self):
|
||||||
task = self._create_task(values={"tag": "test_tag"})
|
task = self._create_task(values={"tags": ["test_tag"]})
|
||||||
db_task = self._get_task(task["uuid"])
|
db_task = self._get_task(task["uuid"])
|
||||||
self.assertIsNotNone(db_task["uuid"])
|
self.assertIsNotNone(db_task["uuid"])
|
||||||
self.assertIsNotNone(db_task["id"])
|
self.assertIsNotNone(db_task["id"])
|
||||||
self.assertEqual(db_task["status"], consts.TaskStatus.INIT)
|
self.assertEqual(db_task["status"], consts.TaskStatus.INIT)
|
||||||
self.assertEqual(db_task["tag"], "test_tag")
|
self.assertEqual(db_task["tags"], ["test_tag"])
|
||||||
|
|
||||||
def test_task_create_without_uuid(self):
|
def test_task_create_without_uuid(self):
|
||||||
_uuid = "19be8589-48b0-4af1-a369-9bebaaa563ab"
|
_uuid = "19be8589-48b0-4af1-a369-9bebaaa563ab"
|
||||||
@ -145,11 +145,11 @@ class TasksTestCase(test.DBTestCase):
|
|||||||
task = self._create_task({})
|
task = self._create_task({})
|
||||||
db.task_update(task["uuid"], {
|
db.task_update(task["uuid"], {
|
||||||
"status": consts.TaskStatus.CRASHED,
|
"status": consts.TaskStatus.CRASHED,
|
||||||
"tag": "test_tag"
|
"tags": ["test_tag"]
|
||||||
})
|
})
|
||||||
db_task = self._get_task(task["uuid"])
|
db_task = self._get_task(task["uuid"])
|
||||||
self.assertEqual(db_task["status"], consts.TaskStatus.CRASHED)
|
self.assertEqual(db_task["status"], consts.TaskStatus.CRASHED)
|
||||||
self.assertEqual(db_task["tag"], "test_tag")
|
self.assertEqual(db_task["tags"], ["test_tag"])
|
||||||
|
|
||||||
def test_task_update_not_found(self):
|
def test_task_update_not_found(self):
|
||||||
self.assertRaises(exceptions.TaskNotFound,
|
self.assertRaises(exceptions.TaskNotFound,
|
||||||
@ -375,7 +375,7 @@ class TasksTestCase(test.DBTestCase):
|
|||||||
"trace": "foo t/b",
|
"trace": "foo t/b",
|
||||||
}
|
}
|
||||||
task1 = self._create_task({"validation_result": validation_result,
|
task1 = self._create_task({"validation_result": validation_result,
|
||||||
"tag": "bar"})
|
"tags": ["bar"]})
|
||||||
key = {
|
key = {
|
||||||
"name": "atata",
|
"name": "atata",
|
||||||
"description": "tatata",
|
"description": "tatata",
|
||||||
@ -408,7 +408,7 @@ class TasksTestCase(test.DBTestCase):
|
|||||||
task1_full = db.task_get_detailed(task1["uuid"])
|
task1_full = db.task_get_detailed(task1["uuid"])
|
||||||
self.assertEqual(validation_result,
|
self.assertEqual(validation_result,
|
||||||
json.loads(task1_full["verification_log"]))
|
json.loads(task1_full["verification_log"]))
|
||||||
self.assertEqual("bar", task1_full["tag"])
|
self.assertEqual(["bar"], task1_full["tags"])
|
||||||
results = task1_full["results"]
|
results = task1_full["results"]
|
||||||
self.assertEqual(1, len(results))
|
self.assertEqual(1, len(results))
|
||||||
self.assertEqual(key, results[0]["key"])
|
self.assertEqual(key, results[0]["key"])
|
||||||
|
@ -224,17 +224,18 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
self.assertEqual("2", self.task_inst.render_template(
|
self.assertEqual("2", self.task_inst.render_template(
|
||||||
task_template=template))
|
task_template=template))
|
||||||
|
|
||||||
@mock.patch("rally.common.objects.Deployment.get",
|
@mock.patch("rally.common.objects.Deployment.get")
|
||||||
return_value={
|
|
||||||
"uuid": "b0d9cd6c-2c94-4417-a238-35c7019d0257",
|
|
||||||
"status": consts.DeployStatus.DEPLOY_FINISHED})
|
|
||||||
@mock.patch("rally.common.objects.Task")
|
@mock.patch("rally.common.objects.Task")
|
||||||
def test_create(self, mock_task, mock_deployment_get):
|
def test_create(self, mock_task, mock_deployment_get):
|
||||||
tag = "a"
|
mock_deployment_get.return_value = {
|
||||||
|
"uuid": "b0d9cd6c-2c94-4417-a238-35c7019d0257",
|
||||||
|
"status": consts.DeployStatus.DEPLOY_FINISHED}
|
||||||
|
tags = ["a"]
|
||||||
self.task_inst.create(
|
self.task_inst.create(
|
||||||
deployment=mock_deployment_get.return_value["uuid"], tag=tag)
|
deployment=mock_deployment_get.return_value["uuid"], tags=tags)
|
||||||
mock_task.assert_called_once_with(
|
mock_task.assert_called_once_with(
|
||||||
deployment_uuid=mock_deployment_get.return_value["uuid"], tag=tag)
|
deployment_uuid=mock_deployment_get.return_value["uuid"],
|
||||||
|
tags=tags)
|
||||||
|
|
||||||
@mock.patch("rally.common.objects.Deployment.get",
|
@mock.patch("rally.common.objects.Deployment.get",
|
||||||
return_value={
|
return_value={
|
||||||
@ -243,10 +244,9 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
"status": consts.DeployStatus.DEPLOY_INIT})
|
"status": consts.DeployStatus.DEPLOY_INIT})
|
||||||
def test_create_on_unfinished_deployment(self, mock_deployment_get):
|
def test_create_on_unfinished_deployment(self, mock_deployment_get):
|
||||||
deployment_id = mock_deployment_get.return_value["uuid"]
|
deployment_id = mock_deployment_get.return_value["uuid"]
|
||||||
tag = "a"
|
|
||||||
self.assertRaises(exceptions.DeploymentNotFinishedStatus,
|
self.assertRaises(exceptions.DeploymentNotFinishedStatus,
|
||||||
self.task_inst.create, deployment=deployment_id,
|
self.task_inst.create, deployment=deployment_id,
|
||||||
tag=tag)
|
tags=["a"])
|
||||||
|
|
||||||
@mock.patch("rally.api.objects.Task")
|
@mock.patch("rally.api.objects.Task")
|
||||||
@mock.patch("rally.api.objects.Deployment.get")
|
@mock.patch("rally.api.objects.Deployment.get")
|
||||||
@ -489,7 +489,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
mock_task.assert_called_once_with(deployment_uuid="deployment_uuid",
|
mock_task.assert_called_once_with(deployment_uuid="deployment_uuid",
|
||||||
tag=None)
|
tags=None)
|
||||||
mock_task.return_value.update_status.assert_has_calls(
|
mock_task.return_value.update_status.assert_has_calls(
|
||||||
[mock.call(consts.TaskStatus.RUNNING),
|
[mock.call(consts.TaskStatus.RUNNING),
|
||||||
mock.call(consts.SubtaskStatus.FINISHED)]
|
mock.call(consts.SubtaskStatus.FINISHED)]
|
||||||
@ -536,7 +536,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
mock_task.assert_called_once_with(deployment_uuid="deployment_uuid",
|
mock_task.assert_called_once_with(deployment_uuid="deployment_uuid",
|
||||||
tag=None)
|
tags=None)
|
||||||
mock_task.return_value.update_status.assert_has_calls(
|
mock_task.return_value.update_status.assert_has_calls(
|
||||||
[mock.call(consts.TaskStatus.RUNNING),
|
[mock.call(consts.TaskStatus.RUNNING),
|
||||||
mock.call(consts.SubtaskStatus.FINISHED)]
|
mock.call(consts.SubtaskStatus.FINISHED)]
|
||||||
@ -575,7 +575,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
self.task_inst.import_results,
|
self.task_inst.import_results,
|
||||||
deployment="deployment_uuid",
|
deployment="deployment_uuid",
|
||||||
task_results=[],
|
task_results=[],
|
||||||
tag="tag")
|
tags=["tag"])
|
||||||
|
|
||||||
|
|
||||||
class BaseDeploymentTestCase(test.TestCase):
|
class BaseDeploymentTestCase(test.TestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user