[Scenario] Split Scenarios - P5

Move under plugins/openstack:
    * Zaqar
    * Mistral
    * Heat
    * Ceilometer

Implements: blueprint split-plugins

Change-Id: I776e47f8bae3a2d1baebc51c213eb981a58d1975
This commit is contained in:
Yair Fried 2015-05-17 16:41:55 +03:00
parent 787b35a650
commit c0f73bffd1
34 changed files with 2265 additions and 0 deletions

View File

@ -0,0 +1,138 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.ceilometer import utils as ceiloutils
class CeilometerAlarms(ceiloutils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Alarms API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_alarm(self, meter_name, threshold, **kwargs):
"""Create an alarm.
This scenarios test POST /v2/alarms.
meter_name and threshold are required parameters for alarm creation.
kwargs stores other optional parameters like 'ok_actions',
'project_id' etc that may be passed while creating an alarm.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param kwargs: specifies optional arguments for alarm creation.
"""
self._create_alarm(meter_name, threshold, kwargs)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario()
def list_alarms(self):
"""Fetch all alarms.
This scenario fetches list of all alarms using GET /v2/alarms.
"""
self._list_alarms()
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_list_alarm(self, meter_name, threshold, **kwargs):
"""Create and get the newly created alarm.
This scenarios test GET /v2/alarms/(alarm_id)
Initially alarm is created and then the created alarm is fetched using
its alarm_id. meter_name and threshold are required parameters
for alarm creation. kwargs stores other optional parameters like
'ok_actions', 'project_id' etc. that may be passed while creating
an alarm.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param kwargs: specifies optional arguments for alarm creation.
"""
alarm = self._create_alarm(meter_name, threshold, kwargs)
self._list_alarms(alarm.alarm_id)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_update_alarm(self, meter_name, threshold, **kwargs):
"""Create and update the newly created alarm.
This scenarios test PUT /v2/alarms/(alarm_id)
Initially alarm is created and then the created alarm is updated using
its alarm_id. meter_name and threshold are required parameters
for alarm creation. kwargs stores other optional parameters like
'ok_actions', 'project_id' etc that may be passed while alarm creation.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param kwargs: specifies optional arguments for alarm creation.
"""
alarm = self._create_alarm(meter_name, threshold, kwargs)
alarm_dict_diff = {"description": "Changed Test Description"}
self._update_alarm(alarm.alarm_id, alarm_dict_diff)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_delete_alarm(self, meter_name, threshold, **kwargs):
"""Create and delete the newly created alarm.
This scenarios test DELETE /v2/alarms/(alarm_id)
Initially alarm is created and then the created alarm is deleted using
its alarm_id. meter_name and threshold are required parameters
for alarm creation. kwargs stores other optional parameters like
'ok_actions', 'project_id' etc that may be passed while alarm creation.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param kwargs: specifies optional arguments for alarm creation.
"""
alarm = self._create_alarm(meter_name, threshold, kwargs)
self._delete_alarm(alarm.alarm_id)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_alarm_and_get_history(self, meter_name, threshold, state,
timeout=60, **kwargs):
"""Create an alarm, get and set the state and get the alarm history.
This scenario makes following queries:
GET /v2/alarms/{alarm_id}/history
GET /v2/alarms/{alarm_id}/state
PUT /v2/alarms/{alarm_id}/state
Initially alarm is created and then get the state of the created alarm
using its alarm_id. Then get the history of the alarm. And finally the
state of the alarm is updated using given state. meter_name and
threshold are required parameters for alarm creation. kwargs stores
other optional parameters like 'ok_actions', 'project_id' etc that may
be passed while alarm creation.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param state: an alarm state to be set
:param timeout: The number of seconds for which to attempt a
successful check of the alarm state
:param kwargs: specifies optional arguments for alarm creation.
"""
alarm = self._create_alarm(meter_name, threshold, kwargs)
self._get_alarm_state(alarm.alarm_id)
self._get_alarm_history(alarm.alarm_id)
self._set_alarm_state(alarm, state, timeout)

View File

@ -0,0 +1,29 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.ceilometer import utils as ceiloutils
class CeilometerMeters(ceiloutils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Meters API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario()
def list_meters(self):
"""Fetch user's meters."""
self._list_meters()

View File

@ -0,0 +1,97 @@
# 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.
import json
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.ceilometer import utils as ceiloutils
class CeilometerQueries(ceiloutils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Queries API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_alarms(self, meter_name, threshold, filter=None,
orderby=None, limit=None, **kwargs):
"""Create an alarm and then query it with specific parameters.
This scenario tests POST /v2/query/alarms
An alarm is first created and then fetched using the input query.
:param meter_name: specifies meter name of alarm
:param threshold: specifies alarm threshold
:param filter: optional filter query dictionary
:param orderby: optional param for specifying ordering of results
:param limit: optional param for maximum number of results returned
:param kwargs: optional parameters for alarm creation
"""
if filter:
filter = json.dumps(filter)
self._create_alarm(meter_name, threshold, kwargs)
self._query_alarms(filter, orderby, limit)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_alarm_history(self, meter_name, threshold,
orderby=None, limit=None, **kwargs):
"""Create an alarm and then query for its history.
This scenario tests POST /v2/query/alarms/history
An alarm is first created and then its alarm_id is used to fetch the
history of that specific alarm.
:param meter_name: specifies meter name of alarm
:param threshold: specifies alarm threshold
:param orderby: optional param for specifying ordering of results
:param limit: optional param for maximum number of results returned
:param kwargs: optional parameters for alarm creation
"""
alarm = self._create_alarm(meter_name, threshold, kwargs)
alarm_filter = json.dumps({"=": {"alarm_id": alarm.alarm_id}})
self._query_alarm_history(alarm_filter, orderby, limit)
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_samples(self, counter_name, counter_type,
counter_unit, counter_volume, resource_id,
filter=None, orderby=None, limit=None,
**kwargs):
"""Create a sample and then query it with specific parameters.
This scenario tests POST /v2/query/samples
A sample is first created and then fetched using the input query.
:param counter_name: specifies name of the counter
:param counter_type: specifies type of the counter
:param counter_unit: specifies name of the counter
:param counter_volume: specifies name of the counter
:param resource_id: specifies resource id for the sample created
:param filter: optional filter query dictionary
:param orderby: optional param for specifying ordering of results
:param limit: optional param for maximum number of results returned
:param kwargs: parameters for sample creation
"""
self._create_sample(counter_name, counter_type, counter_unit,
counter_volume, resource_id, **kwargs)
if filter:
filter = json.dumps(filter)
self._query_samples(filter, orderby, limit)

View File

@ -0,0 +1,50 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally import exceptions
from rally.plugins.openstack.scenarios.ceilometer import utils as ceiloutils
class CeilometerResource(ceiloutils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Resource API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario()
def list_resources(self):
"""Fetch all resources.
This scenario fetches list of all resources using GET /v2/resources.
"""
self._list_resources()
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario()
def get_tenant_resources(self):
"""Get all tenant resources.
This scenario retrieves information about tenant resources using
GET /v2/resources/(resource_id)
"""
resources = self.context["tenant"].get("resources", [])
if not resources:
msg = ("No resources found for tenant: %s"
% self.context["tenant"].get("name"))
raise exceptions.NotFoundException(message=msg)
for res_id in resources:
self._get_resource(res_id)

View File

@ -0,0 +1,32 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.ceilometer import utils as ceiloutils
class CeilometerSamples(ceiloutils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Samples API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario()
def list_samples(self):
"""Fetch all samples.
This scenario fetches list of all samples.
"""
self._list_samples()

View File

@ -0,0 +1,36 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.ceilometer import utils
class CeilometerStats(utils.CeilometerScenario):
"""Benchmark scenarios for Ceilometer Stats API."""
@validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]})
def create_meter_and_get_stats(self, **kwargs):
"""Create a meter and fetch its statistics.
Meter is first created and then statistics is fetched for the same
using GET /v2/meters/(meter_name)/statistics.
:param kwargs: contains optional arguments to create a meter
"""
meter = self._create_meter(**kwargs)
self._get_stats(meter.counter_name)

View File

@ -0,0 +1,232 @@
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import utils as bench_utils
class CeilometerScenario(base.Scenario):
"""Base class for Ceilometer scenarios with basic atomic actions."""
RESOURCE_NAME_PREFIX = "rally_ceilometer_"
def _get_alarm_dict(self, **kwargs):
"""Prepare and return an alarm dict for creating an alarm.
:param kwargs: optional parameters to create alarm
:returns: alarm dictionary used to create an alarm
"""
alarm_id = self._generate_random_name()
alarm = {"alarm_id": alarm_id,
"name": alarm_id,
"description": "Test Alarm"}
alarm.update(kwargs)
return alarm
@base.atomic_action_timer("ceilometer.list_alarms")
def _list_alarms(self, alarm_id=None):
"""List alarms.
List alarm matching alarm_id. It fetches all alarms
if alarm_id is None.
:param alarm_id: specifies id of the alarm
:returns: list of alarms
"""
if alarm_id:
return self.clients("ceilometer").alarms.get(alarm_id)
else:
return self.clients("ceilometer").alarms.list()
@base.atomic_action_timer("ceilometer.create_alarm")
def _create_alarm(self, meter_name, threshold, kwargs):
"""Create an alarm.
:param meter_name: specifies meter name of the alarm
:param threshold: specifies alarm threshold
:param kwargs: contains optional features of alarm to be created
:returns: alarm
"""
kwargs.update({"meter_name": meter_name,
"threshold": threshold})
alarm_dict = self._get_alarm_dict(**kwargs)
alarm = self.clients("ceilometer").alarms.create(**alarm_dict)
return alarm
@base.atomic_action_timer("ceilometer.delete_alarm")
def _delete_alarm(self, alarm_id):
"""Delete an alarm.
:param alarm_id: specifies id of the alarm
"""
self.clients("ceilometer").alarms.delete(alarm_id)
@base.atomic_action_timer("ceilometer.update_alarm")
def _update_alarm(self, alarm_id, alarm_dict_delta):
"""Update an alarm.
:param alarm_id: specifies id of the alarm
:param alarm_dict_delta: features of alarm to be updated
"""
self.clients("ceilometer").alarms.update(alarm_id, **alarm_dict_delta)
@base.atomic_action_timer("ceilometer.get_alarm_history")
def _get_alarm_history(self, alarm_id):
"""Assemble the alarm history requested.
:param alarm_id: specifies id of the alarm
:returns: list of alarm changes
"""
return self.clients("ceilometer").alarms.get_history(alarm_id)
@base.atomic_action_timer("ceilometer.get_alarm_state")
def _get_alarm_state(self, alarm_id):
"""Get the state of the alarm.
:param alarm_id: specifies id of the alarm
:returns: state of the alarm
"""
return self.clients("ceilometer").alarms.get_state(alarm_id)
@base.atomic_action_timer("ceilometer.set_alarm_state")
def _set_alarm_state(self, alarm, state, timeout):
"""Set the state of the alarm.
:param alarm: alarm instance
:param state: an alarm state to be set
:param timeout: The number of seconds for which to attempt a
successful check of the alarm state.
:returns: alarm in the set state
"""
self.clients("ceilometer").alarms.set_state(alarm.alarm_id, state)
return bench_utils.wait_for(alarm,
is_ready=bench_utils.resource_is(state),
update_resource=bench_utils
.get_from_manager(),
timeout=timeout, check_interval=1)
@base.atomic_action_timer("ceilometer.get_meters")
def _list_meters(self):
"""Get list of user's meters."""
return self.clients("ceilometer").meters.list()
@base.atomic_action_timer("ceilometer.list_resources")
def _list_resources(self):
"""List all resources.
:returns: list of all resources
"""
return self.clients("ceilometer").resources.list()
@base.atomic_action_timer("ceilometer.list_samples")
def _list_samples(self):
"""List all Samples.
:returns: list of all samples
"""
return self.clients("ceilometer").samples.list()
@base.atomic_action_timer("ceilometer.get_resource")
def _get_resource(self, resource_id):
"""Retrieve details about one resource."""
return self.clients("ceilometer").resources.get(resource_id)
@base.atomic_action_timer("ceilometer.get_stats")
def _get_stats(self, meter_name):
"""Get stats for a specific meter.
:param meter_name: Name of ceilometer meter
"""
return self.clients("ceilometer").statistics.list(meter_name)
@base.atomic_action_timer("ceilometer.create_meter")
def _create_meter(self, **kwargs):
"""Create a new meter.
:param name_length: Length of meter name to be generated
:param kwargs: Contains the optional attributes for meter creation
:returns: Newly created meter
"""
name = self._generate_random_name()
samples = self.clients("ceilometer").samples.create(
counter_name=name, **kwargs)
return samples[0]
@base.atomic_action_timer("ceilometer.query_alarms")
def _query_alarms(self, filter, orderby, limit):
"""Query alarms with specific parameters.
If no input params are provided, it returns all the results
in the database.
:param limit: optional param for maximum number of results returned
:param orderby: optional param for specifying ordering of results
:param filter: optional filter query
:returns: queried alarms
"""
return self.clients("ceilometer").query_alarms.query(
filter, orderby, limit)
@base.atomic_action_timer("ceilometer.query_alarm_history")
def _query_alarm_history(self, filter, orderby, limit):
"""Query history of an alarm.
If no input params are provided, it returns all the results
in the database.
:param limit: optional param for maximum number of results returned
:param orderby: optional param for specifying ordering of results
:param filter: optional filter query
:returns: alarm history
"""
return self.clients("ceilometer").query_alarm_history.query(
filter, orderby, limit)
@base.atomic_action_timer("ceilometer.create_sample")
def _create_sample(self, counter_name, counter_type, counter_unit,
counter_volume, resource_id=None, **kwargs):
"""Create a Sample with specified parameters.
:param counter_name: specifies name of the counter
:param counter_type: specifies type of the counter
:param counter_unit: specifies name of the counter
:param counter_volume: specifies name of the counter
:param resource_id: specifies resource id for the sample created
:param kwargs: contains optional parameters for creating a sample
:returns: created sample
"""
kwargs.update({"counter_name": counter_name,
"counter_type": counter_type,
"counter_unit": counter_unit,
"counter_volume": counter_volume,
"resource_id": resource_id if resource_id
else self._generate_random_name(
prefix="rally_ctx_resource_")})
return self.clients("ceilometer").samples.create(**kwargs)
@base.atomic_action_timer("ceilometer.query_samples")
def _query_samples(self, filter, orderby, limit):
"""Query samples with specified parameters.
If no input params are provided, it returns all the results
in the database.
:param limit: optional param for maximum number of results returned
:param orderby: optional param for specifying ordering of results
:param filter: optional filter query
:returns: queried samples
"""
return self.clients("ceilometer").query_samples.query(
filter, orderby, limit)

View File

@ -0,0 +1,141 @@
# Copyright 2014: Mirantis Inc.
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import types
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.heat import utils
class HeatStacks(utils.HeatScenario):
"""Benchmark scenarios for Heat stacks."""
RESOURCE_NAME_PREFIX = "rally_stack_"
RESOURCE_NAME_LENGTH = 7
@types.set(template_path=types.FileType)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"]})
def create_and_list_stack(self, template_path):
"""Add a stack and then list all stacks.
Measure the "heat stack-create" and "heat stack-list" commands
performance.
:param template_path: path to stack template file
"""
self._create_stack(template_path)
self._list_stacks()
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario()
def list_stacks_and_resources(self):
"""List all resources from tenant stacks."""
stacks = self._list_stacks()
with base.AtomicAction(
self, "heat.list_resources_of_%s_stacks" % len(stacks)):
for stack in stacks:
self.clients("heat").resources.list(stack.id)
@types.set(template_path=types.FileType)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"]})
def create_and_delete_stack(self, template_path):
"""Add and then delete a stack.
Measure the "heat stack-create" and "heat stack-delete" commands
performance.
:param template_path: path to stack template file
"""
stack = self._create_stack(template_path)
self._delete_stack(stack)
@types.set(template_path=types.FileType)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"]})
def create_check_delete_stack(self, template_path):
"""Create, check and delete a stack.
Measure the performance of the following commands:
- heat stack-create
- heat action-check
- heat stack-delete
:param template_path: path to stack template file
"""
stack = self._create_stack(template_path)
self._check_stack(stack)
self._delete_stack(stack)
@types.set(template_path=types.FileType,
updated_template_path=types.FileType)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"]})
def create_update_delete_stack(self, template_path, updated_template_path):
"""Add, update and then delete a stack.
Measure the "heat stack-create", "heat stack-update"
and "heat stack-delete" commands performance.
:param template_path: path to stack template file
:param updated_template_path: path to updated stack template file
"""
stack = self._create_stack(template_path)
self._update_stack(stack, updated_template_path)
self._delete_stack(stack)
@types.set(template_path=types.FileType)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"]})
def create_suspend_resume_delete_stack(self, template_path):
"""Create, suspend-resume and then delete a stack.
Measure performance of the following commands:
heat stack-create
heat action-suspend
heat action-resume
heat stack-delete
:param template_path: path to stack template file
"""
s = self._create_stack(template_path)
self._suspend_stack(s)
self._resume_stack(s)
self._delete_stack(s)
@validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario()
def list_stacks_and_events(self):
"""List events from tenant stacks."""
stacks = self._list_stacks()
with base.AtomicAction(
self, "heat.list_events_of_%s_stacks" % len(stacks)):
for stack in stacks:
self.clients("heat").events.list(stack.id)

View File

@ -0,0 +1,214 @@
# Copyright 2014: Mirantis Inc.
# 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.
import time
from oslo_config import cfg
from rally.benchmark.scenarios import base
from rally.benchmark import utils as bench_utils
HEAT_BENCHMARK_OPTS = [
cfg.FloatOpt("heat_stack_create_prepoll_delay",
default=2.0,
help="Time(in sec) to sleep after creating a resource before "
"polling for it status."),
cfg.FloatOpt("heat_stack_create_timeout",
default=3600.0,
help="Time(in sec) to wait for heat stack to be created."),
cfg.FloatOpt("heat_stack_create_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack creation."),
cfg.FloatOpt("heat_stack_delete_timeout",
default=3600.0,
help="Time(in sec) to wait for heat stack to be deleted."),
cfg.FloatOpt("heat_stack_delete_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack deletion."),
cfg.FloatOpt("heat_stack_check_timeout",
default=3600.0,
help="Time(in sec) to wait for stack to be checked."),
cfg.FloatOpt("heat_stack_check_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack checking."),
cfg.FloatOpt("heat_stack_update_prepoll_delay",
default=2.0,
help="Time(in sec) to sleep after updating a resource before "
"polling for it status."),
cfg.FloatOpt("heat_stack_update_timeout",
default=3600.0,
help="Time(in sec) to wait for stack to be updated."),
cfg.FloatOpt("heat_stack_update_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack update."),
cfg.FloatOpt("heat_stack_suspend_timeout",
default=3600.0,
help="Time(in sec) to wait for stack to be suspended."),
cfg.FloatOpt("heat_stack_suspend_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack suspend."),
cfg.FloatOpt("heat_stack_resume_timeout",
default=3600.0,
help="Time(in sec) to wait for stack to be resumed."),
cfg.FloatOpt("heat_stack_resume_poll_interval",
default=1.0,
help="Time interval(in sec) between checks when waiting for "
"stack resume."),
]
CONF = cfg.CONF
benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options")
CONF.register_opts(HEAT_BENCHMARK_OPTS, group=benchmark_group)
class HeatScenario(base.Scenario):
"""Base class for Heat scenarios with basic atomic actions."""
@base.atomic_action_timer("heat.list_stacks")
def _list_stacks(self):
"""Return user stack list."""
return list(self.clients("heat").stacks.list())
@base.atomic_action_timer("heat.create_stack")
def _create_stack(self, template):
"""Create a new stack.
:param template: template with stack description.
:returns: object of stack
"""
stack_name = self._generate_random_name(prefix="rally_stack_")
kw = {
"stack_name": stack_name,
"disable_rollback": True,
"parameters": {},
"template": template,
"files": {},
"environment": {}
}
# heat client returns body instead manager object, so we should
# get manager object using stack_id
stack_id = self.clients("heat").stacks.create(**kw)["stack"]["id"]
stack = self.clients("heat").stacks.get(stack_id)
time.sleep(CONF.benchmark.heat_stack_create_prepoll_delay)
stack = bench_utils.wait_for(
stack,
is_ready=bench_utils.resource_is("CREATE_COMPLETE"),
update_resource=bench_utils.get_from_manager(["CREATE_FAILED"]),
timeout=CONF.benchmark.heat_stack_create_timeout,
check_interval=CONF.benchmark.heat_stack_create_poll_interval)
return stack
@base.atomic_action_timer("heat.update_stack")
def _update_stack(self, stack, template):
"""Update an existing stack
:param stack: stack that need to be updated
:param template: Updated template
:returns: object of updated stack
"""
kw = {
"stack_name": stack.stack_name,
"disable_rollback": True,
"parameters": {},
"template": template,
"files": {},
"environment": {}
}
self.clients("heat").stacks.update(stack.id, **kw)
time.sleep(CONF.benchmark.heat_stack_update_prepoll_delay)
stack = bench_utils.wait_for(
stack,
is_ready=bench_utils.resource_is("UPDATE_COMPLETE"),
update_resource=bench_utils.get_from_manager(["UPDATE_FAILED"]),
timeout=CONF.benchmark.heat_stack_update_timeout,
check_interval=CONF.benchmark.heat_stack_update_poll_interval)
return stack
@base.atomic_action_timer("heat.check_stack")
def _check_stack(self, stack):
"""Check given stack.
Check the stack and stack resources.
:param stack: stack that needs to be checked
"""
self.clients("heat").actions.check(stack.id)
bench_utils.wait_for(
stack,
is_ready=bench_utils.resource_is("CHECK_COMPLETE"),
update_resource=bench_utils.get_from_manager(["CHECK_FAILED"]),
timeout=CONF.benchmark.heat_stack_check_timeout,
check_interval=CONF.benchmark.heat_stack_check_poll_interval)
@base.atomic_action_timer("heat.delete_stack")
def _delete_stack(self, stack):
"""Delete given stack.
Returns when the stack is actually deleted.
:param stack: stack object
"""
stack.delete()
bench_utils.wait_for_delete(
stack,
update_resource=bench_utils.get_from_manager(),
timeout=CONF.benchmark.heat_stack_delete_timeout,
check_interval=CONF.benchmark.heat_stack_delete_poll_interval)
@base.atomic_action_timer("heat.suspend_stack")
def _suspend_stack(self, stack):
"""Suspend given stack.
:param stack: stack that needs to be suspended
"""
self.clients("heat").actions.suspend(stack.id)
bench_utils.wait_for(
stack,
is_ready=bench_utils.resource_is("SUSPEND_COMPLETE"),
update_resource=bench_utils.get_from_manager(
["SUSPEND_FAILED"]),
timeout=CONF.benchmark.heat_stack_suspend_timeout,
check_interval=CONF.benchmark.heat_stack_suspend_poll_interval)
@base.atomic_action_timer("heat.resume_stack")
def _resume_stack(self, stack):
"""Resume given stack.
:param stack: stack that needs to be resumed
"""
self.clients("heat").actions.resume(stack.id)
bench_utils.wait_for(
stack,
is_ready=bench_utils.resource_is("RESUME_COMPLETE"),
update_resource=bench_utils.get_from_manager(
["RESUME_FAILED"]),
timeout=CONF.benchmark.heat_stack_resume_timeout,
check_interval=CONF.benchmark.heat_stack_resume_poll_interval)

View File

@ -0,0 +1,49 @@
# Copyright 2015: Mirantis Inc.
# 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.
import yaml
from rally.benchmark.scenarios import base
class MistralScenario(base.Scenario):
"""Base class for Mistral scenarios with basic atomic actions."""
@base.atomic_action_timer("mistral.list_workbooks")
def _list_workbooks(self):
"""Gets list of existing workbooks."""
return self.clients("mistral").workbooks.list()
@base.atomic_action_timer("mistral.create_workbook")
def _create_workbook(self, definition):
"""Create a new workbook.
:param definition: workbook description in string
(yaml string) format
:returns: workbook object
"""
definition = yaml.safe_load(definition)
definition["name"] = self._generate_random_name(definition["name"])
definition = yaml.safe_dump(definition)
return self.clients("mistral").workbooks.create(definition)
@base.atomic_action_timer("mistral.delete_workbook")
def _delete_workbook(self, wb_name):
"""Delete the given workbook.
:param wb_name: the name of workbook that would be deleted.
"""
self.clients("mistral").workbooks.delete(wb_name)

View File

@ -0,0 +1,59 @@
# Copyright 2015: Mirantis Inc.
# 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.
from rally.benchmark.scenarios import base
from rally.benchmark import types as types
from rally.benchmark import validation
from rally import consts
from rally.plugins.openstack.scenarios.mistral import utils
class MistralWorkbooks(utils.MistralScenario):
"""Benchmark scenarios for Mistral workbook."""
@validation.required_clients("mistral")
@validation.required_openstack(users=True)
@validation.required_services(consts.Service.MISTRAL)
@base.scenario()
def list_workbooks(self):
"""Scenario test mistral workbook-list command.
This simple scenario tests the Mistral workbook-list
command by listing all the workbooks.
"""
self._list_workbooks()
@types.set(definition=types.FileType)
@validation.file_exists("definition")
@validation.required_parameters("definition")
@validation.required_clients("mistral")
@validation.required_openstack(users=True)
@validation.required_services(consts.Service.MISTRAL)
@base.scenario(context={"cleanup": ["mistral"]})
def create_workbook(self, definition, do_delete=False):
"""Scenario tests workbook creation and deletion.
This scenario is a very useful tool to measure the
"mistral workbook-create" and "mistral workbook-delete"
commands performance.
:param definition: string (yaml string) representation of given
file content (Mistral workbook definition)
:param do_delete: if False than it allows to check performance
in "create only" mode.
"""
wb = self._create_workbook(definition)
if do_delete:
self._delete_workbook(wb.name)

View File

@ -0,0 +1,58 @@
# Copyright (c) 2014 Red Hat, Inc.
#
# 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.
import random
from rally.benchmark.scenarios import base
from rally.benchmark import validation
from rally.plugins.openstack.scenarios.zaqar import utils as zutils
class ZaqarBasic(zutils.ZaqarScenario):
"""Benchmark scenarios for Zaqar."""
@validation.number("name_length", minval=10)
@base.scenario(context={"cleanup": ["zaqar"]})
def create_queue(self, name_length=10, **kwargs):
"""Create a Zaqar queue with a random name.
:param name_length: length of generated (random) part of name
:param kwargs: other optional parameters to create queues like
"metadata"
"""
self._queue_create(name_length=name_length, **kwargs)
@validation.number("name_length", minval=10)
@base.scenario(context={"cleanup": ["zaqar"]})
def producer_consumer(self, name_length=10,
min_msg_count=50, max_msg_count=200, **kwargs):
"""Serial message producer/consumer.
Creates a Zaqar queue with random name, sends a set of messages
and then retrieves an iterator containing those.
:param name_length: length of generated (random) part of name
:param min_msg_count: min number of messages to be posted
:param max_msg_count: max number of messages to be posted
:param kwargs: other optional parameters to create queues like
"metadata"
"""
queue = self._queue_create(name_length=name_length, **kwargs)
msg_count = random.randint(min_msg_count, max_msg_count)
messages = [{"body": {"id": idx}, "ttl": 360} for idx
in range(msg_count)]
self._messages_post(queue, messages, min_msg_count, max_msg_count)
self._messages_list(queue)
self._queue_delete(queue)

View File

@ -0,0 +1,62 @@
# Copyright (c) 2014 Red Hat, Inc.
#
# 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.
from rally.benchmark.scenarios import base
class ZaqarScenario(base.Scenario):
"""Base class for Zaqar scenarios with basic atomic actions."""
@base.atomic_action_timer("zaqar.create_queue")
def _queue_create(self, name_length=10, **kwargs):
"""Create a Zaqar queue with random name.
:param name_length: length of generated (random) part of name
:param kwargs: other optional parameters to create queues like
"metadata"
:returns: Zaqar queue instance
"""
name = self._generate_random_name(length=name_length)
return self.clients("zaqar").queue(name, **kwargs)
@base.atomic_action_timer("zaqar.delete_queue")
def _queue_delete(self, queue):
"""Removes a Zaqar queue.
:param queue: queue to remove
"""
queue.delete()
def _messages_post(self, queue, messages, min_msg_count, max_msg_count):
"""Post a list of messages to a given Zaqar queue.
:param queue: post the messages to queue
:param messages: messages to post
:param min_msg_count: minimum number of messages
:param max_msg_count: maximum number of messages
"""
with base.AtomicAction(self, "zaqar.post_between_%s_and_%s_messages" %
(min_msg_count, max_msg_count)):
queue.post(messages)
@base.atomic_action_timer("zaqar.list_messages")
def _messages_list(self, queue):
"""Gets messages from a given Zaqar queue.
:param queue: get messages from queue
:returns: messages iterator
"""
return queue.messages()

View File

@ -0,0 +1,97 @@
# 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.
import mock
from rally.plugins.openstack.scenarios.ceilometer import alarms
from tests.unit import test
class CeilometerAlarmsTestCase(test.TestCase):
def test_create_alarm(self):
scenario = alarms.CeilometerAlarms()
scenario._create_alarm = mock.MagicMock()
scenario.create_alarm("fake_meter_name",
"fake_threshold",
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
"fake_threshold",
{"fakearg": "f"})
def test_list_alarm(self):
scenario = alarms.CeilometerAlarms()
scenario._list_alarms = mock.MagicMock()
scenario.list_alarms()
scenario._list_alarms.assert_called_once_with()
def test_create_and_list_alarm(self):
fake_alarm = mock.MagicMock()
scenario = alarms.CeilometerAlarms()
scenario._create_alarm = mock.MagicMock(return_value=fake_alarm)
scenario._list_alarms = mock.MagicMock()
scenario.create_and_list_alarm("fake_meter_name",
"fake_threshold",
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
"fake_threshold",
{"fakearg": "f"})
scenario._list_alarms.assert_called_once_with(fake_alarm.alarm_id)
def test_create_and_update_alarm(self):
fake_alram_dict_diff = {"description": "Changed Test Description"}
fake_alarm = mock.MagicMock()
scenario = alarms.CeilometerAlarms()
scenario._create_alarm = mock.MagicMock(return_value=fake_alarm)
scenario._update_alarm = mock.MagicMock()
scenario.create_and_update_alarm("fake_meter_name",
"fake_threshold",
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
"fake_threshold",
{"fakearg": "f"})
scenario._update_alarm.assert_called_once_with(fake_alarm.alarm_id,
fake_alram_dict_diff)
def test_create_and_delete_alarm(self):
fake_alarm = mock.MagicMock()
scenario = alarms.CeilometerAlarms()
scenario._create_alarm = mock.MagicMock(return_value=fake_alarm)
scenario._delete_alarm = mock.MagicMock()
scenario.create_and_delete_alarm("fake_meter_name",
"fake_threshold",
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
"fake_threshold",
{"fakearg": "f"})
scenario._delete_alarm.assert_called_once_with(fake_alarm.alarm_id)
def test_create_and_get_alarm_history(self):
alarm = mock.Mock(alarm_id="foo_id")
scenario = alarms.CeilometerAlarms()
scenario._create_alarm = mock.MagicMock(return_value=alarm)
scenario._get_alarm_state = mock.MagicMock()
scenario._get_alarm_history = mock.MagicMock()
scenario._set_alarm_state = mock.MagicMock()
scenario.create_alarm_and_get_history(
"meter_name", "threshold", "state", 60, fakearg="f")
scenario._create_alarm.assert_called_once_with(
"meter_name", "threshold", {"fakearg": "f"})
scenario._get_alarm_state.assert_called_once_with("foo_id")
scenario._get_alarm_history.assert_called_once_with("foo_id")
scenario._set_alarm_state.assert_called_once_with(alarm, "state", 60)

View File

@ -0,0 +1,26 @@
# 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.
import mock
from rally.plugins.openstack.scenarios.ceilometer import meters
from tests.unit import test
class CeilometerMetersTestCase(test.TestCase):
def test_list_meters(self):
scenario = meters.CeilometerMeters()
scenario._list_meters = mock.MagicMock()
scenario.list_meters()
scenario._list_meters.assert_called_once_with()

View File

@ -0,0 +1,112 @@
# 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.
import json
import mock
from rally.plugins.openstack.scenarios.ceilometer import queries
from tests.unit import test
class CeilometerQueriesTestCase(test.TestCase):
def test_create_and_query_alarms(self):
scenario = queries.CeilometerQueries()
scenario._create_alarm = mock.MagicMock()
scenario._query_alarms = mock.MagicMock()
scenario.create_and_query_alarms("fake_meter_name",
100, "fake_filter",
"fake_orderby_attribute", 10,
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
100, {"fakearg": "f"})
scenario._query_alarms.assert_called_once_with(
json.dumps("fake_filter"), "fake_orderby_attribute", 10)
def test_create_and_query_alarms_no_filter(self):
scenario = queries.CeilometerQueries()
scenario._create_alarm = mock.MagicMock()
scenario._query_alarms = mock.MagicMock()
scenario.create_and_query_alarms("fake_meter_name",
100, None,
"fake_orderby_attribute", 10,
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name",
100, {"fakearg": "f"})
scenario._query_alarms.assert_called_once_with(
None, "fake_orderby_attribute", 10)
def test_create_and_query_alarm_history(self):
fake_alarm = mock.MagicMock()
fake_alarm.alarm_id = "fake_alarm_id"
scenario = queries.CeilometerQueries()
scenario._create_alarm = mock.MagicMock(return_value=fake_alarm)
scenario._query_alarm_history = mock.MagicMock()
fake_filter = json.dumps({"=": {"alarm_id": fake_alarm.alarm_id}})
scenario.create_and_query_alarm_history("fake_meter_name", 100,
"fake_orderby_attribute", 10,
fakearg="f")
scenario._create_alarm.assert_called_once_with("fake_meter_name", 100,
{"fakearg": "f"})
scenario._query_alarm_history.assert_called_once_with(
fake_filter, "fake_orderby_attribute", 10)
def test_create_and_query_samples(self):
scenario = queries.CeilometerQueries()
scenario._create_sample = mock.MagicMock()
scenario._query_samples = mock.MagicMock()
scenario.create_and_query_samples("fake_counter_name",
"fake_counter_type",
"fake_counter_unit",
"fake_counter_volume",
"fake_resource_id",
"fake_filter",
"fake_orderby_attribute",
10,
fakearg="f")
scenario._create_sample.assert_called_once_with("fake_counter_name",
"fake_counter_type",
"fake_counter_unit",
"fake_counter_volume",
"fake_resource_id",
fakearg="f")
scenario._query_samples.assert_called_once_with(
json.dumps("fake_filter"), "fake_orderby_attribute", 10)
def test_create_and_query_samples_no_filter(self):
scenario = queries.CeilometerQueries()
scenario._create_sample = mock.MagicMock()
scenario._query_samples = mock.MagicMock()
scenario.create_and_query_samples("fake_counter_name",
"fake_counter_type",
"fake_counter_unit",
"fake_counter_volume",
"fake_resource_id",
None,
"fake_orderby_attribute",
10,
fakearg="f")
scenario._create_sample.assert_called_once_with("fake_counter_name",
"fake_counter_type",
"fake_counter_unit",
"fake_counter_volume",
"fake_resource_id",
fakearg="f")
scenario._query_samples.assert_called_once_with(
None, "fake_orderby_attribute", 10)

View File

@ -0,0 +1,47 @@
# 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.
import mock
from rally import exceptions
from rally.plugins.openstack.scenarios.ceilometer import resources
from tests.unit import test
class CeilometerResourcesTestCase(test.TestCase):
def test_list_resources(self):
scenario = resources.CeilometerResource()
scenario._list_resources = mock.MagicMock()
scenario.list_resources()
scenario._list_resources.assert_called_once_with()
def test_get_tenant_resources(self):
scenario = resources.CeilometerResource()
resource_list = ["id1", "id2", "id3", "id4"]
context = {"user": {"tenant_id": "fake"},
"tenant": {"id": "fake", "resources": resource_list}}
scenario.context = context
scenario._get_resource = mock.MagicMock()
scenario.get_tenant_resources()
for resource_id in resource_list:
scenario._get_resource.assert_any_call(resource_id)
def test_get_tenant_resources_with_exception(self):
scenario = resources.CeilometerResource()
resource_list = []
context = {"user": {"tenant_id": "fake"},
"tenant": {"id": "fake", "resources": resource_list}}
scenario.context = context
self.assertRaises(exceptions.NotFoundException,
scenario.get_tenant_resources)

View File

@ -0,0 +1,26 @@
# 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.
import mock
from rally.plugins.openstack.scenarios.ceilometer import samples
from tests.unit import test
class CeilometerSamplesTestCase(test.TestCase):
def test_list_samples(self):
scenario = samples.CeilometerSamples()
scenario._list_samples = mock.MagicMock()
scenario.list_samples()
scenario._list_samples.assert_called_once_with()

View File

@ -0,0 +1,30 @@
# 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.
import mock
from rally.plugins.openstack.scenarios.ceilometer import stats
from tests.unit import test
class CeilometerStatsTestCase(test.TestCase):
def test_create_meter_and_get_stats(self):
fake_meter = mock.MagicMock()
kwargs = mock.MagicMock()
scenario = stats.CeilometerStats()
scenario._create_meter = mock.MagicMock(return_value=fake_meter)
scenario._get_stats = mock.MagicMock()
scenario.create_meter_and_get_stats(**kwargs)
scenario._create_meter.assert_called_once_with(**kwargs)
scenario._get_stats.assert_called_once_with(fake_meter.counter_name)

View File

@ -0,0 +1,170 @@
# 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.
import mock
from oslotest import mockpatch
from rally.plugins.openstack.scenarios.ceilometer import utils
from tests.unit import fakes
from tests.unit import test
BM_UTILS = "rally.benchmark.utils"
CEILOMETER_UTILS = "rally.plugins.openstack.scenarios.ceilometer.utils"
class CeilometerScenarioTestCase(test.TestCase):
def setUp(self):
super(CeilometerScenarioTestCase, self).setUp()
self.scenario = utils.CeilometerScenario()
self.scenario.clients = mock.MagicMock(
return_value=fakes.FakeCeilometerClient())
self.res_is = mockpatch.Patch(BM_UTILS + ".resource_is")
self.get_fm = mockpatch.Patch(BM_UTILS + ".get_from_manager")
self.wait_for = mockpatch.Patch(CEILOMETER_UTILS +
".bench_utils.wait_for")
self.useFixture(self.wait_for)
self.useFixture(self.res_is)
self.useFixture(self.get_fm)
self.gfm = self.get_fm.mock
def test__list_alarms(self):
alarm1_id = "fake_alarm1_id"
alarm2_id = "fake_alarm2_id"
alarm1 = self.scenario._create_alarm("fake_alarm1", 100,
{"alarm_id": alarm1_id})
alarm2 = self.scenario._create_alarm("fake_alarm2", 100,
{"alarm_id": alarm2_id})
result_by_id = self.scenario._list_alarms(alarm1_id)
self.assertEqual([alarm1], result_by_id)
result_no_args = self.scenario._list_alarms()
self.assertEqual(set(result_no_args), set([alarm1, alarm2]))
def test__create_alarm(self):
"""Test _create_alarm returns alarm."""
fake_alarm_dict = {"alarm_id": "fake-alarm-id"}
created_alarm = self.scenario._create_alarm("fake-meter-name", 100,
fake_alarm_dict)
self.assertEqual(created_alarm.alarm_id, "fake-alarm-id")
def test__delete_alarms(self):
"""Test if call to alarms.delete is made to ensure alarm is deleted."""
# pre-populate alarm for this test scenario
fake_alarm_dict = {"alarm_id": "fake-alarm-id"}
fake_alarm = self.scenario._create_alarm("fake-meter-name", 100,
fake_alarm_dict)
self.scenario._delete_alarm(fake_alarm.alarm_id)
self.assertEqual(fake_alarm.status, "DELETED")
def test__update_alarms(self):
"""Test if call to alarms.update is made to ensure alarm is updated."""
# pre-populate alarm for this test scenario
fake_alarm_dict = {"alarm_id": "fake-alarm-id"}
fake_alarm = self.scenario._create_alarm("fake-meter-name", 100,
fake_alarm_dict)
fake_alarm_dict_diff = {"description": "Changed Test Description"}
self.scenario._update_alarm(fake_alarm.alarm_id, fake_alarm_dict_diff)
self.assertEqual(fake_alarm.description, "Changed Test Description")
def test__get_alarm_history(self):
fake_history = self.scenario._get_alarm_history("fake-alarm")
self.assertEqual(fake_history, ["fake-alarm-history"])
def test__get_alarm_state(self):
fake_alarm_dict = {"alarm_id": "alarm-id", "state": "alarm-state"}
fake_alarm = self.scenario._create_alarm("fake-meter-name", 100,
fake_alarm_dict)
fake_state = self.scenario._get_alarm_state(fake_alarm.alarm_id)
self.assertEqual(fake_state, "alarm-state")
@mock.patch(CEILOMETER_UTILS + ".CeilometerScenario.clients")
def test__set_alarm_state(self, mock_clients):
alarm = mock.Mock()
mock_clients("ceilometer").alarms.create.return_value = alarm
return_alarm = self.scenario._set_alarm_state(alarm, "ok", 100)
self.wait_for.mock.assert_called_once_with(
alarm,
is_ready=self.res_is.mock(),
update_resource=self.gfm(),
timeout=100, check_interval=1)
self.res_is.mock.assert_has_calls([mock.call("ok")])
self.assertEqual(self.wait_for.mock(), return_alarm)
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"ceilometer.set_alarm_state")
def test__list_meters(self):
"""Test _list_meters."""
fake_meters = self.scenario._list_meters()
self.assertEqual(fake_meters, ["fake-meter"])
def test__list_resources(self):
"""Test _list_resources."""
fake_resources = self.scenario._list_resources()
self.assertEqual(fake_resources, ["fake-resource"])
def test__list_samples(self):
"""Test _list_samples."""
fake_samples = self.scenario._list_samples()
self.assertEqual(fake_samples, ["fake-samples"])
def test__get_resource(self):
fake_resource_info = self.scenario._get_resource("fake-resource-id")
self.assertEqual(fake_resource_info, ["fake-resource-info"])
def test__get_stats(self):
"""Test _get_stats function."""
fake_statistics = self.scenario._get_stats("fake-meter")
self.assertEqual(fake_statistics, ["fake-meter-statistics"])
def test__create_meter(self):
"""Test _create_meter returns meter."""
self.scenario._generate_random_name = mock.MagicMock(
return_value="fake-counter-name")
created_meter = self.scenario._create_meter()
self.assertEqual(created_meter.counter_name, "fake-counter-name")
def test__query_alarms(self):
expected_result = ["fake-query-result"]
query_result = self.scenario._query_alarms("fake-filter",
"fake-orderby-attribute",
10)
self.assertEqual(query_result, expected_result)
def test__query_alarm_history(self):
expected_result = ["fake-query-result"]
query_result = self.scenario._query_alarm_history(
"fake-filter", "fake-orderby-attribute", 10)
self.assertEqual(query_result, expected_result)
def test__query_samples(self):
expected_result = ["fake-query-result"]
query_result = self.scenario._query_samples("fake-filter",
"fake-orderby-attribute",
10)
self.assertEqual(query_result, expected_result)
def test__create_sample(self):
"""Test _create_sample returns sample."""
self.scenario._generate_random_name = mock.MagicMock(
return_value="test-counter-name")
created_sample = self.scenario._create_sample("test-counter-name",
"fake-counter-type",
"fake-counter-unit",
"fake-counter-volume",
"fake-resource-id")
self.assertEqual(created_sample[0].counter_name, "test-counter-name")

View File

@ -0,0 +1,130 @@
# Copyright 2014: Mirantis Inc.
# 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.
import mock
from rally.plugins.openstack.scenarios.heat import stacks
from tests.unit import test
HEAT_STACKS = "rally.plugins.openstack.scenarios.heat.stacks.HeatStacks"
class HeatStacksTestCase(test.TestCase):
def setUp(self):
super(HeatStacksTestCase, self).setUp()
self.default_template = "heat_template_version: 2013-05-23"
@mock.patch(HEAT_STACKS + "._generate_random_name")
@mock.patch(HEAT_STACKS + "._list_stacks")
@mock.patch(HEAT_STACKS + "._create_stack")
def test_create_and_list_stack(self, mock_create, mock_list,
mock_random_name):
heat_scenario = stacks.HeatStacks()
mock_random_name.return_value = "test-rally-stack"
heat_scenario.create_and_list_stack(
template_path=self.default_template)
mock_create.assert_called_once_with(self.default_template)
mock_list.assert_called_once_with()
@mock.patch(HEAT_STACKS + ".clients")
@mock.patch(HEAT_STACKS + "._list_stacks")
def test_list_stack_and_resources(self, mock_list_stack, mock_clients):
stack = mock.Mock()
mock_list_stack.return_value = [stack]
heat_scenario = stacks.HeatStacks()
heat_scenario.list_stacks_and_resources()
mock_clients("heat").resources.list.assert_called_once_with(stack.id)
self._test_atomic_action_timer(
heat_scenario.atomic_actions(), "heat.list_resources_of_1_stacks")
@mock.patch(HEAT_STACKS + ".clients")
@mock.patch(HEAT_STACKS + "._list_stacks")
def test_list_stack_and_events(self, mock_list_stack, mock_clients):
stack = mock.Mock()
mock_list_stack.return_value = [stack]
heat_scenario = stacks.HeatStacks()
heat_scenario.list_stacks_and_events()
mock_clients("heat").events.list.assert_called_once_with(stack.id)
self._test_atomic_action_timer(
heat_scenario.atomic_actions(), "heat.list_events_of_1_stacks")
@mock.patch(HEAT_STACKS + "._generate_random_name")
@mock.patch(HEAT_STACKS + "._delete_stack")
@mock.patch(HEAT_STACKS + "._create_stack")
def test_create_and_delete_stack(self, mock_create, mock_delete,
mock_random_name):
heat_scenario = stacks.HeatStacks()
fake_stack = object()
mock_create.return_value = fake_stack
mock_random_name.return_value = "test-rally-stack"
heat_scenario.create_and_delete_stack(
template_path=self.default_template)
mock_create.assert_called_once_with(self.default_template)
mock_delete.assert_called_once_with(fake_stack)
@mock.patch(HEAT_STACKS + "._delete_stack")
@mock.patch(HEAT_STACKS + "._check_stack")
@mock.patch(HEAT_STACKS + "._create_stack")
def test_create_check_delete_stack(self, mock_create, mock_check,
mock_delete):
heat_scenario = stacks.HeatStacks()
mock_create.return_value = "fake_stack_create_check_delete"
heat_scenario.create_check_delete_stack(
template_path=self.default_template)
mock_create.assert_called_once_with(self.default_template)
mock_check.assert_called_once_with("fake_stack_create_check_delete")
mock_delete.assert_called_once_with("fake_stack_create_check_delete")
@mock.patch(HEAT_STACKS + "._generate_random_name")
@mock.patch(HEAT_STACKS + "._delete_stack")
@mock.patch(HEAT_STACKS + "._update_stack")
@mock.patch(HEAT_STACKS + "._create_stack")
def test_create_update_delete_stack(self, mock_create, mock_update,
mock_delete, mock_random_name):
heat_scenario = stacks.HeatStacks()
fake_stack = object()
mock_create.return_value = fake_stack
mock_random_name.return_value = "test-rally-stack"
heat_scenario.create_update_delete_stack(
template_path=self.default_template,
updated_template_path=self.default_template)
mock_create.assert_called_once_with(self.default_template)
mock_update.assert_called_once_with(fake_stack, self.default_template)
mock_delete.assert_called_once_with(fake_stack)
@mock.patch(HEAT_STACKS + "._delete_stack")
@mock.patch(HEAT_STACKS + "._resume_stack")
@mock.patch(HEAT_STACKS + "._suspend_stack")
@mock.patch(HEAT_STACKS + "._create_stack")
def test_create_suspend_resume_delete_stack(self,
mock_create,
mock_suspend,
mock_resume,
mock_delete):
heat_scenario = stacks.HeatStacks()
mock_create.return_value = "fake_stack_create_suspend_resume_delete"
heat_scenario.create_suspend_resume_delete_stack(
template_path=self.default_template)
mock_create.assert_called_once_with(self.default_template)
mock_suspend.assert_called_once_with(
"fake_stack_create_suspend_resume_delete")
mock_resume.assert_called_once_with(
"fake_stack_create_suspend_resume_delete")
mock_delete.assert_called_once_with(
"fake_stack_create_suspend_resume_delete")

View File

@ -0,0 +1,185 @@
# Copyright 2014: Mirantis Inc.
# 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.
import mock
from oslotest import mockpatch
from rally import exceptions
from rally.plugins.openstack.scenarios.heat import utils
from tests.unit import test
BM_UTILS = "rally.benchmark.utils"
HEAT_UTILS = "rally.plugins.openstack.scenarios.heat.utils"
CONF = utils.CONF
class HeatScenarioTestCase(test.TestCase):
def setUp(self):
super(HeatScenarioTestCase, self).setUp()
self.stack = mock.Mock()
self.res_is = mockpatch.Patch(BM_UTILS + ".resource_is")
self.get_fm = mockpatch.Patch(BM_UTILS + ".get_from_manager")
self.wait_for = mockpatch.Patch(HEAT_UTILS + ".bench_utils.wait_for")
self.wait_for_delete = mockpatch.Patch(
HEAT_UTILS + ".bench_utils.wait_for_delete")
self.useFixture(self.wait_for)
self.useFixture(self.wait_for_delete)
self.useFixture(self.res_is)
self.useFixture(self.get_fm)
self.gfm = self.get_fm.mock
self.useFixture(mockpatch.Patch("time.sleep"))
self.scenario = utils.HeatScenario()
self.default_template = "heat_template_version: 2013-05-23"
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_list_stacks(self, mock_clients):
stacks_list = []
mock_clients("heat").stacks.list.return_value = stacks_list
scenario = utils.HeatScenario()
return_stacks_list = scenario._list_stacks()
self.assertEqual(stacks_list, return_stacks_list)
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.list_stacks")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_create_stack(self, mock_clients):
mock_clients("heat").stacks.create.return_value = {
"stack": {"id": "test_id"}
}
mock_clients("heat").stacks.get.return_value = self.stack
scenario = utils.HeatScenario()
return_stack = scenario._create_stack(self.default_template)
self.wait_for.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
is_ready=self.res_is.mock(),
check_interval=CONF.benchmark.heat_stack_create_poll_interval,
timeout=CONF.benchmark.heat_stack_create_timeout)
self.res_is.mock.assert_has_calls([mock.call("CREATE_COMPLETE")])
self.assertEqual(self.wait_for.mock(), return_stack)
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.create_stack")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_update_stack(self, mock_clients):
mock_clients("heat").stacks.update.return_value = None
scenario = utils.HeatScenario()
scenario._update_stack(self.stack, self.default_template)
self.wait_for.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
is_ready=self.res_is.mock(),
check_interval=CONF.benchmark.heat_stack_update_poll_interval,
timeout=CONF.benchmark.heat_stack_update_timeout)
self.res_is.mock.assert_has_calls([mock.call("UPDATE_COMPLETE")])
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.update_stack")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_check_stack(self, mock_clients):
scenario = utils.HeatScenario()
scenario._check_stack(self.stack)
mock_clients("heat").actions.check.assert_called_once_with(
self.stack.id)
self.wait_for.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
is_ready=self.res_is.mock(),
check_interval=CONF.benchmark.heat_stack_check_poll_interval,
timeout=CONF.benchmark.heat_stack_check_timeout)
self.res_is.mock.assert_has_calls([mock.call("CHECK_COMPLETE")])
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.check_stack")
def test_delete_stack(self):
scenario = utils.HeatScenario()
scenario._delete_stack(self.stack)
self.stack.delete.assert_called_once_with()
self.wait_for_delete.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
check_interval=CONF.benchmark.heat_stack_delete_poll_interval,
timeout=CONF.benchmark.heat_stack_delete_timeout)
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.delete_stack")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_suspend_stack(self, mock_clients):
scenario = utils.HeatScenario()
scenario._suspend_stack(self.stack)
mock_clients("heat").actions.suspend.assert_called_once_with(
self.stack.id)
self.wait_for.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
is_ready=self.res_is.mock(),
check_interval=CONF.benchmark.heat_stack_suspend_poll_interval,
timeout=CONF.benchmark.heat_stack_suspend_timeout)
self.res_is.mock.assert_has_calls([mock.call("SUSPEND_COMPLETE")])
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.suspend_stack")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_resume_stack(self, mock_clients):
scenario = utils.HeatScenario()
scenario._resume_stack(self.stack)
mock_clients("heat").actions.resume.assert_called_once_with(
self.stack.id)
self.wait_for.mock.assert_called_once_with(
self.stack,
update_resource=self.gfm(),
is_ready=self.res_is.mock(),
check_interval=CONF.benchmark.heat_stack_resume_poll_interval,
timeout=CONF.benchmark.heat_stack_resume_timeout)
self.res_is.mock.assert_has_calls([mock.call("RESUME_COMPLETE")])
self._test_atomic_action_timer(scenario.atomic_actions(),
"heat.resume_stack")
class HeatScenarioNegativeTestCase(test.TestCase):
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_failed_create_stack(self, mock_clients):
mock_clients("heat").stacks.create.return_value = {
"stack": {"id": "test_id"}
}
stack = mock.Mock()
resource = mock.Mock()
resource.stack_status = "CREATE_FAILED"
stack.manager.get.return_value = resource
mock_clients("heat").stacks.get.return_value = stack
scenario = utils.HeatScenario()
try:
ex = self.assertRaises(exceptions.GetResourceErrorStatus,
scenario._create_stack, "stack_name")
self.assertIn("has CREATE_FAILED status", str(ex))
except exceptions.TimeoutException:
raise self.fail("Unrecognized error status")
@mock.patch(HEAT_UTILS + ".HeatScenario.clients")
def test_failed_update_stack(self, mock_clients):
stack = mock.Mock()
resource = mock.Mock()
resource.stack_status = "UPDATE_FAILED"
stack.manager.get.return_value = resource
mock_clients("heat").stacks.get.return_value = stack
scenario = utils.HeatScenario()
try:
ex = self.assertRaises(exceptions.GetResourceErrorStatus,
scenario._update_stack, stack,
"heat_template_version: 2013-05-23")
self.assertIn("has UPDATE_FAILED status", str(ex))
except exceptions.TimeoutException:
raise self.fail("Unrecognized error status")

