Port inner stuff to the new task format
* use new format of a runner section
the schemas of existing plugins are changed to not include "type"
* use "contexts" key instead of "context"
note: the database model still operates the word "context". hope it
will be fixed soon while extendind abilities of contexts
* use new format of a hook section
Change-Id: I2ef6ba7a24b542fb001bce378cadf8c83c774b01
This commit is contained in:
@@ -523,6 +523,7 @@ class _Task(APIGroup):
|
|||||||
workload_obj = subtask_obj.add_workload(
|
workload_obj = subtask_obj.add_workload(
|
||||||
name=workload["name"], description=workload["description"],
|
name=workload["name"], description=workload["description"],
|
||||||
position=workload["position"], runner=workload["runner"],
|
position=workload["position"], runner=workload["runner"],
|
||||||
|
runner_type=workload["runner_type"],
|
||||||
context=workload["context"], hooks=workload["hooks"],
|
context=workload["context"], hooks=workload["hooks"],
|
||||||
sla=workload["sla"], args=workload["args"])
|
sla=workload["sla"], args=workload["args"])
|
||||||
chunk_size = CONF.raw_result_chunk_size
|
chunk_size = CONF.raw_result_chunk_size
|
||||||
|
|||||||
@@ -578,8 +578,17 @@ class TaskCommands(object):
|
|||||||
itr["atomic_actions"]).items()
|
itr["atomic_actions"]).items()
|
||||||
)
|
)
|
||||||
|
|
||||||
results = [
|
results = []
|
||||||
{
|
for w in itertools.chain(*[s["workloads"] for s in task["subtasks"]]):
|
||||||
|
w["runner"]["type"] = w["runner_type"]
|
||||||
|
hooks = [
|
||||||
|
{"name": h["config"]["action"][0],
|
||||||
|
"args": h["config"]["action"][1],
|
||||||
|
"description": h["config"].get("description"),
|
||||||
|
"trigger": {"name": h["config"]["trigger"][0],
|
||||||
|
"args": h["config"]["trigger"][1]}}
|
||||||
|
for h in w["hooks"]]
|
||||||
|
results.append({
|
||||||
"key": {
|
"key": {
|
||||||
"name": w["name"],
|
"name": w["name"],
|
||||||
"description": w["description"],
|
"description": w["description"],
|
||||||
@@ -589,7 +598,7 @@ class TaskCommands(object):
|
|||||||
"runner": w["runner"],
|
"runner": w["runner"],
|
||||||
"context": w["context"],
|
"context": w["context"],
|
||||||
"sla": w["sla"],
|
"sla": w["sla"],
|
||||||
"hooks": [r["config"] for r in w["hooks"]],
|
"hooks": hooks,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"result": w["data"],
|
"result": w["data"],
|
||||||
@@ -597,9 +606,7 @@ class TaskCommands(object):
|
|||||||
"hooks": w["hooks"],
|
"hooks": w["hooks"],
|
||||||
"load_duration": w["load_duration"],
|
"load_duration": w["load_duration"],
|
||||||
"full_duration": w["full_duration"],
|
"full_duration": w["full_duration"],
|
||||||
"created_at": w["created_at"]}
|
"created_at": w["created_at"]})
|
||||||
for w in itertools.chain(
|
|
||||||
*[s["workloads"] for s in task["subtasks"]])]
|
|
||||||
|
|
||||||
print(json.dumps(results, sort_keys=False, indent=4))
|
print(json.dumps(results, sort_keys=False, indent=4))
|
||||||
|
|
||||||
@@ -742,6 +749,13 @@ class TaskCommands(object):
|
|||||||
updated_at += dt.timedelta(seconds=result["full_duration"])
|
updated_at += dt.timedelta(seconds=result["full_duration"])
|
||||||
updated_at = updated_at.strftime(consts.TimeFormat.ISO8601)
|
updated_at = updated_at.strftime(consts.TimeFormat.ISO8601)
|
||||||
pass_sla = all(s.get("success") for s in result["sla"])
|
pass_sla = all(s.get("success") for s in result["sla"])
|
||||||
|
runner_type = result["key"]["kw"]["runner"].pop("type")
|
||||||
|
for h in result["hooks"]:
|
||||||
|
trigger = h["config"]["trigger"]
|
||||||
|
h["config"] = {
|
||||||
|
"description": h["config"].get("description"),
|
||||||
|
"action": (h["config"]["name"], h["config"]["args"]),
|
||||||
|
"trigger": (trigger["name"], trigger["args"])}
|
||||||
workload = {"uuid": "n/a",
|
workload = {"uuid": "n/a",
|
||||||
"name": result["key"]["name"],
|
"name": result["key"]["name"],
|
||||||
"position": result["key"]["pos"],
|
"position": result["key"]["pos"],
|
||||||
@@ -757,6 +771,7 @@ class TaskCommands(object):
|
|||||||
"created_at": result["created_at"],
|
"created_at": result["created_at"],
|
||||||
"updated_at": updated_at,
|
"updated_at": updated_at,
|
||||||
"args": result["key"]["kw"]["args"],
|
"args": result["key"]["kw"]["args"],
|
||||||
|
"runner_type": runner_type,
|
||||||
"runner": result["key"]["kw"]["runner"],
|
"runner": result["key"]["kw"]["runner"],
|
||||||
"hooks": result["hooks"],
|
"hooks": result["hooks"],
|
||||||
"sla": result["key"]["kw"]["sla"],
|
"sla": result["key"]["kw"]["sla"],
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""port-configs-to-new-formats
|
||||||
|
|
||||||
|
Revision ID: 046a38742e89
|
||||||
|
Revises: fab4f4f31f8a
|
||||||
|
Create Date: 2017-09-14 15:58:28.950132
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import json
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from rally import exceptions
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "046a38742e89"
|
||||||
|
down_revision = "fab4f4f31f8a"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
workload_helper = sa.Table(
|
||||||
|
"workloads",
|
||||||
|
sa.MetaData(),
|
||||||
|
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
|
||||||
|
sa.Column("uuid", sa.String(36), nullable=False),
|
||||||
|
|
||||||
|
sa.Column("runner", sa.Text),
|
||||||
|
sa.Column("hooks", sa.Text)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
connection = op.get_bind()
|
||||||
|
|
||||||
|
for workload in connection.execute(workload_helper.select()):
|
||||||
|
runner = json.loads(workload["runner"])
|
||||||
|
runner.pop("type")
|
||||||
|
values = {"runner": json.dumps(runner)}
|
||||||
|
hooks = workload["hooks"]
|
||||||
|
if hooks:
|
||||||
|
values["hooks"] = []
|
||||||
|
for hook in json.loads(hooks):
|
||||||
|
hook_cfg = hook["config"]
|
||||||
|
trigger_cfg = hook_cfg["trigger"]
|
||||||
|
hook["config"] = {
|
||||||
|
"description": hook_cfg.get("description"),
|
||||||
|
"action": (hook_cfg["name"], hook_cfg["args"]),
|
||||||
|
"trigger": (trigger_cfg["name"], trigger_cfg["args"])}
|
||||||
|
values["hooks"].append(hook)
|
||||||
|
values["hooks"] = json.dumps(values["hooks"])
|
||||||
|
connection.execute(workload_helper.update().where(
|
||||||
|
workload_helper.c.uuid == workload.uuid).values(
|
||||||
|
**values))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
raise exceptions.DowngradeNotSupported()
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import copy
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@@ -285,24 +284,27 @@ class Subtask(object):
|
|||||||
def update_status(self, status):
|
def update_status(self, status):
|
||||||
self._update({"status": status})
|
self._update({"status": status})
|
||||||
|
|
||||||
def add_workload(self, name, description, position, runner, context, hooks,
|
def add_workload(self, name, description, position, runner, runner_type,
|
||||||
sla, args):
|
context, hooks, sla, args):
|
||||||
|
# store hooks config as it will look after adding results
|
||||||
|
if hooks:
|
||||||
|
hooks = [{"config": hook} for hook in hooks]
|
||||||
return Workload(task_uuid=self.subtask["task_uuid"],
|
return Workload(task_uuid=self.subtask["task_uuid"],
|
||||||
subtask_uuid=self.subtask["uuid"], name=name,
|
subtask_uuid=self.subtask["uuid"], name=name,
|
||||||
description=description, position=position,
|
description=description, position=position,
|
||||||
runner=runner, hooks=hooks, context=context, sla=sla,
|
runner=runner, runner_type=runner_type, hooks=hooks,
|
||||||
args=args)
|
context=context, sla=sla, args=args)
|
||||||
|
|
||||||
|
|
||||||
class Workload(object):
|
class Workload(object):
|
||||||
"""Represents a workload object."""
|
"""Represents a workload object."""
|
||||||
|
|
||||||
def __init__(self, task_uuid, subtask_uuid, name, description, position,
|
def __init__(self, task_uuid, subtask_uuid, name, description, position,
|
||||||
runner, hooks, context, sla, args):
|
runner, runner_type, hooks, context, sla, args):
|
||||||
self.workload = db.workload_create(
|
self.workload = db.workload_create(
|
||||||
task_uuid=task_uuid, subtask_uuid=subtask_uuid, name=name,
|
task_uuid=task_uuid, subtask_uuid=subtask_uuid, name=name,
|
||||||
description=description, position=position, runner=runner,
|
description=description, position=position, runner=runner,
|
||||||
runner_type=runner["type"], hooks=hooks, context=context, sla=sla,
|
runner_type=runner_type, hooks=hooks, context=context, sla=sla,
|
||||||
args=args)
|
args=args)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
@@ -326,6 +328,11 @@ class Workload(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def to_task(cls, workload):
|
def to_task(cls, workload):
|
||||||
|
"""Format a single workload as a full Task to launch.
|
||||||
|
|
||||||
|
:param workload: A workload config as it stores in database or like in
|
||||||
|
input file (the difference in hook format).
|
||||||
|
"""
|
||||||
task = collections.OrderedDict()
|
task = collections.OrderedDict()
|
||||||
task["version"] = 2
|
task["version"] = 2
|
||||||
task["title"] = "A cropped version of a bigger task."
|
task["title"] = "A cropped version of a bigger task."
|
||||||
@@ -337,9 +344,22 @@ class Workload(object):
|
|||||||
subtask["title"] = workload["name"]
|
subtask["title"] = workload["name"]
|
||||||
subtask["description"] = workload["description"]
|
subtask["description"] = workload["description"]
|
||||||
subtask["scenario"] = {workload["name"]: workload["args"]}
|
subtask["scenario"] = {workload["name"]: workload["args"]}
|
||||||
|
# TODO(andreykurilin): fix database model as soon as the work related
|
||||||
|
# contexts execution stats will start.
|
||||||
|
if "context" in workload:
|
||||||
|
# it is an object from database
|
||||||
subtask["contexts"] = workload["context"]
|
subtask["contexts"] = workload["context"]
|
||||||
runner = copy.copy(workload["runner"])
|
else:
|
||||||
subtask["runner"] = {runner.pop("type"): runner}
|
subtask["contexts"] = workload["contexts"]
|
||||||
subtask["hooks"] = [h["config"] for h in workload["hooks"]]
|
subtask["runner"] = {workload["runner_type"]: workload["runner"]}
|
||||||
|
subtask["hooks"] = []
|
||||||
|
for hook in workload["hooks"]:
|
||||||
|
if "config" in hook:
|
||||||
|
# it is an object from database
|
||||||
|
hook = hook["config"]
|
||||||
|
subtask["hooks"].append({
|
||||||
|
"description": hook.get("description"),
|
||||||
|
"action": dict([hook["action"]]),
|
||||||
|
"trigger": dict([hook["trigger"]])})
|
||||||
subtask["sla"] = workload["sla"]
|
subtask["sla"] = workload["sla"]
|
||||||
return task
|
return task
|
||||||
|
|||||||
@@ -149,10 +149,6 @@ class ConstantScenarioRunner(runner.ScenarioRunner):
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"$schema": consts.JSON_SCHEMA,
|
"$schema": consts.JSON_SCHEMA,
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Type of Runner."
|
|
||||||
},
|
|
||||||
"concurrency": {
|
"concurrency": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
@@ -174,7 +170,6 @@ class ConstantScenarioRunner(runner.ScenarioRunner):
|
|||||||
" from."
|
" from."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type"],
|
|
||||||
"additionalProperties": False
|
"additionalProperties": False
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,10 +258,6 @@ class ConstantForDurationScenarioRunner(runner.ScenarioRunner):
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"$schema": consts.JSON_SCHEMA,
|
"$schema": consts.JSON_SCHEMA,
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Type of Runner."
|
|
||||||
},
|
|
||||||
"concurrency": {
|
"concurrency": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
@@ -284,7 +275,7 @@ class ConstantForDurationScenarioRunner(runner.ScenarioRunner):
|
|||||||
"description": "Operation's timeout."
|
"description": "Operation's timeout."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "duration"],
|
"required": ["duration"],
|
||||||
"additionalProperties": False
|
"additionalProperties": False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,9 +150,6 @@ class RPSScenarioRunner(runner.ScenarioRunner):
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"$schema": consts.JSON_SCHEMA,
|
"$schema": consts.JSON_SCHEMA,
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"times": {
|
"times": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1
|
"minimum": 1
|
||||||
@@ -205,7 +202,7 @@ class RPSScenarioRunner(runner.ScenarioRunner):
|
|||||||
"minimum": 1
|
"minimum": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["type", "times", "rps"],
|
"required": ["times", "rps"],
|
||||||
"additionalProperties": False
|
"additionalProperties": False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,6 @@ class SerialScenarioRunner(runner.ScenarioRunner):
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"$schema": consts.JSON_SCHEMA,
|
"$schema": consts.JSON_SCHEMA,
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"times": {
|
"times": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1
|
"minimum": 1
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class RequiredContextsValidator(validation.Validator):
|
|||||||
|
|
||||||
def validate(self, context, config, plugin_cls, plugin_cfg):
|
def validate(self, context, config, plugin_cls, plugin_cfg):
|
||||||
missing_contexts = []
|
missing_contexts = []
|
||||||
input_context = config.get("context", {})
|
input_context = config.get("contexts", {})
|
||||||
|
|
||||||
for name in self.contexts:
|
for name in self.contexts:
|
||||||
if isinstance(name, tuple):
|
if isinstance(name, tuple):
|
||||||
@@ -304,7 +304,7 @@ class RequiredParamOrContextValidator(validation.Validator):
|
|||||||
msg = ("You should specify either scenario argument %s or"
|
msg = ("You should specify either scenario argument %s or"
|
||||||
" use context %s." % (self.param_name, self.ctx_name))
|
" use context %s." % (self.param_name, self.ctx_name))
|
||||||
|
|
||||||
if self.ctx_name in config.get("context", {}):
|
if self.ctx_name in config.get("contexts", {}):
|
||||||
return
|
return
|
||||||
if self.param_name in config.get("args", {}):
|
if self.param_name in config.get("args", {}):
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class ImageExistsValidator(validation.Validator):
|
|||||||
if not image_args and self.nullable:
|
if not image_args and self.nullable:
|
||||||
return
|
return
|
||||||
|
|
||||||
image_context = config.get("context", {}).get("images", {})
|
image_context = config.get("contexts", {}).get("images", {})
|
||||||
image_ctx_name = image_context.get("image_name")
|
image_ctx_name = image_context.get("image_name")
|
||||||
|
|
||||||
if not image_args:
|
if not image_args:
|
||||||
@@ -162,11 +162,11 @@ class FlavorExistsValidator(validation.Validator):
|
|||||||
self.param_name = param_name
|
self.param_name = param_name
|
||||||
|
|
||||||
def _get_flavor_from_context(self, config, flavor_value):
|
def _get_flavor_from_context(self, config, flavor_value):
|
||||||
if "flavors" not in config.get("context", {}):
|
if "flavors" not in config.get("contexts", {}):
|
||||||
self.fail("No flavors context")
|
self.fail("No flavors context")
|
||||||
|
|
||||||
flavors = [flavors_ctx.FlavorConfig(**f)
|
flavors = [flavors_ctx.FlavorConfig(**f)
|
||||||
for f in config["context"]["flavors"]]
|
for f in config["contexts"]["flavors"]]
|
||||||
resource = types.obj_from_name(resource_config=flavor_value,
|
resource = types.obj_from_name(resource_config=flavor_value,
|
||||||
resources=flavors, typename="flavor")
|
resources=flavors, typename="flavor")
|
||||||
flavor = flavors_ctx.FlavorConfig(**resource)
|
flavor = flavors_ctx.FlavorConfig(**resource)
|
||||||
@@ -223,7 +223,7 @@ class ImageValidOnFlavorValidator(FlavorExistsValidator):
|
|||||||
self.validate_disk = validate_disk
|
self.validate_disk = validate_disk
|
||||||
|
|
||||||
def _get_validated_image(self, config, clients, param_name):
|
def _get_validated_image(self, config, clients, param_name):
|
||||||
image_context = config.get("context", {}).get("images", {})
|
image_context = config.get("contexts", {}).get("images", {})
|
||||||
image_args = config.get("args", {}).get(param_name)
|
image_args = config.get("args", {}).get(param_name)
|
||||||
image_ctx_name = image_context.get("image_name")
|
image_ctx_name = image_context.get("image_name")
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ class RequiredServicesValidator(validation.Validator):
|
|||||||
for service in self.services:
|
for service in self.services:
|
||||||
# NOTE(andreykurilin): validator should ignore services configured
|
# NOTE(andreykurilin): validator should ignore services configured
|
||||||
# via context(a proper validation should be in context)
|
# via context(a proper validation should be in context)
|
||||||
service_config = config.get("context", {}).get(
|
service_config = config.get("contexts", {}).get(
|
||||||
"api_versions@openstack", {}).get(service, {})
|
"api_versions@openstack", {}).get(service, {})
|
||||||
|
|
||||||
if (service not in available_services and
|
if (service not in available_services and
|
||||||
@@ -507,7 +507,7 @@ class RequiredAPIVersionsValidator(validation.Validator):
|
|||||||
"version": versions_str,
|
"version": versions_str,
|
||||||
"found_version": "3"})
|
"found_version": "3"})
|
||||||
else:
|
else:
|
||||||
av_ctx = config.get("context", {}).get(
|
av_ctx = config.get("contexts", {}).get(
|
||||||
"api_versions@openstack", {})
|
"api_versions@openstack", {})
|
||||||
default_version = getattr(clients,
|
default_version = getattr(clients,
|
||||||
self.component).choose_version()
|
self.component).choose_version()
|
||||||
@@ -540,10 +540,10 @@ class VolumeTypeExistsValidator(validation.Validator):
|
|||||||
def validate(self, context, config, plugin_cls, plugin_cfg):
|
def validate(self, context, config, plugin_cls, plugin_cfg):
|
||||||
volume_type = config.get("args", {}).get(self.param, False)
|
volume_type = config.get("args", {}).get(self.param, False)
|
||||||
|
|
||||||
if not volume_type and self.nullable:
|
if not volume_type:
|
||||||
|
if self.nullable:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not volume_type:
|
|
||||||
self.fail("The parameter '%s' is required and should not be empty."
|
self.fail("The parameter '%s' is required and should not be empty."
|
||||||
% self.param)
|
% self.param)
|
||||||
|
|
||||||
@@ -551,7 +551,7 @@ class VolumeTypeExistsValidator(validation.Validator):
|
|||||||
clients = user["credential"].clients()
|
clients = user["credential"].clients()
|
||||||
vt_names = [vt.name for vt in
|
vt_names = [vt.name for vt in
|
||||||
clients.cinder().volume_types.list()]
|
clients.cinder().volume_types.list()]
|
||||||
ctx = config.get("context", {}).get("volume_types", [])
|
ctx = config.get("contexts", {}).get("volume_types", [])
|
||||||
vt_names += ctx
|
vt_names += ctx
|
||||||
if volume_type not in vt_names:
|
if volume_type not in vt_names:
|
||||||
self.fail("Specified volume type %s not found for user %s."
|
self.fail("Specified volume type %s not found for user %s."
|
||||||
|
|||||||
@@ -276,15 +276,15 @@ class TaskEngine(object):
|
|||||||
plugin_cfg=None,
|
plugin_cfg=None,
|
||||||
vtype=vtype))
|
vtype=vtype))
|
||||||
|
|
||||||
if workload["runner"]:
|
if workload["runner_type"]:
|
||||||
results.extend(runner.ScenarioRunner.validate(
|
results.extend(runner.ScenarioRunner.validate(
|
||||||
name=workload["runner"]["type"],
|
name=workload["runner_type"],
|
||||||
context=vcontext,
|
context=vcontext,
|
||||||
config=None,
|
config=None,
|
||||||
plugin_cfg=workload["runner"],
|
plugin_cfg=workload["runner"],
|
||||||
vtype=vtype))
|
vtype=vtype))
|
||||||
|
|
||||||
for context_name, context_conf in workload["context"].items():
|
for context_name, context_conf in workload["contexts"].items():
|
||||||
results.extend(context.Context.validate(
|
results.extend(context.Context.validate(
|
||||||
name=context_name,
|
name=context_name,
|
||||||
context=vcontext,
|
context=vcontext,
|
||||||
@@ -310,8 +310,7 @@ class TaskEngine(object):
|
|||||||
vtype=vtype))
|
vtype=vtype))
|
||||||
|
|
||||||
for hook_conf in workload["hooks"]:
|
for hook_conf in workload["hooks"]:
|
||||||
action_name, action_cfg = list(
|
action_name, action_cfg = hook_conf["action"]
|
||||||
hook_conf["config"]["action"].items())[0]
|
|
||||||
results.extend(hook.HookAction.validate(
|
results.extend(hook.HookAction.validate(
|
||||||
name=action_name,
|
name=action_name,
|
||||||
context=vcontext,
|
context=vcontext,
|
||||||
@@ -319,8 +318,7 @@ class TaskEngine(object):
|
|||||||
plugin_cfg=action_cfg,
|
plugin_cfg=action_cfg,
|
||||||
vtype=vtype))
|
vtype=vtype))
|
||||||
|
|
||||||
trigger_name, trigger_cfg = list(
|
trigger_name, trigger_cfg = hook_conf["trigger"]
|
||||||
hook_conf["config"]["trigger"].items())[0]
|
|
||||||
results.extend(hook.HookTrigger.validate(
|
results.extend(hook.HookTrigger.validate(
|
||||||
name=trigger_name,
|
name=trigger_name,
|
||||||
context=vcontext,
|
context=vcontext,
|
||||||
@@ -461,8 +459,9 @@ class TaskEngine(object):
|
|||||||
description=workload["description"],
|
description=workload["description"],
|
||||||
position=workload["position"],
|
position=workload["position"],
|
||||||
runner=workload["runner"],
|
runner=workload["runner"],
|
||||||
|
runner_type=workload["runner_type"],
|
||||||
hooks=workload["hooks"],
|
hooks=workload["hooks"],
|
||||||
context=workload["context"],
|
context=workload["contexts"],
|
||||||
sla=workload["sla"],
|
sla=workload["sla"],
|
||||||
args=workload["args"])
|
args=workload["args"])
|
||||||
workload["uuid"] = workload_obj["uuid"]
|
workload["uuid"] = workload_obj["uuid"]
|
||||||
@@ -474,10 +473,10 @@ class TaskEngine(object):
|
|||||||
% {"position": workload["position"],
|
% {"position": workload["position"],
|
||||||
"cfg": json.dumps(workload_cfg, indent=3)})
|
"cfg": json.dumps(workload_cfg, indent=3)})
|
||||||
|
|
||||||
runner_cls = runner.ScenarioRunner.get(workload["runner"]["type"])
|
runner_cls = runner.ScenarioRunner.get(workload["runner_type"])
|
||||||
runner_obj = runner_cls(self.task, workload["runner"])
|
runner_obj = runner_cls(self.task, workload["runner"])
|
||||||
context_obj = self._prepare_context(
|
context_obj = self._prepare_context(
|
||||||
workload["context"], workload["name"], workload_obj["uuid"])
|
workload["contexts"], workload["name"], workload_obj["uuid"])
|
||||||
try:
|
try:
|
||||||
with ResultConsumer(workload, self.task, subtask_obj, workload_obj,
|
with ResultConsumer(workload, self.task, subtask_obj, workload_obj,
|
||||||
runner_obj, self.abort_on_sla_failure):
|
runner_obj, self.abort_on_sla_failure):
|
||||||
@@ -746,14 +745,15 @@ class TaskConfig(object):
|
|||||||
# validation step
|
# validation step
|
||||||
pass
|
pass
|
||||||
|
|
||||||
wconf["context"] = wconf.pop("contexts", {})
|
wconf.setdefault("contexts", {})
|
||||||
|
|
||||||
if "runner" in wconf:
|
if "runner" in wconf:
|
||||||
runner_type, runner_cfg = list(wconf["runner"].items())[0]
|
runner = list(wconf["runner"].items())[0]
|
||||||
runner_cfg["type"] = runner_type
|
wconf["runner_type"], wconf["runner"] = runner
|
||||||
wconf["runner"] = runner_cfg
|
|
||||||
else:
|
else:
|
||||||
wconf["runner"] = {"serial": {}}
|
wconf["runner_type"] = "serial"
|
||||||
|
wconf["runner"] = {}
|
||||||
|
|
||||||
wconf.setdefault("sla", {"failure_rate": {"max": 0}})
|
wconf.setdefault("sla", {"failure_rate": {"max": 0}})
|
||||||
|
|
||||||
hooks = wconf.get("hooks", [])
|
hooks = wconf.get("hooks", [])
|
||||||
@@ -764,14 +764,17 @@ class TaskConfig(object):
|
|||||||
"Check task format documentation for more "
|
"Check task format documentation for more "
|
||||||
"details.")
|
"details.")
|
||||||
trigger_cfg = hook_cfg["trigger"]
|
trigger_cfg = hook_cfg["trigger"]
|
||||||
wconf["hooks"].append({"config": {
|
wconf["hooks"].append({
|
||||||
"description": hook_cfg["description"],
|
"description": hook_cfg["description"],
|
||||||
"action": {hook_cfg["name"]: hook_cfg["args"]},
|
"action": (hook_cfg["name"], hook_cfg["args"]),
|
||||||
"trigger": {
|
"trigger": (
|
||||||
trigger_cfg["name"]: trigger_cfg["args"]}}
|
trigger_cfg["name"], trigger_cfg["args"])})
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
wconf["hooks"].append({"config": hook_cfg})
|
hook_cfg["action"] = list(
|
||||||
|
hook_cfg["action"].items())[0]
|
||||||
|
hook_cfg["trigger"] = list(
|
||||||
|
hook_cfg["trigger"].items())[0]
|
||||||
|
wconf["hooks"].append(hook_cfg)
|
||||||
|
|
||||||
workloads.append(wconf)
|
workloads.append(wconf)
|
||||||
sconf["workloads"] = workloads
|
sconf["workloads"] = workloads
|
||||||
@@ -815,7 +818,7 @@ class TaskConfig(object):
|
|||||||
for hook_cfg in hooks:
|
for hook_cfg in hooks:
|
||||||
trigger_cfg = hook_cfg["trigger"]
|
trigger_cfg = hook_cfg["trigger"]
|
||||||
subtask["hooks"].append(
|
subtask["hooks"].append(
|
||||||
{"description": hook_cfg["description"],
|
{"description": hook_cfg.get("description"),
|
||||||
"action": {
|
"action": {
|
||||||
hook_cfg["name"]: hook_cfg["args"]},
|
hook_cfg["name"]: hook_cfg["args"]},
|
||||||
"trigger": {
|
"trigger": {
|
||||||
|
|||||||
@@ -43,10 +43,9 @@ class HookExecutor(object):
|
|||||||
self.task = task
|
self.task = task
|
||||||
|
|
||||||
self.triggers = collections.defaultdict(list)
|
self.triggers = collections.defaultdict(list)
|
||||||
for hook in config.get("hooks", []):
|
for hook_cfg in config.get("hooks", []):
|
||||||
hook_cfg = hook["config"]
|
action_name = hook_cfg["action"][0]
|
||||||
action_name = list(hook_cfg["action"].keys())[0]
|
trigger_name = hook_cfg["trigger"][0]
|
||||||
trigger_name = list(hook_cfg["trigger"].keys())[0]
|
|
||||||
action_cls = HookAction.get(action_name)
|
action_cls = HookAction.get(action_name)
|
||||||
trigger_obj = HookTrigger.get(
|
trigger_obj = HookTrigger.get(
|
||||||
trigger_name)(hook_cfg, self.task, action_cls)
|
trigger_name)(hook_cfg, self.task, action_cls)
|
||||||
@@ -216,7 +215,7 @@ class HookTrigger(plugin.Plugin, validation.ValidatablePluginMixin):
|
|||||||
|
|
||||||
def __init__(self, hook_cfg, task, hook_cls):
|
def __init__(self, hook_cfg, task, hook_cls):
|
||||||
self.hook_cfg = hook_cfg
|
self.hook_cfg = hook_cfg
|
||||||
self.config = self.hook_cfg["trigger"][self.get_name()]
|
self.config = self.hook_cfg["trigger"][1]
|
||||||
self.task = task
|
self.task = task
|
||||||
self.hook_cls = hook_cls
|
self.hook_cls = hook_cls
|
||||||
self._runs = []
|
self._runs = []
|
||||||
@@ -230,7 +229,7 @@ class HookTrigger(plugin.Plugin, validation.ValidatablePluginMixin):
|
|||||||
LOG.info("Hook action %s is triggered for Task %s by %s=%s"
|
LOG.info("Hook action %s is triggered for Task %s by %s=%s"
|
||||||
% (self.hook_cls.get_name(), self.task["uuid"],
|
% (self.hook_cls.get_name(), self.task["uuid"],
|
||||||
event_type, value))
|
event_type, value))
|
||||||
action_cfg = list(self.hook_cfg["action"].values())[0]
|
action_cfg = self.hook_cfg["action"][1]
|
||||||
action = self.hook_cls(self.task, action_cfg,
|
action = self.hook_cls(self.task, action_cfg,
|
||||||
{"event_type": event_type, "value": value})
|
{"event_type": event_type, "value": value})
|
||||||
action.run_async()
|
action.run_async()
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import copy
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import hashlib
|
import hashlib
|
||||||
import itertools
|
import itertools
|
||||||
@@ -33,7 +32,7 @@ def _process_hooks(hooks):
|
|||||||
"""Prepare hooks data for report."""
|
"""Prepare hooks data for report."""
|
||||||
hooks_ctx = []
|
hooks_ctx = []
|
||||||
for hook in hooks:
|
for hook in hooks:
|
||||||
hook_ctx = {"name": list(hook["config"]["action"].keys())[0],
|
hook_ctx = {"name": hook["config"]["action"][0],
|
||||||
"desc": hook["config"].get("description", ""),
|
"desc": hook["config"].get("description", ""),
|
||||||
"additive": [], "complete": []}
|
"additive": [], "complete": []}
|
||||||
|
|
||||||
@@ -138,7 +137,7 @@ def _process_workload(workload, workload_cfg, pos):
|
|||||||
"met": method,
|
"met": method,
|
||||||
"pos": str(pos),
|
"pos": str(pos),
|
||||||
"name": method + (pos and " [%d]" % (pos + 1) or ""),
|
"name": method + (pos and " [%d]" % (pos + 1) or ""),
|
||||||
"runner": workload["runner"]["type"],
|
"runner": workload["runner_type"],
|
||||||
"config": json.dumps(workload_cfg, indent=2),
|
"config": json.dumps(workload_cfg, indent=2),
|
||||||
"hooks": _process_hooks(workload["hooks"]),
|
"hooks": _process_hooks(workload["hooks"]),
|
||||||
"description": workload.get("description", ""),
|
"description": workload.get("description", ""),
|
||||||
@@ -212,8 +211,8 @@ def _make_source(tasks):
|
|||||||
workload_cfg["scenario"] = {workload["name"]: workload["args"]}
|
workload_cfg["scenario"] = {workload["name"]: workload["args"]}
|
||||||
workload_cfg["description"] = workload["description"]
|
workload_cfg["description"] = workload["description"]
|
||||||
workload_cfg["contexts"] = workload["context"]
|
workload_cfg["contexts"] = workload["context"]
|
||||||
runner = copy.copy(workload["runner"])
|
workload_cfg["runner"] = {
|
||||||
workload_cfg["runner"] = {runner.pop("type"): runner}
|
workload["runner_type"]: workload["runner"]}
|
||||||
workload_cfg["hooks"] = [h["config"]
|
workload_cfg["hooks"] = [h["config"]
|
||||||
for h in workload["hooks"]]
|
for h in workload["hooks"]]
|
||||||
workload_cfg["sla"] = workload["sla"]
|
workload_cfg["sla"] = workload["sla"]
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class Trigger(hook.HookTrigger):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def context(self):
|
def context(self):
|
||||||
action_name, action_cfg = list(self.hook_cfg["action"].items())[0]
|
action_name, action_cfg = self.hook_cfg["action"]
|
||||||
trigger_name, trigger_cfg = list(self.hook_cfg["trigger"].items())[0]
|
trigger_name, trigger_cfg = self.hook_cfg["trigger"]
|
||||||
return {"description": self.hook_cfg["description"],
|
return {"description": self.hook_cfg["description"],
|
||||||
"name": action_name,
|
"name": action_name,
|
||||||
"args": action_cfg,
|
"args": action_cfg,
|
||||||
|
|||||||
@@ -553,7 +553,8 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
"name": "Foo.bar", "description": "descr",
|
"name": "Foo.bar", "description": "descr",
|
||||||
"position": 2,
|
"position": 2,
|
||||||
"args": {"key1": "value1"},
|
"args": {"key1": "value1"},
|
||||||
"runner": {"type": "rruunneerr"},
|
"runner_type": "rruunneerr",
|
||||||
|
"runner": {"arg1": "args2"},
|
||||||
"hooks": [],
|
"hooks": [],
|
||||||
"sla": {"failure_rate": {"max": 0}},
|
"sla": {"failure_rate": {"max": 0}},
|
||||||
"sla_results": {"sla": [{"success": True}]},
|
"sla_results": {"sla": [{"success": True}]},
|
||||||
@@ -565,10 +566,16 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
task_id = "foo_task_id"
|
task_id = "foo_task_id"
|
||||||
|
|
||||||
task_obj = self._make_task(data=[{"atomic_actions": {"foo": 1.1}}])
|
task_obj = self._make_task(data=[{"atomic_actions": {"foo": 1.1}}])
|
||||||
|
|
||||||
|
def fix_r(workload):
|
||||||
|
cfg = workload["runner"]
|
||||||
|
cfg["type"] = workload["runner_type"]
|
||||||
|
return cfg
|
||||||
|
|
||||||
result = map(lambda x: {"key": {"kw": {"sla": x["sla"],
|
result = map(lambda x: {"key": {"kw": {"sla": x["sla"],
|
||||||
"args": x["args"],
|
"args": x["args"],
|
||||||
"context": x["context"],
|
"context": x["context"],
|
||||||
"runner": x["runner"],
|
"runner": fix_r(x),
|
||||||
"hooks": x["hooks"]},
|
"hooks": x["hooks"]},
|
||||||
"pos": x["position"],
|
"pos": x["position"],
|
||||||
"name": x["name"],
|
"name": x["name"],
|
||||||
@@ -1089,7 +1096,8 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
"subtasks": [{"workloads": [{
|
"subtasks": [{"workloads": [{
|
||||||
"name": "fake_name",
|
"name": "fake_name",
|
||||||
"position": "fake_pos",
|
"position": "fake_pos",
|
||||||
"args": {}, "runner": {}, "context": {}, "sla": {},
|
"args": {}, "runner_type": "foo",
|
||||||
|
"runner": {}, "context": {}, "sla": {},
|
||||||
"hooks": {},
|
"hooks": {},
|
||||||
"load_duration": 3.2,
|
"load_duration": 3.2,
|
||||||
"full_duration": 3.5,
|
"full_duration": 3.5,
|
||||||
@@ -1181,8 +1189,12 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
"name": "Foo.bar", "description": "descr",
|
"name": "Foo.bar", "description": "descr",
|
||||||
"position": 2,
|
"position": 2,
|
||||||
"args": {"key1": "value1"},
|
"args": {"key1": "value1"},
|
||||||
"runner": {"type": "rruunneerr"},
|
"runner_type": "constant",
|
||||||
"hooks": [{"config": {"type": "hookk"}}],
|
"runner": {"time": 3},
|
||||||
|
"hooks": [{"config": {
|
||||||
|
"description": "descr",
|
||||||
|
"action": ("foo", {"arg1": "v1"}),
|
||||||
|
"trigger": ("t", {"a2", "v2"})}}],
|
||||||
"pass_sla": True,
|
"pass_sla": True,
|
||||||
"sla": {"failure_rate": {"max": 0}},
|
"sla": {"failure_rate": {"max": 0}},
|
||||||
"sla_results": {"sla": [{"success": True}]},
|
"sla_results": {"sla": [{"success": True}]},
|
||||||
@@ -1196,14 +1208,25 @@ class TaskCommandsTestCase(test.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
results = [
|
results = [
|
||||||
{"hooks": workload["hooks"],
|
{"hooks": [{"config": {
|
||||||
|
"name": "foo",
|
||||||
|
"args": {"arg1": "v1"},
|
||||||
|
"description": "descr",
|
||||||
|
"trigger": {"name": "t",
|
||||||
|
"args": {"a2", "v2"}}}}],
|
||||||
"key": {"name": workload["name"],
|
"key": {"name": workload["name"],
|
||||||
"description": workload["description"],
|
"description": workload["description"],
|
||||||
"pos": workload["position"],
|
"pos": workload["position"],
|
||||||
"kw": {
|
"kw": {
|
||||||
"args": workload["args"],
|
"args": workload["args"],
|
||||||
"runner": workload["runner"],
|
"runner": {"type": "constant", "time": 3},
|
||||||
"hooks": [h["config"] for h in workload["hooks"]],
|
"hooks": [{"name": "foo",
|
||||||
|
"args": {"arg1": "v1"},
|
||||||
|
"description": "descr",
|
||||||
|
"trigger": {
|
||||||
|
"name": "t",
|
||||||
|
"args": {"a2", "v2"}
|
||||||
|
}}],
|
||||||
"sla": workload["sla"],
|
"sla": workload["sla"],
|
||||||
"context": workload["context"]}},
|
"context": workload["context"]}},
|
||||||
"sla": workload["sla_results"]["sla"],
|
"sla": workload["sla_results"]["sla"],
|
||||||
|
|||||||
@@ -1965,3 +1965,135 @@ class MigrationWalkTestCase(rtest.DBTestCase,
|
|||||||
conn.execute(
|
conn.execute(
|
||||||
deployment_table.delete().where(
|
deployment_table.delete().where(
|
||||||
deployment_table.c.uuid == deployment_uuid))
|
deployment_table.c.uuid == deployment_uuid))
|
||||||
|
|
||||||
|
def _pre_upgrade_046a38742e89(self, engine):
|
||||||
|
deployment_table = db_utils.get_table(engine, "deployments")
|
||||||
|
task_table = db_utils.get_table(engine, "tasks")
|
||||||
|
subtask_table = db_utils.get_table(engine, "subtasks")
|
||||||
|
workload_table = db_utils.get_table(engine, "workloads")
|
||||||
|
|
||||||
|
self._046a38742e89_deployment_uuid = str(uuid.uuid4())
|
||||||
|
self._046a38742e89_task_uuid = str(uuid.uuid4())
|
||||||
|
subtask_uuid = str(uuid.uuid4())
|
||||||
|
workloads = [
|
||||||
|
{
|
||||||
|
"runner": {"type": "constant",
|
||||||
|
"times": 1000}},
|
||||||
|
{
|
||||||
|
"runner": {"type": "rps",
|
||||||
|
"rps": 300},
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"config": {"args": {"arg1": "v1"},
|
||||||
|
"description": "descr",
|
||||||
|
"name": "foo",
|
||||||
|
"trigger": {"name": "bar",
|
||||||
|
"args": {"arg2": "v2"}}}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
with engine.connect() as conn:
|
||||||
|
conn.execute(
|
||||||
|
deployment_table.insert(),
|
||||||
|
[{
|
||||||
|
"uuid": self._046a38742e89_deployment_uuid,
|
||||||
|
"name": str(uuid.uuid4()),
|
||||||
|
"config": "{}",
|
||||||
|
"enum_deployments_status": consts.DeployStatus.DEPLOY_INIT,
|
||||||
|
"credentials": six.b(json.dumps([])),
|
||||||
|
"users": six.b(json.dumps([]))
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
task_table.insert(),
|
||||||
|
[{
|
||||||
|
"uuid": self._046a38742e89_task_uuid,
|
||||||
|
"created_at": timeutils.utcnow(),
|
||||||
|
"updated_at": timeutils.utcnow(),
|
||||||
|
"status": consts.TaskStatus.FINISHED,
|
||||||
|
"validation_result": six.b(json.dumps({})),
|
||||||
|
"deployment_uuid": self._046a38742e89_deployment_uuid
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
subtask_table.insert(),
|
||||||
|
[{
|
||||||
|
"uuid": subtask_uuid,
|
||||||
|
"created_at": timeutils.utcnow(),
|
||||||
|
"updated_at": timeutils.utcnow(),
|
||||||
|
"task_uuid": self._046a38742e89_task_uuid,
|
||||||
|
"context": six.b(json.dumps([])),
|
||||||
|
"sla": six.b(json.dumps([])),
|
||||||
|
"run_in_parallel": False
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
for workload in workloads:
|
||||||
|
conn.execute(
|
||||||
|
workload_table.insert(),
|
||||||
|
[{
|
||||||
|
"uuid": str(uuid.uuid4()),
|
||||||
|
"name": "foo",
|
||||||
|
"task_uuid": self._046a38742e89_task_uuid,
|
||||||
|
"subtask_uuid": subtask_uuid,
|
||||||
|
"created_at": timeutils.utcnow(),
|
||||||
|
"updated_at": timeutils.utcnow(),
|
||||||
|
"position": 0,
|
||||||
|
"runner": json.dumps(workload["runner"]),
|
||||||
|
"runner_type": "",
|
||||||
|
"context": "",
|
||||||
|
"context_execution": "",
|
||||||
|
"statistics": "",
|
||||||
|
"hooks": json.dumps(workload.get("hooks", "")),
|
||||||
|
"sla": "",
|
||||||
|
"sla_results": "",
|
||||||
|
"args": "",
|
||||||
|
"load_duration": 0,
|
||||||
|
"pass_sla": True,
|
||||||
|
"min_duration": 0,
|
||||||
|
"max_duration": 1
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
|
||||||
|
def _check_046a38742e89(self, engine, data):
|
||||||
|
deployment_table = db_utils.get_table(engine, "deployments")
|
||||||
|
task_table = db_utils.get_table(engine, "tasks")
|
||||||
|
subtask_table = db_utils.get_table(engine, "subtasks")
|
||||||
|
workload_table = db_utils.get_table(engine, "workloads")
|
||||||
|
|
||||||
|
subtask_uuid = None
|
||||||
|
|
||||||
|
with engine.connect() as conn:
|
||||||
|
task_uuid = self._046a38742e89_task_uuid
|
||||||
|
for workload in conn.execute(workload_table.select().where(
|
||||||
|
workload_table.c.task_uuid == task_uuid)).fetchall():
|
||||||
|
if subtask_uuid is None:
|
||||||
|
subtask_uuid = workload.subtask_uuid
|
||||||
|
|
||||||
|
runner = json.loads(workload.runner)
|
||||||
|
self.assertNotIn("type", runner)
|
||||||
|
|
||||||
|
hooks = json.loads(workload.hooks)
|
||||||
|
if hooks:
|
||||||
|
for hook in hooks:
|
||||||
|
hook_cfg = hook["config"]
|
||||||
|
self.assertEqual(2, len(hook_cfg["action"]))
|
||||||
|
self.assertEqual(2, len(hook_cfg["trigger"]))
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
workload_table.delete().where(
|
||||||
|
workload_table.c.uuid == workload.uuid))
|
||||||
|
conn.execute(
|
||||||
|
subtask_table.delete().where(
|
||||||
|
subtask_table.c.uuid == subtask_uuid))
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
task_table.delete().where(task_table.c.uuid == task_uuid))
|
||||||
|
|
||||||
|
deployment_uuid = self._046a38742e89_deployment_uuid
|
||||||
|
conn.execute(
|
||||||
|
deployment_table.delete().where(
|
||||||
|
deployment_table.c.uuid == deployment_uuid))
|
||||||
|
|||||||
@@ -311,21 +311,24 @@ class SubtaskTestCase(test.TestCase):
|
|||||||
name = "w"
|
name = "w"
|
||||||
description = "descr"
|
description = "descr"
|
||||||
position = 0
|
position = 0
|
||||||
runner = {"type": "runner"}
|
runner_type = "runner"
|
||||||
|
runner = {}
|
||||||
context = {"users": {}}
|
context = {"users": {}}
|
||||||
sla = {"failure_rate": {"max": 0}}
|
sla = {"failure_rate": {"max": 0}}
|
||||||
args = {"arg": "xxx"}
|
args = {"arg": "xxx"}
|
||||||
hooks = [{"config": {"foo": "bar"}}]
|
hooks = [{"foo": "bar"}]
|
||||||
|
|
||||||
workload = subtask.add_workload(name, description=description,
|
workload = subtask.add_workload(
|
||||||
position=position, runner=runner,
|
name, description=description, position=position,
|
||||||
context=context, sla=sla, args=args,
|
runner_type=runner_type, runner=runner, context=context, sla=sla,
|
||||||
hooks=hooks)
|
args=args, hooks=hooks)
|
||||||
mock_workload.assert_called_once_with(
|
mock_workload.assert_called_once_with(
|
||||||
task_uuid=self.subtask["task_uuid"],
|
task_uuid=self.subtask["task_uuid"],
|
||||||
subtask_uuid=self.subtask["uuid"], name=name,
|
subtask_uuid=self.subtask["uuid"], name=name,
|
||||||
description=description, position=position, runner=runner,
|
description=description, position=position,
|
||||||
context=context, sla=sla, args=args, hooks=hooks)
|
runner_type=runner_type, runner=runner,
|
||||||
|
context=context, sla=sla, args=args,
|
||||||
|
hooks=[{"config": h} for h in hooks])
|
||||||
self.assertIs(workload, mock_workload.return_value)
|
self.assertIs(workload, mock_workload.return_value)
|
||||||
|
|
||||||
|
|
||||||
@@ -345,14 +348,16 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
name = "w"
|
name = "w"
|
||||||
description = "descr"
|
description = "descr"
|
||||||
position = 0
|
position = 0
|
||||||
runner = {"type": "constant"}
|
runner_type = "constant"
|
||||||
|
runner = {"times": 3}
|
||||||
context = {"users": {}}
|
context = {"users": {}}
|
||||||
sla = {"failure_rate": {"max": 0}}
|
sla = {"failure_rate": {"max": 0}}
|
||||||
args = {"arg": "xxx"}
|
args = {"arg": "xxx"}
|
||||||
hooks = [{"config": {"foo": "bar"}}]
|
hooks = [{"config": {"foo": "bar"}}]
|
||||||
workload = objects.Workload("uuid1", "uuid2", name=name,
|
workload = objects.Workload("uuid1", "uuid2", name=name,
|
||||||
description=description, position=position,
|
description=description, position=position,
|
||||||
runner=runner, context=context, sla=sla,
|
runner=runner, runner_type=runner_type,
|
||||||
|
context=context, sla=sla,
|
||||||
args=args, hooks=hooks)
|
args=args, hooks=hooks)
|
||||||
mock_workload_create.assert_called_once_with(
|
mock_workload_create.assert_called_once_with(
|
||||||
task_uuid="uuid1", subtask_uuid="uuid2", name=name, hooks=hooks,
|
task_uuid="uuid1", subtask_uuid="uuid2", name=name, hooks=hooks,
|
||||||
@@ -367,7 +372,7 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
mock_workload_create.return_value = self.workload
|
mock_workload_create.return_value = self.workload
|
||||||
workload = objects.Workload("uuid1", "uuid2", name="w",
|
workload = objects.Workload("uuid1", "uuid2", name="w",
|
||||||
description="descr", position=0,
|
description="descr", position=0,
|
||||||
runner={"type": "foo"}, context=None,
|
runner_type="foo", runner={}, context=None,
|
||||||
sla=None, args=None, hooks=[])
|
sla=None, args=None, hooks=[])
|
||||||
|
|
||||||
workload.add_workload_data(0, {"data": "foo"})
|
workload.add_workload_data(0, {"data": "foo"})
|
||||||
@@ -383,7 +388,8 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
name = "w"
|
name = "w"
|
||||||
description = "descr"
|
description = "descr"
|
||||||
position = 0
|
position = 0
|
||||||
runner = {"type": "constant"}
|
runner_type = "constant"
|
||||||
|
runner = {"times": 3}
|
||||||
context = {"users": {}}
|
context = {"users": {}}
|
||||||
sla = {"failure_rate": {"max": 0}}
|
sla = {"failure_rate": {"max": 0}}
|
||||||
args = {"arg": "xxx"}
|
args = {"arg": "xxx"}
|
||||||
@@ -394,8 +400,9 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
hooks = []
|
hooks = []
|
||||||
workload = objects.Workload("uuid1", "uuid2", name=name,
|
workload = objects.Workload("uuid1", "uuid2", name=name,
|
||||||
description=description, position=position,
|
description=description, position=position,
|
||||||
runner=runner, context=context, sla=sla,
|
runner=runner, runner_type=runner_type,
|
||||||
args=args, hooks=hooks)
|
context=context, sla=sla, args=args,
|
||||||
|
hooks=hooks)
|
||||||
|
|
||||||
workload.set_results(load_duration=load_duration,
|
workload.set_results(load_duration=load_duration,
|
||||||
full_duration=full_duration,
|
full_duration=full_duration,
|
||||||
@@ -417,11 +424,15 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
"name": "Foo.bar",
|
"name": "Foo.bar",
|
||||||
"description": "Make something useful (or not).",
|
"description": "Make something useful (or not).",
|
||||||
"position": 3,
|
"position": 3,
|
||||||
"runner": {"type": "constant", "times": 3},
|
"runner_type": "constant",
|
||||||
"context": {"users": {}},
|
"runner": {"times": 3},
|
||||||
|
"contexts": {"users": {}},
|
||||||
"sla": {"failure_rate": {"max": 0}},
|
"sla": {"failure_rate": {"max": 0}},
|
||||||
"args": {"key1": "value1"},
|
"args": {"key1": "value1"},
|
||||||
"hooks": [{"config": {"hook1": "xxx"}}],
|
"hooks": [{"config": {
|
||||||
|
"action": ["foo", {"arg1": "v1"}],
|
||||||
|
"trigger": ["bar", {"arg2": "v2"}]
|
||||||
|
}}],
|
||||||
"sla_results": {"sla": []},
|
"sla_results": {"sla": []},
|
||||||
"context_execution": {},
|
"context_execution": {},
|
||||||
"start_time": "2997.23.12",
|
"start_time": "2997.23.12",
|
||||||
@@ -444,8 +455,10 @@ class WorkloadTestCase(test.TestCase):
|
|||||||
("title", workload["name"]),
|
("title", workload["name"]),
|
||||||
("description", workload["description"]),
|
("description", workload["description"]),
|
||||||
("scenario", {workload["name"]: workload["args"]}),
|
("scenario", {workload["name"]: workload["args"]}),
|
||||||
("contexts", workload["context"]),
|
("contexts", workload["contexts"]),
|
||||||
("runner", {"constant": {"times": 3}}),
|
("runner", {"constant": {"times": 3}}),
|
||||||
("hooks", [h["config"] for h in workload["hooks"]]),
|
("hooks", [{"action": {"foo": {"arg1": "v1"}},
|
||||||
|
"trigger": {"bar": {"arg2": "v2"}},
|
||||||
|
"description": None}]),
|
||||||
("sla", workload["sla"])])])])
|
("sla", workload["sla"])])])])
|
||||||
self.assertEqual(expected_task, objects.Workload.to_task(workload))
|
self.assertEqual(expected_task, objects.Workload.to_task(workload))
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class EventTriggerTestCase(test.TestCase):
|
|||||||
super(EventTriggerTestCase, self).setUp()
|
super(EventTriggerTestCase, self).setUp()
|
||||||
self.hook_cls = mock.MagicMock(__name__="name")
|
self.hook_cls = mock.MagicMock(__name__="name")
|
||||||
self.trigger = event.EventTrigger(
|
self.trigger = event.EventTrigger(
|
||||||
{"trigger": {"event": {"unit": "iteration", "at": [1, 4, 5]}},
|
{"trigger": ("event", {"unit": "iteration", "at": [1, 4, 5]}),
|
||||||
"action": {"foo": {}}},
|
"action": ("foo", {})},
|
||||||
mock.MagicMock(), self.hook_cls)
|
mock.MagicMock(), self.hook_cls)
|
||||||
|
|
||||||
@ddt.data((dict(unit="time", at=[0, 3, 5]), True),
|
@ddt.data((dict(unit="time", at=[0, 3, 5]), True),
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class PeriodicTriggerTestCase(test.TestCase):
|
|||||||
super(PeriodicTriggerTestCase, self).setUp()
|
super(PeriodicTriggerTestCase, self).setUp()
|
||||||
self.hook_cls = mock.MagicMock(__name__="name")
|
self.hook_cls = mock.MagicMock(__name__="name")
|
||||||
self.trigger = periodic.PeriodicTrigger(
|
self.trigger = periodic.PeriodicTrigger(
|
||||||
{"trigger": {"periodic": {"unit": "iteration", "step": 2}},
|
{"trigger": ("periodic", {"unit": "iteration", "step": 2}),
|
||||||
"action": {"foo": {}}},
|
"action": ("foo", {})},
|
||||||
mock.MagicMock(), self.hook_cls)
|
mock.MagicMock(), self.hook_cls)
|
||||||
|
|
||||||
@ddt.data((dict(unit="time", step=1), True),
|
@ddt.data((dict(unit="time", step=1), True),
|
||||||
@@ -74,9 +74,9 @@ class PeriodicTriggerTestCase(test.TestCase):
|
|||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
def test_on_event_start_end(self, value, should_call):
|
def test_on_event_start_end(self, value, should_call):
|
||||||
trigger = periodic.PeriodicTrigger(
|
trigger = periodic.PeriodicTrigger(
|
||||||
{"trigger": {"periodic": {"unit": "time",
|
{"trigger": ("periodic", {"unit": "time",
|
||||||
"step": 3, "start": 2, "end": 9}},
|
"step": 3, "start": 2, "end": 9}),
|
||||||
"action": {"foo": {}}},
|
"action": ("foo", {})},
|
||||||
mock.MagicMock(), self.hook_cls)
|
mock.MagicMock(), self.hook_cls)
|
||||||
trigger.on_event("time", value)
|
trigger.on_event("time", value)
|
||||||
self.assertEqual(should_call, self.hook_cls.called)
|
self.assertEqual(should_call, self.hook_cls.called)
|
||||||
|
|||||||
@@ -38,11 +38,13 @@ class ConstantScenarioRunnerTestCase(test.TestCase):
|
|||||||
self.args = {"a": 1}
|
self.args = {"a": 1}
|
||||||
self.task = mock.MagicMock()
|
self.task = mock.MagicMock()
|
||||||
|
|
||||||
@ddt.data(({"times": 4, "concurrency": 2,
|
@ddt.data(({"times": 4,
|
||||||
"timeout": 2, "type": "constant",
|
"concurrency": 2,
|
||||||
|
"timeout": 2,
|
||||||
"max_cpu_count": 2}, True),
|
"max_cpu_count": 2}, True),
|
||||||
({"times": 4, "concurrency": 5,
|
({"times": 4,
|
||||||
"timeout": 2, "type": "constant",
|
"concurrency": 5,
|
||||||
|
"timeout": 2,
|
||||||
"max_cpu_count": 2}, False),
|
"max_cpu_count": 2}, False),
|
||||||
({"foo": "bar"}, False))
|
({"foo": "bar"}, False))
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
@@ -267,8 +269,9 @@ class ConstantForDurationScenarioRunnerTestCase(test.TestCase):
|
|||||||
self.context["iteration"] = 14
|
self.context["iteration"] = 14
|
||||||
self.args = {"a": 1}
|
self.args = {"a": 1}
|
||||||
|
|
||||||
@ddt.data(({"duration": 0, "concurrency": 2,
|
@ddt.data(({"duration": 0,
|
||||||
"timeout": 2, "type": "constant_for_duration"}, True),
|
"concurrency": 2,
|
||||||
|
"timeout": 2}, True),
|
||||||
({"foo": "bar"}, False))
|
({"foo": "bar"}, False))
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
def test_validate(self, config, valid):
|
def test_validate(self, config, valid):
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
@ddt.data(
|
@ddt.data(
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 1,
|
"start": 1,
|
||||||
"end": 3,
|
"end": 3,
|
||||||
@@ -47,7 +46,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 1,
|
"start": 1,
|
||||||
"end": 10,
|
"end": 10,
|
||||||
@@ -58,7 +56,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 1,
|
"start": 1,
|
||||||
"end": 2,
|
"end": 2,
|
||||||
@@ -69,7 +66,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 2,
|
"start": 2,
|
||||||
"end": 1,
|
"end": 1,
|
||||||
@@ -81,7 +77,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 2,
|
"start": 2,
|
||||||
"end": 1,
|
"end": 1,
|
||||||
@@ -93,7 +88,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"times": 1,
|
"times": 1,
|
||||||
"rps": 100,
|
"rps": 100,
|
||||||
"max_concurrency": 50,
|
"max_concurrency": 50,
|
||||||
@@ -103,14 +97,12 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": 0.000001
|
"rps": 0.000001
|
||||||
},
|
},
|
||||||
"valid": False
|
"valid": False
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": {
|
"rps": {
|
||||||
"start": 1,
|
"start": 1,
|
||||||
"end": 10,
|
"end": 10,
|
||||||
@@ -121,7 +113,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": 0,
|
"rps": 0,
|
||||||
"times": 55
|
"times": 55
|
||||||
},
|
},
|
||||||
@@ -129,7 +120,6 @@ class RPSScenarioRunnerTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"type": "rps",
|
|
||||||
"rps": 2,
|
"rps": 2,
|
||||||
"times": 55,
|
"times": 55,
|
||||||
"foo": "bar"
|
"foo": "bar"
|
||||||
|
|||||||
@@ -247,8 +247,8 @@ class RequiredContextsValidatorTestCase(test.TestCase):
|
|||||||
"users": [mock.MagicMock()], })
|
"users": [mock.MagicMock()], })
|
||||||
|
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
{"config": {"context": {"c1": 1, "c2": 2, "c3": 3}}},
|
{"config": {"contexts": {"c1": 1, "c2": 2, "c3": 3}}},
|
||||||
{"config": {"context": {"c1": 1, "c2": 2, "c3": 3, "a": 1}}}
|
{"config": {"contexts": {"c1": 1, "c2": 2, "c3": 3, "a": 1}}}
|
||||||
)
|
)
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
def test_validate(self, config):
|
def test_validate(self, config):
|
||||||
@@ -261,15 +261,18 @@ class RequiredContextsValidatorTestCase(test.TestCase):
|
|||||||
contexts=("c1", "c2", "c3"))
|
contexts=("c1", "c2", "c3"))
|
||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
validation.ValidationError,
|
validation.ValidationError,
|
||||||
validator.validate, self.credentials, {"context": {"a": 1}},
|
validator.validate, self.credentials, {"contexts": {"a": 1}},
|
||||||
None, None)
|
None, None)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"The following context(s) are required but missing from "
|
"The following context(s) are required but missing from "
|
||||||
"the input task file: c1, c2, c3", e.message)
|
"the input task file: c1, c2, c3", e.message)
|
||||||
|
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
{"config": {"context": {"c1": 1, "c2": 2, "c3": 3, "b1": 1, "a1": 1}}},
|
{"config": {
|
||||||
{"config": {"context": {"c1": 1, "c2": 2, "c3": 3,
|
"contexts": {"c1": 1, "c2": 2, "c3": 3,
|
||||||
|
"b1": 1, "a1": 1}}},
|
||||||
|
{"config": {
|
||||||
|
"contexts": {"c1": 1, "c2": 2, "c3": 3,
|
||||||
"b1": 1, "b2": 2, "a1": 1}}},
|
"b1": 1, "b2": 2, "a1": 1}}},
|
||||||
)
|
)
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
@@ -284,7 +287,7 @@ class RequiredContextsValidatorTestCase(test.TestCase):
|
|||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
validation.ValidationError,
|
validation.ValidationError,
|
||||||
validator.validate, self.credentials,
|
validator.validate, self.credentials,
|
||||||
{"context": {"c1": 1, "c2": 2}}, None, None)
|
{"contexts": {"c1": 1, "c2": 2}}, None, None)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"The following context(s) are required but missing "
|
"The following context(s) are required but missing "
|
||||||
"from the input task file: 'a1 or a2', 'b1 or b2'", e.message)
|
"from the input task file: 'a1 or a2', 'b1 or b2'", e.message)
|
||||||
@@ -302,20 +305,20 @@ class RequiredParamOrContextValidatorTestCase(test.TestCase):
|
|||||||
|
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
{"config": {"args": {"image": {"name": ""}},
|
{"config": {"args": {"image": {"name": ""}},
|
||||||
"context": {"custom_image": {"name": "fake_image"}}}},
|
"contexts": {"custom_image": {"name": "fake_image"}}}},
|
||||||
{"config": {"context": {"custom_image": {"name": "fake_image"}}}},
|
{"config": {"contexts": {"custom_image": {"name": "fake_image"}}}},
|
||||||
{"config": {"args": {"image": {"name": "fake_image"}},
|
{"config": {"args": {"image": {"name": "fake_image"}},
|
||||||
"context": {"custom_image": ""}}},
|
"contexts": {"custom_image": ""}}},
|
||||||
{"config": {"args": {"image": {"name": "fake_image"}}}},
|
{"config": {"args": {"image": {"name": "fake_image"}}}},
|
||||||
{"config": {"args": {"image": {"name": ""}},
|
{"config": {"args": {"image": {"name": ""}},
|
||||||
"context": {"custom_image": {"name": ""}}}}
|
"contexts": {"custom_image": {"name": ""}}}}
|
||||||
)
|
)
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
def test_validate(self, config):
|
def test_validate(self, config):
|
||||||
self.validator.validate(self.credentials, config, None, None)
|
self.validator.validate(self.credentials, config, None, None)
|
||||||
|
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
{"config": {"args": {}, "context": {}},
|
{"config": {"args": {}, "contexts": {}},
|
||||||
"err_msg": "You should specify either scenario argument image or "
|
"err_msg": "You should specify either scenario argument image or "
|
||||||
"use context custom_image."},
|
"use context custom_image."},
|
||||||
{"config": {},
|
{"config": {},
|
||||||
|
|||||||
@@ -85,20 +85,19 @@ class ImageExistsValidatorTestCase(test.TestCase):
|
|||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_validator_image_from_context(self):
|
def test_validator_image_from_context(self):
|
||||||
config = {"args": {
|
config = {
|
||||||
"image": {"regex": r"^foo$"}}, "context": {
|
"args": {"image": {"regex": r"^foo$"}},
|
||||||
"images": {
|
"contexts": {"images": {"image_name": "foo"}}}
|
||||||
"image_name": "foo"}}}
|
|
||||||
|
|
||||||
self.validator.validate(self.context, config, None, None)
|
self.validator.validate(self.context, config, None, None)
|
||||||
|
|
||||||
@mock.patch("%s.openstack_types.GlanceImage.transform" % PATH,
|
@mock.patch("%s.openstack_types.GlanceImage.transform" % PATH,
|
||||||
return_value="image_id")
|
return_value="image_id")
|
||||||
def test_validator_image_not_in_context(self, mock_glance_image_transform):
|
def test_validator_image_not_in_context(self, mock_glance_image_transform):
|
||||||
config = {"args": {
|
config = {
|
||||||
"image": "fake_image"}, "context": {
|
"args": {"image": "fake_image"},
|
||||||
"images": {
|
"contexts": {
|
||||||
"fake_image_name": "foo"}}}
|
"images": {"fake_image_name": "foo"}}}
|
||||||
|
|
||||||
clients = self.context[
|
clients = self.context[
|
||||||
"users"][0]["credential"].clients.return_value
|
"users"][0]["credential"].clients.return_value
|
||||||
@@ -266,7 +265,7 @@ class FlavorExistsValidatorTestCase(test.TestCase):
|
|||||||
def test__get_flavor_from_context(self, mock_flavor_config,
|
def test__get_flavor_from_context(self, mock_flavor_config,
|
||||||
mock_obj_from_name):
|
mock_obj_from_name):
|
||||||
config = {
|
config = {
|
||||||
"context": {"images": {"fake_parameter_name": "foo_image"}}}
|
"contexts": {"images": {"fake_parameter_name": "foo_image"}}}
|
||||||
|
|
||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
validators.validation.ValidationError,
|
validators.validation.ValidationError,
|
||||||
@@ -274,7 +273,7 @@ class FlavorExistsValidatorTestCase(test.TestCase):
|
|||||||
config, "foo_flavor")
|
config, "foo_flavor")
|
||||||
self.assertEqual("No flavors context", e.message)
|
self.assertEqual("No flavors context", e.message)
|
||||||
|
|
||||||
config = {"context": {"images": {"fake_parameter_name": "foo_image"},
|
config = {"contexts": {"images": {"fake_parameter_name": "foo_image"},
|
||||||
"flavors": [{"flavor1": "fake_flavor1"}]}}
|
"flavors": [{"flavor1": "fake_flavor1"}]}}
|
||||||
result = self.validator._get_flavor_from_context(config, "foo_flavor")
|
result = self.validator._get_flavor_from_context(config, "foo_flavor")
|
||||||
self.assertEqual("<context flavor: %s>" % result.name, result.id)
|
self.assertEqual("<context flavor: %s>" % result.name, result.id)
|
||||||
@@ -457,11 +456,12 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
|
|||||||
"min_disk": 0
|
"min_disk": 0
|
||||||
}
|
}
|
||||||
# Get image name from context
|
# Get image name from context
|
||||||
result = self.validator._get_validated_image({"args": {
|
result = self.validator._get_validated_image({
|
||||||
"image": {"regex": r"^foo$"}}, "context": {
|
"args": {
|
||||||
"images": {
|
"image": {"regex": r"^foo$"}},
|
||||||
"image_name": "foo"}
|
"contexts": {
|
||||||
}}, mock.Mock(), "image")
|
"images": {"image_name": "foo"}}},
|
||||||
|
mock.Mock(), "image")
|
||||||
self.assertEqual(image, result)
|
self.assertEqual(image, result)
|
||||||
|
|
||||||
clients = mock.Mock()
|
clients = mock.Mock()
|
||||||
@@ -819,7 +819,7 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
|
|||||||
clients = self.context["users"][0]["credential"].clients()
|
clients = self.context["users"][0]["credential"].clients()
|
||||||
|
|
||||||
clients.nova.choose_version.return_value = nova
|
clients.nova.choose_version.return_value = nova
|
||||||
config = {"context": {"api_versions@openstack": {}}}
|
config = {"contexts": {"api_versions@openstack": {}}}
|
||||||
|
|
||||||
if err_msg:
|
if err_msg:
|
||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
@@ -839,7 +839,7 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
|
|||||||
[version])
|
[version])
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"context": {"api_versions@openstack": {"nova": {"version": 2}}}}
|
"contexts": {"api_versions@openstack": {"nova": {"version": 2}}}}
|
||||||
|
|
||||||
if err_msg:
|
if err_msg:
|
||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
@@ -890,7 +890,7 @@ class VolumeTypeExistsValidatorTestCase(test.TestCase):
|
|||||||
clients = self.context["users"][0]["credential"].clients()
|
clients = self.context["users"][0]["credential"].clients()
|
||||||
clients.cinder().volume_types.list.return_value = []
|
clients.cinder().volume_types.list.return_value = []
|
||||||
ctx = {"args": {"volume_type": "fake_type"},
|
ctx = {"args": {"volume_type": "fake_type"},
|
||||||
"context": {"volume_types": ["fake_type"]}}
|
"contexts": {"volume_types": ["fake_type"]}}
|
||||||
result = self.validator.validate(self.context, ctx, None, None)
|
result = self.validator.validate(self.context, ctx, None, None)
|
||||||
|
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
@@ -899,7 +899,7 @@ class VolumeTypeExistsValidatorTestCase(test.TestCase):
|
|||||||
clients = self.context["users"][0]["credential"].clients()
|
clients = self.context["users"][0]["credential"].clients()
|
||||||
clients.cinder().volume_types.list.return_value = []
|
clients.cinder().volume_types.list.return_value = []
|
||||||
config = {"args": {"volume_type": "fake_type"},
|
config = {"args": {"volume_type": "fake_type"},
|
||||||
"context": {"volume_types": ["fake_type_2"]}}
|
"contexts": {"volume_types": ["fake_type_2"]}}
|
||||||
e = self.assertRaises(
|
e = self.assertRaises(
|
||||||
validators.validation.ValidationError,
|
validators.validation.ValidationError,
|
||||||
self.validator.validate, self.context, config, None, None)
|
self.validator.validate, self.context, config, None, None)
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
"sla_results": {"sla": {}}, "pass_sla": True,
|
"sla_results": {"sla": {}}, "pass_sla": True,
|
||||||
"position": 0,
|
"position": 0,
|
||||||
"name": "Foo.bar", "description": "Description!!",
|
"name": "Foo.bar", "description": "Description!!",
|
||||||
"runner": {"type": "constant"},
|
"runner_type": "constant",
|
||||||
|
"runner": {},
|
||||||
"statistics": {"atomics": {
|
"statistics": {"atomics": {
|
||||||
"foo_action": {"max_duration": 19, "min_duration": 10}}},
|
"foo_action": {"max_duration": 19, "min_duration": 10}}},
|
||||||
"full_duration": 40, "load_duration": 32,
|
"full_duration": 40, "load_duration": 32,
|
||||||
@@ -90,8 +91,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"description": "Foo",
|
"description": "Foo",
|
||||||
"action": {"sys_call": "foo cmd"},
|
"action": ("sys_call", "foo cmd"),
|
||||||
"trigger": {"event": {"at": [2, 5], "unit": "iteration"}}},
|
"trigger": ("event", {"at": [2, 5], "unit": "iteration"})},
|
||||||
"results": [
|
"results": [
|
||||||
{
|
{
|
||||||
"status": "success",
|
"status": "success",
|
||||||
@@ -120,8 +121,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
"summary": {"success": 2}},
|
"summary": {"success": 2}},
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"action": {"sys_call": "bar cmd"},
|
"action": ("sys_call", "bar cmd"),
|
||||||
"trigger": {"event": {"at": [1, 2, 4], "unit": "time"}}},
|
"trigger": ("event", {"at": [1, 2, 4], "unit": "time"})},
|
||||||
"results": [
|
"results": [
|
||||||
{
|
{
|
||||||
"status": "success",
|
"status": "success",
|
||||||
@@ -186,11 +187,14 @@ class PlotTestCase(test.TestCase):
|
|||||||
"name": "Foo.bar_%s" % i,
|
"name": "Foo.bar_%s" % i,
|
||||||
"description": "Make something useful (or not).",
|
"description": "Make something useful (or not).",
|
||||||
"position": i,
|
"position": i,
|
||||||
"runner": {"type": "constant", "times": 3},
|
"runner_type": "constant",
|
||||||
"context": {"users": {}},
|
"runner": {"times": 3},
|
||||||
|
"contexts": {"users": {}},
|
||||||
"sla": {"failure_rate": {"max": 0}},
|
"sla": {"failure_rate": {"max": 0}},
|
||||||
"args": {"key1": "value1"},
|
"args": {"key1": "value1"},
|
||||||
"hooks": [{"config": {"hook1": "xxx"}}],
|
"hooks": [{"config": {
|
||||||
|
"action": ("foo", {}),
|
||||||
|
"trigger": ("xxx", {})}}],
|
||||||
"sla_results": {"sla": []},
|
"sla_results": {"sla": []},
|
||||||
"start_time": "2997.23.12",
|
"start_time": "2997.23.12",
|
||||||
"load_duration": 42,
|
"load_duration": 42,
|
||||||
@@ -225,7 +229,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
"args": {},
|
"args": {},
|
||||||
"context": {"key": "context"},
|
"context": {"key": "context"},
|
||||||
"sla": {"key": "sla"},
|
"sla": {"key": "sla"},
|
||||||
"runner": {"type": "crunner"},
|
"runner_type": "crunner",
|
||||||
|
"runner": {},
|
||||||
"hooks": []}
|
"hooks": []}
|
||||||
]}
|
]}
|
||||||
]}]
|
]}]
|
||||||
@@ -262,7 +267,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
"args": {},
|
"args": {},
|
||||||
"context": {"key": "context"},
|
"context": {"key": "context"},
|
||||||
"sla": {"key": "sla"},
|
"sla": {"key": "sla"},
|
||||||
"runner": {"type": "crunner"},
|
"runner_type": "crunner",
|
||||||
|
"runner": {},
|
||||||
"hooks": []}
|
"hooks": []}
|
||||||
]},
|
]},
|
||||||
{"title": "subtask title3",
|
{"title": "subtask title3",
|
||||||
@@ -274,7 +280,8 @@ class PlotTestCase(test.TestCase):
|
|||||||
"args": {},
|
"args": {},
|
||||||
"context": {"key": "context"},
|
"context": {"key": "context"},
|
||||||
"sla": {"key": "sla"},
|
"sla": {"key": "sla"},
|
||||||
"runner": {"type": "crunner"},
|
"runner_type": "crunner",
|
||||||
|
"runner": {},
|
||||||
"hooks": []}
|
"hooks": []}
|
||||||
]}
|
]}
|
||||||
]})
|
]})
|
||||||
|
|||||||
@@ -37,15 +37,16 @@ class MyException(exceptions.RallyException):
|
|||||||
class TaskEngineTestCase(test.TestCase):
|
class TaskEngineTestCase(test.TestCase):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _make_workload(name, args=None, description=None, context=None,
|
def _make_workload(name, args=None, description=None, contexts=None,
|
||||||
sla=None, runner=None, hooks=None, position=0):
|
sla=None, runner=None, hooks=None, position=0):
|
||||||
return {"uuid": "foo",
|
return {"uuid": "foo",
|
||||||
"name": name,
|
"name": name,
|
||||||
"position": position,
|
"position": position,
|
||||||
"description": description,
|
"description": description,
|
||||||
"args": args,
|
"args": args,
|
||||||
"context": context or {},
|
"contexts": contexts or {},
|
||||||
"runner": runner or {"type": "serial"},
|
"runner_type": runner[0] if runner else "serial",
|
||||||
|
"runner": runner[1] if runner else {},
|
||||||
"sla": sla or {},
|
"sla": sla or {},
|
||||||
"hooks": hooks or []}
|
"hooks": hooks or []}
|
||||||
|
|
||||||
@@ -153,12 +154,13 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
|
|
||||||
scenario_name = "Foo.bar"
|
scenario_name = "Foo.bar"
|
||||||
runner_type = "MegaRunner"
|
runner_type = "MegaRunner"
|
||||||
hook_conf = {"action": {"c": "c_args"},
|
hook_conf = {"action": ("c", "c_args"),
|
||||||
"trigger": {"d": "d_args"}}
|
"trigger": ("d", "d_args")}
|
||||||
workload = {"name": scenario_name,
|
workload = {"name": scenario_name,
|
||||||
"runner": {"type": runner_type},
|
"runner_type": runner_type,
|
||||||
"context": {"a": "a_conf"},
|
"runner": {},
|
||||||
"hooks": [{"config": hook_conf}],
|
"contexts": {"a": "a_conf"},
|
||||||
|
"hooks": [hook_conf],
|
||||||
"sla": {"foo_sla": "sla_conf"},
|
"sla": {"foo_sla": "sla_conf"},
|
||||||
"position": 2}
|
"position": 2}
|
||||||
|
|
||||||
@@ -169,7 +171,7 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
|
|
||||||
mock_scenario_runner_validate.assert_called_once_with(
|
mock_scenario_runner_validate.assert_called_once_with(
|
||||||
name=runner_type, context=None, config=None,
|
name=runner_type, context=None, config=None,
|
||||||
plugin_cfg={"type": runner_type}, vtype=None)
|
plugin_cfg={}, vtype=None)
|
||||||
self.assertEqual([mock.call(name="a",
|
self.assertEqual([mock.call(name="a",
|
||||||
context=None,
|
context=None,
|
||||||
config=None,
|
config=None,
|
||||||
@@ -204,7 +206,7 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
"There is no such runner"]
|
"There is no such runner"]
|
||||||
scenario_cls = mock_scenario_get.return_value
|
scenario_cls = mock_scenario_get.return_value
|
||||||
scenario_cls.get_default_context.return_value = {}
|
scenario_cls.get_default_context.return_value = {}
|
||||||
workload = self._make_workload(name="sca", runner={"type": "b"})
|
workload = self._make_workload(name="sca", runner=("b", {}))
|
||||||
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
||||||
mock.Mock())
|
mock.Mock())
|
||||||
|
|
||||||
@@ -230,7 +232,7 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
mock_task_instance.subtasks = [{"workloads": [
|
mock_task_instance.subtasks = [{"workloads": [
|
||||||
self._make_workload(name="sca"),
|
self._make_workload(name="sca"),
|
||||||
self._make_workload(name="sca", position=1,
|
self._make_workload(name="sca", position=1,
|
||||||
context={"a": "a_conf"})
|
contexts={"a": "a_conf"})
|
||||||
]}]
|
]}]
|
||||||
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
||||||
mock.Mock())
|
mock.Mock())
|
||||||
@@ -282,12 +284,12 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
scenario_cls = mock_scenario_get.return_value
|
scenario_cls = mock_scenario_get.return_value
|
||||||
scenario_cls.get_default_context.return_value = {}
|
scenario_cls.get_default_context.return_value = {}
|
||||||
mock_task_instance = mock.MagicMock()
|
mock_task_instance = mock.MagicMock()
|
||||||
hook_conf = {"action": {"c": "c_args"},
|
hook_conf = {"action": ("c", "c_args"),
|
||||||
"trigger": {"d": "d_args"}}
|
"trigger": ("d", "d_args")}
|
||||||
mock_task_instance.subtasks = [{"workloads": [
|
mock_task_instance.subtasks = [{"workloads": [
|
||||||
self._make_workload(name="sca"),
|
self._make_workload(name="sca"),
|
||||||
self._make_workload(name="sca", position=1,
|
self._make_workload(name="sca", position=1,
|
||||||
hooks=[{"config": hook_conf}])
|
hooks=[hook_conf])
|
||||||
]}]
|
]}]
|
||||||
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
||||||
mock.Mock())
|
mock.Mock())
|
||||||
@@ -315,12 +317,12 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
scenario_cls = mock_scenario_get.return_value
|
scenario_cls = mock_scenario_get.return_value
|
||||||
scenario_cls.get_default_context.return_value = {}
|
scenario_cls.get_default_context.return_value = {}
|
||||||
mock_task_instance = mock.MagicMock()
|
mock_task_instance = mock.MagicMock()
|
||||||
hook_conf = {"action": {"c": "c_args"},
|
hook_conf = {"action": ("c", "c_args"),
|
||||||
"trigger": {"d": "d_args"}}
|
"trigger": ("d", "d_args")}
|
||||||
mock_task_instance.subtasks = [{"workloads": [
|
mock_task_instance.subtasks = [{"workloads": [
|
||||||
self._make_workload(name="sca"),
|
self._make_workload(name="sca"),
|
||||||
self._make_workload(name="sca", position=1,
|
self._make_workload(name="sca", position=1,
|
||||||
hooks=[{"config": hook_conf}])
|
hooks=[hook_conf])
|
||||||
]}]
|
]}]
|
||||||
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
eng = engine.TaskEngine(mock.MagicMock(), mock.MagicMock(),
|
||||||
mock.Mock())
|
mock.Mock())
|
||||||
@@ -353,7 +355,7 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
|
|
||||||
mock_task_instance = mock.MagicMock()
|
mock_task_instance = mock.MagicMock()
|
||||||
wconf1 = self._make_workload(name="SomeScen.scenario",
|
wconf1 = self._make_workload(name="SomeScen.scenario",
|
||||||
context={"users": {}})
|
contexts={"users": {}})
|
||||||
wconf2 = self._make_workload(name="SomeScen.scenario",
|
wconf2 = self._make_workload(name="SomeScen.scenario",
|
||||||
position=1)
|
position=1)
|
||||||
subtask1 = {"workloads": [wconf1, wconf2]}
|
subtask1 = {"workloads": [wconf1, wconf2]}
|
||||||
@@ -452,9 +454,9 @@ class TaskEngineTestCase(test.TestCase):
|
|||||||
"context": {},
|
"context": {},
|
||||||
"workloads": [
|
"workloads": [
|
||||||
self._make_workload(name="a.task", description="foo",
|
self._make_workload(name="a.task", description="foo",
|
||||||
context={"context_a": {"a": 1}}),
|
contexts={"context_a": {"a": 1}}),
|
||||||
self._make_workload(name="a.task", description="foo",
|
self._make_workload(name="a.task", description="foo",
|
||||||
context={"context_a": {"b": 2}},
|
contexts={"context_a": {"b": 2}},
|
||||||
position=2)]}]
|
position=2)]}]
|
||||||
|
|
||||||
mock_task_config.return_value = mock_task_instance
|
mock_task_config.return_value = mock_task_instance
|
||||||
@@ -1064,6 +1066,6 @@ class TaskConfigTestCase(test.TestCase):
|
|||||||
workload = task.subtasks[0]["workloads"][0]
|
workload = task.subtasks[0]["workloads"][0]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{"description": "descr",
|
{"description": "descr",
|
||||||
"action": {"hook_action": {"k1": "v1"}},
|
"action": ("hook_action", {"k1": "v1"}),
|
||||||
"trigger": {"hook_trigger": {"k2": "v2"}}},
|
"trigger": ("hook_trigger", {"k2": "v2"})},
|
||||||
workload["hooks"][0]["config"])
|
workload["hooks"][0])
|
||||||
|
|||||||
@@ -55,18 +55,18 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
super(HookExecutorTestCase, self).setUp()
|
super(HookExecutorTestCase, self).setUp()
|
||||||
self.conf = {
|
self.conf = {
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{"config": {
|
{
|
||||||
"description": "dummy_action",
|
"description": "dummy_action",
|
||||||
"action": {
|
"action": (
|
||||||
"dummy_hook": {"status": consts.HookStatus.SUCCESS}
|
"dummy_hook", {"status": consts.HookStatus.SUCCESS}
|
||||||
},
|
),
|
||||||
"trigger": {
|
"trigger": (
|
||||||
"event": {
|
"event", {
|
||||||
"unit": "iteration",
|
"unit": "iteration",
|
||||||
"at": [1],
|
"at": [1],
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
self.task = mock.MagicMock()
|
self.task = mock.MagicMock()
|
||||||
@@ -78,7 +78,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
hook_executor.on_event(event_type="iteration", value=1)
|
hook_executor.on_event(event_type="iteration", value=1)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{"config": self.conf["hooks"][0]["config"],
|
[{"config": self.conf["hooks"][0],
|
||||||
"results": [{
|
"results": [{
|
||||||
"triggered_by": {"event_type": "iteration", "value": 1},
|
"triggered_by": {"event_type": "iteration", "value": 1},
|
||||||
"started_at": fakes.FakeTimer().timestamp(),
|
"started_at": fakes.FakeTimer().timestamp(),
|
||||||
@@ -90,15 +90,16 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
@mock.patch("rally.task.hook.HookExecutor._timer_method")
|
@mock.patch("rally.task.hook.HookExecutor._timer_method")
|
||||||
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
||||||
def test_result_optional(self, mock_timer, mock__timer_method):
|
def test_result_optional(self, mock_timer, mock__timer_method):
|
||||||
hook_args = list(self.conf["hooks"][0]["config"]["action"].values())[0]
|
hook_args = self.conf["hooks"][0]["action"][1]
|
||||||
hook_args["error"] = ["Exception", "Description", "Traceback"]
|
hook_args["error"] = ["Exception", "Description", "Traceback"]
|
||||||
|
|
||||||
hook_args["output"] = {"additive": None, "complete": None}
|
hook_args["output"] = {"additive": None, "complete": None}
|
||||||
|
|
||||||
hook_executor = hook.HookExecutor(self.conf, self.task)
|
hook_executor = hook.HookExecutor(self.conf, self.task)
|
||||||
hook_executor.on_event(event_type="iteration", value=1)
|
hook_executor.on_event(event_type="iteration", value=1)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{"config": self.conf["hooks"][0]["config"],
|
[{"config": self.conf["hooks"][0],
|
||||||
"results": [{
|
"results": [{
|
||||||
"triggered_by": {"event_type": "iteration", "value": 1},
|
"triggered_by": {"event_type": "iteration", "value": 1},
|
||||||
"started_at": fakes.FakeTimer().timestamp(),
|
"started_at": fakes.FakeTimer().timestamp(),
|
||||||
@@ -112,7 +113,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_empty_result(self):
|
def test_empty_result(self):
|
||||||
hook_executor = hook.HookExecutor(self.conf, self.task)
|
hook_executor = hook.HookExecutor(self.conf, self.task)
|
||||||
self.assertEqual([{"config": self.conf["hooks"][0]["config"],
|
self.assertEqual([{"config": self.conf["hooks"][0],
|
||||||
"results": [],
|
"results": [],
|
||||||
"summary": {}}],
|
"summary": {}}],
|
||||||
hook_executor.results())
|
hook_executor.results())
|
||||||
@@ -127,7 +128,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
hook_executor.on_event(event_type="iteration", value=1)
|
hook_executor.on_event(event_type="iteration", value=1)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{"config": self.conf["hooks"][0]["config"],
|
[{"config": self.conf["hooks"][0],
|
||||||
"results": [{
|
"results": [{
|
||||||
"triggered_by": {"event_type": "iteration", "value": 1},
|
"triggered_by": {"event_type": "iteration", "value": 1},
|
||||||
"error": {"etype": "Exception",
|
"error": {"etype": "Exception",
|
||||||
@@ -140,15 +141,14 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
||||||
def test_time_event(self, mock_timer):
|
def test_time_event(self, mock_timer):
|
||||||
trigger_args = list(
|
trigger_args = self.conf["hooks"][0]["trigger"][1]
|
||||||
self.conf["hooks"][0]["config"]["trigger"].values())[0]
|
|
||||||
trigger_args["unit"] = "time"
|
trigger_args["unit"] = "time"
|
||||||
|
|
||||||
hook_executor = hook.HookExecutor(self.conf, self.task)
|
hook_executor = hook.HookExecutor(self.conf, self.task)
|
||||||
hook_executor.on_event(event_type="time", value=1)
|
hook_executor.on_event(event_type="time", value=1)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{"config": self.conf["hooks"][0]["config"],
|
[{"config": self.conf["hooks"][0],
|
||||||
"results": [{
|
"results": [{
|
||||||
"triggered_by": {"event_type": "time", "value": 1},
|
"triggered_by": {"event_type": "time", "value": 1},
|
||||||
"started_at": fakes.FakeTimer().timestamp(),
|
"started_at": fakes.FakeTimer().timestamp(),
|
||||||
@@ -159,8 +159,8 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
||||||
def test_time_periodic(self, mock_timer):
|
def test_time_periodic(self, mock_timer):
|
||||||
self.conf["hooks"][0]["config"]["trigger"] = {
|
self.conf["hooks"][0]["trigger"] = ("periodic",
|
||||||
"periodic": {"unit": "time", "step": 2}}
|
{"unit": "time", "step": 2})
|
||||||
hook_executor = hook.HookExecutor(self.conf, self.task)
|
hook_executor = hook.HookExecutor(self.conf, self.task)
|
||||||
|
|
||||||
for i in range(1, 7):
|
for i in range(1, 7):
|
||||||
@@ -168,7 +168,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{
|
[{
|
||||||
"config": self.conf["hooks"][0]["config"],
|
"config": self.conf["hooks"][0],
|
||||||
"results":[
|
"results":[
|
||||||
{
|
{
|
||||||
"triggered_by": {"event_type": "time", "value": 2},
|
"triggered_by": {"event_type": "time", "value": 2},
|
||||||
@@ -196,8 +196,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
@mock.patch("rally.common.utils.Stopwatch", autospec=True)
|
@mock.patch("rally.common.utils.Stopwatch", autospec=True)
|
||||||
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
@mock.patch("rally.common.utils.Timer", side_effect=fakes.FakeTimer)
|
||||||
def test_timer_thread(self, mock_timer, mock_stopwatch):
|
def test_timer_thread(self, mock_timer, mock_stopwatch):
|
||||||
trigger_args = list(
|
trigger_args = self.conf["hooks"][0]["trigger"][1]
|
||||||
self.conf["hooks"][0]["config"]["trigger"].values())[0]
|
|
||||||
trigger_args["unit"] = "time"
|
trigger_args["unit"] = "time"
|
||||||
hook_executor = hook.HookExecutor(self.conf, self.task)
|
hook_executor = hook.HookExecutor(self.conf, self.task)
|
||||||
|
|
||||||
@@ -212,7 +211,7 @@ class HookExecutorTestCase(test.TestCase):
|
|||||||
self.assertTrue(hook_executor._timer_stop_event.wait(1))
|
self.assertTrue(hook_executor._timer_stop_event.wait(1))
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[{"config": self.conf["hooks"][0]["config"],
|
[{"config": self.conf["hooks"][0],
|
||||||
"results": [{
|
"results": [{
|
||||||
"triggered_by": {"event_type": "time", "value": 1},
|
"triggered_by": {"event_type": "time", "value": 1},
|
||||||
"started_at": fakes.FakeTimer().timestamp(),
|
"started_at": fakes.FakeTimer().timestamp(),
|
||||||
@@ -316,8 +315,8 @@ class TriggerTestCase(test.TestCase):
|
|||||||
# test_on_event and test_get_results in one test.
|
# test_on_event and test_get_results in one test.
|
||||||
right_values = [5, 7, 12, 13]
|
right_values = [5, 7, 12, 13]
|
||||||
|
|
||||||
cfg = {"trigger": {self.DummyTrigger.get_name(): right_values},
|
cfg = {"trigger": (self.DummyTrigger.get_name(), right_values),
|
||||||
"action": {"fake": {}}}
|
"action": ("fake", {})}
|
||||||
task = mock.MagicMock()
|
task = mock.MagicMock()
|
||||||
hook_cls = mock.MagicMock(__name__="fake")
|
hook_cls = mock.MagicMock(__name__="fake")
|
||||||
dummy_trigger = self.DummyTrigger(cfg, task, hook_cls)
|
dummy_trigger = self.DummyTrigger(cfg, task, hook_cls)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class TriggerTestCase(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch("rally.task.trigger.LOG.warning")
|
@mock.patch("rally.task.trigger.LOG.warning")
|
||||||
def test_warning(self, mock_log_warning):
|
def test_warning(self, mock_log_warning):
|
||||||
self.DummyTrigger({"trigger": {self.id(): {}}}, None, None)
|
self.DummyTrigger({"trigger": (self.id(), {})}, None, None)
|
||||||
|
|
||||||
mock_log_warning.assert_called_once_with(
|
mock_log_warning.assert_called_once_with(
|
||||||
"Please contact Rally plugin maintainer. The plugin '%s'"
|
"Please contact Rally plugin maintainer. The plugin '%s'"
|
||||||
@@ -52,8 +52,8 @@ class TriggerTestCase(test.TestCase):
|
|||||||
descr = "descr"
|
descr = "descr"
|
||||||
|
|
||||||
trigger_obj = self.DummyTrigger({
|
trigger_obj = self.DummyTrigger({
|
||||||
"trigger": {trigger_name: trigger_cfg},
|
"trigger": (trigger_name, trigger_cfg),
|
||||||
"action": {action_name: action_cfg},
|
"action": (action_name, action_cfg),
|
||||||
"description": descr}, None, None)
|
"description": descr}, None, None)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|||||||
@@ -477,6 +477,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
"start_time": 23.77,
|
"start_time": 23.77,
|
||||||
"position": 77,
|
"position": 77,
|
||||||
"runner": "runner-config",
|
"runner": "runner-config",
|
||||||
|
"runner_type": "runner-type",
|
||||||
"context": "ctx-config",
|
"context": "ctx-config",
|
||||||
"hooks": "hooks-config",
|
"hooks": "hooks-config",
|
||||||
"sla": "sla-config",
|
"sla": "sla-config",
|
||||||
@@ -507,6 +508,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
sub_task.add_workload.assert_called_once_with(
|
sub_task.add_workload.assert_called_once_with(
|
||||||
name=workload["name"], description=workload["description"],
|
name=workload["name"], description=workload["description"],
|
||||||
position=workload["position"], runner=workload["runner"],
|
position=workload["position"], runner=workload["runner"],
|
||||||
|
runner_type=workload["runner_type"],
|
||||||
context=workload["context"], sla=workload["sla"],
|
context=workload["context"], sla=workload["sla"],
|
||||||
hooks=workload["hooks"], args=workload["args"]
|
hooks=workload["hooks"], args=workload["args"]
|
||||||
)
|
)
|
||||||
@@ -538,6 +540,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
"start_time": 23.77,
|
"start_time": 23.77,
|
||||||
"position": 77,
|
"position": 77,
|
||||||
"runner": "runner-config",
|
"runner": "runner-config",
|
||||||
|
"runner_type": "runner-type",
|
||||||
"context": "ctx-config",
|
"context": "ctx-config",
|
||||||
"hooks": "hooks-config",
|
"hooks": "hooks-config",
|
||||||
"sla": "sla-config",
|
"sla": "sla-config",
|
||||||
@@ -569,6 +572,7 @@ class TaskAPITestCase(test.TestCase):
|
|||||||
sub_task.add_workload.assert_called_once_with(
|
sub_task.add_workload.assert_called_once_with(
|
||||||
name=workload["name"], description=workload["description"],
|
name=workload["name"], description=workload["description"],
|
||||||
position=workload["position"], runner=workload["runner"],
|
position=workload["position"], runner=workload["runner"],
|
||||||
|
runner_type=workload["runner_type"],
|
||||||
context=workload["context"], sla=workload["sla"],
|
context=workload["context"], sla=workload["sla"],
|
||||||
hooks=workload["hooks"], args=workload["args"]
|
hooks=workload["hooks"], args=workload["args"]
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user