[Scenario] Split Scenarios - P5
Move under plugins/openstack: * Zaqar * Mistral * Heat * Ceilometer Implements: blueprint split-plugins Change-Id: I776e47f8bae3a2d1baebc51c213eb981a58d1975
This commit is contained in:
parent
787b35a650
commit
c0f73bffd1
138
rally/plugins/openstack/scenarios/ceilometer/alarms.py
Normal file
138
rally/plugins/openstack/scenarios/ceilometer/alarms.py
Normal 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)
|
29
rally/plugins/openstack/scenarios/ceilometer/meters.py
Normal file
29
rally/plugins/openstack/scenarios/ceilometer/meters.py
Normal 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()
|
97
rally/plugins/openstack/scenarios/ceilometer/queries.py
Normal file
97
rally/plugins/openstack/scenarios/ceilometer/queries.py
Normal 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)
|
50
rally/plugins/openstack/scenarios/ceilometer/resources.py
Normal file
50
rally/plugins/openstack/scenarios/ceilometer/resources.py
Normal 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)
|
32
rally/plugins/openstack/scenarios/ceilometer/samples.py
Normal file
32
rally/plugins/openstack/scenarios/ceilometer/samples.py
Normal 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()
|
36
rally/plugins/openstack/scenarios/ceilometer/stats.py
Normal file
36
rally/plugins/openstack/scenarios/ceilometer/stats.py
Normal 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)
|
232
rally/plugins/openstack/scenarios/ceilometer/utils.py
Normal file
232
rally/plugins/openstack/scenarios/ceilometer/utils.py
Normal 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)
|
0
rally/plugins/openstack/scenarios/heat/__init__.py
Normal file
0
rally/plugins/openstack/scenarios/heat/__init__.py
Normal file
141
rally/plugins/openstack/scenarios/heat/stacks.py
Normal file
141
rally/plugins/openstack/scenarios/heat/stacks.py
Normal 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)
|
214
rally/plugins/openstack/scenarios/heat/utils.py
Normal file
214
rally/plugins/openstack/scenarios/heat/utils.py
Normal 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)
|
49
rally/plugins/openstack/scenarios/mistral/utils.py
Normal file
49
rally/plugins/openstack/scenarios/mistral/utils.py
Normal 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)
|
59
rally/plugins/openstack/scenarios/mistral/workbooks.py
Normal file
59
rally/plugins/openstack/scenarios/mistral/workbooks.py
Normal 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)
|
0
rally/plugins/openstack/scenarios/zaqar/__init__.py
Normal file
0
rally/plugins/openstack/scenarios/zaqar/__init__.py
Normal file
58
rally/plugins/openstack/scenarios/zaqar/basic.py
Normal file
58
rally/plugins/openstack/scenarios/zaqar/basic.py
Normal 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)
|
62
rally/plugins/openstack/scenarios/zaqar/utils.py
Normal file
62
rally/plugins/openstack/scenarios/zaqar/utils.py
Normal 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()
|
@ -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)
|
@ -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()
|
@ -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)
|
@ -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)
|
@ -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()
|
@ -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)
|
170
tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py
Normal file
170
tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py
Normal 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")
|
130
tests/unit/plugins/openstack/scenarios/heat/test_stacks.py
Normal file
130
tests/unit/plugins/openstack/scenarios/heat/test_stacks.py
Normal 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")
|
185
tests/unit/plugins/openstack/scenarios/heat/test_utils.py
Normal file
185
tests/unit/plugins/openstack/scenarios/heat/test_utils.py
Normal 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")
|
62
tests/unit/plugins/openstack/scenarios/mistral/test_utils.py
Normal file
62
tests/unit/plugins/openstack/scenarios/mistral/test_utils.py
Normal 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")
|
@ -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)
|
52
tests/unit/plugins/openstack/scenarios/zaqar/test_basic.py
Normal file
52
tests/unit/plugins/openstack/scenarios/zaqar/test_basic.py
Normal 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)
|
76
tests/unit/plugins/openstack/scenarios/zaqar/test_utils.py
Normal file
76
tests/unit/plugins/openstack/scenarios/zaqar/test_utils.py
Normal 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")
|
Loading…
x
Reference in New Issue
Block a user