View File

@ -0,0 +1,62 @@
# Copyright 2015: Mirantis Inc.
# 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.
import mock
from rally.plugins.openstack.scenarios.mistral import utils
from tests.unit import test
MISTRAL_UTILS = "rally.plugins.openstack.scenarios.mistral.utils"
class MistralScenarioTestCase(test.TestCase):
def _test_atomic_action_timer(self, atomic_actions, name):
action_duration = atomic_actions.get(name)
self.assertIsNotNone(action_duration)
self.assertIsInstance(action_duration, float)
@mock.patch(MISTRAL_UTILS + ".MistralScenario.clients")
def test_list_workbooks(self, mock_clients):
wbs_list = []
mock_clients("mistral").workbooks.list.return_value = wbs_list
scenario = utils.MistralScenario()
return_wbs_list = scenario._list_workbooks()
self.assertEqual(wbs_list, return_wbs_list)
self._test_atomic_action_timer(scenario.atomic_actions(),
"mistral.list_workbooks")
@mock.patch(MISTRAL_UTILS + ".MistralScenario.clients")
def test_create_workbook(self, mock_clients):
definition = "version: \"2.0\"\nname: wb"
mock_clients("mistral").workbooks.create.return_value = "wb"
scenario = utils.MistralScenario()
wb = scenario._create_workbook(definition)
self.assertEqual("wb", wb)
self._test_atomic_action_timer(scenario.atomic_actions(),
"mistral.create_workbook")
@mock.patch(MISTRAL_UTILS + ".MistralScenario.clients")
def test_delete_workbook(self, mock_clients):
wb = mock.Mock()
wb.name = "wb"
mock_clients("mistral").workbooks.delete.return_value = "ok"
scenario = utils.MistralScenario()
scenario._delete_workbook(wb.name)
mock_clients("mistral").workbooks.delete.assert_called_once_with(
wb.name
)
self._test_atomic_action_timer(scenario.atomic_actions(),
"mistral.delete_workbook")

View File

@ -0,0 +1,55 @@
# Copyright 2015: Mirantis Inc.
# 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.
import mock
from rally.plugins.openstack.scenarios.mistral import workbooks
from tests.unit import test
MISTRAL_WBS = ("rally.plugins.openstack.scenarios."
"mistral.workbooks.MistralWorkbooks")
class MistralWorkbooksTestCase(test.TestCase):
@mock.patch(MISTRAL_WBS + "._list_workbooks")
def test_list_workbooks(self, mock_list):
mistral_scenario = workbooks.MistralWorkbooks()
mistral_scenario.list_workbooks()
mock_list.assert_called_once_with()
@mock.patch(MISTRAL_WBS + "._create_workbook")
def test_create_workbook(self, mock_create):
mistral_scenario = workbooks.MistralWorkbooks()
definition = "---\nversion: \"2.0\"\nname: wb"
fake_wb = mock.MagicMock()
fake_wb.name = "wb"
mock_create.return_value = fake_wb
mistral_scenario.create_workbook(definition)
self.assertEqual(1, mock_create.called)
@mock.patch(MISTRAL_WBS + "._delete_workbook")
@mock.patch(MISTRAL_WBS + "._create_workbook")
def test_create_delete_workbook(self, mock_create, mock_delete):
mistral_scenario = workbooks.MistralWorkbooks()
definition = "---\nversion: \"2.0\"\nname: wb"
fake_wb = mock.MagicMock()
fake_wb.name = "wb"
mock_create.return_value = fake_wb
mistral_scenario.create_workbook(definition, do_delete=True)
self.assertEqual(1, mock_create.called)
mock_delete.assert_called_once_with(fake_wb.name)

View File

@ -0,0 +1,52 @@
# Copyright (c) 2014 Red Hat, Inc.
#
# 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.
import mock
from rally.plugins.openstack.scenarios.zaqar import basic
from tests.unit import test
BASE = "rally.plugins.openstack.scenarios.zaqar."
BASIC = BASE + "basic.ZaqarBasic."
class ZaqarBasicTestCase(test.TestCase):
@mock.patch(BASIC + "_generate_random_name", return_value="fizbit")
def test_create_queue(self, mock_gen_name):
scenario = basic.ZaqarBasic()
scenario._queue_create = mock.MagicMock()
scenario.create_queue(name_length=10)
scenario._queue_create.assert_called_once_with(name_length=10)
@mock.patch(BASIC + "_generate_random_name", return_value="kitkat")
def test_producer_consumer(self, mock_gen_name):
scenario = basic.ZaqarBasic()
messages = [{"body": {"id": idx}, "ttl": 360} for idx
in range(20)]
queue = mock.MagicMock()
scenario._queue_create = mock.MagicMock(return_value=queue)
scenario._messages_post = mock.MagicMock()
scenario._messages_list = mock.MagicMock()
scenario._queue_delete = mock.MagicMock()
scenario.producer_consumer(name_length=10, min_msg_count=20,
max_msg_count=20)
scenario._queue_create.assert_called_once_with(name_length=10)
scenario._messages_post.assert_called_once_with(queue, messages,
20, 20)
scenario._messages_list.assert_called_once_with(queue)
scenario._queue_delete.assert_called_once_with(queue)

View File

@ -0,0 +1,76 @@
# Copyright (c) 2014 Red Hat, Inc.
#
# 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.
import mock
from rally.plugins.openstack.scenarios.zaqar import utils
from tests.unit import fakes
from tests.unit import test
UTILS = "rally.plugins.openstack.scenarios.zaqar.utils."
class ZaqarScenarioTestCase(test.TestCase):
@mock.patch(UTILS + "ZaqarScenario._generate_random_name",
return_value="kitkat")
def test_queue_create(self, mock_gen_name):
queue = {}
fake_zaqar = fakes.FakeZaqarClient()
fake_zaqar.queue = mock.MagicMock(return_value=queue)
fake_clients = fakes.FakeClients()
fake_clients._zaqar = fake_zaqar
scenario = utils.ZaqarScenario(clients=fake_clients)
result = scenario._queue_create(name_length=10)
self.assertEqual(queue, result)
fake_zaqar.queue.assert_called_once_with("kitkat")
self._test_atomic_action_timer(scenario.atomic_actions(),
"zaqar.create_queue")
def test_queue_delete(self):
queue = fakes.FakeQueue()
queue.delete = mock.MagicMock()
scenario = utils.ZaqarScenario()
scenario._queue_delete(queue)
queue.delete.assert_called_once_with()
self._test_atomic_action_timer(scenario.atomic_actions(),
"zaqar.delete_queue")
def test_messages_post(self):
queue = fakes.FakeQueue()
queue.post = mock.MagicMock()
messages = [{"body": {"id": "one"}, "ttl": 100},
{"body": {"id": "two"}, "ttl": 120},
{"body": {"id": "three"}, "ttl": 140}]
min_msg_count = max_msg_count = len(messages)
scenario = utils.ZaqarScenario()
scenario._messages_post(queue, messages, min_msg_count, max_msg_count)
queue.post.assert_called_once_with(messages)
def test_messages_list(self):
queue = fakes.FakeQueue()
queue.messages = mock.MagicMock()
scenario = utils.ZaqarScenario()
scenario._messages_list(queue)
queue.messages.assert_called_once_with()
self._test_atomic_action_timer(scenario.atomic_actions(),
"zaqar.list_messages")